本文詳細介紹了可綜合有限狀態機的Verilog coding styles,以及one-always FSMs和two-always FSMs的優缺點。
State Machine Classification
根據狀態機輸出生成的方式有兩種類型狀態機,
Moore State Machine,輸出僅是當前狀態(present state)的函數。
Mealy State Machine, 輸出是當前狀態和輸入的函數。可以看到下圖中的虛線標註了Mealy State Machine Only
除了根據狀態輸出的生成方式分類,還可以根據狀態編碼的方式進行分類, binary-encode,gray-encode, Johnson-encode, one-hot-encode。
FSM Verilog Modules
Guideline:使用一個單獨的模塊(module)編碼狀態機,方便狀態機定義(definition)、修改(modification)和調試(debug)。
State Assignments
Guideline:使用symbolic parameters進行狀態賦值,增加可讀性,簡化狀態的修改
下面是相應的binary encoding和one-hot encoding
Parameter definitions for binary encoding
parameter [2:0] // synopsys enum codeIDLE = 3'd0,S1 = 3'd1,S2 = 3'd2,S3 = 3'd3,ERROR = 3'd4;Parameter definitions for verbose one-hotencoding
parameter [4:0] IDLE = 5'b00001,S1 = 5'b00010,S2 = 5'b00100,S3 = 5'b01000,ERROR = 5'b10000;Theone-hot encoding can yield very efficient FSMs for state machines that have many interconnections with complex equations, including a large number of connections to one particular state. State Machine Coding styles for Synthesis(後面會實例分析這個問題)
也可以使用宏定義(`define)定義狀態名稱, `define會創建一個全局定義(global definition),parameters會創建一個局部定義(local definition),從而parameters定義允許設計在不同的模塊具有多個同名的之間狀態定義,例如IDLE。
Two-Always Block State Machine
Two-Always狀態機包含生成下一狀態的組合邏輯(next state combinational logic)、生成輸出的組合邏輯(output combinational logic)和更新當前狀態的時序邏輯(clocked present state logic)。
Sequential Always Block
Guideline:在建模時序邏輯時,僅使用Verilog非阻塞賦值。(當然,這也不全對,參考使用阻塞賦值和非阻塞賦值建模的分頻時鐘)
always @(posedge clk or posedge rst)if (rst) state <= IDLE;else state <= next;Combinational Always Block
Guideline:在建模組合邏輯always語句塊中僅使用阻塞賦值。
該always語句塊用於獲得需要被更新的下一個狀態值,其被一個敏感列表(當前狀態和輸入)。
應該在always語句塊之後編碼一個默認的下一個狀態賦值語句。默認賦值可以是X(綜合工具don't cares)、IDLE和任意狀態。因為存在組合邏輯綜合出鎖存器問題,這在實例解析Verilog綜合出鎖存器的問題中曾經探討過。
always @(state or i1 or i2 or i3 or i4) beginnext = IDLE;case (state)IDLE: begin next = ERROR; if (!i1) next = IDLE; if (i1 & i2) next = S1; if (i1 & !i2 & i3) next = S2;endS1: ...
FSM Output Generation
輸出邏輯可在編碼在連續賦值assign中
assign rd_out = (state == READ) & !rd_strobe_n;也可以編碼在組合邏輯always語句塊中。
case(state) ... READ: if (!rd_strobe_n) rd_out = 1'b1;One-Always Block State Machine
one-always狀態機比two always的仿真效率更高,但是難以修改和調試。
往期精彩
Reference paper :
http://bbs.eetop.cn/thread-870738-1-1.html