zoukankan      html  css  js  c++  java
  • (转帖) 有限狀態機FSM coding style整理 (SOC) (Verilog)

    来源:http://www.codesoso.net/Record/101092_95120_21.html

    来源:http://www.cnblogs.com/oomusou/archive/2011/06/05/fsm_coding_style.html

    Moore FSM架构

    一般在写FSM时,会以Moore FSM为主,所以先讨论Moore。由上图可知,Moore FSM内部由3个block所构成:Next state logic,State register与Output logic。

    Next state logic:纯粹的组合逻辑,以整个module的input与目前的state为输入,目的在产生下一个state值存入state register。

    State register:由D-FF所构成,将Next state logic所产生的state存入register。

    Output logic:纯粹的组合逻辑,根据目前的state产生整个module的output。

    所以可以发现,整个Moore FSM事实上是由2块的组合逻辑与1块D-FF所构成,我们常听到所谓的一段式、二段式与三段式FSM,事实上就是由这3个block排列组合而成。

    Moore FSM各种coding style比较

     Moore FSM各种coding style比较

    为了要实际比较各种coding style,在此举一个简单的例子,若input w_i为连续2个clk为high,则output会在下1个clk产生周期为1 T的high pulse,timing diagram如下图所示。

    因此设计了Moore FSM,state diagram如上图所示,接下来要做的就是用各种coding style来实现这个Moore FSM。

    simple_fsm_moore_3_always_best.v / Verilog

     1 /* 
     2 (C) OOMusou 2011 http://oomusou.cnblogs.com
     3 
     4 Filename    : simple_fsm_moore_3_always_best.v
     5 Synthesizer : Quartus II 8.1
     6 Description : 3 always block for moore fsm (BEST)
     7 Release     : Jun.05,2011 1.0
     8 */
     9 
    10 module simple_fsm (
    11   clk,
    12   rst_n,
    13   w_i,
    14   z_o
    15 );
    16 
    17 input  clk;
    18 input  rst_n;
    19 input  w_i;
    20 output z_o;
    21 
    22 parameter IDLE = 2'b00;
    23 parameter S0   = 2'b01;
    24 parameter S1   = 2'b10;
    25 
    26 reg [1:0] curr_state;
    27 reg [1:0] next_state;
    28 reg z_o;
    29 
    30 // state reg
    31 always@(posedge clk or negedge rst_n)
    32   if (~rst_n) curr_state <= IDLE;
    33   else        curr_state <= next_state;
    34     
    35 // next state logic    
    36 always@(*)
    37   case (curr_state)
    38     IDLE    : if (w_i) next_state = S0;
    39               else     next_state = IDLE;
    40     S0      : if (w_i) next_state = S1;
    41               else     next_state = IDLE;
    42     S1      : if (w_i) next_state = S1;
    43               else     next_state = IDLE;
    44     default :          next_state = IDLE;
    45   endcase    
    46 
    47 // output logic
    48 always@(*)
    49   case (curr_state)
    50     IDLE    : z_o = 1'b0;
    51     S0      : z_o = 1'b0;
    52     S1      : z_o = 1'b1;
    53     default : z_o = 1'b0;
    54   endcase
    55   
    56 endmodule

    個always是一個推薦的寫法。

    Testbench

    simple_fsm_tb.v / Verilog

     1 /* 
     2 (C) OOMusou 2011 http://oomusou.cnblogs.com
     3 
     4 Filename : simple_fsm_tb.v
     5 Simulator : ModelSim SE 6.3e + Debussy 5.4 v9
     6 Description : testbench for FSM
     7 Release : Jun.05,2011 1.0
     8  */
     9 
    10  module simple_fsm_tb;
    11 
    12  reg clk = 1'b1;
    13  reg rst_n = 1'b1;
    14  reg w_i = 1'b0;
    15  wire z_o;
    16 
    17  // clk
    18  always #10 clk = ~clk;
    19 
    20  event after_rst;
    21 
    22  // rst_n
    23  initial begin
    24   #6; // 6ns
    25   rst_n = 1'b0;
    26   #30; // 36ns
    27   rst_n = 1'b1;
    28   ->after_rst; 
    29  end
    30 
    31  // w_i
    32  initial begin
    33   @(after_rst);
    34   repeat(2)@(posedge clk); // 60ns
    35   w_i <= 1'b1;
    36   @(posedge clk); // 80 ns
    37   w_i <= 1'b0;
    38   @(posedge clk); // 100 ns
    39   w_i <= 1'b1;
    40   repeat(2)@(posedge clk); // 140 ns
    41   w_i <= 1'b0;
    42   @(posedge clk); // 160 ns
    43   w_i <= 1'b1;
    44   repeat(3)@(posedge clk); // 220 ns
    45   w_i <= 1'b0;
    46 end
    47 
    48 initial begin
    49   $fsdbDumpfile("simple_fsm.fsdb");
    50   $fsdbDumpvars(0, simple_fsm_tb);
    51 end
    52 
    53 simple_fsm u_simple_fsm (
    54   .clk (clk),
    55   .rst_n (rst_n),
    56   .w_i (w_i),
    57   .z_o (z_o)
    58 );
    59 
    60 endmodule

     

     1 /* 
     2 (C) OOMusou 2011 http://oomusou.cnblogs.com
     3 
     4 Filename    : simple_fsm_moore_3_always_best.v
     5 Synthesizer : Quartus II 8.1
     6 Description : 3 always block for moore fsm (BEST)
     7 Release     : Jun.05,2011 1.0
     8 */
     9 
    10 module simple_fsm (
    11   clk,
    12   rst_n,
    13   w_i,
    14   z_o
    15 );
    16 
    17 input  clk;
    18 input  rst_n;
    19 input  w_i;
    20 output z_o;
    21 
    22 parameter IDLE = 2'b00;
    23 parameter S0   = 2'b01;
    24 parameter S1   = 2'b10;
    25 
    26 reg [1:0] curr_state;
    27 reg [1:0] next_state;
    28 reg z_o;
    29 
    30 // state reg
    31 always@(posedge clk or negedge rst_n)
    32   if (~rst_n) curr_state <= IDLE;
    33   else        curr_state <= next_state;
    34     
    35 // next state logic    
    36 always@(*)
    37   case (curr_state)
    38     IDLE    : if (w_i) next_state = S0;
    39               else     next_state = IDLE;
    40     S0      : if (w_i) next_state = S1;
    41               else     next_state = IDLE;
    42     S1      : if (w_i) next_state = S1;
    43               else     next_state = IDLE;
    44     default :          next_state = IDLE;
    45   endcase    
    46 
    47 // output logic
    48 always@(*)
    49   case (curr_state)
    50     IDLE    : z_o = 1'b0;
    51     S0      : z_o = 1'b0;
    52     S1      : z_o = 1'b1;
    53     default : z_o = 1'b0;
    54   endcase
    55   
    56 endmodule

    simple_fsm_moore_3_always_best.v / Verilog

     1 /* 
     2 (C) OOMusou 2011 http://oomusou.cnblogs.com
     3 
     4 Filename : simple_fsm_tb.v
     5 Simulator : ModelSim SE 6.3e + Debussy 5.4 v9
     6 Description : testbench for FSM
     7 Release : Jun.05,2011 1.0
     8  */
     9 
    10  module simple_fsm_tb;
    11 
    12  reg clk = 1'b1;
    13  reg rst_n = 1'b1;
    14  reg w_i = 1'b0;
    15  wire z_o;
    16 
    17  // clk
    18  always #10 clk = ~clk;
    19 
    20  event after_rst;
    21 
    22  // rst_n
    23  initial begin
    24   #6; // 6ns
    25   rst_n = 1'b0;
    26   #30; // 36ns
    27   rst_n = 1'b1;
    28   ->after_rst; 
    29  end
    30 
    31  // w_i
    32  initial begin
    33   @(after_rst);
    34   repeat(2)@(posedge clk); // 60ns
    35   w_i <= 1'b1;
    36   @(posedge clk); // 80 ns
    37   w_i <= 1'b0;
    38   @(posedge clk); // 100 ns
    39   w_i <= 1'b1;
    40   repeat(2)@(posedge clk); // 140 ns
    41   w_i <= 1'b0;
    42   @(posedge clk); // 160 ns
    43   w_i <= 1'b1;
    44   repeat(3)@(posedge clk); // 220 ns
    45   w_i <= 1'b0;
    46 end
    47 
    48 initial begin
    49   $fsdbDumpfile("simple_fsm.fsdb");
    50   $fsdbDumpvars(0, simple_fsm_tb);
    51 end
    52 
    53 simple_fsm u_simple_fsm (
    54   .clk (clk),
    55   .rst_n (rst_n),
    56   .w_i (w_i),
    57   .z_o (z_o)
    58 );
    59 
    60 endmodule
    Testbench

    1.使用3always (三段式)

    使用1个always描述state register,因为是D-FF且含clk,所以使用nonblocking。

    由于state register区块并不包含任何逻辑,所以不会因为不同FSM而有不同写法,不同FSM只会改变next state logic与output logic的写法。

    使用1个always描述output logic,因为是纯粹组合逻辑,所以使用blocking。

    根据Moore FSM架构图所示,output logic的结果只与目前state有关,所以只需用case对state做一次分类即可。

    使用3个always写法有几个优点:

    1.可忠实地反映出原本的Moore FSM硬件架构
    2.可轻易地将state diagram改用Verilog表示
    3.将Next state logic与output logic分开,可降低code的复杂度,便于日后维护。

    Mealy FSM架构

    谈完了Moore FSM,接下来谈Mealy FSM,与Moore FSM的差别只在于Moore FSM的output logic只由目前state决定,但是Mealy FSM可由目前state与input共同决定。

    将之前的例子用Mealy FSM重新改写,原本在Moore FSM下,若input w_i为连续2个clk为high,则output会在下1个clk产生周期为1 T的high pulse,若改用Mealy FSM,则output会提早1个clk出现,如下图所示。

    原本Moore FSM需要3个state,若改用Mealy FSM后,会只剩下2个state,接下来要用各种coding style来实现Mealy FSM。

    1.使用3always (三段式)

    simple_fsm_mealy_3_always_best.v / Verilog

    之前提到使用Mealy FSM会少Moore FSM 1个state,且output会早Moore FSM 1个clk,所以最后特别将output在敲一级delay 1个clk,这样Mealy FSM就会完全与Moore FSM一样。

    使用3个always写法有几个优点:

    1.可忠实地反映出原本的Mealy FSM硬件架构
    2.可轻易地将state diagram改用Verilog表示
    3.将Next state logic与output logic分开,可降低code的复杂度,便于日后维护

     1 /* 
     2 (C) OOMusou 2011 http://oomusou.cnblogs.com
     3 
     4 Filename    : simple_fsm_mealy_3_always_best.v
     5 Synthesizer : Quartus II 8.1
     6 Description : 3 always block for mealy fsm (BEST)
     7 Release     : Jun.05,2011 1.0
     8 */
     9 
    10 module simple_fsm (
    11   clk,
    12   rst_n,
    13   w_i,
    14   z_o
    15 );
    16 
    17 input  clk;
    18 input  rst_n;
    19 input  w_i;
    20 output z_o;
    21 
    22 parameter IDLE = 2'b00;
    23 parameter S0   = 2'b01;
    24 
    25 reg [1:0] curr_state;
    26 reg [1:0] next_state;
    27 reg z;
    28 reg z_o;
    29 
    30 // state reg
    31 always@(posedge clk or negedge rst_n)
    32   if (~rst_n) curr_state <= IDLE;
    33   else        curr_state <= next_state;
    34     
    35 // next state logic    
    36 always@(*)
    37   case (curr_state)
    38     IDLE    : if (w_i) next_state = S0;
    39               else     next_state = IDLE;
    40     S0      : if (w_i) next_state = S0;
    41               else     next_state = IDLE;
    42     default :          next_state = IDLE;
    43   endcase    
    44 
    45 // output logic
    46 always@(*)
    47   case (curr_state)
    48     IDLE    : if (w_i) z = 1'b0;
    49               else     z = 1'b0;      
    50     S0      : if (w_i) z = 1'b1;
    51               else     z = 1'b0;
    52     default :          z = 1'b0;
    53   endcase
    54 
    55 // mealy output to delay 1 clk for moore  
    56 always@(posedge clk or negedge rst_n)
    57   if (~rst_n) z_o <= 1'b0;
    58   else        z_o <= z;
    59     
    60 endmodule
    simple_fsm_mealy_3_always_best.v / Verilog

    Conclusion
    1.3个always与2个always (state register与next state logic合一)是两种推荐的写法,而且这两种写法无论要描述Moore FSM或者Mealy FSM都没问题,其他写法都不推荐,个人是比较喜欢2个always写法(state register + next state logic),因为这种写法最精简,各种需求都可描述,也不用担心是否要提前一个clk判断,最为直觉不易错。

    2.实务上不会特别拘泥使用Moore或者Mealy,只要符合需求即可,一般会以Moore FSM为正宗。

    3.实务上为了timing更好,会在Moore FSM的output logic多敲一级。

    4.Mealy会比Moore少1个state,且output会比Moore早1个clk。

    5.Moore与Mealy之间可以互换,只要在Mealy的output多敲一级即可。

  • 相关阅读:
    ASP.NET 表单验证 Part.1(理解表单验证)
    Silverlight 简介 Part.3(设计 Siverlight 页面)
    ASP.NET 成员资格 Part.3(LoginStatus、LoginView、PasswordRecovery)
    ASP.NET 网站部署 Part.1(安装IIS、复制文件部署网站)
    ASP.NET Dynamic Data Part.1(创建动态数据应用程序)
    ASP.NET 安全模型 Part.2(SSL)
    ASP.NET MVC Part.2(扩展基本的 MVC 应用程序)
    ASP.NET 网站部署 Part.2(使用 Web 部署)
    开发高级 Web 部件
    创建 Web 部件(WebPart 类、简单的 Web 部件)
  • 原文地址:https://www.cnblogs.com/zlh840/p/3460908.html
Copyright © 2011-2022 走看看