verilog实战(1)自动售卖饮料机

在这里插入图片描述
verilog代码如下:

/*
date:   2022/8/31
author: Xingxing Zhou
*/

module  auto_selll_drinks(
    input   wire            sys_clk     ,
    input   wire            sys_rst_n   ,
    input   wire            Ten_Yuan    ,
    input   wire            Twenty_Yuan ,
    input   wire            Fifty_Yuan  ,

    output  wire            out_drink   ,
    output  reg     [7:0]   out_money
);

// define states
parameter   IDLE    =   4'd0    ,       //  No money 
            S_10    =   4'd1    ,       //  10 yuan
            S_20    =   4'd2    ,       //  20 yuan
            S_30    =   4'd3    ,       //  30 yuan
            S_40    =   4'd4    ,       //  40 yuan
            S_50    =   4'd5    ,       //  50 yuan
            S_60    =   4'd6    ,       //  60 yuan
            S_70    =   4'd7    ,       //  70 yuan
            S_80    =   4'd8    ,       //  80 yuan
            S_90    =   4'd9    ,       //  90 yuan
            S_100   =   4'd10   ,       //  100 yuan
            S_110   =   4'd11   ,       //  110 yuan
            S_120   =   4'd12   ;       //  120 yuan

reg     [3:0]       state       ;
reg     [3:0]       next_state  ;

always @(posedge sys_clk or negedge sys_rst_n) begin
    if(!sys_rst_n)begin
        state <= IDLE;
    end
    else begin
        state <= next_state;
    end
end

always @(*) begin
    case(state)
        IDLE:   begin
                    if(Ten_Yuan)begin
                        next_state <= S_10;
                    end
                    else if(Twenty_Yuan)begin
                        next_state <= S_20;
                    end
                    else if(Fifty_Yuan) begin
                        next_state <= S_50;
                    end
                    else begin
                        next_state <= IDLE;
                    end
                end
        S_10:   begin
                   if(Ten_Yuan)begin
                        next_state <= S_20;
                    end
                    else if(Twenty_Yuan)begin
                        next_state <= S_30;
                    end
                    else if(Fifty_Yuan) begin
                        next_state <= S_60;
                    end
                    else begin
                        next_state <= S_10;
                    end
 
                end
                

        S_20:   begin
                    if(Ten_Yuan)begin
                        next_state <= S_30;
                    end
                    else if(Twenty_Yuan)begin
                        next_state <= S_40;
                    end
                    else if(Fifty_Yuan) begin
                        next_state <= S_70;
                    end
                    else begin
                        next_state <= S_20;
                    end
                end
        S_30:   begin
                    if(Ten_Yuan)begin
                        next_state <= S_40;
                    end
                    else if(Twenty_Yuan)begin
                        next_state <= S_50;
                    end
                    else if(Fifty_Yuan) begin
                        next_state <= S_80;
                    end
                    else begin
                        next_state <= S_30;
                    end

                end
        S_40:   begin
                    if(Ten_Yuan)begin
                        next_state <= S_50;
                    end
                    else if(Twenty_Yuan)begin
                        next_state <= S_60;
                    end
                    else if(Fifty_Yuan) begin
                        next_state <= S_90;
                    end
                    else begin
                        next_state <= S_40;
                    end

                end
        S_50:   begin
                    if(Ten_Yuan)begin
                        next_state <= S_60;
                    end
                    else if(Twenty_Yuan)begin
                        next_state <= S_70;
                    end
                    else if(Fifty_Yuan) begin
                        next_state <= S_100;
                    end
                    else begin
                        next_state <= S_50;
                    end

                end
        S_60:   next_state <= (Ten_Yuan) ? S_70 : (Twenty_Yuan) ? S_80 : (Fifty_Yuan) ? S_110 : S_60;
        S_70:   next_state <= (Ten_Yuan) ? S_80 : (Twenty_Yuan) ? S_90 : (Fifty_Yuan) ? S_120 : S_70;
        S_80:   next_state <= IDLE;
        S_90:   next_state <= IDLE;
        S_100:  next_state <= IDLE;
        S_110:  next_state <= IDLE;
        S_120:  next_state <= IDLE;
        default:next_state <= IDLE;

    endcase
end

assign out_drink = ((state == S_80) || (state == S_90) || (state == S_100) || (state == S_110) || (state == S_120));

always @(*) begin
    if(state == S_80)begin
        out_money <= 8'd0;
    end
    else if(state == S_90) begin
        out_money <= 8'd10;
    end
    else if(state == S_100) begin
        out_money <= 8'd20;
    end
    else if(state == S_110) begin
        out_money <= 8'd30;
    end
    else if(state == S_120) begin
        out_money <= 8'd40;
    end
    else begin
        out_money <= 8'd0;
    end
end

endmodule

testbench编写如下:

module tb_auto_sell_drinks;

reg             sys_clk     ;
reg             sys_rst_n   ;
reg             Ten_Yuan    ;
reg             Twenty_Yuan ;
reg             Fifty_Yuan  ;

wire            out_drink   ;
wire    [7:0]   out_money   ;

integer i;
task    buy_drink;
    i = $random() % 3;
    if(i == 0) begin
        Ten_Yuan <= 1'b1;
        @(posedge sys_clk);
        Ten_Yuan <= 1'b0;
        #50;
    end
    else if(i == 1) begin
        Twenty_Yuan <= 1'b1;
        @(posedge sys_clk);
        Twenty_Yuan <= 1'b0;
        #50;
    end
    else begin
        Fifty_Yuan <= 1'b1;
        @(posedge sys_clk);
        Fifty_Yuan <= 1'b0;
        #50;
    end
endtask

initial begin
    sys_clk = 1'b0;
    sys_rst_n = 1'b0;
    Ten_Yuan = 1'b0;
    Fifty_Yuan = 1'b0;
    Twenty_Yuan = 1'b0;
    #40
    sys_rst_n = 1'b1;
    repeat(20) begin
        buy_drink();
    end
    $finish;
end

always #10 sys_clk = ~sys_clk;

auto_selll_drinks u_auto_sell_drinks(
    .sys_clk    (sys_clk)       ,
    .sys_rst_n  (sys_rst_n)     ,
    .Ten_Yuan   (Ten_Yuan)      ,
    .Twenty_Yuan(Twenty_Yuan)   ,
    .Fifty_Yuan (Fifty_Yuan)    ,

    .out_drink  (out_drink)     ,
    .out_money  (out_money)     
);

initial begin
    $fsdbDumpfile("tb.fsdb");
    $fsdbDumpvars;
end

endmodule

仿真波形入下:
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值