14复杂状态机

该博客介绍了如何使用Verilog设计一个可乐机自动售货机的状态机。模块包括IDLE、HALF、ONE、ONE_HALF和TWO等状态,分别对应不同的硬币投入情况。当投入2.5元或3元时,状态机会吐出可乐,并在投入3元时进行找零。通过波形图和rtl视图展示了设计的逻辑流程,同时提供了仿真程序以验证设计的正确性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、实现的功能
实现可乐机
能够投入5毛和1块的硬币
2.5元吐出可乐
3元的时候吐出可乐并且进行找零

二、实现
1、状态图
在这里插入图片描述在这里插入图片描述

2、波形图
在这里插入图片描述
3、rtl视图
在这里插入图片描述

4.程序
模块程序

module complex_fsm
(
    input   wire    sys_clk,
    input   wire    sys_rst_n,
    input   wire    pi_money_one,
    input   wire    pi_money_half,
    
    output  reg     po_cola,
    output  reg     po_money

);

wire    [1:0]   pi_money;
reg     [4:0]   state;

/* parameter   IDLE    = 5'b00001;
parameter   HALF    = 5'b00010;
parameter   ONE     = 5'b00100;
parameter   ONE_HALF= 5'b01000;
parameter   TWO     = 5'b10000; */


parameter   IDLE    = 5'b00001,
            HALF    = 5'b00010,
            ONE     = 5'b00100,
            ONE_HALF= 5'b01000,
            TWO     = 5'b10000;
            
assign  pi_money = {pi_money_one,pi_money_half};

always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        state <= IDLE;
    else    case(state)
                IDLE:   if (pi_money == 2'b01)
                            state <= HALF;
                        else if (pi_money == 2'b10)
                            state <= ONE;
                        else
                            state <= IDLE;
                HALF:   if (pi_money == 2'b01)
                            state <= ONE;
                        else if (pi_money == 2'b10)
                            state <= ONE_HALF;
                        else
                            state <= HALF;
                ONE:    if (pi_money == 2'b01)
                            state <= ONE_HALF;
                        else if (pi_money == 2'b10)
                            state <= TWO;
                        else
                            state <= ONE;
                ONE_HALF: if (pi_money == 2'b01)
                            state <= TWO;
                        else if (pi_money == 2'b10)
                            state <= IDLE;
                        else
                            state <= ONE_HALF;
                TWO:    if (pi_money == 2'b01)
                            state <= IDLE;
                        else if (pi_money == 2'b10)
                            state <= IDLE;
                        else
                            state <= TWO;  
                default: state <= IDLE;
            endcase
            
always@(posedge sys_clk or negedge sys_rst_n)
    if (sys_rst_n == 1'b0)
        po_cola <= 1'b0;
    else if (state == TWO)
        po_cola <= 1'b1;
    else
        po_cola <= 1'b0;

always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n ==1'b0)
        po_money <= 1'b0;
    else if((state == TWO)&&(pi_money == 2'b10))
        po_money <= 1'b1;
    else
        po_money <= 1'b0;
               
endmodule

其中下面两种方式是一样的,后面的方式比较简单
在这里插入图片描述

仿真程序

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

reg sys_clk;
reg sys_rst_n;
reg pi_money_one;
reg pi_money_half;
reg random_data_gen;

wire po_cola;
wire po_money;

always #10 sys_clk = ~sys_clk;

initial
    begin
        sys_clk = 1'b0;
        sys_rst_n <= 1'b0;
        #20
        sys_rst_n <= 1'b1;
    end
always@(posedge sys_clk or negedge sys_rst_n)
    if (sys_rst_n == 1'b0)
        random_data_gen <= 1'b0;
    else
        random_data_gen <= {$random} %2;

always@(posedge sys_clk or negedge sys_rst_n)
    if (sys_rst_n == 1'b0)
        pi_money_half <= 1'b0;
    else
        pi_money_half <= random_data_gen;
        
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        pi_money_one <= 1'b0;
    else
        pi_money_one <= ~random_data_gen;
        /*只有一个投币口,避免5毛和1块同时产生数据对其取反就避免了*/
        
initial
    begin
        $timeformat (-9,0,"ns",6);
        $monitor ("@time %t:pi_money_one=%b pi_money_half=%b pi_money=%b state=%b po_cola=%b po_money=%b",$time, pi_money_one, pi_money_half, pi_money, state, po_cola, po_money);
    end
/*连接出来,可以对状态机内部进行观察*/
wire [1:0] pi_money = complex_fsm_inst.pi_money;
wire [4:0] state = complex_fsm_inst.state;


complex_fsm complex_fsm_inst
(
    .sys_clk       (sys_clk      ) ,
    .sys_rst_n     (sys_rst_n    ) ,
    .pi_money_one  (pi_money_one ) ,
    .pi_money_half (pi_money_half) ,

    .po_cola       (po_cola      ) ,
    .po_money      (po_money     )

);     

endmodule  


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值