1 reg[3:0] cs, ns;2 always @(posedge clk or negedge rst_n) begin
3 if (!rst_n) begin
4 cs <= idle;
5 cmd <= 3'b111;
6 end
7 else begin
8 case (cs)
9 idle : if (wr_req) begin cs <= wr_s1; cmd <= 3'b011; end
10 else if (rd_req) begin cs <= rd_s1; cmd <= 3'b011; end
11 else begin cs <= idle; cmd <= 3'b111; end
12 wr_s1: begin cs <= wr_s2; cmd <= 3'b101; end
13 wr_s2: begin cs <= idle; cmd <= 3'b111; end
14 rd_s1: if (wr_req) begin cs <= wr_s2; cmd <= 3'b101; end
15 else begin cs <= rd_s2; cmd <= 3'b110; end
16 rd_s2: if (wr_req) begin cs <= wr_s1; cmd <= 3'b011; end
17 else begin cs <= idle; cmd <= 3'b111; end
18 default : cs <= idle;
19 endcase
20 end
21 end
1 reg[3:0] cs, ns;2 //---------- 時序邏輯 ------------------
3 always @(posedge clk or negedge rst_n) begin
4 if (!rst_n)
5 cs <= idle;
6 else
7 cs <= ns;
8 end
9 //---------- 組合邏輯 ------------------
10 always @(*) begin
11 case (cs)
12 idle : if (wr_req) begin cs <= wr_s1; cmd <= 3'b011; end
13 else if (rd_req) begin cs <= rd_s1; cmd <= 3'b011; end
14 else begin cs <= idle; cmd <= 3'b111; end
15 wr_s1: begin cs <= wr_s2; cmd <= 3'b101; end
16 wr_s2: begin cs <= idle; cmd <= 3'b111; end
17 rd_s1: if (wr_req) begin cs <= wr_s2; cmd <= 3'b101; end
18 else begin cs <= rd_s2; cmd <= 3'b110; end
19 rd_s2: if (wr_req) begin cs <= wr_s1; cmd <= 3'b011; end
20 else begin cs <= idle; cmd <= 3'b111; end
21 default : cs <= idle;
22 endcase
23 end
1 reg[3:0] cs, ns;(1)一段式狀態機不利於維護(簡單狀態機可以用);2 //---------- 時序邏輯 ------------------
3 always @(posedge clk or negedge rst_n) begin
4 if (!rst_n)
5 cs <= idle;
6 else
7 cs <= ns;
8 end
9 //---------- 組合邏輯 ------------------
10 always @(*) begin
11 case (cs) //現態
12 idle : if (wr_req) begin cs <= wr_s1; end
13 else if (rd_req) begin cs <= rd_s1; end
14 else begin cs <= idle; end
15 wr_s1: begin cs <= wr_s2; end
16 wr_s2: begin cs <= idle; end
17 rd_s1: if (wr_req) begin cs <= wr_s2; end
18 else begin cs <= rd_s2; end
19 rd_s2: if (wr_req) begin cs <= wr_s1; end
20 else begin cs <= idle; end
21 default : cs <= idle;
22 endcase
23 end
24 //---------- 時序邏輯 ------------------
25 always @(posedge clk or negedge rst_n) begin
26 if (!rst_n)
27 cmd <= 3'b011;
28 else begin
29 case (ns) //次態
30 idle : if (wr_req) begin cmd <= 3'b011; end
31 else if (rd_req) begin cmd <= 3'b011; end
32 else begin cmd <= 3'b111; end
33 wr_s1: begin cmd <= 3'b101; end
34 wr_s2: begin cmd <= 3'b111; end
35 rd_s1: if (wr_req) begin cmd <= 3'b101; end
36 else begin cmd <= 3'b110; end
37 rd_s2: if (wr_req) begin cmd <= 3'b011; end
38 else begin cmd <= 3'b111; end
39 default : ;
40 endcase
41 end
42 end
(2)兩段式狀態機是常見寫法,時序邏輯進行狀態切換,時序邏輯實現各個輸入、輸出以及狀態判斷,利於維護,不過組合邏輯容易出現毛刺等常見問題;
(3)三段式狀態機推薦寫法,**易維護,時序邏輯輸出解決了兩段式寫法種組合邏輯的毛刺問題,但是耗費資源多一些且三段式從輸入到輸出比一段式和兩段式會延時乙個時鐘週期。
**:
Verilog 狀態機寫法
狀態機是時序電路的 所有時序電路都能通過狀態機實現。以前寫程式時喜歡用一段式狀態機,現在流行用三段式。好象三段時也沒多大優點。在cpld中暫存器較少,個人感覺用一段式也可以,主要是省資源。時序電路的狀態是乙個狀態變數集合,這些狀態變數在任意時刻的值都包含了為確定電路的未來行為而必需考慮的所有歷史資訊...
三種狀態機 分析 對比和小結
本文簡化所有邏輯重點講解狀態機的框架。先給幾點小結 小結1.在原理圖和實際變現上來說,一段式和三段式完全一致,但在 量大的情況下三段式 更容易維護。小結2.二段式的輸出由組合邏輯驅動,不僅可能輸出毛刺,而且不利於時許約束 分析。小結3.狀態機有著流水線的 缺點 上電之初若不全面指定初始狀態,則可能有...
描述狀態機的三種方法 小結
author ssszw email szwsongzhengwei 163.com 用乙個 always 模組用時序邏輯電路同時描述狀態轉移和狀態輸出。使用時序邏輯電路和組合邏輯電路同時描述狀態的轉移和輸出 always posedge clk begin case current state s...