(轉帖) 有限狀態機FSM coding style整理 (SOC) (Verilog)

來源:http://www.codesoso.net/Record/101092_95120_21.htmlhtml

 

 

來源:http://www.cnblogs.com/oomusou/archive/2011/06/05/fsm_coding_style.html架構

Moore FSM架構ide

通常在寫FSM時,會以Moore FSM爲主,因此先討論Moore。由上圖可知,Moore FSM內部由3個block所構成:Next state logic,State register與Output logic。spa

Next state logic:純粹的組合邏輯,以整個module的input與目前的state爲輸入,目的在產生下一個state值存入state register。.net

State register:由D-FF所構成,將Next state logic所產生的state存入register。設計

Output logic:純粹的組合邏輯,根據目前的state產生整個module的output。code

因此能夠發現,整個Moore FSM事實上是由2塊的組合邏輯與1塊D-FF所構成,咱們常聽到所謂的一段式、二段式與三段式FSM,事實上就是由這3個block排列組合而成。htm

Moore FSM各類coding style比較blog

 Moore FSM各類coding style比較ip

爲了要實際比較各類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多敲一級便可。

相關文章
相關標籤/搜索