状态机FSM:3元一瓶可乐例

文章介绍了状态机的概念,包括Moore型和Mealy型,并通过一个3元可乐购买的例子展示了Mealy型状态机的RTL代码实现。代码中使用了独热码来节省FPGA中的组合逻辑资源。此外,文章还包含了状态机的视图、RTL视图、测试代码以及仿真和打印信息,展示了状态机在接收金钱输入后如何控制可乐输出的过程。
摘要由CSDN通过智能技术生成


前言

状态机:Finite State Machine,用于处理/描述具有前后顺序的事情。例如计数器就可以使用状态机来表示。
在这里插入图片描述
Moore型状态机:输出与当前状态有关,与输入无关。
Mealy型状态机:输出不仅和当前状态有关,还和输入有关。
下面以一瓶3元的可乐进行举例,细节见图示文字:
在这里插入图片描述由于Mealy型节省资源,故根据此状态结构绘制波形图。
在这里插入图片描述


一、rtl代码

module fsm
(
input wire sys_clk,
input wire sys_rst_n,
input wire  money,
output reg  cola
);

//独热码:每个状态只有1个bit为高电平,其他为低电平,故三(4)个状态使用3(4)位宽变量
//优点:将3个bit位的比较器变成1个bit位的比较器,节省组合逻辑的资源;但状态变量需要的位宽较多
//fpga中,组合逻辑资源较少,但寄存器资源较多,故使用独热码(独热码编码的状态机可以在高速系统下运行)
//多个比特位的比较器,每个比特位到达比较器的时间会因为布局的走线长短不同而导致延时的不同,就会导致输出的不稳定/不准确
parameter IDLE=3'b001;
parameter ONE=3'b010;
parameter TWO=3'b100;

/* //二进制码:两个位宽即可
//位宽较少,减少了寄存器资源的使用,但综合器综合时无法进行比较器的优化,使用的组合逻辑资源比较多
parameter IDLE=2'b00;十进制的0
parameter ONE= 2'b01;十进制的1
parameter TWO= 2'b10;十进制的2 */

/* //格雷码(是独热码和二进制码的折中,状态数比较多的时候使用):只有1个bit位是不同的
//相邻状态转换时只有一个状态是发生反转的,不仅可以消除状态转换时,由多条信号线的传输延时造成的毛刺,还会降低功耗
parameter IDLE=2'b00;0
parameter ONE= 2'b01;1
parameter TWO= 2'b11;2
parameter TWO= 2'b10;3 */

//总结:fpga中,低速系统中,如果状态机中状态的个数小于4个,使用二进制码;4-24,独热码;大于24,格雷码
//但在高速系统中,使用独热码
reg [2:0] state;

always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n==1'b0)
        state<=IDLE;
    else case(state)
        IDLE:if(money==1'b1)
                 state<=ONE;
             else
                 state<=IDLE;
        ONE:if(money==1'b1)
                 state<=TWO;
             else
                 state<=ONE;
        TWO:if(money==1'b1)
                 state<=IDLE;
             else
                 state<=TWO;
        default:state<=IDLE;
        endcase
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n==1'b0)
        cola<=1'b0;
    else if((state==TWO)&&(money==1'b1))
        cola<=1'b1;
    else
        cola<=1'b0;

endmodule

二、状态机视图

在这里插入图片描述
!money是不投钱,money为投钱。

三、rtl视图

在这里插入图片描述
stste为状态机。

四、测试代码

`timescale 1ns/1ns
module tb_fsm();

reg sys_clk;
reg sys_rst_n;
reg money;
wire cola;

initial
    begin
    sys_clk=1'b1;
    sys_rst_n<=1'b0;
    #20
    sys_rst_n<=1'b1;
    end

always #10 sys_clk=~sys_clk;

always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n==1'b0)
        money<=1'b0;
    else
        money<={$random}%2;

wire [2:0] state=fsm_inst.state;//将实例化中的state变量赋值给state,就可以在仿真代码中读取模块内部的变量进行监测
initial
    begin
        $timeformat(-9,0,"ns",6);
        $monitor("@time %t:money=%b,state=%b,cola=%b",$time,money,state,cola);
    end

fsm fsm_inst
(
.sys_clk  (sys_clk  ),
.sys_rst_n(sys_rst_n),
. money   ( money   ),
. cola    ( cola    )
);

endmodule

五、仿真结果

在这里插入图片描述可以看出,仿真结构与波形图原理相同。

六、打印信息

在这里插入图片描述
打印的信息中,输出与输入延迟一个时钟周期,可以参考红色方框中的红色线和黑色线。红色方框为买到一瓶可乐的完整过程。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小年痴槑

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值