Verilog设计过程中状态机的设计方法

描述

“本文主要分享了在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

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分