自动售货机VerilogHDL程序一个简单的自动售卖饮料机的程序。
该机器具有投币,显示余额,购买六种饮料,退钱等功能,为了更具实用性,增添了饮料选择允许提示和投币允许提示的功能。
具体形容,可投入一元、五元、十元和二十元面值的钱币,显示出当前的余额,并根据当前的余额提示能购买哪些饮料,选择某种饮料,则输出选定的饮料,同时余额减去相应的金钱。
若选择退钱,机器就退出所有的钱,余额清零。
下图为功能示意图:程序的状态表:程序中包含了一个状态机,定义了一个任务(task)和函数(function),用该任务调用了该函数,使用若干分支语句,详见附后源程序和测试程序。
附上程序编译仿真图:源程序如下:`define one 3'b001`define five 3'b010`define ten 3'b011`define twenty 3'b100module automart(money,state,moneyout,coinable,adrkable,bdrkable,cdrkable,drkout1,drkout2,drkout3,drkout4,drkout5,drkout6,coin,clk,reset,moneyback,choice1,choice2,choice3,choice4,choice5,choice6);input[2:0] coin;//投币输入,分为1、5、10、20元四种输入input clk,reset,moneyback,choice1,choice2,choice3,choice4,choice5,choice6;//moneyback为退钱输入,choice1~6是饮料选择output moneyout,coinable,adrkable,bdrkable,cdrkable,drkout1,drkout2,drkout3,drkout4,drkout5,drkout6;//依次为退钱输出,投币许可提示,饮料选择许可,6种饮料输出output[2:0] state;//状态记录output[7:0] money;//余额显示reg[7:0] money;reg[2:0] state;reg moneyout,coinable,backable,adrkable,bdrkable,cdrkable;parameter A=3'b000, B=3'b001, C=3'b010,D=3'b011, E=4'b100; assign drkout1=choice1&adrkable;assign drkout2=choice2&adrkable;assign drkout3=choice3&bdrkable;assign drkout4=choice4&bdrkable;assign drkout5=choice5&cdrkable;assign drkout6=choice6&cdrkable;always@(posedge clk)repeat(1)@(posedge clk)if (!reset)beginstate<=A;money=0;moneyout=0;endelsebegincase(state)A: begin//初始状态A,可投币进入别的状态coinable=1;backable=0;adrkable=0;bdrkable=0;cdrkable=0;endB: begin//状态B,只能买1元的饮料,可退钱或投币coinable=1;backable=1;adrkable=1;bdrkable=0;cdrkable=0;endC: begin//状态C,可买1或2元的饮料,退钱或投币coinable=1;backable=1;adrkable=1;bdrkable=1;cdrkable=0;endD: begin//状态D,可买三档价格饮料,可退钱或投币coinable=1;backable=1;adrkable=1;bdrkable=1;cdrkable=1;endE: begin//状态E,可买三档价格饮料,可退钱,不可继续投钱coinable=0;backable=1;adrkable=1;bdrkable=1;cdrkable=1;enddefault: state=A;endcasecondition(money,state,coin,coinable);//调用任务endalways@(negedge drkout1 or negedge drkout2)money=money-8'h01;//买1元的饮料,余额减1元always@(negedge drkout3 or negedge drkout4)money=money-8'h02;//买2元的饮料,余额减2元always@(negedge drkout5 or negedge drkout6)money=money-8'h04;//买4元的饮料,余额减4元always@(negedge moneyback)beginif(backable)beginmoneyout=1;money=0;//选择退钱,则推出金钱,余额清零endelsemoney=money+0;endtask condition;//该任务可以判断余额的改变,状态切换inout[7:0] moneycon;inout[2:0] statecon;input[2:0] coincon;input coinablecon;beginif (coinablecon)//允许投币时begincase (coincon)//根据投币面值改变余额,切换状态`one : moneycon=moneycon+8'h01;`five : moneycon=moneycon+8'h05;`ten : moneycon=moneycon+8'h0a;`twenty : moneycon=moneycon+8'h14;default: moneycon=moneycon+0; //无投币则余额不变endcasestatecon=condition_s(moneycon);//调用函数endelse if (moneycon<8'h14)//不允许投币时,根据余额变化statecon=condition_s(moneycon);//直接切换状态endendtaskfunction [2:0] condition_s;//根据余额的值切换状态的函数input [7:0] money_s;reg [7:0] money_s;beginif (money_s==0)condition_s=A;else if(money_s==8'h01)condition_s=B;else if(money_s==8'h02||money_s==8'h03)condition_s=C;else if(money_s>=8'h04&&money_s<8'h14)condition_s=D;else condition_s=E;endendfunctionendmodule测试程序如下:`timescale 100ns/1ns`define clk_cycle 50module test;reg moneyback,choice1,choice2,choice3,choice4,choice5,choice6; reg [2:0] coin;reg clk,reset;wire[7:0] money;wire[2:0] state;wire moneyout,coinable,adrkable,bdrkable,cdrkable,drkout1,drkout2,drkout3,drkout4,drkout5,drkout6;parameter one=3'b001,five=3'b010,ten=3'b011,twenty=3'b100;always #`clk_cycle clk= ~clk;initialbegincoin=0;moneyback=0;clk=0;choice1=0;choice2=0;choice3=0;choice4=0;choice5=0;choice6=0;reset=1;#10 reset=0;#200 reset=1;#400 coin=one;//投币1元,#220 coin=0;#200 coin=one;//投1元,余额2元#220 coin=0;#200 coin=five;//投5元,余额7元#220 coin=0;#200 coin=twenty;//投20元,余27#220 coin=0;#200 choice1=1;//买1元饮料,余26#220 choice1=0;#200 choice3=1;//买2元饮料,余24#220 choice3=0;#200 choice4=1;//买2元饮料,余22#220 choice4=0;#200 choice5=1;//买4元饮料,余18#220 choice5=0;#200 choice6=1;//买4元饮料,余14#220 choice6=0;#200 choice6=1;//买4元饮料,余10#220 choice6=0;#200 choice6=1;//买4元饮料,余6#220 choice6=0;#200 choice6=1;//买4元饮料,余2#220 choice6=0;#200 coin=five;//投5元,余7#220 coin=0;#200 moneyback=1;//退钱#220 moneyback=0;endautomart m(.money(money),.state(state),.moneyout(moneyout), .coinable(coinable),.adrkable(adrkable),.bdrkable(bdrkable),.cdrkable(cdrkable),.drkout1(drkout1),.drkout2(drkout2),.drkout3(drkout3),.drkout4(drkout4),.drkout5(drkout5),.drkout6(drkout6),.coin(coin),.clk(clk),.reset(reset),.moneyback(moneyback),.choice1(choice1),.choice2(choice2),.choice3(choice3),.choice4(choice4),.choice5(choice5),.choice6(choice6));endmodule。