Verilog自动售货机设计

来源:互联网 发布:新型网络诈骗手段 编辑:程序博客网 时间:2024/05/17 06:17

我们实习的内容,设计一个自动售货机的控制器,实现以下功能:

a.   机器只接受1元硬币和5元纸币;

b.   机器共提供4种货物,价格分别为2元、2元、3元、3元;

c.   顾客先选择需要的一种或者多种货物,再确认所选货物后,进入投币状态。当顾客选择的货物卖光时,本实验中,只需在顾客确认货物之时,提示顾客货物卖光,并返回初始状态即可。(每种货物数量初始值为63。顾客确认货物时,需提供确认选择和重新选择两个选项。)

d.    若等待60s,顾客不投币,则返回初始状态;顾客投币后,系统自动计算所投钱币。若投币够,则出货找零。若自客户确认货物之后60s,投币不够,则退币并返回初始状态。(本实验中,退币过程只需将记录顾客投入钱币清零即可)。

主要是运用有限状态机的方法。

状态描述表状态S0S1S2S3S4S5S6S7S8状态描述初始化状态选择货物确认选择判断是否卖光是否在60s内投币投币金额是否足够是否需要找零找零出货

自动售货机代码:

//Vending Machinemodule VendingMac (clk,money_input,select,confirm,init,left1,left2,left3,left4,change,out);  input clk;  input [2:0] money_input;  input [1:4] select;  input confirm,init;  input [5:0] left1,left2,left3,left4;  output integer change;  output reg [1:4] out;  reg [1:4] select_sta;  reg [3:0] sta;  reg isSelled;  reg timeCnting;  reg [8:0] time_cnt;  reg [1:0] opt;  integer money_sum;    parameter S_select=4'b0000,S_confirm=4'b0001,S_allselled=4'b0010,S_60sec=4'b0011,            S_enough=4'b0100,S_requirechange=4'b0101,S_change=4'b0110,S_out=4'b0111,            S_init=4'b1000;    initial  begin    sta=S_init;  end    always @(posedge clk)  begin    if(clk && timeCnting)      time_cnt=time_cnt+1;    if(timeCnting==0)      time_cnt=0;  end    always @(posedge init or posedge clk)  begin    if(clk)      begin        case(sta)          S_init:          begin            select_sta=4'b0000;            timeCnting=0;            money_sum=0;            change=0;            out=0;            opt=0;                        sta=S_select;          end          S_select:          begin            select_sta=select|select_sta;            if(confirm || init)              begin                opt={confirm,init};                sta=S_confirm;              end          end          S_confirm:          begin            if(opt==2'b10 || opt==2'b11)              sta=S_allselled;            else if(opt==2'b01)              begin                //select_sta=4'b0000;                sta=S_init;              end          end          S_allselled:          begin            isSelled=0;            if(select_sta[1]==1 && left1<=0)              isSelled=1;            if(select_sta[2]==1 && left2<=0)              isSelled=1;            if(select_sta[3]==1 && left3<=0)              isSelled=1;            if(select_sta[4]==1 && left4<=0)              isSelled=1;                        if(isSelled)              begin                //select_sta=4'b0000;                sta=S_init;              end            else              begin                timeCnting=1;                sta=S_60sec;              end          end          S_60sec:          begin            if(time_cnt<500)//wait 10000 timepiece              begin                if(money_input!=0)//wait 10000 timepiece                  begin                    money_sum=money_sum+money_input;                  end              end            else if(time_cnt==500)              if(money_sum!=0)                sta=S_enough;            else              sta=S_init;          end          S_enough:          begin            if(select_sta[1]==1)              money_sum=money_sum-2;            if(select_sta[2]==1)              money_sum=money_sum-2;            if(select_sta[3]==1)              money_sum=money_sum-3;            if(select_sta[4]==1)              money_sum=money_sum-3;                          if(money_sum>=0)              sta=S_requirechange;            else              sta=S_init;          end          S_requirechange:          begin            if(money_sum==0)              sta=S_out;            else if(money_sum>0)              sta=S_change;          end          S_change:          begin            change=money_sum;            sta=S_out;          end          S_out:          begin            out=select_sta;            sta=S_init;          end        endcase      end  endendmodule
测试代码:
`timescale 1ns/1ns`include "./VendingMac.v"module VendingMac_top;  reg clk;  reg [2:0] money_input;  reg [3:0] select;  reg confirm,init;  reg [5:0] left1,left2,left3,left4;  wire [2:0] change;  wire [3:0] out;    initial  begin    clk=0;    select=4'b0000;    confirm=0;    init=0;    money_input=0;    left1=63;    left2=63;    left3=63;    left4=63;  end    always  begin    #10 clk=~clk;    #10 clk=~clk;  end    initial  begin    #40    #10 select=4'b0100;//posedge1    #10 select=4'b0000;    #10 select=4'b0001;//posedge2    #10 select=4'b0000;    #10 confirm=1;    #10 confirm=0;    #60    #10 money_input=1;    #10 money_input=0;    #10 money_input=5;    #10 money_input=0;    #10 money_input=5;    #10 money_input=0;  end    initial  begin    $monitor($time,,,"select=%b,money_input=%d,confirm=%d,init=%d,out=%b,change=%d",select,money_input,confirm,init,out,change);    #60000 $finish;  end    VendingMac v1(clk,money_input,select,confirm,init,left1,left2,left3,left4,change,out);endmodule


0 0