之前一直烦脑我写的代码好难维护,在网上看多了发现人家说三段状态机多么多么的好,我就马上去查什么是三段式状态机。发现我之前写的全是一段式代码,怪不得我老是没办法提高自己的水平。) R, Z# q( |5 y! i0 ]8 |; M
所以我在网上找到一些特别有用的二段和三段式写法不但是给自己看的也是为提高自己的技术的各位看的。0 I' f! B) Z) Z& N
" C- P: V. T. F% E; k: x8 \
: y6 B6 ?5 E7 [2 N) [ r7 x c8 SAbstract/ J. M& K# A* x5 b3 z1 ~
FSM在數位電路中非常重要,藉由FSM,可以讓數位電路也能循序地執行起演算法。本文將詳細討論各種FSM coding style的優缺點,並歸納出推薦的coding style。 Introduction
6 n: _; G3 v( t: A6 U0 J* C使用環境:Debussy 5.4 v9 + ModelSim SE 6.3e + Quartus II 8.1 本文將討論以下主題: 1.Moore FSM的架構 2.Moore FSM各種coding style比較 3.Mealy FSM架構 4.Mealy FSM各種coding style比較 5.實務上推薦的coding style 6.Conclusion 若要讓數位電路也能循序地執行演算法,最簡單的方式可以使用D-FF產生counter,根據counter的值去決定要執行不同的程式碼,如此也能達到使數位電路循序執行演算法的目的,不過這種方式僅適用於很簡單的演算法,在一般規模的演算法若使用counter方式,程式碼將不容易維護,所以實務上會使用FSM方式來實現演算法。 其實FSM方式也是利用counter來實現,所謂的counter,並不是只有counter = counter + 1才算是counter,FSM的state register就是廣義的counter,只是這種counter不是一直加1而已,而是有自己的遞增規則。FSM只是提供了一種較為高階與較容易維護的方式來實現演算法。 Moore FSM架構 http://images.cnblogs.com/cnblogs_com/oomusou/201106/201106052038383584.gif 一般在寫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比較 http://images.cnblogs.com/cnblogs_com/oomusou/201106/201106052038396027.gif 為了要實際比較各種coding style,在此舉一個簡單的例子,若input w_i為連續2個clk為high,則output會在下1個clk產生周期為1 T的high pulse,timing diagram如上圖所示。 http://images.cnblogs.com/cnblogs_com/oomusou/201106/201106062055393332.gif 因此設計了Moore FSM,state diagram如上圖所示,接下來要做的就是用各種coding style來實現這個Moore FSM。 1.使用3個always (三段式) http://images.cnblogs.com/cnblogs_com/oomusou/201106/201106052154153519.gif simple_fsm_moore_3_always_best.v / Verilog [url=]http://common.cnblogs.com/images/copycode.gif[/url]( q+ v6 r9 X5 n1 K
1 /* 7 d# O$ ^2 o( b |0 Q
2 (C) OOMusou 2011 http://oomusou.cnblogs.com4 u) q/ t- P4 a# Q1 C/ l
3 , P9 S! h8 S# t6 }' \
4 Filename : simple_fsm_moore_3_always_best.v5 k+ h5 z7 x6 i- a U; s
5 Synthesizer : Quartus II 8.1
% [& Q g5 o& Y' X3 h4 O; ^+ m 6 Description : 3 always block for moore fsm (BEST)& k+ H# [2 H+ \) e f1 V* W
7 Release : Jun.05,2011 1.07 j" `% i4 B' F$ C( i& ~) c
8 */0 i2 E# r |7 F, y4 ?
9 & s/ @% u: G7 ?$ T* `1 W- q. z
10 module simple_fsm (& \2 ]2 b9 c3 A3 E3 B6 d
11 clk,
& p6 p5 k) U2 F( t% W12 rst_n,
! M P; q% r, {/ }13 w_i,7 a- T. C/ X& t( c
14 z_o
6 s6 L, J8 }6 P/ _' z15 );8 m; J2 ^& O& Y2 d
16 - z! A, X; h" M$ s( V6 S5 J
17 input clk;
1 K3 ?6 h9 x5 \9 T3 l) v18 input rst_n;
0 h! H( d& L D' o4 K4 q19 input w_i;& |/ v* p. O; E3 b% ^& N* B4 {
20 output z_o;( S% h% R" W+ n# [
21
/ b; p1 e. w( m$ y% X% i4 k22 parameter IDLE = 2'b00;
M4 e+ t+ z' D* {9 B23 parameter S0 = 2'b01;9 ]$ v9 i, g+ b) {& \7 p
24 parameter S1 = 2'b10;/ Y7 B, Z9 v/ p6 n6 v4 K
25 : I' u- B1 j; y
26 reg [1:0] curr_state;
1 Q3 E1 w& T2 O |5 t27 reg [1:0] next_state;
0 n1 S# {* ~- F5 K; o+ W28 reg z_o;
/ X$ C, [, ]; P( m2 y0 a29
( s s+ K k0 Z2 _30 // state reg
6 D# S: I: p5 J1 d% W31 always@(posedge clk or negedge rst_n)+ C% i( k7 r [$ G( L
32 if (~rst_n) curr_state <= IDLE;
/ q8 v/ c# `1 K; ~$ ]" c33 else curr_state <= next_state;% y/ C) J0 F _* T% [# q# r9 C. S6 j
34
c* \' P- b. R% ]3 q- Y35 // next state logic
, I+ x1 e6 u( z" t36 always@(*)
! K! `& V; B9 E! U37 case (curr_state)
9 R( N+ E5 C, O0 j38 IDLE : if (w_i) next_state = S0;
" F7 K& R3 }9 E; k' A$ \4 d39 else next_state = IDLE;$ d7 _$ A1 m! z; S0 C
40 S0 : if (w_i) next_state = S1;1 f8 R+ l& I' f, }) d+ m' ?
41 else next_state = IDLE;6 n7 R% ~, v' v1 B$ g. ?1 j8 i
42 S1 : if (w_i) next_state = S1;) P* t( | G# P8 D0 V. G
43 else next_state = IDLE;5 h! m' F# I- [- z/ l
44 default : next_state = IDLE;; j0 l: P$ A( n1 e* x y0 s! p4 s
45 endcase
3 H6 D6 v2 ^% ?' m% H* M: T) e46
3 U0 N5 }/ a0 `; C# `+ C# O47 // output logic1 x, K+ C' X, V2 W4 o
48 always@(*)
( ?3 C" a) P4 o- J0 S49 case (curr_state)6 S- j2 a& B7 K% T6 n' r& m8 O/ p
50 IDLE : z_o = 1'b0;4 I3 B4 ~& R% y0 K7 A
51 S0 : z_o = 1'b0;
~8 L3 y: f9 ~. f52 S1 : z_o = 1'b1;& \2 V0 s) ]0 p: {7 @
53 default : z_o = 1'b0; l7 m( [+ @3 \; x" m
54 endcase
# K2 M! j, P" U4 c* y55 ) Z) e7 v* P$ c8 _
56 endmodule[url=]http://common.cnblogs.com/images/copycode.gif[/url]+ ^4 x* |1 G/ Q: W% C2 l& b
! X j! ]7 n n8 c& @( x3 }
35行 [url=]http://common.cnblogs.com/images/copycode.gif[/url]7 Z5 l' u& E& u8 ^2 D
// next state logic
& {' b) R1 C7 T, `0 F9 L. valways@(*)
6 w. ~$ ?) i3 P: \ case (curr_state)
: n3 ]. Z% {# Q IDLE : if (w_i) next_state = S0;
. V! w* ?& [% p. `& S else next_state = IDLE;( v) T- \" J3 G( w
S0 : if (w_i) next_state = S1;
2 n) K8 e) R+ z( j2 [' h6 F0 L/ `& ^ else next_state = IDLE;
1 w# M- u! J9 f1 q S1 : if (w_i) next_state = S1;
1 g" D( w4 m, J( f9 B& q else next_state = IDLE;
+ ~% g! }0 L2 u- N* T default : next_state = IDLE;
) T h2 r/ {; N& h4 a1 V4 d endcase [url=]http://common.cnblogs.com/images/copycode.gif[/url]; j* ^) i' A9 ^; H( e' K
; U: {: r- S* I t# h) @使用1個always描述next state logic,因為是純粹組合邏輯,所以使用blocking。 根據Moore FSM架構圖所示,next state logic的結果與input與目前state有關,所以先用case對目前state做一次大分類,然後每個state再根據input做if判斷。 30行 // state reg
5 [; H2 g$ _: [8 Aalways@(posedge clk or negedge rst_n)
& e" R+ K/ y" p8 ?$ Y if (~rst_n) curr_state <= IDLE;
: c. m- h; Y# q) N% m8 S6 D else curr_state <= next_state;* t1 a5 x3 x: W, B) u0 ?$ P' f
使用1個always描述state register,因為是D-FF且含clk,所以使用nonblocking。 由於state register區塊並不包含任何邏輯,所以不會因為不同FSM而有不同寫法,不同FSM只會改變next state logic與output logic的寫法。 47行 [url=]http://common.cnblogs.com/images/copycode.gif[/url]
; P+ m8 R, _, E4 ~// output logic
% V. W3 c+ r$ z0 [always@(*)9 B2 Y* j% z% W- x( s2 g
case (curr_state)& Q' l. x1 Q5 r, x7 y7 G3 l6 [4 O
IDLE : z_o = 1'b0;; | Z! z" ~% [6 g- O* u8 X9 n
S0 : z_o = 1'b0;
8 j+ S/ S* F! r6 O8 Z S1 : z_o = 1'b1;1 k- P" p- k0 f f1 \. r
default : z_o = 1'b0;; e" F; |& X1 p, W- B4 c
endcase[url=]http://common.cnblogs.com/images/copycode.gif[/url]
" I# Q0 p8 X3 W8 `; ~% m/ T. U: R1 p x9 ?2 i8 v
使用1個always描述output logic,因為是純粹組合邏輯,所以使用blocking。 根據Moore FSM架構圖所示,output logic的結果只與目前state有關,所以只需用case對state做一次分類即可。 使用3個always寫法有幾個優點: 1.可忠實地反映出原本的Moore FSM硬體架構
' g2 s( z/ P, E( |- D2.可輕易地將state diagram改用Verilog表示
6 V& L$ i/ e# y! b3.將Next state logic與output logic分開,可降低code的複雜度,便於日後維護5 Z4 A6 X) F- v$ R! c
3個always是一個推薦的寫法。 Testbench simple_fsm_tb.v / Verilog [url=]http://common.cnblogs.com/images/copycode.gif[/url]; m" o1 X0 Z% `1 ~8 W' E) g6 u* H
1 /*
, w8 V1 V4 ?$ C# ~2 (C) OOMusou 2011 http://oomusou.cnblogs.com
8 M8 f0 G a" c }, J( N4 C. L6 Y' ^3 1 F/ i4 x: x& O
4 Filename : simple_fsm_tb.v
+ _) ?) v q" [% z2 z5 Simulator : ModelSim SE 6.3e + Debussy 5.4 v9
- F- \" ~6 S3 x7 y8 l4 }* h0 `5 A6 Description : testbench for FSM
- z. E; W. Y& j( u* J* J" t: N, Z+ ]7 Release : Jun.05,2011 1.03 s m( X5 A5 ~7 P- K* P
8 */- ]' }& O' C- a3 M# B* o
9 % l( ]% s; n# w* F7 Q
10 module simple_fsm_tb;1 n3 Y5 e3 T; N
11 % u. n! y# M# J! T
12 reg clk = 1'b1;' e- x5 S; H4 R1 c3 J# `* N3 U4 w
13 reg rst_n = 1'b1;. H( D. N' ~* W! s# R( k& H
14 reg w_i = 1'b0;/ j) V" J( I# p7 h
15 wire z_o;
# K+ N6 a) `$ B) r; Z8 K16
1 [7 E* {! E' E17 // clk
* F2 ~3 Q. t' Z c9 j18 always #10 clk = ~clk; B, w4 f4 q$ i. p8 Q* j
19 : e7 [+ b) g7 ]9 @$ Z
20 event after_rst;
, x: L/ m" l# ]8 G! P21 ) B/ N5 X0 f- q O
22 // rst_n
0 A/ ^! b% }) f3 W* A23 initial begin5 E9 W# g# ?1 z& R- F$ c
24 #6; // 6ns4 T5 B4 p* d, h' q7 ]% d) T
25 rst_n = 1'b0;
9 u( v# M" e( P! P, G26 #30; // 36ns
+ m4 x5 i# B( ^- w U27 rst_n = 1'b1;5 `. r' S* \+ @% @
28 ->after_rst;
0 P3 y- k! y: s5 a& G29 end6 n F& M( F: ~, f
30 # l: w) d% B' B5 s/ t1 t9 \5 B6 y
31 // w_i% Y" O" r+ T" U4 F
32 initial begin
( p! R H9 u+ N' {: n5 H33 @(after_rst);1 n5 t9 y" r) s/ v( @- z- U- j6 W$ X
34 repeat(2)@(posedge clk); // 60ns
4 ]1 e, K+ C) G. Y2 }. z. f35 w_i <= 1'b1;
7 o6 o4 t$ {2 j0 }36 @(posedge clk); // 80 ns
6 A9 Z/ o" A8 y' n; k9 \37 w_i <= 1'b0;
1 u+ q$ Z& @# m8 ^4 }3 `( C38 @(posedge clk); // 100 ns9 `( a8 n! q4 ]$ S x! u
39 w_i <= 1'b1;, U8 V. E X! k# N: j
40 repeat(2)@(posedge clk); // 140 ns& n6 |! @! c! I; Z5 n
41 w_i <= 1'b0;' s2 h$ A% ~* e* @5 l% u# e
42 @(posedge clk); // 160 ns
2 b7 N4 x% E9 [5 B1 P! ~4 p43 w_i <= 1'b1;2 s n8 c$ [* x6 M" |& z$ t
44 repeat(3)@(posedge clk); // 220 ns8 [3 |( M. H+ y
45 w_i <= 1'b0;
3 y( q) |6 A: |3 q46 end
7 C1 a% f! M( f47
; e9 m: t. q1 r; k3 y# h48 initial begin
6 ]: }2 i5 U. \# T$ I, O4 M49 $fsdbDumpfile("simple_fsm.fsdb");
; y8 K) v% ~' Z% [+ X50 $fsdbDumpvars(0, simple_fsm_tb);- S: d$ D5 K) @. b# d2 u, u; L
51 end4 ~, e1 z' l5 L! K
52
3 M9 d4 s k5 a$ K L+ |53 simple_fsm u_simple_fsm (! }1 H o0 _: t- ^/ c& I3 v
54 .clk (clk),; [) [$ L+ W. a3 }" {: z! J
55 .rst_n (rst_n),7 s% ^ n4 X+ v" Z% |6 ]" |& D
56 .w_i (w_i),
2 d! ^. @0 e3 N" U57 .z_o (z_o)1 I) _3 n, l+ |7 w7 K
58 );: {' Z/ f' ?* m. q8 w5 O
59 , y P( P- h1 b+ b
60 endmodule' G8 U, D* y" [+ H0 P. h; |. ^1 d
[url=]http://common.cnblogs.com/images/copycode.gif[/url]$ w" y' W$ S/ a& K) S( o
1 f. I, ^7 g/ V( l2 o
執行結果 http://images.cnblogs.com/cnblogs_com/oomusou/201106/201106060949236708.gif 2.使用2個always (二段式) 由於要使用2個always去描述3個block,根據排列組合原理,C3取2,共有3種可能,我們一個一個討論。 2.1 state register與next state logic合一 http://images.cnblogs.com/cnblogs_com/oomusou/201106/201106061010415140.gif simple_fsm_moore_2_always_0_cs_ns_good.v / Verilog [url=]http://common.cnblogs.com/images/copycode.gif[/url]. M- g" t9 k$ ]( {% a
1 /*
: X! i# n; _" g9 N; ~ 2 (C) OOMusou 2011 http://oomusou.cnblogs.com
0 U5 c8 J+ B2 Y. L 3 , _/ J3 R3 E* s# V
4 Filename : simple_fsm_moore_2_always_0_cs_ns_good.v1 n! s* I- |& a! N. ^- a) u& x
5 Synthesizer : Quartus II 8.1
! Y" m m) z; q- ^3 v 6 Description : 2 always block for moore fsm (GOOD)
! H9 ]8 ^" ?/ }& z7 e( N0 h 7 Release : Jun.05,2011 1.0
H0 s5 _, _; B: @ 8 */8 T& g5 v f5 k
9
' i& H6 W2 r1 ]10 module simple_fsm (
, k, Y1 |& A1 G% A11 clk,, m$ r+ w. s% P% P) r4 e) g P
12 rst_n, y- _7 L {2 ~
13 w_i,& ]( ]. g* ?% H6 N
14 z_o
% B- p+ V2 @8 I15 );
4 F. C% i! O5 w16 . s: ~: E: `/ O) G# K' I
17 input clk;
! E$ a/ x5 F2 i$ Y! E# O18 input rst_n;
7 G. @( S6 S" \19 input w_i;4 t/ S0 W4 d1 w7 A: ~6 X
20 output z_o;
4 _- B& |) _; U21
, g" [% o+ H1 r; y22 parameter IDLE = 2'b00;
" I5 [9 o3 j, k% H23 parameter S0 = 2'b01;0 Q7 @$ E* ?" M4 o2 R' Q& T, q
24 parameter S1 = 2'b10;# V3 ]$ h. r' L5 ~+ G
25
E- E8 S) L" _' d26 reg [1:0] curr_state;2 ~! G! W) r+ [. @6 y( T% _1 s
27 reg z_o;4 e w% o" p2 W+ M
28
; O1 w, b4 p* G: x29 // state reg + next state logic
" H% x; Z( Q6 E5 Z30 always@(posedge clk or negedge rst_n)' V. j3 H2 \2 r# m
31 if (~rst_n) curr_state <= IDLE;
. L" z i6 l: x$ M1 J. N# d; L% L1 d32 else4 B' X# K5 M: b+ }1 M
33 case (curr_state)
# J7 X4 |% s6 B3 a. k2 [( \8 h34 IDLE : if (w_i) curr_state <= S0;( x5 A7 Q: ]7 L4 b* B9 @: S3 K% v# x
35 else curr_state <= IDLE;
# r6 r$ e+ o7 c8 {36 S0 : if (w_i) curr_state <= S1;
( X2 ?. D, l) G5 @! I37 else curr_state <= IDLE;
" R- V; h# p) m; r' Z38 S1 : if (w_i) curr_state <= S1;, t; W7 `1 l- {
39 else curr_state <= IDLE;* }' n: U: o$ O2 b; U& J1 I
40 default : curr_state <= IDLE;
4 z3 K: o* q* a4 Z! K: D1 ?9 g. @; i41 endcase; `" y' ^+ j4 n
42
2 U! d1 @7 Q# v43 // output logic
( Z3 g* N `- g- a1 f' P3 m44 always@(*)
! j: S/ H2 ~3 ]' q6 d$ H45 case (curr_state)! W5 K. y% p+ @% R5 b; q ]
46 IDLE : z_o = 1'b0;
0 F8 V! F1 J' ~4 l/ \47 S0 : z_o = 1'b0;
4 r6 _7 G1 p% ?48 S1 : z_o = 1'b1;$ {! W' t( N: V4 R/ f. B4 @, {
49 default : z_o = 1'b0;
9 @; |% j$ O6 X% y; f! m6 x" T- I50 endcase
' {7 X% }! M1 O5 C }51 ; t r* Q& t" b1 K& Y4 y: O
52 endmodule[url=]http://common.cnblogs.com/images/copycode.gif[/url]; I3 _ |. P; _8 C3 s6 _( Q
% b3 [) G8 V0 R" ]. A/ B7 s5 I/ C9 t29行 [url=]http://common.cnblogs.com/images/copycode.gif[/url]. r( h, B6 F. X& Y+ o
// state reg + next state logic/ S" v: F7 @0 n# l7 x) f
always@(posedge clk or negedge rst_n)
- E/ g6 O) _5 J$ V if (~rst_n) curr_state <= IDLE;
5 b; O# ?+ c8 ?$ w" n else, x2 B) I/ ~8 O. j2 \; ]) U
case (curr_state)
9 h9 d& P( C9 H+ G IDLE : if (w_i) curr_state <= S0;0 _7 D9 ?/ L0 ?# B. L6 Y6 @
else curr_state <= IDLE;
+ {% W4 u ^/ j* u# V/ B' t$ T5 a S0 : if (w_i) curr_state <= S1;
( ?4 A% [5 F0 j" T else curr_state <= IDLE;8 t P! E2 V3 J% d/ G6 g
S1 : if (w_i) curr_state <= S1;
3 @; N2 L* i" i! Q+ U else curr_state <= IDLE;
9 e' t# J4 f5 w4 F" D* a. G' O4 X7 A default : curr_state <= IDLE;, }, }8 }& |; J
endcase[url=]http://common.cnblogs.com/images/copycode.gif[/url]
* d6 H [, u( m, M; K8 q# S2 o# ?0 V2 }0 I& h' C3 {
將state register與next state logic合起來用1個always去描述,雖然next state logic是純粹的組合邏輯,為了遷就於帶clk的state register,且要用一個always描述,就必須改用nonblocking。 由於state register與next state logic合一,所以可以少宣告next_state reg,不過這並不會影響合成結果,只是可以少打幾個字而已。 因為next state logic由input與state所構成,所以先用case對state做一次大分類,然後每個state再根據input做if判斷。 43行 [url=]http://common.cnblogs.com/images/copycode.gif[/url]
8 S* B6 t& J' F( Z# b// output logic# y( O) z% {" U" M( K5 e
always@(*)+ z) j4 H0 Y0 y( f$ u! A# N3 C+ J; T0 o
case (curr_state)
- n) B2 v5 U Z, H8 L# t+ d- j IDLE : z_o = 1'b0;
) r* S o& h+ O( e ]7 k+ R S0 : z_o = 1'b0;! _' T" P/ y/ h* ?# S+ b( r
S1 : z_o = 1'b1;
- E9 C# y9 H2 Z' U, [ default : z_o = 1'b0;
: U6 L0 d) k2 h. c3 h$ d) j- @ endcase[url=]http://common.cnblogs.com/images/copycode.gif[/url]
3 ?; m/ Q4 v+ s- ^6 g8 L0 k! ]3 p2 c# v& C- ?$ k& I. q& B* e
使用1個always描述output logic,因為是純粹組合邏輯,所以使用blocking。 根據Moore FSM架構圖所示,output logic的結果只與目前state有關,所以只需用case對state做一次分類即可。 使用2個always (state register與next state logic合一)寫法有幾個優點: 1.程式碼較3個always寫法精簡; f- D+ s3 w* q( ^
2.可輕易地將state diagram改用Verilog表示1 G! d: a8 R) |; t
3.因為state register原本程式碼就不多,將next state logic與state register合一後,next state logic仍與output logic分開,因此不會增加code的複雜度,便於日後維護
8 F$ t. T7 Y: [6 Q7 N1 h2 I+ d2個always (state register與next state logic合一)也是一個推薦的寫法。 接下來要討論的都是不推薦的寫法,主要目的是了解為什麼不推薦的原因。 2.2 state register與output logic合一 http://images.cnblogs.com/cnblogs_com/oomusou/201106/2011060610403484.gif simple_fsm_moore_2_always_1_cs_ol_ng.v / Verilog [url=]http://common.cnblogs.com/images/copycode.gif[/url]. U& |% h/ b! _; ~; l- _1 ?4 R
1 /*
/ j: G0 ~4 H6 r+ e 2 (C) OOMusou 2011 http://oomusou.cnblogs.com$ g* M6 W! m; l7 L$ K
3
! _/ L p! Z4 f7 | 4 Filename : simple_fsm_moore_2_always_1_cs_ol_ng.v
5 U" c8 d; N1 ?$ e 5 Synthesizer : Quartus II 8.12 s7 o6 u4 M" B& B# c4 j
6 Description : 2 always block for moore fsm (NO GOOD)
+ f) z* D! S5 J; _- S" X 7 Release : Jun.05,2011 1.0
0 k* }6 z# Y( ]9 W& l 8 */
/ p7 k! |% R5 P! h 9 5 j7 I5 R; U% K
10 module simple_fsm (, t) m# Y! `, K1 w4 g% ?+ n
11 clk,3 @, I* H5 x1 G' p' Q
12 rst_n,1 |! _8 Z9 D5 ?& J
13 w_i,
) }7 ~* o+ R6 n/ G. Y! v) E+ f14 z_o5 j0 N" H x; d, N# m
15 );
B6 Q4 u/ x, a9 u16 " g* T3 E2 T3 b: I0 B, e1 N
17 input clk;- x* `" a. U* F0 o& w
18 input rst_n;8 J. v9 a) v9 M. V
19 input w_i;
( f) L5 E% {7 _" a20 output z_o;
- e7 t# s& s+ k% \* ?21
/ l! ~( e4 B2 z9 k22 parameter IDLE = 2'b00;
# \! |8 k3 r* X( \+ Y23 parameter S0 = 2'b01;
7 g' |2 E3 |& B! \24 parameter S1 = 2'b10;
. x; [2 p6 |! b3 b. l: b& G3 F25 ( N, d0 a4 L7 V$ o) t2 j" a8 V
26 reg [1:0] curr_state;
9 @; d" l" k. C4 P& T27 reg [1:0] next_state;
8 y7 V: f9 l7 H( n$ t28 reg z_o;
j, g1 ^6 D7 Y8 l {: k2 X! n29
6 h/ \& F! F+ @( y; C( t30 // state reg + output logic
( w/ \; p$ E F4 o! H( f* m31 always@(posedge clk or negedge rst_n), ]# B" c# l% m0 z8 F7 s* b" Q2 E+ T
32 if (~rst_n) {curr_state, z_o} <= {IDLE, 1'b0};
$ C4 Z; [3 F' n4 F/ i1 |8 @2 h33 else begin/ u4 Y0 m3 x" E4 l! |# l
34 curr_state <= next_state;0 M: Y; e9 y) S% w# o
35
. d! [& D1 u0 l36 case (next_state)
- o; ~5 c' {' A4 O37 IDLE : z_o <= 1'b0;
' E" D) ?0 @9 ], @/ c) w5 p; y% G38 S0 : z_o <= 1'b0;
$ X+ Z' `' C3 b2 O# G39 S1 : z_o <= 1'b1;0 T8 w' b2 ~3 j/ S
40 default : z_o <= 1'b0;2 v ~) X$ o1 ~( J( w- F
41 endcase9 m, ~( w9 C! l. b# c! j9 G& M
42 end$ v8 n! b7 O# q3 O/ @* D
43 " d! A6 w: j, b5 o8 i6 X( u
44 // next state logic 1 S- u% n. @6 _
45 always@(*)
" c0 `) M; b) r5 [$ J6 O* K46 case (curr_state)' M' I3 s" T0 |9 B8 M, \9 H4 f
47 IDLE : if (w_i) next_state = S0;
+ T4 {. M9 D0 x/ V) `$ R5 |48 else next_state = IDLE;6 M$ W: t# m9 r+ `
49 S0 : if (w_i) next_state = S1;
6 _3 F: |" R0 R6 x50 else next_state = IDLE;' X+ d# v: w1 d" @/ T p
51 S1 : if (w_i) next_state = S1;% e' ^% R) Q& Y1 o8 Q- V
52 else next_state = IDLE;5 E3 T3 j6 Q3 G. |
53 default : next_state = IDLE;
1 Q" A) {9 i9 R' b# y, n) K0 n6 |! V54 endcase
: O5 ?& Y" S3 I1 G3 ~55
* E) u7 n' `2 d: V p4 ^" J56 endmodule[url=]http://common.cnblogs.com/images/copycode.gif[/url]( L! `% X( A) a7 ^( D( S k
' b$ N9 o. H5 s3 g& k& O1 P30行 [url=]http://common.cnblogs.com/images/copycode.gif[/url]+ E4 K% a+ U+ q. x1 e
// state reg + output logic
) ^0 e. W0 O+ [; A' xalways@(posedge clk or negedge rst_n)
' e9 w0 G. K2 [ if (~rst_n) {curr_state, z_o} <= {IDLE, 1'b0};
9 Y3 }! H3 F9 g7 p else begin1 Q; @) n- f- s0 K( M: a
curr_state <= next_state;
5 h* y7 C2 C p, y" E
- |8 x# A% P) t. A case (next_state)) q2 Y% `* W0 y* z4 W, {
IDLE : z_o <= 1'b0;, g+ I% h6 J5 B9 s
S0 : z_o <= 1'b0;) b) c6 }! @. T( V* h" k2 L
S1 : z_o <= 1'b1;
( d/ M$ Z+ B0 ~# f default : z_o <= 1'b0;9 z& u# Q: K1 Y' t! D4 ^
endcase[url=]http://common.cnblogs.com/images/copycode.gif[/url]
% G! A6 P7 C) m" V
& r! Q3 F( m5 H+ s/ ?將state register與output logic合起來用1個always去描述,雖然output logic是純粹的組合邏輯,為了遷就於帶clk的state register,且要用一個always描述,就必須改用nonblocking。 因為output logic只與state有關,所以只用case對state做一次分類即可。 這種寫法最大的問題是:output logic必須用next_state去判斷!! 依照Moore FSM的架構圖得知,output logic只與目前state有關,之前的幾種FSM寫法,output logic也是由目前state去判斷,為什麼這種寫法要靠next_state去判斷呢? 主要原因是根據Moore FSM的定義,output logic只與目前state有關,且是個純粹的組合邏輯,但目前強迫將state register與output logic放在同一個always,迫使output logic必須使用nonblocking的方式呈現,也就是若output logic仍然使用目前state去做判斷,則output logic會多delay 1個clk,為了讓output logic結果正常,只好提前1個clk做判斷,也就是提前到next_state去做判斷。 所以當我們從state diagram換成Verilog表示時,若使用2個always,且是state register與output logic合一時,必須很小心要使用next_state去做output logic判斷,因為這個地方很不直覺,很容易出錯,所以不推薦這種寫法。 44行 [url=]http://common.cnblogs.com/images/copycode.gif[/url]
. Y0 @& P- _0 P7 A. j& f% C# ]// next state logic
! t6 ?8 Z1 A: P- t- {always@(*)$ E; w, ]$ H5 u5 n
case (curr_state)
* j' b- D) L$ U IDLE : if (w_i) next_state = S0;
G0 T/ z, ^4 [& e6 A# c2 z) ` else next_state = IDLE;
6 p+ H% K( Z6 [+ p S0 : if (w_i) next_state = S1;0 Z5 c( s) D3 B/ U) A
else next_state = IDLE;" D. l: |: |1 W3 d
S1 : if (w_i) next_state = S1;
8 x0 g& s: i( R6 b/ j3 K else next_state = IDLE;
4 W- w" [( a$ _/ s% x* ]9 ]7 y default : next_state = IDLE;& }' C2 t/ t k' e, b; I1 E8 x8 v
endcase [url=]http://common.cnblogs.com/images/copycode.gif[/url]. g/ H% u: c, H6 @
& {( _8 A1 X1 `; Z
使用1個always描述next state logic,因為是純粹組合邏輯,所以使用blocking。 根據Moore FSM架構圖所示,next state logic的結果與input與目前state有關,所以先用case對目前state做一次大分類,然後每個state再根據input做if判斷。 使用2個always (state register與output logic合一)寫法的缺點: 當使用1個always去描述state register與output logic時,output logic必須使用next_state做判斷,而非用目前state判斷,由於寫法不直覺,一不小心很容易弄錯2 P. {' S8 D9 B9 ^5 M/ m! t7 B
不推薦2個always (state register與output logic合一)寫法。 或許你會說,在實務上卻常看到state register與output logic合一的寫法,為什麼不會出問題?那是因為儘管是用Moore FSM,我們為了timing更好,常會在output時多敲一個D-FF,讓Output Logic的組合邏輯不要與其他module的input的組合邏輯合併,避免造成critical path,假如是這種需求,state register與output logic合一後,可以直接判斷curr_state,不用提早一個clk判斷next_state。 2.3 next state logic與output logic合一 http://images.cnblogs.com/cnblogs_com/oomusou/201106/201106061539099897.gif simple_fsm_moore_2_always_2_ns_ol_ng.v / Verilog [url=]http://common.cnblogs.com/images/copycode.gif[/url]
. j/ @* v1 Z, h 1 /* 8 R! q; \8 P8 }) K S$ \1 P' E+ H
2 (C) OOMusou 2011 http://oomusou.cnblogs.com
* X$ I3 _9 g) P$ J 3 8 p5 h7 m9 W0 M( A$ Q
4 Filename : simple_fsm_moore_2_always_2_ns_ol_ng.v
$ d8 v1 R$ v3 L: g# m* |) B 5 Synthesizer : Quartus II 8.1
+ ]; {- }, n: s7 T" Z. d* C0 { 6 Description : 2 always block for moore fsm (NO GOOD)6 p1 O% f4 f% G
7 Release : Jun.05,2011 1.0, y& `# g( I5 u& a: p9 D5 \2 F, k+ i; F+ {
8 */
3 c' g+ W3 X7 {; E6 _ W% m: T 9 ) i/ x6 Y$ j9 Z" \
10 module simple_fsm (
" b" f* t% @1 r, D2 H" V11 clk,
4 ]; V- S6 S8 V+ o0 @12 rst_n,
; I& c, y0 r4 X. d1 }3 B; n13 w_i,
k/ F" U6 Q& [1 d' `# p: Z14 z_o
# s# x$ r4 ^$ R' p8 L( j15 ); R; T3 M5 m6 w
16
+ z9 _4 d1 p; ?% g) H* j4 }17 input clk;% X# T/ d+ q; V- ] _2 h
18 input rst_n;
, a0 X. }( Q) G8 p& d0 ?2 ?' k4 [19 input w_i;
$ e4 @- p4 s* _1 }# }20 output z_o;# e) L5 d0 Y C2 J4 R. r `8 D' n% f
21 . F% [) \9 `/ Z" V0 k( f
22 parameter IDLE = 2'b00;0 w8 f" R) r" u7 h
23 parameter S0 = 2'b01;5 Q4 e2 g$ J; X/ M) v& |
24 parameter S1 = 2'b10;
. D1 D _ V5 u' V25
B2 [9 p2 S9 O( r26 reg [1:0] curr_state;: }6 J" D6 |! E `; t* Z
27 reg [1:0] next_state;4 G* ~# {) y8 H& ^/ u1 l5 X
28 reg z_o;
, t2 Y: R, y$ |29
1 p5 p: l* r& Y/ i30 // state reg. x7 D/ I$ N: ^3 k5 Y
31 always@(posedge clk or negedge rst_n)1 k5 G; P9 z* B
32 if (~rst_n) curr_state <= IDLE;
/ N7 T* E& o* q; y7 g5 g7 N& x5 D33 else curr_state <= next_state;
- `( k; h2 }% ]2 ~34 0 i6 z3 M, j) ?0 j% N+ s5 B7 q
35 // next state logic + output logic
" A; h, D6 i' R9 O1 T- S; I5 o36 always@(*): C$ |! Q3 ^0 s2 o: o' ]: i# g
37 case (curr_state)+ B3 n4 r% f7 V- s, j S2 K
38 IDLE : if (w_i) {next_state, z_o} = {S0 , 1'b0};9 H% a5 U8 f n, k
39 else {next_state, z_o} = {IDLE, 1'b0};! A& L; `2 ?0 c) Q/ C( R
40 S0 : if (w_i) {next_state, z_o} = {S1 , 1'b0};( k9 {/ a9 S9 w, S
41 else {next_state, z_o} = {IDLE, 1'b0};
- M* d1 V3 T$ @, y. Z42 S1 : if (w_i) {next_state, z_o} = {S1 , 1'b1}; // always output 1'b11 ]# i! j; b- Q. R6 y1 {6 N& l
43 else {next_state, z_o} = {IDLE, 1'b1}; // always output 1'b1. e+ j2 ~# l9 D, C: K
44 default : {next_state, z_o} = {IDLE, 1'b0};
; i7 i7 j9 z& |& ?2 a/ X45 endcase
4 |6 `8 _9 e% Y46 $ o+ p8 I. j& H- |
47 endmodule[url=]http://common.cnblogs.com/images/copycode.gif[/url]3 _5 r* M1 O8 W& U6 f k" n
9 j8 k( ]7 G7 w+ I8 ?& x8 c30行 // state reg
& a; p( C9 d9 s5 yalways@(posedge clk or negedge rst_n)
2 A2 ^' J& e# O4 J& v1 {0 Z4 n if (~rst_n) curr_state <= IDLE;- a7 ]' V' \+ S- I$ D( X
else curr_state <= next_state;
1 [6 U! |1 l% Q5 i3 f2 S7 @使用1個always描述state register,因為是D-FF且含clk,所以使用nonblocking。 由於state register區塊並不包含任何邏輯,所以不會因為不同FSM而有不同寫法,不同FSM只會改變next state logic與output logic的寫法。 35行 [url=]http://common.cnblogs.com/images/copycode.gif[/url]
! P+ @ H: @" Q/ _" r) W1 ]// next state logic + output logic 5 n7 {! v: z Q5 P' m6 [
always@(*)7 z9 b! N9 H3 s( @9 {
case (curr_state)1 I% y, j/ E8 q' }) i* V
IDLE : if (w_i) {next_state, z_o} = {S0 , 1'b0};
( K0 T+ ]9 }7 e+ e" L- W else {next_state, z_o} = {IDLE, 1'b0};, c5 U9 U ?% i1 r* {( K$ z& h8 p
S0 : if (w_i) {next_state, z_o} = {S1 , 1'b0};2 D7 W1 l. |0 ^3 E- L* y+ W1 O; ]
else {next_state, z_o} = {IDLE, 1'b0};7 U/ p/ b m1 N1 M2 y# |2 J' r. U
S1 : if (w_i) {next_state, z_o} = {S1 , 1'b1}; // always output 1'b1( B2 o( p' x7 `6 ]. y
else {next_state, z_o} = {IDLE, 1'b1}; // always output 1'b1
6 B' P. b) M+ y& w' ~2 _ default : {next_state, z_o} = {IDLE, 1'b0};
e) s- `; {0 p3 d2 U* Q endcase[url=]http://common.cnblogs.com/images/copycode.gif[/url]6 h! V7 X$ t) f. K( x2 N( J4 @
2 b/ p7 o4 y; d: m7 b3 T6 X將next state logic與output logic使用同一個always去描述,由於next state logic與output logic都是純粹的組合邏輯,所以使用blocking描述沒有問題。 由於next state logic與input與目前state有關,但output logic卻只與目前state有關,因為都是先用目前state做case判斷,然後再對input做if判斷,所以會出現output兩次都出現1的情形,起因於output logic只與目前state有關,與input無關,固任何input都會出現1。 使用2個always (next state logic與output logic合一)寫法的缺點: 1.將next state logic與output logic合一只會增加code的複雜度,日後維護會更加困難
; z$ ?7 ~5 } @' q2.很類似Mealy FSM寫法,容易讓人誤以為是Mealy FSM! E7 u* \+ ~/ ~ g
不推薦2個always (next state logic與output logic合一)寫法。 3.使用1個always (一段式) http://images.cnblogs.com/cnblogs_com/oomusou/201106/201106052038403910.gif simple_fsm_moore_1_always_ng.v / Verilog [url=]http://common.cnblogs.com/images/copycode.gif[/url]
0 w6 J+ q1 W p& e" Q- h( M 1 /*
; `/ z# U' @: v0 s! B' f$ r' ^ 2 (C) OOMusou 2011 http://oomusou.cnblogs.com
- q6 c7 g% f8 L! r$ [( @ 3
2 c1 Z% ]. B8 Z4 R# u 4 Filename : simple_fsm_moore_1_always_ng.v
2 ~% k9 T$ ?& P+ Y 5 Synthesizer : Quartus II 8.18 d% l F' W$ G7 `
6 Description : 1 always block for moore fsm (NO GOOD)3 K+ ^; \9 Q" P
7 Release : Jun.05,2011 1.0
' j3 F8 b! h$ m" B. D& I6 g 8 */- m* ^4 }- ? L! ~: K2 W
9
5 e3 ~; N6 Y! G, A10 module simple_fsm ($ h H$ s' m! [: e* ]
11 clk,# Z* Y# V6 o5 e% c }+ s. o
12 rst_n,) y6 t8 B% `+ s
13 w_i,$ {0 v) A/ G+ \% r; I
14 z_o0 ?5 ^' E) P5 B- x" M+ y% n+ y
15 );: M- ]8 w, w( l+ B
16 4 [0 _5 g6 h) {) d& i% F
17 input clk;
4 ^% b! t2 B/ f% k18 input rst_n;
7 g! [; K% a+ \# l1 h/ z19 input w_i;
) Z! D8 w/ E9 B4 S20 output z_o;
: f, z8 D- }: Z7 }; N- A21 & \' D9 I# M5 m$ L; A8 |
22 parameter IDLE = 2'b00;
% a" Z0 ]7 i" ?0 u5 ^- ?23 parameter S0 = 2'b01;
: N; F' c, U4 ~2 J24 parameter S1 = 2'b10;+ V4 \5 W1 i# K; F$ j0 x) w
25
. ` H1 Z7 w& u7 O26 reg [1:0] curr_state;* N+ N9 ?# K7 X
27 reg z_o;
9 [! G4 t: b/ z1 S5 F/ ^28 9 R1 w! \. q7 H% y. V
29 always@(posedge clk or negedge rst_n): z: X( m, t2 Y7 K
30 if (~rst_n) {curr_state, z_o} <= {IDLE, 1'b0};
2 V8 M$ V& q. J( J31 else
' G9 R9 j' K% c" v- {' y32 case (curr_state)
3 R; @8 V) l: f33 IDLE : if (w_i) {curr_state, z_o} <= {S0, 1'b0};" h" ~0 j' m; m% K4 X
34 else {curr_state, z_o} <= {IDLE, 1'b0};
% m0 T* r% y# n4 C35 S0 : if (w_i) {curr_state, z_o} <= {S1, 1'b1}; //?
$ v' s F9 ^) A; A3 z- m+ f36 else {curr_state, z_o} <= {IDLE, 1'b0};
6 x& ]* o! t O% t( N2 ]37 S1 : if (w_i) {curr_state, z_o} <= {S1, 1'b1};0 \* P/ C! {+ a
38 else {curr_state, z_o} <= {IDLE, 1'b0}; //?1 p( t$ k1 x, M: T, x) y+ J
39 default : {curr_state, z_o} <= {IDLE, 1'b0};! {) u# A: w9 U$ Y% B
40 endcase6 D5 c; z" r% `& T% U# [
41 , j9 b' W( o* i7 u `
42 endmodule[url=]http://common.cnblogs.com/images/copycode.gif[/url]5 p. H% q; {" |6 M- r& x# B: a t
1 `7 t2 Y6 O0 ~8 F' e29行 [url=]http://common.cnblogs.com/images/copycode.gif[/url]
+ Z: |, W1 l+ Y- galways@(posedge clk or negedge rst_n)
% i) T* R3 ]3 w2 y: G! q# D. W if (~rst_n) {curr_state, z_o} <= {IDLE, 1'b0};! Z$ d4 }7 J$ A! g' R% _9 W' p
else
8 o1 ^# a: G7 f$ z( y case (curr_state)
" Q' P8 N: a( g |. P, {# z IDLE : if (w_i) {curr_state, z_o} <= {S0, 1'b0};
9 Y2 {) c& ]1 C8 {/ \$ m" F else {curr_state, z_o} <= {IDLE, 1'b0};
' L* e- X) H) Y" @% P2 h S0 : if (w_i) {curr_state, z_o} <= {S1, 1'b1}; //?
4 |$ Q4 e. W% Q else {curr_state, z_o} <= {IDLE, 1'b0};
/ O. ^8 t2 ~- Q* `6 g S1 : if (w_i) {curr_state, z_o} <= {S1, 1'b1};
+ m% {, Q6 g! V" D9 H/ U6 C+ m9 D1 b else {curr_state, z_o} <= {IDLE, 1'b0}; //?
4 g# \3 A7 w0 ~% m% R default : {curr_state, z_o} <= {IDLE, 1'b0};9 Y" ]' r' O1 Y/ _8 f
endcase[url=]http://common.cnblogs.com/images/copycode.gif[/url]
! j. G& v4 i/ U! C" C
# ]- E: S% V& Z l使用1個always同時描述next state logic、state register與output logic,雖然next state logic與output logic是純粹的組合邏輯,但為了遷就於帶clk的state register,所以必須使用nonblocking。 根據之前的經驗,由於Moore FSM的output logic只與目前state state有關,且是純粹的組合邏輯,若硬要與state register用同一個always去描述,判斷上會出現一些問題,需提早1個clk用next state判斷(在state register與output logic合一時曾經遇過)。 在1個always內,連next_state也省了,所以在35行 S0 : if (w_i) {curr_state, z_o} <= {S1, 1'b1};) a- ] E+ a7 q. T0 }; v9 x
當目前state為S0且輸入為1'b1時,output必須提前為1,因為這是在nonblocking內!! 37行 S1 : if (w_i) {curr_state, z_o} <= {S1, 1'b1};
: B' ]! L8 V* z5 @同理,在目前state為S1且輸入為1'b1時,output也必須提前為1,也因為這是在nonblocking內!! 使用1個always寫法的缺點: 1.因為使用nonblocking去描述output logic,所以要提早1個clk判斷,要特別小心處理,一不小心很容易弄錯
P) L. M, ^/ z. q0 G2.1個always內同時包含next state logic與output logic,會增加code的複雜度,日後維護更加困難2 f8 s; {6 N) i
不推薦1個always寫法。 Mealy FSM架構 http://images.cnblogs.com/cnblogs_com/oomusou/201106/201106062055403233.gif 談完了Moore FSM,接下來談Mealy FSM,與Moore FSM的差別只在於Moore FSM的output logic只由目前state決定,但是Mealy FSM可由目前state與input共同決定。 Mealy FSM各種coding style比較 http://images.cnblogs.com/cnblogs_com/oomusou/201106/20110606205541692.gif 將之前的例子用Mealy FSM重新改寫,原本在Moore FSM下,若input w_i為連續2個clk為high,則output會在下1個clk產生週期為1 T的high pulse,若改用Mealy FSM,則output會提早1個clk出現,如上圖所示。 http://images.cnblogs.com/cnblogs_com/oomusou/201106/201106062055418151.gif 原本Moore FSM需要3個state,若改用Mealy FSM後,會只剩下2個state,接下來要用各種coding style來實現Mealy FSM。 1.使用3個always (三段式) http://images.cnblogs.com/cnblogs_com/oomusou/201106/201106062106115936.gif simple_fsm_mealy_3_always_best.v / Verilog [url=]http://common.cnblogs.com/images/copycode.gif[/url]7 Z6 q% [ t( @/ c
1 /*
8 ~8 I) U7 U+ S+ \ 2 (C) OOMusou 2011 http://oomusou.cnblogs.com
( i' Y6 D7 e r" w% z2 S 3 3 B% D* b1 N$ o, C* C C
4 Filename : simple_fsm_mealy_3_always_best.v1 s [0 d7 i5 X9 M' T' A
5 Synthesizer : Quartus II 8.1! f) P3 ?, d. i5 | ]
6 Description : 3 always block for mealy fsm (BEST)
E; H6 y# _6 _! ]- _' \0 ^9 {9 X" q 7 Release : Jun.05,2011 1.07 i- s# O: T" V1 b, u$ d: D
8 */2 C% s! V7 {% R% ~
9
. f+ j% D% \' r. ^( R! R10 module simple_fsm (; t0 d" j5 D" Q. I0 O/ ?0 H: P
11 clk," i0 i7 _8 Z6 s# G
12 rst_n,6 V: Q7 ~& V/ |5 ~5 ^
13 w_i,
0 L+ j# n( q# [% d% R2 I$ [14 z_o
4 Z' s& m! ~* A7 g, u. |7 D15 );
& b6 O& s2 Y D8 P- U/ a- S: q4 o16 % r2 j8 K( k2 E) [9 N
17 input clk;
2 I- q% ~, o4 c3 g) A18 input rst_n;
/ \3 l" t3 Z4 j6 V19 input w_i;
3 ?' v6 H) F% p. w- ~8 F20 output z_o;
6 Q& i4 F4 p7 M7 ~" Z$ Y1 q* ^21 1 M. o" y( q( A* W! g
22 parameter IDLE = 2'b00;
0 Q5 L! B# M. d23 parameter S0 = 2'b01;
/ y1 p% T; x) Z X6 v* a4 I0 z% ?24 * q! k* t' U4 n- U, \9 m) `6 Z
25 reg [1:0] curr_state;
5 ^- v' }) r/ M. {& W) p) H& W26 reg [1:0] next_state;3 Y2 f% I2 a8 d+ w N! t
27 reg z;
- V F3 b/ u- ?$ @28 reg z_o;
/ ?8 J1 T M+ x0 L4 c- R/ [29
/ p( q* B7 n4 B( Z( U4 B30 // state reg8 y) J% \% d" }: ]9 ?% d7 c, g
31 always@(posedge clk or negedge rst_n)9 A" |+ f% F5 V
32 if (~rst_n) curr_state <= IDLE; \, `: U% E: A
33 else curr_state <= next_state;
0 Q r( {0 ] ?& ^. L34
) s8 a3 G$ I. \! h35 // next state logic ; i0 z) X7 H' U+ G+ W
36 always@(*)
# T$ _. }5 `2 }+ d) ]7 X37 case (curr_state)
6 N) B. C3 D: D6 @- Y38 IDLE : if (w_i) next_state = S0;
0 I- Y+ `: q9 [0 b39 else next_state = IDLE;
9 E; C9 s) ~6 A* B! B7 K40 S0 : if (w_i) next_state = S0;9 O- {# W; V- Q3 {
41 else next_state = IDLE;/ J1 b0 o+ G q1 w7 s8 V8 K
42 default : next_state = IDLE;
& u. T9 |. X' R# i3 y9 @: k43 endcase
; ^1 G5 n p. n2 O6 O44
3 l# e; \6 h/ f- {. `9 m45 // output logic5 b1 g% N$ K0 x1 u$ P
46 always@(*)" E2 T% P8 o$ G0 F5 T; G
47 case (curr_state)
* w* ~7 e( z- ]/ z7 Q48 IDLE : if (w_i) z = 1'b0;" L, Q3 c3 g& g6 J$ C; t6 }) ]: e# b
49 else z = 1'b0;
) i( ]( e1 z$ [( i5 {4 c50 S0 : if (w_i) z = 1'b1;
* @; [1 N5 Y6 }0 y! W3 O51 else z = 1'b0;
4 Y( b7 Y& P# R7 f6 P* Q$ W52 default : z = 1'b0;
. K2 O v' y# a2 {4 h$ {53 endcase$ G8 G# j+ L. |# K# p
54
5 n8 [* o& ]7 J1 l0 u* \7 A1 ^0 ]55 // mealy output to delay 1 clk for moore
, [" D+ o) D+ W- k56 always@(posedge clk or negedge rst_n)2 f8 [: y7 N% o/ ^
57 if (~rst_n) z_o <= 1'b0;" O; @: s* t( _0 p7 L+ U7 V9 l
58 else z_o <= z;1 M# ~7 J5 ~+ M
59
2 A6 M! R) `/ u60 endmodule[url=]http://common.cnblogs.com/images/copycode.gif[/url]2 X; {) C4 _' P; r" E; f
6 H& C+ Y* ~. {3 n/ m' K
30行 // state reg
1 k) D: ^9 P' c* y# Calways@(posedge clk or negedge rst_n)' ?( x5 H# J+ B( C
if (~rst_n) curr_state <= IDLE;
0 `- g b& k7 f3 s. i3 g else curr_state <= next_state;8 G# x+ k; ]$ g& E; ]
使用1個always描述state register。 35行 [url=]http://common.cnblogs.com/images/copycode.gif[/url]' f7 S" Z0 G" R T% ]
// next state logic
: W/ o0 N2 S7 x6 e! H1 ualways@(*)
* J2 e# | K$ G case (curr_state)
' I- [3 N4 c2 f" y1 l2 ?* x- c; d IDLE : if (w_i) next_state = S0;9 E5 x Y! F0 o8 U- G7 H( }+ [
else next_state = IDLE;
; p9 z& \. j( O& o S0 : if (w_i) next_state = S0;
6 s; c) ]$ {. q0 S else next_state = IDLE;$ O1 ?- G% D6 i C- m/ Q
default : next_state = IDLE;
5 t2 |5 D4 Z& B endcase [url=]http://common.cnblogs.com/images/copycode.gif[/url]
7 {/ C: F& R) e# D* D
# H% B8 ?8 T2 P使用1個always描述next state logic。 45行 [url=]http://common.cnblogs.com/images/copycode.gif[/url]- ]1 ~+ h5 n5 J, N [; C% g- I d
// output logic
/ n& z0 d! z' h+ ~( Ualways@(*)
8 v. r5 U% e) Y2 R8 b" g# z case (curr_state)
7 n, z* P, a1 J5 ?! B IDLE : if (w_i) z = 1'b0;7 |: W5 s, h4 K' z+ a
else z = 1'b0;
& h# R. A! r; j0 A; w9 ^. q S0 : if (w_i) z = 1'b1;9 d5 m H" R" ?6 W4 n
else z = 1'b0;
7 C1 f: X. s/ M0 a6 z default : z = 1'b0;* E. t/ d3 M' D3 {" M! j; M; H2 C, `
endcase[url=]http://common.cnblogs.com/images/copycode.gif[/url]3 H) E( U4 H1 F
$ |1 y- L. X. D! R8 o
使用1個always描述output logic。 以上3個always寫法與Moore FSM的3個always並無差異,基本上只要state diagram畫的出來,就能等效地用Verilog描述出來。 55行 // mealy output to delay 1 clk for moore
3 b* |/ p3 k# ]- ^; }# Jalways@(posedge clk or negedge rst_n)9 q. r; Y, z3 j9 J
if (~rst_n) z_o <= 1'b0;0 {! w: ^" z( V, c' ?6 x7 o
else z_o <= z;
1 q) B% C" z4 ?- G! R之前提到使用Mealy FSM會少Moore FSM 1個state,且output會早Moore FSM 1個clk,所以最後特別將output在敲一級delay 1個clk,這樣Mealy FSM就會完全與Moore FSM一樣。 使用3個always寫法有幾個優點: 1.可忠實地反映出原本的Mealy FSM硬體架構
9 L+ `4 c$ b8 W2.可輕易地將state diagram改用Verilog表示
9 ^+ p" S q0 I+ \3.將Next state logic與output logic分開,可降低code的複雜度,便於日後維護
. O1 l/ R0 i3 E: S# l5 e3個always是一個推薦的寫法。 2.使用2個always (兩段式) 由於要使用2個always去描述3個block,根據排列組合原理,C3取2,共有3種可能,我們一個一個討論。 2.1 state register與next state logic合一 http://images.cnblogs.com/cnblogs_com/oomusou/201106/201106062204201676.gif simple_fsm_mealy_2_always_0_cs_ns_good.v / Verilog [url=]http://common.cnblogs.com/images/copycode.gif[/url]
8 V3 n( I/ o" O 1 /* 3 J6 \+ G0 a+ Y3 S* I3 ]; M) B
2 (C) OOMusou 2011 http://oomusou.cnblogs.com y& d; R! S/ R
3
. S8 P3 ?& ^4 f 4 Filename : simple_fsm_mealy_2_always_0_cs_ns_good.v F( b; k; K# \; a1 O
5 Synthesizer : Quartus II 8.10 k1 U @9 j& ^0 u$ r+ X( }
6 Description : 2 always block for mealy fsm (GOOD)
v% x, ]/ l5 c; B$ S/ S. z( O 7 Release : Jun.05,2011 1.0
4 E" M2 `$ ?' y. }9 o/ W& V3 z" o. n 8 */
[+ l/ b# {- d$ o# P Q) s M 9
5 g# z4 ~! t1 Z# n. C% Y10 module simple_fsm (
3 P( B ]0 `- C11 clk,
' ?1 s) n6 ]9 e/ r12 rst_n,
* N0 Q, G, i/ N2 k$ l13 w_i,2 N2 o0 M7 _- K( n) O
14 z_o6 w9 F% i( B1 A+ Q+ g
15 );1 k. Z$ k& e5 }3 @; o. A4 l8 I8 {% L
16 ' u/ x: t5 p8 Q4 i) O& v. e" z
17 input clk;- p% }3 q9 f& y6 q- j. o9 N
18 input rst_n;- E& Z: ^ R N4 N2 m7 S
19 input w_i;
" s8 u. Y* E6 F20 output z_o;7 U2 v2 b6 z# g( l3 J5 f V
21 ; J1 f! }* ~( y
22 parameter IDLE = 2'b00;& e: P* @& S) ?$ }
23 parameter S0 = 2'b01;/ x' J5 d2 D$ J& m/ ^
24
/ W' @1 D6 ~9 j# ^25 reg [1:0] curr_state;& d+ ?7 l0 x3 T& P
26 reg z;+ t; E, l R9 K8 F1 U8 D1 x
27 reg z_o;
: Y4 ^/ f8 m# e" b7 a28
1 ~8 q. ~2 R. I; O: x29 // state reg + next state logic6 b: z$ P8 b% I7 p% B$ m. b
30 always@(posedge clk or negedge rst_n)
7 L! A2 R8 Q: O+ U; n31 if (~rst_n) curr_state <= IDLE;
2 r+ g; W; {. Z3 K% e$ ], Y1 i32 else1 [& Q* u) ^: n
33 case (curr_state): A- ?) P- @- U1 J
34 IDLE : if (w_i) curr_state <= S0;; \6 s1 _+ U2 g0 v# T$ X3 k
35 else curr_state <= IDLE;; m( f' ^4 F3 r5 [( l. x: T
36 S0 : if (w_i) curr_state <= S0;* t6 j" w5 q* M2 C2 W
37 else curr_state <= IDLE;! D' h- ~$ Z; f6 n4 V" N
38 default : curr_state <= IDLE;
6 W8 m, q& v$ G1 M39 endcase
3 Y$ m( u, o- g1 R/ e2 _$ Z2 X# [40 . \& ~, U( {: p, W6 o V- Y% [
41 // output logic9 @, g- l7 \! L
42 always@(*)
4 R1 ^7 M7 b6 e: G' ?% f% D43 case (curr_state)' a# f6 N1 u# B
44 IDLE : if (w_i) z = 1'b0;5 ?% v& b5 B) |- e2 a* Z
45 else z = 1'b0;
. K9 } N- v# i5 v* s# |46 S0 : if (w_i) z = 1'b1;
0 ?! w1 R- W2 e0 e* x( i47 else z = 1'b0;
2 T2 \$ G$ W' r) c* P2 M, z48 default : z = 1'b0;& g7 [: W- g; v9 O5 t
49 endcase+ n+ u. Y6 h, G+ L1 F
50 3 a1 c! V: r0 H
51 // mealy output to delay 1 clk for moore
2 k# e' x; p' E) e52 always@(posedge clk or negedge rst_n)& ]2 {" q$ y! j8 x2 {3 A8 h
53 if (~rst_n) z_o <= 1'b0;/ r0 d1 c+ B/ I3 K4 u
54 else z_o <= z;
" @7 V! C0 p9 V! m- i7 T. I55 , o9 B" B$ r/ F' E
56 endmodule[url=]http://common.cnblogs.com/images/copycode.gif[/url]
' s* U2 k# z2 q' X% [7 {9 k% I" K+ E9 X T; D9 i+ g2 x
29行 [url=]http://common.cnblogs.com/images/copycode.gif[/url]
5 p$ K3 F4 ^, o Z// state reg + next state logic
3 A5 Q- m" {8 W3 Jalways@(posedge clk or negedge rst_n)0 I( ^7 G9 I o2 _( T. A
if (~rst_n) curr_state <= IDLE;
0 Y- j& V7 g$ O else
# a) c, \3 x% _# q$ {7 y' _9 I8 r case (curr_state)0 J, }/ z" J, g! y! ?/ g( `
IDLE : if (w_i) curr_state <= S0;
' }) h0 I- Z0 w! I/ O5 _4 k else curr_state <= IDLE;; q F8 |. _ w
S0 : if (w_i) curr_state <= S0;
+ b4 `! S; v8 c8 _+ B/ A9 R* q else curr_state <= IDLE;% _+ X/ ?6 v' o5 A6 |
default : curr_state <= IDLE;
9 @- \$ x1 k4 L( l3 A* o% x w: Z endcase[url=]http://common.cnblogs.com/images/copycode.gif[/url]
/ U# {6 a7 D! h' o. G9 \. @- f4 O3 J: D3 E) M s
使用1個always同時描述state register與next state logic。 41行 [url=]http://common.cnblogs.com/images/copycode.gif[/url], G( Z+ m+ _* u6 ~# g2 T8 T! h6 c
// output logic
6 X( W% ?9 q; T q' A) dalways@(*)3 v1 H1 d- \( B% ?1 T( t2 W4 ]
case (curr_state)+ r- E) h! }4 H( l) L- a: \
IDLE : if (w_i) z = 1'b0;
9 d' q0 m9 Y$ f else z = 1'b0;) f! l! N% n8 e% z5 c
S0 : if (w_i) z = 1'b1;
( [* Q# a, h$ s else z = 1'b0;, u# Q* I' Z7 X' D% T) ^1 ^
default : z = 1'b0;
+ u$ \6 C# c+ C+ h' V% e* b+ ^+ ` endcase[url=]http://common.cnblogs.com/images/copycode.gif[/url]+ j, a5 |" e4 ?
3 T, N/ O _3 T7 C4 N使用1個always描述output logic。 以上2個always寫法(state register與next state logic合一)與Moore FSM的2個always寫法(state register與next state logic合一)並無差異,基本上只要state diagram畫的出來,就能等效地用Verilog描述出來。 51行 // mealy output to delay 1 clk for moore
" e' L9 Q$ `* ?5 ?always@(posedge clk or negedge rst_n)
; d6 X# [; h# J ] if (~rst_n) z_o <= 1'b0;
3 B* z6 ], c" l% R( ^9 |3 f else z_o <= z;' t4 _% j# I* y
之前提到使用Mealy FSM會少Moore FSM 1個state,且output會早Moore FSM 1個clk,所以最後特別將output在敲一級delay 1個clk,這樣Mealy FSM就會完全與Moore FSM一樣。 使用2個always (state register與next state logic合一)寫法有幾個優點: 1.程式碼較3個always寫法精簡% H* }# B7 n1 _& ^4 L
2.可輕易地將state diagram改用Verilog表示
1 P9 o" y T% ?5 T/ G3.因為state register原本程式碼就不多,將next state logic與state register合一後,next state logic仍與output logic分開,因此不會增加code的複雜度,便於日後維護
) M4 ~8 T$ Q2 }0 d/ u2 ^2個always (state register與next state logic合一)也是一個推薦的寫法。 接下來要討論的都是不推薦的寫法,主要目的是了解為什麼不推薦的原因。 2.2 state register與output logic合一 http://images.cnblogs.com/cnblogs_com/oomusou/201106/201106070634371434.gif 雖然理論上可以用1個always同時描述state register與output logic,但實際上做不到,因為Mealy FSM的output logic是目前state與input的純粹組合邏輯,與state register合一後,就必須使用nonblocking描述,之前Moore FSM還可以提前一個state去做判斷,但Mealy FSM還有input,該如何提前1個clk去判斷input呢? 2個always (state register與output logic合一)無法描述Mealy FSM。 2.3 next state logic與output logic合一 http://images.cnblogs.com/cnblogs_com/oomusou/201106/201106070634388892.gif simple_fsm_mealy_2_always_2_ns_ol_ng.v / Verilog [url=]http://common.cnblogs.com/images/copycode.gif[/url]0 r( _$ i' g1 X7 Y
1 /* 9 \! x0 s7 O k* m! H0 ~
2 (C) OOMusou 2011 http://oomusou.cnblogs.com
2 I9 M, r3 U% C) l& L( u: _3 K 3
' X; J' t! _8 S$ r, @ 4 Filename : simple_fsm_mealy_2_always_2_ns_ol_ng.v
* m, u, s# b& j- W: Y 5 Synthesizer : Quartus II 8.1& J, Y( k( q+ u! m- k
6 Description : 2 always block for mealy fsm (NO GOOD)
4 H1 r; i7 C% y$ I: M( v# G 7 Release : Jun.05,2011 1.04 w4 ?4 b' O& n" ], @9 i/ h. k
8 */
2 e; n, `- a2 X# p 9 " W1 C( @: h7 T' v0 i; J, \ Q
10 module simple_fsm (
/ h6 ]0 l. W* M$ V11 clk,
1 Y. K+ f3 [/ f12 rst_n,
0 o4 f" a5 r! h3 I* E) f- Q13 w_i,5 I$ E) h9 x! h/ V5 }: @& n4 C+ F
14 z_o* J: a4 q( d% K. C# F
15 );
* X% O& q- `5 j. Z7 U; A% O16 ) x* J! @9 R8 j
17 input clk;0 h. n/ B1 _' c" _
18 input rst_n;
* r' C8 o1 ^2 g2 _! I# y V19 input w_i;1 G k. d. Q, ]7 [+ p
20 output z_o;
) ]8 ?# }2 |/ N4 [' _* T/ K! b) g9 V6 I, Q21 7 R) w( s( ? C9 C7 _0 ~
22 parameter IDLE = 2'b00;& g5 _" @% d) X: h+ n4 c" Q5 y
23 parameter S0 = 2'b01;2 p% z; {' I9 p3 k0 `$ S& L
24
& s+ I/ k' K1 h! X. `& S$ f25 reg [1:0] curr_state;
( Q4 e0 u; n @ U; M# U) @- m& k26 reg [1:0] next_state;+ y! N* P7 B7 I+ A$ a* {
27 reg z;. |& U8 j9 U( v( E3 F
28 reg z_o;
, O& k( v! k' P+ c, x6 B29 / W7 @7 h# P3 k1 Q& I7 f
30 // state reg* ~, c: d) g% C* V
31 always@(posedge clk or negedge rst_n)
4 g3 z; a/ n5 L( w" _32 if (~rst_n) curr_state <= IDLE;# ^+ M9 ?; t9 j. e3 }# a( A% z
33 else curr_state <= next_state;0 h7 ?; ?* O0 Z& a
34
/ L2 v C9 s8 H35 // next state logic + output logic q- N0 ^7 L$ T6 A: u' I6 L
36 always@(*)
$ _7 q: { j) }9 P( [/ ?4 A37 case (curr_state)) F3 h, l+ T+ P5 G" ^
38 IDLE : if (w_i) {next_state, z} = {S0 , 1'b0};$ s1 E& ]: C, F
39 else {next_state, z} = {IDLE, 1'b0};, ?' V3 Q! H" Y
40 S0 : if (w_i) {next_state, z} = {S0 , 1'b1};$ }3 M* i" d2 d% m6 H y2 e
41 else {next_state, z} = {IDLE, 1'b0};
! s; f3 x, `( Q0 q* N/ J/ M5 a, g42 default : {next_state, z} = {IDLE, 1'b0};8 }1 s$ v0 Q. H2 \( L; X
43 endcase
9 z8 q2 E6 V9 K! |' J2 F44 + J( u( p. L# O; G* [* h: z! b8 v
45 // mealy output to delay 1 clk for moore
4 {7 O! n4 E/ |1 f( d0 o! t46 always@(posedge clk or negedge rst_n)) U% [7 N& U/ R/ c( n
47 if (~rst_n) z_o <= 1'b0;
, v+ N- r5 M/ p2 M& j5 H0 L& ?48 else z_o <= z; f" O7 i) K. f! T3 Q3 r
49
- O ~7 a$ T9 W7 }3 O50 endmodule[url=]http://common.cnblogs.com/images/copycode.gif[/url]4 y2 w- ^7 V8 r# r0 J* _
0 @% b' l) j, V8 [! x4 \9 N9 D, F30行 // state reg
t( h: @. v' i! V5 V' l. `' palways@(posedge clk or negedge rst_n)% x1 Y! a g7 t& n
if (~rst_n) curr_state <= IDLE;
# z# Q) D" C0 j9 c L else curr_state <= next_state;
. b" ]% J. F6 X" f使用1個always描述state register。 35行 [url=]http://common.cnblogs.com/images/copycode.gif[/url]& q6 N* V, j0 e8 ]
// next state logic + output logic 8 F) S% l" Q/ K9 L. m
always@(*)
. a# m! m- h# N case (curr_state)1 F2 |! F6 y1 ~8 D7 k: m
IDLE : if (w_i) {next_state, z} = {S0 , 1'b0};# ~0 ? n; _+ X$ l, `) d
else {next_state, z} = {IDLE, 1'b0};
6 u a, [+ ^ Y" S S0 : if (w_i) {next_state, z} = {S0 , 1'b1};4 k, w# L8 O- T
else {next_state, z} = {IDLE, 1'b0};$ b8 F5 t# k+ v( f2 f ^1 F
default : {next_state, z} = {IDLE, 1'b0};
7 D1 V( @$ c! m- X4 b9 |# W2 ~- n& r endcase[url=]http://common.cnblogs.com/images/copycode.gif[/url]; h$ Q9 b0 p& ~9 o- M
, D% `/ c6 O& ^- i4 _使用1個always同時描述next state logic與output logic,因為兩者都是純粹的組合邏輯,所以使用blocking。 45行 // mealy output to delay 1 clk for moore - c0 t+ R5 ^4 {
always@(posedge clk or negedge rst_n)
5 W6 C7 P% E1 @+ P- `! n+ I if (~rst_n) z_o <= 1'b0;
' v& I M- ?% u% D& c$ \0 w else z_o <= z;; i. A: G& G2 p1 K! ]
之前提到使用Mealy FSM會少Moore FSM 1個state,且output會早Moore FSM 1個clk,所以最後特別將output在敲一級delay 1個clk,這樣Mealy FSM就會完全與Moore FSM一樣。 使用2個always (next state logic與output logic合一)寫法的缺點: 將next state logic與output logic合一只會增加code的複雜度,日後維護會更加困難+ _* f7 s5 k: | g* h
不推薦2個always (next state logic與output logic合一)寫法。 3.使用1個always (一段式) http://images.cnblogs.com/cnblogs_com/oomusou/201106/201106070654206414.gif 理論上存在使用1個always同時描述next state logic、state register與output logic,但實際上做不到,理由與2個always (state register與output logic合一)的理由一樣,1個always必須使用nonblocking描述,而Mealy FSM的output logic是目前state與input的組合邏輯,我們無法提前1個clk去判斷input,所以無法使用1個always去描述。 1個always 無法描述Mealy FSM。 只要output logic使用nonblocking去描述,就無法實現Mealy FSM output。, ^! Z& W l8 q6 D
實務上推薦的coding style 如之前所述,實務上為了timing更好,常在Moore FSM的output logic再多敲一級,以下為推薦的coding style: http://images.cnblogs.com/cnblogs_com/oomusou/201107/201107192248215766.gif 1.使用2個always (兩段式) http://images.cnblogs.com/cnblogs_com/oomusou/201107/201107192137268414.gif simple_fsm_moore_2_always_0_cs_ns_good_pratical.v / Verilog [url=]http://common.cnblogs.com/images/copycode.gif[/url]
7 a& G2 t. _+ A a5 W8 ? u 1 /* ! m: t8 ~1 a7 {1 a% I. l
2 (C) OOMusou 2011 http://oomusou.cnblogs.com! d* r/ |' H* j* c4 t5 O5 K! G
3 ! k3 t1 d/ b: D( I! i5 j1 B
4 Filename : simple_fsm_moore_2_always_0_cs_ns_good.v
; n F# H. t0 }% a2 L 5 Synthesizer : Quartus II 8.1
0 t+ p6 E; ~/ V5 j X) F" p 6 Description : 2 always block for moore fsm (GOOD)) C9 [# e, Z$ }6 E+ N
7 Release : Jun.05,2011 1.0
0 ~( R2 Z! D. x 8 */- r t# U' \9 V% r& ]# n; T% h
9 . V y* M+ S0 u% d; i3 T% f. }
10 module simple_fsm (. p/ a+ V1 I; X& V! {" J Q
11 clk,
9 z0 `' X8 \, `! V _12 rst_n,
: L9 a$ j) e# i+ E: c6 x6 @13 w_i,6 y8 m9 {4 W6 [$ e6 A- h
14 z_o
5 B0 y9 Y7 Y7 M' i15 );
# `( @2 }6 ]8 X- g: i$ h3 M16
/ b$ i! s5 q. b# Y17 input clk;& P! i( U; w( r$ W! J( ?
18 input rst_n; O/ Y& N# ~% C n
19 input w_i;2 x- g8 B$ x9 P
20 output z_o;. H6 I& w$ m- J* d( ~% e: n
21
2 O+ i6 y0 j7 i8 D22 parameter IDLE = 2'b00;: r) R9 ~3 O7 j4 _( }
23 parameter S0 = 2'b01;9 J8 y; [% @; M# p: {2 [5 A
24 parameter S1 = 2'b10;
+ V/ j# W8 ~2 F! z' j6 ^25
+ O: { l3 z" {26 reg [1:0] curr_state;
' L. U9 c6 e6 Z2 O27 reg z_o;4 ?% E8 I! g7 g
28
* |! E$ N4 w4 B% J% \# g/ w; u- H& ^+ d29 // state reg + next state logic
& Z4 @7 ^# I- u* Q& [. a3 N" o! u4 M30 always@(posedge clk or negedge rst_n)( e! x& ~3 ]: x* G/ z6 x
31 if (~rst_n) curr_state <= IDLE;
, S& Y0 c b0 T4 E8 B4 j. o: r! p# L32 else0 ?7 O7 v' w J" A4 A2 ]
33 case (curr_state). X3 y- ~& _5 z
34 IDLE : if (w_i) curr_state <= S0;* B& {3 N7 N+ ~5 G- n. T5 }; d
35 else curr_state <= IDLE;6 l! W5 D4 {7 u/ C
36 S0 : if (w_i) curr_state <= S1;
; q/ p& }$ A6 c% N; n. L! v0 s37 else curr_state <= IDLE;1 @" q3 e. ]8 ? W& o
38 S1 : if (w_i) curr_state <= S1;( [7 m* s+ y" I: @$ l, P
39 else curr_state <= IDLE;
& X% I% R c8 p2 E40 default : curr_state <= IDLE;
" s/ j( ~7 D8 F" B5 I/ S41 endcase( E+ U" s) G& Z% h. Z2 ]
42 3 c& B% w' \! w* E! _5 Y
43 // output logic% }$ H' [1 P9 M( n- K: ?% u/ }
44 always@(posedge clk or negedge rst_n)
3 ^+ C3 D( U# i. b45 if (~rst_n)
, K# l8 ~- g4 a2 r46 z_o <= 1'b0;
' q6 o; `) u) ]. J# N! x47 else
% t1 Y( d- h9 K, i9 Z48 case (curr_state)1 q' j2 R; i6 i& q! u6 {
49 IDLE : z_o <= 1'b0;6 U% |8 H. M/ b+ u6 x. U
50 S0 : z_o <= 1'b0;2 Y$ G/ p0 J; y7 o: j7 r ?2 A
51 S1 : z_o <= 1'b1;. @2 ]- ^$ ~' w. e+ R
52 default : z_o <= 1'b0;
" B8 ?$ r3 q4 S" Q h/ B1 o& i53 endcase
2 N; J. m" R: s2 D" B/ a( Y54
# d, P, A* t! R55 endmodule[url=]http://common.cnblogs.com/images/copycode.gif[/url]( b3 I$ C/ T$ M7 J7 A
# y0 U& B: d' _6 q* A
29行 [url=]http://common.cnblogs.com/images/copycode.gif[/url]: v; r1 {' [# q7 G( O B2 @
// state reg + next state logic0 {# }8 x- o/ {4 @8 Q
always@(posedge clk or negedge rst_n)
6 [, p- `- O# x& d if (~rst_n) curr_state <= IDLE; ?% M$ R$ O5 B N% |% y2 r: |
else
" R i. ~* j- O3 e7 b% l$ |' m case (curr_state)
; ~5 Y* Y. s. j* |1 v, h8 Z: v IDLE : if (w_i) curr_state <= S0;, O% z# g; `' C, M- O+ }6 s
else curr_state <= IDLE;- {5 i5 _( U& R7 g4 ~, @/ v) `0 l' e
S0 : if (w_i) curr_state <= S1;
5 A. ?# t; S/ m# O0 S6 v5 e else curr_state <= IDLE;
+ E: g' c+ s6 b. M9 S' t S1 : if (w_i) curr_state <= S1;
% ]& T/ r3 w. K" S else curr_state <= IDLE;
2 _8 l4 n: p$ a/ G1 x default : curr_state <= IDLE;
1 z% A2 x0 B' S" v endcase[url=]http://common.cnblogs.com/images/copycode.gif[/url]) R) w/ e1 t: c
' B$ G0 w5 j3 ]1 v使用2個always,且state register與next state logic合一,只要判斷curr_state即可,不用擔心是否要提早1個clk判斷。 43行 [url=]http://common.cnblogs.com/images/copycode.gif[/url]
0 X5 u7 K; ~9 w7 Y# i3 G// output logic' X3 F& E; [$ M
always@(posedge clk or negedge rst_n)- m; v% |% |5 ^/ m6 d/ I2 ?
if (~rst_n)
) m) h% S" F& ~1 g) v& {9 s+ m. l8 l z_o <= 1'b0;
3 K. x- }, u7 E else
' a" N) n. {, {: P% \ case (curr_state)
# n6 _- U% u/ M, w0 l9 S) ? IDLE : z_o <= 1'b0;9 \- Z( c# H4 C5 [' a: J' R! O# M
S0 : z_o <= 1'b0;- ^& j3 x1 a4 D
S1 : z_o <= 1'b1;% z% W& u2 \0 e4 a( N) y* Y) f
default : z_o <= 1'b0;
: Z* g. N. R6 j I, B- K8 c endcase[url=]http://common.cnblogs.com/images/copycode.gif[/url]
) y- [7 E# J" k
4 I7 a1 d/ `% P/ u! J) Foutput logic也敲clk,只要判斷curr_state即可,不用擔心是否要提早1個clk判斷。 2.使用3個always (三段式) http://images.cnblogs.com/cnblogs_com/oomusou/201107/201107192138251792.gif simple_fsm_moore_3_always_practical.v / Verilog [url=]http://common.cnblogs.com/images/copycode.gif[/url]# [+ Q. J8 R" o/ ^ Y# F& Y8 B
1 /* + J7 o" d/ Z" m4 t
2 (C) OOMusou 2011 http://oomusou.cnblogs.com
& ?- H! _. _# w# U 3
2 |8 w& u: y% m 4 Filename : simple_fsm_moore_3_always_practical.v: V, Q" d1 ~' X
5 Synthesizer : Quartus II 8.16 O- S2 P7 Z. A2 |- W# P
6 Description : 3 always block for moore fsm (BEST) T. H' L: o7 X5 C" ~2 [& d* }
7 Release : Jun.05,2011 1.0
% Z& ]. V; g4 C3 S$ g S9 D3 `5 S 8 */
) p2 E- x( N8 ~$ Z8 X+ o g; \ 9 # J% Q* e0 x. G. y5 B& G- K
10 module simple_fsm (7 R; s# j7 g a. f8 w" o8 I/ O
11 clk,: i4 e, |4 M( d6 a V% Y3 D
12 rst_n,6 N% `% x: ?" j7 l' w' x
13 w_i,( u! j; c' u+ j8 n
14 z_o
j' `) ~! |, k) J8 v+ X15 );
2 V% O0 k% E9 V" s) W16 [4 c: ~. ^3 e9 q3 I
17 input clk;1 h# s$ ~+ y/ U; O
18 input rst_n;
7 H: a! U7 |4 g" O19 input w_i;
) B$ I* @1 o- B6 |# o) {$ f20 output z_o;5 Z6 R4 W, T q5 U
21 2 w% e# h& q- ~3 u5 Z1 P2 o' D
22 parameter IDLE = 2'b00;$ k. V: v( E, V: J- d7 O+ Q
23 parameter S0 = 2'b01;7 W- m6 x! p, I+ @' C0 u b/ e6 c
24 parameter S1 = 2'b10;! N M* J4 a' p
25 * {* Y: P' C0 i
26 reg [1:0] curr_state;
- a8 I8 S* I, Z1 ]. D1 Y% v27 reg [1:0] next_state;% x" M$ @5 c4 k) W+ {. r3 c
28 reg z_o;0 Y& D' s+ D r
29 " I* t, E1 r& y! y; ~- m
30 // state reg
! G4 S8 N0 o$ p% }" [31 always@(posedge clk or negedge rst_n)
+ \' M* M7 [! o p; ~- M/ E32 if (~rst_n) curr_state <= IDLE;
/ S# H2 v# w+ U; J _: {4 U! S33 else curr_state <= next_state;9 ]" S1 I) W+ i8 o6 V
34
: Q) `, N/ {! N6 k; Y1 Q( O35 // next state logic ; j' y/ b# J7 |6 Y
36 always@(*)1 D) T* [8 c! j! j
37 case (curr_state)
) K" w' ~. k/ Z% p1 R8 y38 IDLE : if (w_i) next_state = S0;2 ~$ @6 k/ p9 I8 o+ N
39 else next_state = IDLE;
2 P& j, ^7 Z2 e2 n40 S0 : if (w_i) next_state = S1;3 }2 _- S9 T5 D" q$ _ {
41 else next_state = IDLE;
7 N( R/ B& y j9 {# g. N42 S1 : if (w_i) next_state = S1;
. b( A0 l3 b4 [) S/ b& @' I43 else next_state = IDLE;
2 i4 O' _4 G6 ^! e1 ~2 {7 a44 default : next_state = IDLE;3 j7 i" R" M" D$ b/ w. z2 ?# S
45 endcase
: [( `* \* d% G4 u- s8 u, r/ y5 p46
3 m. b" f3 k: O: |47 // output logic5 R1 y8 r" v) ~0 I O) a: {
48 always@(posedge clk or negedge rst_n)
+ B' Z6 q I. p0 |0 @- K49 if (~rst_n) z_o <= 1'b0;
+ J) E$ r7 c' ~! T1 }, ^50 else - R" C% z3 M* \8 U6 R' P. m' P
51 case (curr_state)4 w% ~; T9 m; X9 r6 w6 l' D& T
52 IDLE : z_o <= 1'b0;2 _3 N7 G1 o) W7 B3 i
53 S0 : z_o <= 1'b0;
/ h& @1 \6 a& N+ I: |) {$ e54 S1 : z_o <= 1'b1;! k! d s7 z% }
55 default : z_o <= 1'b0;
+ |# h/ W; x4 \" ?' ^$ [) p56 endcase
$ T: r4 h0 ^. W6 f) h0 D57
5 h, W4 }4 X: s$ a7 q5 B: l58 endmodule[url=]http://common.cnblogs.com/images/copycode.gif[/url]
) p. a' [$ s! N9 M4 y6 G! t5 n7 ], g
5 w6 y5 O( S; {9 G30行 // state reg
: T/ M& w; j+ ?) malways@(posedge clk or negedge rst_n)
. B" Q* y8 ~: {& _+ j7 b& X' z if (~rst_n) curr_state <= IDLE;
6 w/ z# r0 F E. }2 n$ {0 h8 T else curr_state <= next_state;/ F `- |3 d2 {# Z6 D
使用1個always描述state register。 35行 [url=]http://common.cnblogs.com/images/copycode.gif[/url]+ q( P9 U. y+ r; k! N3 q) o2 a
// next state logic 8 H& f. \+ \) A) e
always@(*)
% h* U# J9 T5 ~5 M, P! f! J case (curr_state); O. u$ A* F: m$ n' K. r& M
IDLE : if (w_i) next_state = S0;* V( t# t0 ~; p( ~9 s* t0 A" F9 U
else next_state = IDLE;2 f& R& M# O3 L
S0 : if (w_i) next_state = S1;
5 E" V8 H9 f0 R& O else next_state = IDLE;
# h- g- r0 v# Z* k S1 : if (w_i) next_state = S1;) X# f ?, P$ X# }+ q
else next_state = IDLE;2 ^1 W& w( x7 D: n" [
default : next_state = IDLE;. Q* m2 E+ }3 W0 s6 }' I+ @
endcase [url=]http://common.cnblogs.com/images/copycode.gif[/url]( l2 k- ]9 |, r& b7 Q: @
# T& W) Y: v6 Y) c! s使用1個always描述next state logic,為純粹組合邏輯,所以使用blocking。 47行 [url=]http://common.cnblogs.com/images/copycode.gif[/url]
0 L2 ]9 r. K( m// output logic* d" u) n' Z! U
always@(posedge clk or negedge rst_n)
3 k6 [) Q+ U6 c8 l } if (~rst_n) z_o <= 1'b0;
) f. M: E0 G$ Z+ n else 2 |* V* D4 u" T: r8 C2 J4 M8 F3 K( S
case (curr_state)
4 C# w6 Y5 [4 N P& D IDLE : z_o <= 1'b0;
|$ }& D ^, ]7 h( p4 v S0 : z_o <= 1'b0;% V g3 q. l5 c" Z- `
S1 : z_o <= 1'b1;
# J) \% t e6 P" U* S default : z_o <= 1'b0;7 d7 z9 J8 B7 i) O
endcase[url=]http://common.cnblogs.com/images/copycode.gif[/url]
3 P& d8 I/ H1 ]
- u- W- D& M- D9 h" N7 N! C9 s* P使用1個always描述output logic,因為output logic也敲clk,只要判斷curr_state即可,不用擔心是否要提早1個clk判斷。 看到這裡,或許你會問:『為了timing好,多敲一級會多delay一個clk,若我output logic提前1個clk用next_state判斷,不就既可有較好的timing,也不會多delay一個clk?』 http://images.cnblogs.com/cnblogs_com/oomusou/201107/20110719225555853.gif 1.使用3個always (三段式) http://images.cnblogs.com/cnblogs_com/oomusou/201107/201107192310123304.gif simple_fsm_moore_3_always_practical2.v / Verilog [url=]http://common.cnblogs.com/images/copycode.gif[/url]- s: _+ I. M# a
1 /* ' j7 k& n9 c$ ]
2 (C) OOMusou 2011 http://oomusou.cnblogs.com; i* A) J/ Y, G" v4 n6 V
3
2 R1 v7 r- x+ W' ` 4 Filename : simple_fsm_moore_3_always_practical2.v) D1 |; [" a- a3 v, d2 ]1 B
5 Synthesizer : Quartus II 8.1
( v j# J* k/ v9 k4 _1 V2 T 6 Description : 3 always block for moore fsm (BEST)2 I0 f& Y" Q/ ?, f
7 Release : Jun.05,2011 1.0
. R4 w& h$ u9 L5 t 8 */
! T! n, W: ?; ^ G w 9
) X i% { Q% L7 T10 module simple_fsm (2 h- [) L, o' Q# [) C$ ]7 w# M
11 clk," d& p- D$ A; o' ^
12 rst_n,! K) R7 L0 Z1 Y. S
13 w_i,* z0 R. O2 q' c% V* x2 d
14 z_o
8 V! B3 p, J. m# i( B2 C15 );, |, c5 P& C- G6 v) ^
16 # f4 u/ o0 l+ i; z8 K. l% b( B5 b
17 input clk;
$ t; _& M3 c3 Z9 E, e8 Z7 Z) t+ r18 input rst_n;% r8 p! K/ i. L/ w8 a; b$ |
19 input w_i;' @2 }2 Z0 a7 j" x* {
20 output z_o;( O# O5 ?% i7 O/ A" N
21 $ p% v; P4 {# ~
22 parameter IDLE = 2'b00;/ ]$ @5 Z% D _$ c$ ^
23 parameter S0 = 2'b01;
9 U. w9 B5 }# W24 parameter S1 = 2'b10;4 S/ F& L$ R2 s3 Y" v) |
25 9 q6 ]) T. B- e6 D
26 reg [1:0] curr_state;8 T$ e F |% I
27 reg [1:0] next_state;
/ S: _ ]/ @3 _4 g28 reg z_o;
, i4 u3 | M& T6 P* m1 g29
( @# ?7 T( _" _% ]7 x% u8 d$ T8 I30 // state reg
' E5 [0 o' m7 h3 g31 always@(posedge clk or negedge rst_n)9 ?4 e# K7 G6 a/ \
32 if (~rst_n) curr_state <= IDLE;( `+ R [. b( o6 U
33 else curr_state <= next_state;( [. N8 J( j" h7 b' o6 W
34 ( g4 o6 p$ c; w3 G* Z" q
35 // next state logic * j8 ?1 d G! } @5 v6 u! C. Z' `
36 always@(*)
0 ?- U+ D, G$ b0 r/ V: U5 B37 case (curr_state)
; v9 B- E; N( N0 k6 c: u6 P, }, Q# R+ `38 IDLE : if (w_i) next_state = S0; Z; d- d, C, |: z6 S9 ^+ `$ ^* s0 C5 K
39 else next_state = IDLE;- b4 A6 W$ ^ {
40 S0 : if (w_i) next_state = S1;
D. X& \# u x/ R' v: Z41 else next_state = IDLE;& t9 W6 {% a( y
42 S1 : if (w_i) next_state = S1;
- y$ v* Y" c% b4 j5 }% ~43 else next_state = IDLE;
9 P H: l2 y) J; {1 U44 default : next_state = IDLE;
( O/ {5 W% E% f: ^7 `" K8 r4 @5 R45 endcase
' T# k0 H; M7 J+ P$ [46 4 f6 h5 x$ Y8 O, w5 v4 A
47 // output logic+ E& P0 s7 a M7 o
48 always@(posedge clk or negedge rst_n)6 T' H p7 x: T$ s1 U
49 if (~rst_n) z_o <= 1'b0;
" S1 _4 Q- m6 F9 G- c' C" o, D, i50 else
# e1 w8 ]! I+ r9 T9 X$ P1 I# L! i5 K) c51 case (next_state)
/ b$ R: f+ M+ ?* F+ n$ \7 T$ p52 IDLE : z_o <= 1'b0;
7 j$ K# ]: X, c6 ?53 S0 : z_o <= 1'b0;
; F2 m6 N0 X8 ?. P; ~54 S1 : z_o <= 1'b1;% i* i6 c2 A4 B
55 default : z_o <= 1'b0;$ k9 i3 Z- `' |0 l; m
56 endcase- p- v& v( C' T3 y) p
57
% }& Z: U& \5 \. ^+ Z D58 endmodule[url=]http://common.cnblogs.com/images/copycode.gif[/url] n0 x9 D+ B8 J% ?- X
$ t! k2 h) ~+ i# I3 h( L
47行 [url=]http://common.cnblogs.com/images/copycode.gif[/url]4 f; z. @0 _0 W- k
// output logic2 B' G6 D! }' R" v% D/ Z
always@(posedge clk or negedge rst_n)/ Z4 N( K& _; z5 Q3 C t5 b
if (~rst_n) z_o <= 1'b0;- y* a1 D; | K
else 8 F0 w) W$ l# c7 ]+ ~( W) W2 ^; S& Z
case (next_state)
; E9 b4 M. p9 Q1 j2 z, D IDLE : z_o <= 1'b0;
; y2 z' [$ ~$ S8 U" w2 S S0 : z_o <= 1'b0;% R( c6 X# R# ?3 o
S1 : z_o <= 1'b1;
* w& \0 L i, X1 i5 D default : z_o <= 1'b0;8 Q1 \7 ]2 S/ K. b3 R
endcase[url=]http://common.cnblogs.com/images/copycode.gif[/url]
0 p' r* S7 x5 s/ d7 s
7 b. Q% R! a2 @) i5 m: ]: ~- |+ z) o使用1個always去描述output logic,重點是,使用next_state去判斷,因此可以提早一個clk,這樣無論是在Simulator或者經過Synthesizer合成後的結果都會一樣,而且既可在output敲過D flip-flop,也不會多delay一個clk。 不過這種寫法也不是沒有缺點,由於next_state本身是一個純粹的組合邏輯,拿來當output logic的判斷,timing會稍微差一點,很可能critical path就出現在這裡,前一個例子的output logic用的是curr_state,是一個D flip-flop,沒有組合邏輯,所以timing比較好。 另外一個缺點是output logic必須判斷next_state,很容易出錯,觀念必須非常清楚。 . T( m# L* a$ X% p# v$ W' m
|