数字系统设计实验七(完结):verilog实现简易饮料贩售机

1.问题重述:
自动售饮料机是一个典型的利用状态机进行电路设计的例子。要求采用有限状态机设计,使用case语句来描述各个状态之间的转移关系。假定每瓶饮料售价为2.5元,可使用 2 种硬市,即5角(half_dollar)、1元(one_dollar),机器有找零功能。下图是该自动售饮料机的示意图。
在程序中,可以定义5个状态,代表不同时刻机器的不同状态。在系统复位后机器开始运行,在每一次出售饮料的过程中记录其状态,表示投币者已投入钱币数目的变化,在下一次售出前,首先reset将系统清零。
在这里插入图片描述

2.问题分析:
1)题目要求运用状态机来描述自动贩卖机,那么这时的输出(即找零和取饮料)是与用户的输入(投币)有关的,所以在这里应该运用mealy机。
2)对于工作模式的认识与建模:认为在这个机器中,有如下的工作模式:投入两元时,再投入五角,则出饮料,而不找零,进行清零;投入两元时,再投入一元,则出饮料,找零五角,进行清零。考虑到没有按键等交互功能,并且时钟频率较高的情况下,同时投下1元和五角的几率很低,这种情况可以忽略,即不会同时使元和角输入同时为1的可能。那么相应的,找零也不会出现找出1块钱的情况,只有要已经输入2元,在输入1元的情况下,会找出5角的零钱。这样可以大大简化状态机的设计。
3)在这里定义五个状态,由于输入可以为5角和1元,由yuan_in和jiao_in分别来表示,所以输入的状态定位0元,0.5元,1元,1.5元,2元五种,在yuan_in,jiao_in的控制下,在五种状态间进行状态转移。

4)输出包括取饮料和找零,当然也包括币值的显示和取饮料、找零的led显示。取饮料用一位二进制表示good_out,找零用jiao_out来表示。币值显示跟随状态机,用两个一位十进制数seg_shiyuan和seg_yiyuan来显示,之后用前面所做过的译码器来实现。另外是led_drink和led_exchange分别表示对应的led灯的亮灭,这和输入状态的good_out和jiao_out使绑定的。亮表示正在进行该动作。
5)根据上面描述,画出如下状态机转移图:
在这里插入图片描述

状态转移图对mealy机状态转移的描述不是十分清晰。下面再用状态转移表进行描述:
在这里插入图片描述

3.代码展现:
虽然通过上面的分析,为了代码的完备性,这里的代码还是考虑了同时投下一元和五角的情况,即每个状态机中对应的输入情况都有四种(00,01,10,11)。
.v文件:

