状态机的基本要素:输入、输出、状态。
状态机根据状态变化是否与输入条件有关分为两类:即Moore型状态机和Mealy型状态机。
Moore型状态机的状态变化仅和当前状态有关,而与输入条件无关;
Mealy型状态机的状态变化不仅和当前状态有关,还取决于当前的输入条件。
一段式状态机是把所有的逻辑都放在一个always块内,不易维护,状态复杂容易出错。
二段式状态机是把时序逻辑和组合逻辑分开,时序逻辑里进行当前状态和下一状态的切换,组合逻辑里是新各个输入、输出以及状态判断,相对容易维护,但是组合逻辑容易出现毛刺。
三段式状态机用时序逻辑去描述输出,解决毛刺问题,但是资源也耗费多一些【三段式状态机也可以用组合逻辑去描述输出】。模板代码如下:
//时序逻辑描述状态更新
always @ (posedge clk or negedge rst_n)
if(~rst_n)
current_state <= S1;
else
current_state <= next_state;
//组合逻辑描述状态转移
always @ (*) begin
next_state = x; //初始化
case(current_state)
S1:
if(...)
next_state = S2;
S2:
if(...)
next_state = S3;
...
endcase
end
//时序逻辑描述次态寄存器输出
always @ (posedge clk or negedge rst_n) begin
if(~rst_n) begin
out <= 2'b00;
end else begin
case(next_state)
S1:
out <= 2'b01;
S2:
out <= 2'b11;
default:
out <= 2'b11;
endcase
end
end
对于状态较多的设计,可以参考如下状态定义方式:
typedef enum reg [6:0] {S_IDLE,S_DATA,S_S0,S_S1,S_S2,....,S_ACK} STATE_FSM;
STATE_FSM current_state;
STATE_FSM next_state;
========================================================================
示例:
描述
某同步时序电路的状态转换图如下,→上表示“C/Y”,圆圈内为现态,→指向次态。
请使用D触发器和必要的逻辑门实现此同步时序电路,用Verilog语言描述。
module FSM(
input C ,
input clk ,
input rst_n,
output wire Y
);
parameter ST0 = 2'b00;
parameter ST1 = 2'b01;
parameter ST2 = 2'b10;
parameter ST3 = 2'b11;
reg[1:0] cur_state;
reg[1:0] next_state;
reg Y_r;
always@(posedge clk or negedge rst_n)
if(!rst_n)
cur_state <= ST0;
else
cur_state <= next_state;
always@(*)
case (cur_state)
ST0: next_state = C? ST1:ST0;
ST1: next_state = C? ST1:ST3;
ST2: next_state = C? ST2:ST0;
ST3: next_state = C? ST2:ST3;
endcase
always@(*)
case (cur_state)
ST0: Y_r = 1'b0;
ST1: Y_r = 1'b0;
ST2: Y_r = C? 1'b1:1'b0;
ST3: Y_r = 1'b1;
endcase
assign Y = Y_r;
endmodule
【题目来自牛客网】