四段式狀態機
在 FPGA中,相信有FPGA學習經驗的都能了解,現在流行的狀態機設計,一般可分為一段式、兩段式和三段式,如果不了解的,可以自行百度。 上面的三種設計法雖然很流行,但設計時仍然要考慮很多因素,導致總是要反反復復調試才能設計成功。這不符合明德揚一次考慮一個因素、一次性設計正確的設計理念。為此,明德揚特推出四段式狀態機的寫法。
四段式不是指三個always代碼,而是四段程序。使用四段式的寫法,可參照明德揚GVIM特色指令Ztj產生的狀態機模板。 第一段,同步時序的always模塊,格式化描述次態遷移到現態寄存器。
1 2 3 4 5 6 7 8
|
always@(posedge clk or negedge rst_n)begin if(!rst_n)begin state_c <= IDLE; end else begin state_c <= state_n; end end
|
第二段,組合邏輯的always模塊,描述狀態轉移條件判斷。注意轉移條件用信號來表示,信號名要按明德揚規則來命名。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
|
always@(*)begin case(state_c) IDLE:begin if(idle2s1_start)begin state_n = S1; end else begin state_n = state_c; end end S1:begin if(s12s2_start)begin state_n = S2; end else begin state_n = state_c; end end S2:begin if(s22idl)begin state_n = IDLE; end else begin state_n = state_c; end end default:begin state_n = IDLE; end endcase end
assign idle2s1_start = state_c==IDLE && ; assign s12s2_start = state_c==S1 && ; assign s22idl_start = state_c==S2 && ;
|
第三段,用assign定義轉移條件。注意條件一定要加上現態。
1 2 3
|
assign idle2s1_start = state_c==IDLE && ; assign s12s2_start = state_c==S1 && ; assign s22idl_start = state_c==S2 && ;
|
第四段,設計輸出信號。明德揚規范要求一個always設計一個信號,因此有多少個輸出信號,就有多少個always。
1 2 3 4 5 6 7 8 9 10 11
|
always @(posedge clk or negedge rst_n)begin if(!rst_n)begin out1 <=1'b0 end else if(state_c==S1)begin out1 <= 1'b1; end else begin out1 <= 1'b0; end end
|
明德揚四段式狀態機符合一次只考慮一個因素的設計理念。第一段代碼,照抄格式,完全不用想其他的。第二段代碼,只考慮狀態之間的跳轉,也就是說各個狀態機之間跳轉關系。第三段代碼,只考慮跳轉條件。第三段,每個信號逐個設計。 明德揚為了保證一次設計正確,還制定了一些規范。例如第二段的跳轉條件,只準用信號名代替,并且制定了跳轉條件的命名規范,1是解決了命名困難的問題,2是對轉移條件一目了然,如idl2s1_start,就可以看出是IDLE跳到S1狀態的條件。還有,明德揚規定轉移條件的格式,一定是“ 當前狀態&&具體條件”,以防想不到的情況出現。有了這些規范的保證,無論多復雜的場合,任何設計都能有條理、有步驟地一次性設計正確。
|