本篇文章描述狀態(tài)機的一段式、二段式、三段式區(qū)別
一、狀態(tài)機
再次給出狀態(tài)機的示意圖:
1.1、摩爾型,輸出只與狀態(tài)寄存器的輸出狀態(tài)有關
1.2、米粒型,輸出不僅與狀態(tài)寄存器的輸出狀態(tài)有關,還與組合邏輯的輸入有關
二、一段式、二段式、三段式區(qū)別
根據(jù)狀態(tài)機的結構,狀態(tài)機描述方式 可分為:一段式、二段式、三段式
1.1、一段式
整個狀態(tài)機寫到一個 always 模塊里面。在該模塊中既描述狀態(tài)轉(zhuǎn)移,又描述狀態(tài)的輸入和輸出。
1.2、二段式
用兩個 always 模塊來描述狀態(tài)機。
1.2.1、其中一個 always 模塊采用同步時序描述狀態(tài)轉(zhuǎn)移;
1.2.2、另一個 always模塊采用組合邏輯判斷狀態(tài)轉(zhuǎn)移條件,描述狀態(tài)轉(zhuǎn)移規(guī)律及其輸出,注意組合邏輯輸出要用阻塞賦值。
1.3、三段式
在兩個 always 模塊描述方法基礎上,使用三個 always 模塊。
1.3.1、 一個 always 模塊采用同步時序描述狀態(tài)轉(zhuǎn)移;
1.3.2、一個 always 采用組合邏輯判斷狀態(tài)轉(zhuǎn)移條件,描述狀態(tài)轉(zhuǎn)移規(guī)律,注意組合邏輯輸出要用阻塞賦值;
1.3.3、另一個 always 模塊描述狀態(tài)輸出(可以用組合電路輸出,也可以時序電路輸出),注意組合邏輯輸出要用阻塞賦值。
1.4、綜合
可以看出兩段式有限狀態(tài)機與一段式有限狀態(tài)機的區(qū)別是將時序部分(狀態(tài)轉(zhuǎn)移)和組合部分(判斷狀態(tài)轉(zhuǎn)移條件和產(chǎn)生輸出)分開,寫為兩個always語句,即為兩段式有限狀態(tài)機。將組合部分中的判斷狀態(tài)轉(zhuǎn)移條件和產(chǎn)生輸出再分開寫,則為三段式有限狀態(tài)機。
三、自動售貨機、一段式
module auto_sell( input clk, input rst_n, input coin_one, input coin_half, output reg water, output reg coin_back ); parameter ZERO = 3'b000; parameter HALF = 3'b001; parameter ONE = 3'b010; parameter ONE_HALF = 3'b011; parameter TWO = 3'b100; //一段式狀態(tài)機 reg [2:0] status; always@(posedge clk,negedge rst_n)begin if(!rst_n) begin status <= ZERO; water <= 0; coin_back <= 0; end else case(status) ZERO : begin water <= 0; coin_back <= 0; if(coin_half) status <= HALF; else if(coin_one) status <= ONE; else status <= status; end HALF : begin water <= 0; coin_back <= 0; if(coin_half) status <= ONE; else if(coin_one) status <= ONE_HALF; else status <= status; end ONE : begin water <= 0; coin_back <= 0; if(coin_half) status <= ONE_HALF; else if(coin_one) status <= TWO; else status <= status; end ONE_HALF : begin if(coin_half) begin status <= TWO; water <= 1'b0; coin_back <= 1'b0; end else if(coin_one) begin status <= ZERO; water <= 1'b1; coin_back <= 1'b0; end else begin status <= status; water <= 1'b0; coin_back <= 1'b0; end end TWO : begin if(coin_half) begin status <= ZERO; water <= 1'b1; coin_back <= 1'b0; end else if(coin_one) begin status <= ZERO; water <= 1'b1; coin_back <= 1'b1; end else begin status <= status; water <= 1'b0; coin_back <= 1'b0; end end default: begin status <= ZERO; water <= 1'b0; coin_back <= 1'b0; end endcase end endmodule
四、自動售貨機、二段式
1.1、二段式,寫法一
module auto_sell( input clk, input rst_n, input coin_one, input coin_half, output reg water, output reg coin_back ); parameter ZERO = 3'b000; parameter HALF = 3'b001; parameter ONE = 3'b010; parameter ONE_HALF = 3'b011; parameter TWO = 3'b100; //--------------------二段式 1 ok-------------------------- //二段式狀態(tài)機 reg [2:0] c_status; reg [2:0] n_status; //狀態(tài)轉(zhuǎn)移 always@(posedge clk,negedge rst_n)begin if(!rst_n) c_status <= ZERO; else c_status <= n_status; end //描述狀態(tài)轉(zhuǎn)移規(guī)律以及輸出 always@(posedge clk,negedge rst_n)begin if(!rst_n) begin n_status <= ZERO; water <= 1'b0; coin_back <= 1'b0; end else case(c_status) ZERO : begin water <= 1'b0; coin_back <= 1'b0; if(coin_half) n_status <= HALF; else if(coin_one) n_status <= ONE; else n_status <= ZERO; end HALF : begin water <= 1'b0; coin_back <= 1'b0; if(coin_half) n_status <= ONE; else if(coin_one) n_status <= ONE_HALF; else n_status <= HALF; end ONE : begin water <= 1'b0; coin_back <= 1'b0; if(coin_half) n_status <= ONE_HALF; else if(coin_one) n_status <= TWO; else n_status <= ONE; end ONE_HALF : begin water <= 1'b0; coin_back <= 1'b0; if(coin_half) n_status <= TWO; else if(coin_one) begin n_status <= ZERO; water <= 1'b1; coin_back <= 1'b0; end else n_status <= ONE_HALF; end TWO : begin water <= 1'b0; coin_back <= 1'b0; if(coin_half) begin n_status <= ZERO; water <= 1'b1; coin_back <= 1'b0; end else if(coin_one) begin n_status <= ZERO; water <= 1'b1; coin_back <= 1'b1; end else n_status <= TWO; end default: n_status <= ZERO; endcase end endmodule
1.2、二段式,寫法二
module auto_sell( input clk, input rst_n, input coin_one, input coin_half, output reg water, output reg coin_back ); parameter ZERO = 3'b000; parameter HALF = 3'b001; parameter ONE = 3'b010; parameter ONE_HALF = 3'b011; parameter TWO = 3'b100; //---------------------二段式 2 ok-------------------------------------- //二段式狀態(tài)機 reg [2:0] status; //狀態(tài)轉(zhuǎn)移 always@(posedge clk,negedge rst_n)begin if(!rst_n) status <= ZERO; else begin case(status) ZERO : begin if(coin_half) status <= HALF; else if(coin_one) status <= ONE; else status <= ZERO; end HALF : begin if(coin_half) status <= ONE; else if(coin_one) status <= ONE_HALF; else status <= HALF; end ONE : begin if(coin_half) status <= ONE_HALF; else if(coin_one) status <= TWO; else status <= ONE; end ONE_HALF : begin if(coin_half) status <= TWO; else if(coin_one) begin status <= ZERO; end else status <= ONE_HALF; end TWO : begin if(coin_half) begin status <= ZERO; end else if(coin_one) begin status <= ZERO; end else status <= TWO; end default: status <= ZERO; endcase end end //輸出 時序邏輯 always@(posedge clk,negedge rst_n)begin if(!rst_n) begin water <= 1'b1; coin_back <= 1'b0; end else case(status) ONE_HALF: begin if(coin_one) begin water <= 1'b1; coin_back <= 1'b0; end else begin water <= 1'b0; coin_back <= 1'b0; end end TWO: begin if(coin_half) begin water <= 1'b1; coin_back <= 1'b0; end else if(coin_one) begin water <= 1'b1; coin_back <= 1'b1; end else begin water <= 1'b0; coin_back <= 1'b0; end end default: begin water <= 1'b0; coin_back <= 1'b0; end endcase end endmodule
五、自動售貨機、三段式
module auto_sell( input clk, input rst_n, input coin_one, input coin_half, output reg water, output reg coin_back ); parameter ZERO = 3'b000; parameter HALF = 3'b001; parameter ONE = 3'b010; parameter ONE_HALF = 3'b011; parameter TWO = 3'b100; //三段式狀態(tài)機 reg [2:0] c_status; reg [2:0] n_status; //狀態(tài)轉(zhuǎn)移 always@(posedge clk,negedge rst_n)begin if(!rst_n) c_status <= ZERO; else c_status <= n_status; end //狀態(tài)轉(zhuǎn)移規(guī)律及狀態(tài)輸出,組合邏輯輸出只與輸入有關 //如果有n_status = n_status,電路會出錯; always@(*)begin case(c_status) ZERO : begin if(coin_half) n_status = HALF; else if(coin_one) n_status = ONE; else n_status = ZERO; end HALF : begin if(coin_half) n_status = ONE; else if(coin_one) n_status = ONE_HALF; else n_status = HALF; end ONE : begin if(coin_half) n_status = ONE_HALF; else if(coin_one) n_status = TWO; else n_status = ONE; end ONE_HALF : begin if(coin_half) n_status = TWO; else if(coin_one) n_status = ZERO; else n_status = ONE_HALF; end TWO : begin if(coin_half) n_status = ZERO; else if(coin_one) n_status = ZERO; else n_status = TWO; end default: n_status = ZERO; endcase end always@(posedge clk,negedge rst_n)begin if(!rst_n) begin water = 1'b1; coin_back = 1'b0; end else case(c_status) ONE_HALF: begin if(coin_one) begin water = 1'b1; coin_back = 1'b0; end else begin water = 1'b0; coin_back = 1'b0; end end TWO: begin if(coin_half) begin water = 1'b1; coin_back = 1'b0; end else if(coin_one) begin water = 1'b1; coin_back = 1'b1; end else begin water = 1'b0; coin_back = 1'b0; end end default: begin water = 1'b0; coin_back = 1'b0; end endcase end endmodule
六、仿真腳本
`timescale 1ns/1ps module auto_sell_tb; reg clk; reg rst_n; reg coin_one; reg coin_half; wire water; wire coin_back; initial begin clk = 0; rst_n = 0; coin_one = 0; coin_half = 0; #20; rst_n = 1; //延時200us #10000 //投2.5元 coin_half = 1; #20; coin_half = 0; #20; coin_one = 1; #20; coin_one = 0; #20; coin_half = 1; #20; coin_half = 0; #20; coin_half = 1; #20; coin_half = 0; #20; //延時200us #10000 //投3元 coin_half = 1; #20; coin_half = 0; #20; coin_one = 1; #20; coin_one = 0; #20; coin_half = 1; #20; coin_half = 0; #20; coin_one = 1; #20; coin_one = 0; #20; //延時200us #10000 $stop; end auto_sell auto_sell_inst( .clk (clk), .rst_n (rst_n), .coin_one (coin_one), .coin_half (coin_half), .water (water), .coin_back (coin_back) ); always #10 clk = ~clk; endmodule
七、仿真結果
-
寄存器
+關注
關注
31文章
5359瀏覽量
120790 -
仿真
+關注
關注
50文章
4111瀏覽量
133782 -
時序電路
+關注
關注
1文章
114瀏覽量
21723 -
狀態(tài)機
+關注
關注
2文章
492瀏覽量
27593
原文標題:筆記連載精選 |【狀態(tài)機:一段式、二段式、三段式】 【原理及verilog仿真】篇
文章出處:【微信號:HXSLH1010101010,微信公眾號:FPGA技術江湖】歡迎添加關注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關推薦
評論