`timescale 1ns / 1ps
//
// Company: 
// Engineer: jeffery

module machine(
/*input*/   clk,rst,yuan_in,jiao_in,
/*output*/  good_out,yuan_out,jiao_out,
            led_drink,led_exchange,//输出信号中显示出饮料、找零的指示灯
            segment,chip           //显示的led灯,使用第6题中的动态扫描输出
);
input  wire clk,rst, yuan_in, jiao_in;
output reg good_out,yuan_out,jiao_out;
output wire led_drink,led_exchange;
output wire [6:0] segment;
output wire [1:0] chip;


parameter state00=3'd0,state05=3'd1,
          state10=3'd2,state15=3'd3,   
          state20=3'd4;//连续定义parameter这里要是逗号隔开的!!
       
//这个assign块的含义是,这两个输出是互相绑定的
assign led_drink=good_out;
assign led_exchange=(jiao_out||yuan_out);
          
//这个always语句是对状态的转移进行定义
reg [2:0]state;
reg [7:0]number;//这个数字是用于产生
always @(posedge clk or negedge rst)
    begin
        if(!rst)
            begin
            state=state00;
            good_out=0;
            yuan_out=0;
            jiao_out=0;
            number=0;
            end
        else
            begin
            case(state) 
state00:
                    begin
                    if(yuan_in==0 && jiao_in==0)
                        begin
                        state=state00;
                        good_out=0;
                        yuan_out=0;
                        jiao_out=0;
                        number[7:4]=0;
                        number[3:0]=0;
                        end
                    else if(yuan_in==0 && jiao_in==1)
                        begin
                        state=state05;
                        good_out=0;
                        yuan_out=0;
                        jiao_out=0;
                        number[7:4]=0;
                        number[3:0]=5;
                        end
                    else if(yuan_in==1 && jiao_in==0)
                        begin
                        state=state10;
                        good_out=0;
                        yuan_out=0;
                        jiao_out=0;
                        number[7:4]=1;
                        number[3:0]=0;
                        end
                    else if(yuan_in==1 && jiao_in==1)
                        begin
                        state=state15;
                        good_out=0;
                        yuan_out=0;
                        jiao_out=0;
                        number[7:4]=1;
                        number[3:0]=5;
                        end
                    end
                state05:
                    begin
                    if(yuan_in==0 && jiao_in==0)
                        begin 
   state=state05;
                        good_out=0;
                        yuan_out=0;
                        jiao_out=0;
                        number[7:4]=0;
                        number[3:0]=5;
                        end
                    else if(yuan_in==0 && jiao_in==1)
                        begin
                        state=state10;
                        good_out=0;
                        yuan_out=0;
                        jiao_out=0;
                        number[7:4]=1;
                        number[3:0]=0;
                        end
                    else if(yuan_in==1 && jiao_in==0)
                        begin
                        state=state15;
                        good_out=0;
                        yuan_out=0;
                        jiao_out=0;
                        number[7:4]=1;
                        number[3:0]=5;
                        end
                    else if(yuan_in==1 && jiao_in==1)
                        begin
                        state=state20;
                        good_out=0;
                        yuan_out=0;
                        jiao_out=0;
                        number[7:4]=2;
                        number[3:0]=0;
                        end
                    end
                state10:
                    begin
                    if(yuan_in==0 && jiao_in==0)
                        begin
                        state=state10;
                        good_out=0;
                        yuan_out=0;
                        jiao_out=0; 
 number[7:4]=1;
                        number[3:0]=0;
                        end
                    else if(yuan_in==0 && jiao_in==1)
                        begin
                        state=state15;
                        good_out=0;
                        yuan_out=0;
                        jiao_out=0;
                        number[7:4]=1;
                        number[3:0]=5;
                        end
                    else if(yuan_in==1 && jiao_in==0)
                        begin
                        state=state20;
                        good_out=0;
                        yuan_out=0;
                        jiao_out=0;
                        number[7:4]=2;
                        number[3:0]=0;
                        end
                    else if(yuan_in==1 && jiao_in==1)
                        begin
                        state=state00;
                        good_out=1;
                        yuan_out=0;
                        jiao_out=0;
                        number[7:4]=0;
                        number[3:0]=0;
                        end
                    end
                state15:
                    begin
                    if(yuan_in==0 && jiao_in==0)
                        begin
                        state=state15;
                        good_out=0;
                        yuan_out=0;
                        jiao_out=0;
                        number[7:4]=1;
                        number[3:0]=5;
                        end
                    else if(yuan_in==0 && jiao_in==1) 
 begin
                        state=state20;
                        good_out=0;
                        yuan_out=0;
                        jiao_out=0;
                        number[7:4]=2;
                        number[3:0]=0;
                        end
                    else if(yuan_in==1 && jiao_in==0)
                        begin
                        state=state00;
                        good_out=1;
                        yuan_out=0;
                        jiao_out=0;
                        number[7:4]=0;
                        number[3:0]=0;
                        end
                    else if(yuan_in==1 && jiao_in==1)
                        begin
                        state=state00;
                        good_out=1;
                        yuan_out=0;
                        jiao_out=1;
                        number[7:4]=0;
                        number[3:0]=0;
                        end
                    end
                state20:
                    begin
                    if(yuan_in==0 && jiao_in==0)
                        begin
                        state=state20;
                        good_out=0;
                        yuan_out=0;
                        jiao_out=0;
                        number[7:4]=2;
                        number[3:0]=0;
                        end
                    else if(yuan_in==0 && jiao_in==1)
                        begin
                        state=state00;
                        good_out=1;
                        yuan_out=0; 
   jiao_out=0;
                        number[7:4]=0;
                        number[3:0]=0;
                        end
                    else if(yuan_in==1 && jiao_in==0)
                        begin
                        state=state00;
                        good_out=1;
                        yuan_out=0;
                        jiao_out=1;
                        number[7:4]=0;
                        number[3:0]=0;
                        end
                    else if(yuan_in==1 && jiao_in==1)
                        begin
                        state=state00;
                        good_out=1;
                        yuan_out=1;
                        jiao_out=0;
                        number[7:4]=0;
                        number[3:0]=0;
                        end
                    end
                default:
                        begin
                        state=state00;
                        good_out=0;
                        yuan_out=0;
                        jiao_out=0;
                        number[7:4]=0;
                        number[3:0]=0;
                        end
            endcase
            end
    end
//这里将会是例化regment译码器
wire [7:0] number_show;
assign number_show=number;//由于reg类型变量无法直接作为例化的输入端口,
                           //所以这里要通过连续赋值语句将其赋给wire型变量
led myled(.number(number_show),.segment(segment),.chip(chip),.clk(clk),.rst(rst));   

endmodule 

led module:


`timescale 1ns / 1ps
//
// Company: 
// Engineer: jeffery

module led(number,segment,chip,clk,rst);

