“本文主要分享了在Verilog设计过程中状态机的一些设计方法。
关于状态机
状态机本质是对具有逻辑顺序或时序顺序事件的一种描述方法,也就是说具有逻辑顺序和时序规律的事情都适用状态机描述。状态机的基本要素有三个:状态、输出和输入。
根据状态机的输出是否与输入条件有关,可将状态机分为:
摩尔(Moore)型和米里(Mealy)型。
摩尔型状态机:输出仅与当前状态有关,而与输入条件无关。
米里型状态机:输出不仅依赖于当前状态,还取决于输入条件。
状态机的逻辑通常用“case”语句或者“if-else”语句来描述,枚举当前状态和输入的所有可能组合,并为下一个状态和输出制定适当的值。
RTL级状态机描述常用语法:
wire、reg;
parameter,用于描述状态名称,增强代码可读性;
always,根据主时钟沿,完成同步时序的状态迁移;根据信号敏感表,完成组合逻辑输出。
case/endcase:其中default是可选的关键字,用于指明当所列的所有条件都不匹配时的操作;一般的FSM设计都会加上default关键字描述FSM所需的补集状态。
task/endtask。
几种状态机的描述方法
一段式FSM描述方法:一个always块里面,即描述状态转移,又描述状态的输入和输出。
两段式FSM描述方法:两个always块,一个采用同步时序描述状态转移;另一个模块采用组合逻辑判断状态转移条件,描述状态转移规律。
三段式FSM描述方法:第一个always模块采用同步时序描述状态转移;第二个采用组合逻辑判断状态转移条件,描述状态转移规律;第三个always模块使用同步时序电路,描述每个状态的输出。
一段式:
reg [2:0] Next_State;//下一个状态 parameter IDLE = 3‘b000; parameter S1 = 3’b001; parameter S2 = 3‘b010; parameter CLEAR = 3’b100;
//--------------------------------------------------------------------------------//------ 在一个always中包含状态、输入和输出。 always@(posedge clk or posedge rst) begin if(rst) begin Next_State 《= IDLE; out 《= 2‘b00; end else begin case(Next_State) IDLE : begin if(key_in == 1’b1) begin Next_State 《= S1; out 《= 2‘b01;
end else begin Next_State 《= IDLE; out 《= 2’b00; end end S1 : begin if(key_in == 1‘b1) begin Next_State 《= S2; out 《= 2’b10; end else begin Next_State 《= S1; out 《= 2‘b01;
end end S2 : begin if(key_in == 1’b1) begin Next_State 《= CLEAR; out 《= 2‘b11; end else begin Next_State 《= S2; out 《= 2’b10; end end CLEAR : begin if(key_in == 1‘b1) begin Next_State 《= IDLE; out 《= 2’b00;
end else begin Next_State 《= CLEAR; out 《= 2‘b11; end end endcase end end
两段式:
reg [2:0] Next_State;//下一个状态 reg [2:0] Current_State;//当前状态
parameter IDLE = 3’b000; parameter S1 = 3‘b001; parameter S2 = 3’b010; parameter CLEAR = 3‘b100;
//-------------------------------------------------------------------------------- always@(posedge clk or posedge rst) begin if(rst) Current_State 《= IDLE; else Current_State 《= Next_State; end always@(*)
// always@(rst or Current_State or key_in) begin case(Current_State) IDLE : begin idle_out;// out = 2’b00; if(key_in == 1‘b1) Next_State = S1; else Next_State = IDLE; end S1 : begin s1_out;// out = 2’b01; if(key_in == 1‘b1) Next_State = S2; else Next_State = S1; end S2 : begin s2_out;// out = 2’b10; if(key_in == 1‘b1) Next_State = CLEAR; else Next_State = S2; end CLEAR : begin clear_out;
// out = 2’b11; if(key_in == 1‘b1) Next_State = IDLE; else Next_State = CLEAR; end endcase end
//-------------------------------------------------------------------------------- task idle_out; out = 2’b00; endtask task s1_out; out = 2‘b01; endtask
task s2_out; out = 2’b10; endtask
task clear_out; out = 2‘b11; endtask
三段式:
//-------------------------------------------------------------------------------- reg [2:0] Next_State;//下一个状态 reg [2:0] Current_State;//当前状态 parameter IDLE = 3’b000; parameter S1 = 3‘b001; parameter S2 = 3’b010; parameter CLEAR = 3‘b100;
//-------------------------------------------------------------------------------- always@(posedge clk or posedge rst) begin if(rst) Current_State 《= IDLE; else Current_State 《= Next_State; end
//--------------------------------------------------------------------------------// always@(rst or Current_State or key_in) always@(*) begin case(Current_State) IDLE : begin if(key_in == 1’b1) Next_State = S1; else Next_State = IDLE; end S1 : begin if(key_in == 1‘b1) Next_State = S2; else Next_State = S1; end S2 : begin if(key_in == 1’b1) Next_State = CLEAR; else Next_State = S2; end CLEAR : begin if(key_in == 1‘b1) Next_State = IDLE; else Next_State = CLEAR; end endcase end
//-------------------------------------------------------------------------------- always@(posedge clk or posedge rst) begin if(rst) begin out 《= 2’b00; end else begin case(Next_State) IDLE : begin out 《= 2‘b00; end S1 : begin out 《= 2’b01; end S2 : begin out 《= 2‘b10; end CLEAR : begin out 《= 2’b11; end endcase end end
//--------------------------------------------------------------------------------
结论:
一段式状态机比较适合在状态较少的情况下使用,因为所有的状态、输入和输出都在一起,可能不是很适合阅读、理解、维护;
二段式状态机比一段式要容易理解,但是由于输出是组合逻辑,容易存在不稳定与毛刺隐患;
三段式状态机比一段式更容易理解,用时序逻辑代替组合逻辑消除了不稳定与毛刺的隐患,但是代码量会稍微多一点;
责任编辑:haq
全部0条评论
快来发表一下你的评论吧 !