1 什么是有限状态机
有限状态机是由寄存器组和组合逻辑构成的硬件时序电路;
其状态(即由寄存器组的1和0的组合状态所构成的有限个状态),只能在同一时钟跳变沿的情况下,才能从一个状态转向另一个状态;
究竟转向哪一个状态,不但取决于各个输入值,还取决于当前的状态。
状态机可用于产生在时钟跳变沿时刻开关的复杂的控制逻辑,是数字逻辑的控制核心。
2 FSM的种类和不同点
3 设计举例
状态转换图三要素:
- 当前的状态
- 转移的条件
- 转移的结果
表示方法一:
module fsm (Clock, Reset, A, K2, K1);
input Clock, Reset, A; //定义时钟、复位和输入信号
output K2, K1; //定义输出控制信号的端口
reg K2, K1; //定义输出控制信号的寄存器
reg [1:0] state; //定义状态寄存器
parameter Idle = 2’b00;
parameter Start = 2’b01;
parameter Stop = 2’b10;
parameter Clear = 2’b11;
//定义状态变量参数值
always @(posedge Clock or negedge Reset)
if (!Reset) begin //定义复位后的初始状态和输出值
state <= Idle;
K2<=0;
K1<=0;
end
else
case (state)
Idle: begin
if (A) begin
state <= Start;
K1 <= 0;
end
else
state <= Idle;
end
Start: begin
if (!A)
state <= Stop;
else
state <= Start;
end
Stop: begin //符合条件进入新状态,否则留在原状态
if (A) begin
state <= Clear;
K2 <= 1;
end
else
state <= Stop;
end
Clear: begin
if (!A) begin
state <= Idle;
K2<=0; K1<=1;
end
else
state <= Clear;
end
endcase
endmodule
上述方法的输入、输出纠缠不清,表达得不太清楚。
在比较复杂的状态机设计过程中,我们往往把状态的变化与输出开关的控制分成两部分来考虑。
就像前面讲过的Mealy状态机输出部分的组合逻辑。
为了调试方便,还常常把每一个输出开关写成一个个独立的always组合块。在调试多输出状态机时,这样做比较容易发现问题和改正模块编写中出现的问题。说明如下:
表示方法二(⭐️):
module fsm (Clock, Reset, A, K2, K1);
input Clock, Reset, A;
output K2, K1;
reg K2, K1;
reg [3:0] state;
parameter Idle = 4’b1000,
Start = 4’b0100,
Stop = 4’b0010,
Clear = 4’b0001;
//--- 每一个时钟沿产生一次可能的状态变化---
always @(posedge Clock or negedge Reset) begin
if (!Reset)
state <= Idle;
else
state <= nextstate;
end
//------ 产生下一状态的组合逻辑 -------------------
always @(state or A) begin
case (state)
Idle: if (A) nextstate = Start;
else nextstate = Idle;
Start: if (!A) nextstate = Stop;
else nextstate = Start;
Stop: if (A) nextstate = Clear;
else nextstate = Stop;
Clear: if (!A) nextstate = Idle;
else nextstate = Clear;
default: nextstate =2'bxx;
endcase
end
//---- 产生输出K1的组合逻辑 --------------
always @(state or Reset or A) begin
if (!Reset)
K1=0;
else begin
if (state == Clear && !A) //从Clear转向 Idle
K1 = 1;
else
K1 = 0;
end
end
//--- 产生输出K2的组合逻辑 ---------------
always @(state or Reset or A ) begin
if (!Reset)
K2 = 0;
else begin
if (state == Stop && A) // 从Stop转向 Clear
K2 = 1;
else
K2 = 0;
end
end
endmodule