状态机的一段式、二段式、三段式的区别

本篇文章描述状态机的一段式、二段式、三段式区别
一、状态机
再次给出状态机的示意图:
1.1、摩尔型,输出只与状态寄存器的输出状态有关
1.2、米粒型,输出不仅与状态寄存器的输出状态有关,还与组合逻辑的输入有关
二、一段式、二段式、三段式区别
根据状态机的结构,状态机描述方式 可分为:一段式、二段式、三段式
1.1、一段式
整个状态机写到一个 always 模块里面。在该模块中既描述状态转移,又描述状态的输入和输出 。
1.2、二段式
用两个 always 模块来描述状态机。
1.2.1、其中一个 always 模块采用同步时序描述状态转移;
1.2.2、另一个 always模块采用组合逻辑判断状态转移条件,描述状态转移规律及其输出 ,注意组合逻辑输出要用阻塞赋值。
1.3、三段式
在两个 always 模块描述方法基础上,使用三个 always 模块。
1.3.1、 一个 always 模块采用同步时序描述状态转移;
1.3.2、一个 always 采用组合逻辑判断状态转移条件,描述状态转移规律,注意组合逻辑输出要用阻塞赋值;
1.3.3、另一个 always 模块描述状态输出(可以用组合电路输出,也可以时序电路输出),注意组合逻辑输出要用阻塞赋值。
1.4、综合
可以看出两段式有限状态机与一段式有限状态机的区别是将时序部分(状态转移)和组合部分(判断状态转移条件和产生输出)分开,写为两个 always语句,即为两段式有限状态机。将组合部分中的判断状态转移条件和产生输出再分开写,则为三段式有限状态机。
三、自动售货机、一段式
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; //一段式状态机 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-------------------------- //二段式状态机 reg [2:0] c_status; reg [2:0] n_status; //状态转移 always@(posedge clk,negedge rst_n)begin if(!rst_n) c_status <= zero; else c_status <= n_status; end //描述状态转移规律以及输出 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-------------------------------------- //二段式状态机 reg [2:0] status; //状态转移 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; //三段式状态机 reg [2:0] c_status; reg [2:0] n_status; //状态转移 always@(posedge clk,negedge rst_n)begin if(!rst_n) c_status <= zero; else c_status <= n_status; end //状态转移规律及状态输出,组合逻辑输出只与输入有关 //如果有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
七、仿真结果


Oculus Go正在开发无控制器模式,仅需凝视即可启动APP
格力进军手机市场,线上结合线下拓展销售渠道
英国Pickering公司公布三管齐下方案 应对产品淘汰问题
或门芯片 或门芯片74ls系列
STM32中断,看着一篇就够了
状态机的一段式、二段式、三段式的区别
OmniVision推出首款采用嵌入式技术的单芯片传感器
Mindspeed和SpiderCloud在可扩展企业级3G小蜂窝领域开展创新
什么是基频晶振?什么又是泛音晶振?两种在电路中的使用有何区别?
嬴彻科技正式发布首个全栈卡车自动驾驶软硬件系统
OLED显示器面板2025年出货量将超230万片
浅淡CAN总线,CAN总线网络拓扑结构
全球化的布局,这是伟创力的一大优势
空间光调制器用于单光纤成像技术
PyTorch教程-18.3高斯过程推理
广芯电子推出低压差线性稳压器和小封装LDO
跨境电商B2B、B2C的新产品推荐
多维科技TMR215x系列线性磁场传感器芯片
小米5S plus和小米Note2大对比,哪个值得入手?
手把手教你读懂FET(图文解说)
s