input [7:0] number;
input clk,rst;
output reg [6:0] segment;
output reg [1:0] chip;


//这个always语句是完成了选通信号的逐个开启,0,1两个状态
reg cnt;
always @(posedge clk or negedge rst)//rst信号的下降沿将触发这个模块,是他们在任何条件都进行复位操作
    begin
    if(!rst)
        cnt=0;
    else
        cnt=cnt+1;
    end

    
    
//这个部分是对每次选择的数字,以及对应显示的片进行了选择
reg [3:0] number_reading;//number_reading是用来表示通过片选信号按顺序显示数字,这时正在读取的数字
always @(posedge clk or negedge rst)
    begin
    if(!rst)
        begin
        number_reading=1'd0;
        chip=2'b00;
        end
    else
        begin
            case(cnt)
            1'b0: 
                begin
  number_reading=number[3:0];
                chip=2'b01;
                end
            1'b1: 
                begin
                number_reading=number[7:4];
                chip=2'b10;
                end
            default: 
                begin
                number_reading=4'd0;
                chip=2'b00;
                end
            endcase
        end
    end
    
//这个always语句是对segment进行了数字编码
always @(posedge clk or negedge rst)
    begin
    if(!rst)
        segment=7'b0;
    else
        begin
            case(number_reading)
            4'd0: segment=7'b1111110;
            4'd1: segment=7'b0110000;
            4'd2: segment=7'b1101101;
            4'd3: segment=7'b1111001;
            4'd4: segment=7'b0110011;
            4'd5: segment=7'b1011011;
            4'd6: segment=7'b1011111;
            4'd7: segment=7'b1110000;
            4'd8: segment=7'b1111111;
            4'd9: segment=7'b1111011;
            default: segment=7'b0;
            endcase
        end
    
    end
    
endmodule

tb文件:

`timescale 1ns / 1ps
module tb();

reg clk, rst, yuan_in, jiao_in;
wire good_out,yuan_out,jiao_out;
wire led_drink,led_exchange;
wire [6:0] segment;
wire [1:0] chip;


machine my_machine(
/*input*/   clk,rst,yuan_in,jiao_in,
/*output*/  good_out,yuan_out,jiao_out,
            led_drink,led_exchange,//输出信号中显示出饮料、找零的指示灯
            segment,chip           //显示的led灯,使用第6题中的动态扫描输出
);

initial
    begin
    clk=1;
    rst=1;
    yuan_in=0;
    jiao_in=0;
    
    #8 rst=0;
    #8 rst=1;//检测复位信号是否能够让输出不再为x
    
    #4 yuan_in=1;jiao_in=0;
    #4 yuan_in=0;jiao_in=0;
    #4 yuan_in=1;jiao_in=0;
    #4 yuan_in=0;jiao_in=0;
    #4 yuan_in=1;jiao_in=0;//测试连续投三个1元
    #4 yuan_in=0;jiao_in=0;//必须要留够一定时间,这样才能使扫描显示的led正常显示,方便测试

    
    #4 yuan_in=0;jiao_in=1;
    #4 yuan_in=0;jiao_in=0;
    #4 yuan_in=0;jiao_in=1;
    #4 yuan_in=0;jiao_in=0;
    #4 yuan_in=0;jiao_in=1;
    #4 yuan_in=0;jiao_in=0;
 #4 yuan_in=0;jiao_in=1;
    #4 yuan_in=0;jiao_in=0;
    #4 yuan_in=0;jiao_in=1;//测试连续投五个五角
    #4 yuan_in=0;jiao_in=0;
    
    #4 yuan_in=0;jiao_in=1;
    #4 yuan_in=0;jiao_in=0;
    #4 yuan_in=1;jiao_in=0;
    #4 yuan_in=0;jiao_in=0;
    #4 yuan_in=0;jiao_in=1;
    #4 yuan_in=0;jiao_in=0;
    #4 yuan_in=1;jiao_in=0;//测试五角--一元--五角--一元
    #4 yuan_in=0;jiao_in=0;
    
    #4 yuan_in=0;jiao_in=1;
    #4 yuan_in=0;jiao_in=0;
    #4 yuan_in=1;jiao_in=1;
    #4 yuan_in=0;jiao_in=0;
    #4 yuan_in=0;jiao_in=0;
    #4 yuan_in=0;jiao_in=0;
    #4 yuan_in=0;jiao_in=1;//测试五角--一元-五角-不投--五角--一元
    #4 yuan_in=0;jiao_in=0;

    
    end

always
    begin
    #2 clk=~clk;//这里定义的时钟周期为4个时间单位
    end
endmodule


4.实验结果:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
从上到下分别为:
连续投3个一元,
连续投5个五角,
五角——一元——五角——一元,
五角——一元五角同时投——不投——五角

  • 21
    点赞
  • 103
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值