logo资料库

自动售货机verilog.doc

第1页 / 共10页
第2页 / 共10页
第3页 / 共10页
第4页 / 共10页
第5页 / 共10页
第6页 / 共10页
第7页 / 共10页
第8页 / 共10页
资料共10页,剩余部分请下载后查看
自动售货机设计 一、实验目的 1、实现自动售货机的功能; 2、运用状态机原理设计。 二、实验内容  这种自动售货机只销售听装与瓶装两种罐装可乐,售价均为 1.5 元。顾客只能通过 两个不同的投币口分别投入五角的硬币或者一元硬币。一次交易可以买多罐,且自 动找零。若钱不够,则自动退币。并且在购买之前只要一按下取消键 cancel 就马上 无条件退币。  此机器的硬件示范电路,以二個按键电路代替二個投币孔,以两个八段数码管显示 投币数量,再以 4hz 闪烁之 led 來显示退币,以两个八段数码管显示退币数量。此 机器就采用 1024hz 的系统 clock 信号同步所有的买卖行为,并且作为弹跳消除电路 的基准参考脉冲。这个电路虽然是纯数位电路但是可作为一个自动售货机的控制核 心电路加上驱动器就可以用来驱动机械装置。  下图为自动售货机的操作盘,有两个投币按钮,分別为五角硬币与一元硬币。每投 入一个硬币就将下方的 LED 指示灯号点亮到具体数额,并且最高上限只能接受 9.5 元的金额。另外,每一种饮料商品都配置 3 个灯号(分别显示存货、选择数量与出 货等三个信息)与一个选择购买的按钮。每按一次选择购买按钮,选择数量显示加 1,并且存货自动计算,若没有货存,则货存灯灭,一旦选择商品与投币金额足够, 就需要按下确定要购买的按键;当然也可以后悔不买而按下取消键,让机器退回已 经投入的硬币。如若投入的钱币不足以购所有的饮料,则退币。退币时货存更改为 原状态。 三、程序设计 module auto_vending(clk,cel_cola,cel_diet,reset,coin_ten,coin_five,ok_buy,cancel_buy,//输入 led_cola_ok,led_diet_ok,led_buy,led_cancel,led_cola_out,led_diet_out,shu_cola_sel,shu_diet_se l, led_display,shu_money_return,Hex);//输出 input clk,cel_cola,cel_diet,reset,coin_ten,coin_five,ok_buy,cancel_buy; output led_cola_ok,led_diet_ok,//表示还有存货 led_buy,led_cancel,//表示选择购买和取消购买 led_cola_out,led_diet_out;//显示表示已出货 //led_return;//每四秒闪烁一次代表被退之硬币 wire [10:0]led_cola_sel,led_diet_sel;////选中饮料的数量 output [6:0]shu_cola_sel,shu_diet_sel; output [13:0]led_display;//表示投币的金额 output [13:0]shu_money_return; wire ok,cancel,money_ok;//在 ok_or_cancel 出来的 //wire [10:0]no_diet,no_cola;//售货机内的饮料数量 wire [10:0]money_return; //reg [10:0]no_sock_cola,no_sock_diet; wire [10:0]total_count,total_consum; output [13:0]Hex;
assign Hex=14'b111_111_111_11111; parameter Idle = 2'd0, S1 = 2'd1, S2 = 2'd2; reg [1:0]state; reg clk_1; reg rst; reg [29:0]count; always@(posedge clk)//sheng cheng 1s de shi zhong begin if(count==30'd25000000) begin clk_1<=~clk_1; count<=0; end else count<=count+1; end always@(posedge clk_1 or negedge reset) if(!reset) begin state <=Idle; rst<=0; end else case (state) Idle: begin rst<=0; state<=S1; end begin S1: rst<=1; if(ok_buy||cancel_buy) state<=Idle; end endcase wire buyok; toubi u1(rst,clk,coin_five,coin_ten,led_display,total_count); select_drink u2(clk,rst,cel_cola,cel_diet,/*no_cola,no_diet,*/
led_cola_sel,led_diet_sel,/*led_cola_ok,led_diet_ok,*/total_consum); ok_or_cancel u3(clk,rst,ok_buy,cancel_buy,ok,cancel,led_buy,led_cancel); give_check u4(reset,buyok,clk,ok,money_ok,rst,led_cola_out,led_diet_out, led_cola_sel,led_diet_sel,led_cola_ok,led_diet_ok/*no_cola,no_diet*/); coin_return u5(clk,rst,ok_buy,money_return,total_count,total_consum,money_ok,cancel_buy,cancel); xianshi q1(led_cola_sel,shu_cola_sel); xianshi q2(led_diet_sel,shu_diet_sel); xianshi2 w2(money_return,shu_money_return); endmodule //用来显示 ///显示数量的 module xianshi(a,b); input [10:0]a; output reg [6:0]b; always@(a) case(a) 11'd0:b<=7'b1000000; 11'd1:b<=7'b1111001; 11'd2:b<=7'b0100100; 11'd3:b<=7'b0110000; 11'd4:b<=7'b0011001; 11'd5:b<=7'b0010010; 11'd6:b<=7'b0000010; 11'd7:b<=7'b1111000; 11'd8:b<=7'b0000000; 11'd9:b<=7'b0010000; endcase endmodule //钱数显示 module xianshi2(total_count,led_display); input [10:0]total_count; output reg [13:0]led_display; always@(total_count) case(total_count) 11'd0: led_display<=14'b1000000_1000000; 11'd1: led_display<=14'b1000000_0010010;
11'd2: led_display<=14'b1111001_1000000; 11'd3: led_display<=14'b1111001_0010010; 11'd4: led_display<=14'b0100100_1000000; 11'd5: led_display<=14'b0100100_0010010; 11'd6: led_display<=14'b0110000_1000000; 11'd7: led_display<=14'b0110000_0010010; 11'd8: led_display<=14'b0011001_1000000; 11'd9: led_display<=14'b0011001_0010010; 11'd10: led_display<=14'b0010010_1000000; 11'd11: led_display<=14'b0010010_0010010; 11'd12: led_display<=14'b0000010_1000000; 11'd13: led_display<=14'b0000010_0010010; 11'd14: led_display<=14'b1111000_1000000; 11'd15: led_display<=14'b1111000_0010010; 11'd16: led_display<=14'b0000000_1000000; 11'd17: led_display<=14'b0000000_0010010; 11'd18: led_display<=14'b0010000_1000000; 11'd19: led_display<=14'b0010000_0010010; endcase endmodule //去抖模块 module qudou(clk,reset,k,key); input k,reset,clk; output reg key; reg [10:0]clock; always@(posedge clk) if(!reset) clock<=11'd0; else begin if(k) begin key<=1; clock<=0; end else begin clock<=clock+1; if(clock==1000) begin clock<=11'b0; key=0;
end end end endmodule /////投币电路 module toubi(reset,clk,coin_05,coin_10,led_display,total_count);//加一个去抖模块 input reset,clk,coin_05,coin_10; output [13:0]led_display; output reg[10:0]total_count;//统计投入里面的金币 wire qu_coin_05,qu_coin_10; qudou a1(clk,reset,coin_05,qu_coin_05); qudou a2(clk,reset,coin_10,qu_coin_10); reg [10:0]count_1,count_2; always@(negedge qu_coin_05 or negedge reset) begin if(!reset) begin count_1<=11'd0; end else if(!qu_coin_05) begin count_1 <= count_1+11'd1; end end always@(negedge qu_coin_10 or negedge reset) if(!reset) begin count_2<=11'd0; end else if(!coin_10) begin count_2<=count_2+11'd2; end always@(count_1 or count_2) total_count<=count_2+count_1; xianshi2 a4(total_count,led_display); endmodule //饮料选择处理模块 module select_drink(clk,reset,select_cola,select_diet/*,sock_cola,sock_diet*/, cola_sel,diet_sel,/*led_cola_ok,led_diet_ok,*/total_consum); input clk,reset,select_cola,select_diet;
//input [10:0]sock_cola,sock_diet;//系统内部库存数量 output [10:0]cola_sel,diet_sel;//选中的饮料数量 reg [10:0]cola,diet; //output led_cola_ok,led_diet_ok;//除去选中的饮料外,是否还有余量 output [10:0]total_consum;//消费金额 reg [10:0]cola_sel,diet_sel; //reg led_cola_ok,led_diet_ok; wire select_cola_out,select_diet_out; qudou a3(clk,reset,select_cola,select_cola_out); qudou a4(clk,reset,select_diet,select_diet_out); reg [10:0]total_consum_2,total_consum_1,total_consum; always@(total_consum_2 or total_consum_1) total_consum<=total_consum_2+total_consum_1; always@(negedge reset or negedge select_cola_out ) if(!reset) begin cola_sel<=0; total_consum_1<=0; end else if(!select_cola_out) begin cola_sel<=cola_sel+1; total_consum_1<=total_consum_1+11'd3; end always@(negedge reset or negedge select_diet_out) if(!reset) begin diet_sel<=0; total_consum_2<=0; end else if(!select_diet_out) begin diet_sel<=diet_sel+1; total_consum_2<=total_consum_2+11'd3; end /* always@(posedge clk or negedge reset) if(!reset) begin led_cola_ok<=1; led_diet_ok<=1;
else end begin cola <= sock_cola; diet <= sock_diet; if(cola_sel >= cola) led_cola_ok <= 0; if(diet_sel >= diet) led_diet_ok <= 0; end */ Endmodule //确认与取消电路模块 module ok_or_cancel(clk,reset,ok_buy,cancel_buy, ok,cancel,//给其他模块使用 led_buy,led_cancel);//对外显示 input clk,reset,ok_buy,cancel_buy; output reg ok,cancel; output reg led_buy,led_cancel; always@(posedge clk or negedge reset) if(!reset) begin ok<=0; cancel<=0; led_buy<=0; led_cancel<=0; end else if(ok_buy) begin ok<=1; led_buy<=1; cancel<=0; led_cancel<=0; end else if(cancel_buy)
begin ok<=0; cancel<=1; led_buy<=0; led_cancel<=1; end endmodule //出货并计算存货模块 module give_check(reset,buyok,clk,ok,money_ok,rst,led_cola_out,led_diet_out, cola_out,diet_out,led_cola_ok,led_diet_ok/*no_cola,no_diet*/); input reset,clk,ok,rst,money_ok; input [10:0]cola_out,diet_out;//从售货机内取出的饮料数量 output reg led_cola_ok,led_diet_ok;//显示是否还有饮料 reg [10:0]no_cola,no_diet,sock_cola,sock_diet;//输出的饮料之后售货机内部剩余数量 output led_cola_out,led_diet_out;//售货机输出饮料时 led 亮 reg led_cola_out,led_diet_out; reg [1:0]state; parameter S1=2'd0, S2=2'd1, S3=2'd2; reg s1,s2; output reg buyok; always@(posedge clk or negedge reset) if(!reset) begin sock_cola<=11'd5; sock_diet<=11'd5; end else if(!rst) begin led_cola_out<=0; led_diet_out<=0; state<=S1; s1<=0; s2<=0; no_cola<=sock_cola; no_diet<=sock_diet; buyok<=0; end else case(state) S1: if(ok && money_ok)
分享到:
收藏