当前位置:   article > 正文

verilog 实现自动售卖机_verilog自动售货机

verilog自动售货机

题目如下所示:
请设计状态机电路,实现自动售卖机功能,A饮料5元钱,B饮料10元钱,售卖机可接收投币5元钱和10元钱,每次投币只可买一种饮料,考虑找零的情况。

电路的接口如下图所示。sel信号会先于din信号有效,且在购买一种饮料时值不变。

sel为选择信号,用来选择购买饮料的种类,sel=0,表示购买A饮料,sel=1,表示购买B饮料;
din表示投币输入,din=0表示未投币,din=1表示投币5元,din=2表示投币10元,不会出现din=3的情况;
drinks_out表示饮料输出,drinks_out=0表示没有饮料输出,drinks_out=1表示输出A饮料,drinks_out=2表示输出B饮料,不出现drinks_out =3的情况,输出有效仅保持一个时钟周期;
change_out表示找零输出,change_out=0表示没有找零,change_out=1表示找零5元,输出有效仅保持一个时钟周期。
接口电路图如下
在这里插入图片描述
程序编写:
module sale(
input clk,
input rst_n,
input sel, //sel = 0 A drinks
//sel = 1 B drinks
input [1:0] din, // din = 0 no money
// din = 1 5r
// din = 2 10r
output reg [1:0] drinks_out, //drinks_out = 0 no drinks output
// drinks_out = 1 out A drinks
// drinks_out = 2 out B drinks
output reg change_out // change_out = 0 no change
// change_out =1 chang 5r
);
parameter IDLE = 'd0;
parameter S0 = 'd1; //此状态为饮料B 但第一次只投了五元钱

reg [1:0]cur_state;
reg [1:0]next_state;

always@(posedge clk or negedge rst_n)
begin
if(rst_n == 'd0)
begin
cur_state <= IDLE;
next_state <= 'd0;
end
else
cur_state <= next_state;
end

always@(*)
begin
	case(cur_state)
		IDLE : next_state = sel?(din==1 ? S0 : IDLE):IDLE;  //sel=1 即选择B饮料,判断第一次投入的是五元钱还是10元钱,若投的是五元钱则进入状态S0,等待第二次投钱
		S0 : next_state = (din == 0) ? S0 : IDLE;
		default: next_state = IDLE;
	
	endcase
	
end
always@(posedge clk or negedge rst_n)
begin
	if(rst_n == 'd0)
	drinks_out <= 'd0;
	else if(sel == 'd0)
	begin
		if((cur_state==IDLE&&din==1)||(cur_state ==IDLE&&din==2))
		drinks_out <= 'd1;
		else
		drinks_out <= 'd0;
	end
	else if(sel == 'd1)
	begin
		if((cur_state == IDLE&&din=='d2)||(cur_state ==S0&&din=='d1)||(cur_state ==S0&&din=='d2)) 
		drinks_out <= 'd2;
		else
		drinks_out <= 'd0;
	end
end

always@(posedge clk or negedge rst_n) //这里涉及到第一次投入的是五元钱第二次投入五元钱还是十元钱的情况,第二次投入五元则不找零,投入十元则找零
begin
	if(rst_n =='d0)
	change_out <= 'd0;
	else if(sel =='d0)
	begin
		if(cur_state ==IDLE&&din=='d2)
		change_out <= 'd1;
		else
		change_out <= 'd0;
	end
	else if(sel =='d1)
	begin
		if(cur_state == S0&&din=='d2)
		change_out <= 'd1;
		else
		change_out <= 'd0;
	end
end
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49

endmodule

-------------------------------------------------------——————————————————————————————————
编写testbench测试:

module sale_tb;

reg clk;
reg rst_n;
reg sel;
reg [1:0] din;

wire [1:0]drinks_out;
wire change_out;

initial begin
clk = 0;
forever #5 clk = ~clk;
end

initial begin
rst_n = 0;
sel = 0;
din = 0;
#100
rst_n = 1;
#10
sel = 0;
#10
din = 1;
#10
sel =1;
#10
din =2;
#10
sel =1;
#10
din=1;
#10
din =2;
#10
sel =0;
#10
din =2;
#10
din= 0;
#100

$finish;
  • 1

end
sale sale_m0(
.clk(clk),
.rst_n(rst_n),
.sel(sel), //sel = 0 A drinks
//sel = 1 B drinks
.din(din), // din = 0 no money
// din = 1 5r
// din = 2 10r
.drinks_out(drinks_out), //drinks_out = 0 no drinks output
// drinks_out = 1 out A drinks
// drinks_out = 2 out B drinks
.change_out(change_out) // change_out = 0 no change
// change_out =1 chang 5r
);

endmodule

仿真结果:
在这里插入图片描述

代码下载(包含testbench):
https://download.csdn.net/download/weixin_44413306/85844663

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/喵喵爱编程/article/detail/910217
推荐阅读
相关标签
  

闽ICP备14008679号