任务要求
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/51d79fda0fd183ce81006940e1a98bc7.png)
任务拆分
首先是要划分不同的状态,不投币,投了0.5元,投了1元,投了1.5元,投了2元,投了2.5元,投了三元。状态的输入有两个,一个是1元,一个0.5元。输出有三个,一个是给可乐不找零,不给可乐找零,还有led根据不同的输出,实现不同的功能。最后还有延迟的要求,需要按键按下之后,10秒不操作就归零(可乐机吃钱事件)。
verilog代码
module cola_ma_top
#(
parameter cnt_20_ms = 'd999_999,
parameter cnt_0_5s = 'd24_999_999,
parameter cnt_1s = 'd49_999_999
)
(
input clk,
input rst_n,
input key1,
input key2,
output reg [3:0] led,
output reg [1:0] out_1
);
parameter IDLE = 'b0000001;
parameter mo_0_5 = 'b0000010;
parameter mo_1_0 = 'b0000100;
parameter mo_1_5 = 'b0001000;
parameter mo_2_0 = 'b0010000;
parameter LED_water1 = 'b0100000;
parameter LED_water2 = 'b1000000;
reg [6:0]state;
wire key1_temp ;
wire key2_temp;
wire [3:0]led1;
wire [3:0]led2;
reg [27:0] cnt0;
reg work_water;
reg rst;
reg cnt_20_flag;
reg cnt_en;
reg en_key1_temp;
reg en_key2_temp;
wire en_key1;
wire en_key2;
always@(posedge clk or negedge rst_n)
if(!rst_n || cnt_20_flag)
state <= IDLE;
else case(state)
IDLE:
if(key1_temp)
state <= mo_0_5;
else if(key2_temp)
state <= mo_1_0;
else
state <= IDLE;
mo_0_5: if(key1_temp)
state <= mo_1_0;
else if(key2_temp)
state <= mo_1_5;
else
state <= mo_0_5;
mo_1_0: if(key1_temp)
state <= mo_1_5;
else if(key2_temp)
state <= mo_2_0;
else
state <= mo_1_0;
mo_1_5: if(key1_temp)
state <= mo_2_0;
else if(key2_temp)
state <= LED_water1;
else
state <= mo_1_5;
mo_2_0: if(key1_temp)
state <= LED_water1;
else if(key2_temp)
state <= LED_water2;
else
state <= mo_2_0;
LED_water1: if(key1_temp)
state <= mo_0_5;
else if(key2_temp)
state <= mo_1_0;
else
state <= LED_water1;
LED_water2: if(key1_temp)
state <= mo_0_5;
else if(key2_temp)
state <= mo_0_5;
else
state <= LED_water2;
default: state <= IDLE;
endcase
always@(posedge clk or negedge rst_n)
if(!rst_n)
led <= 4'd0;
else
case(state)
IDLE: led <= 4'b0000;
mo_0_5: led <= 4'b0001;
mo_1_0: led <= 4'b0011;
mo_1_5: led <= 4'b0111;
mo_2_0: led <= 4'b1111;
LED_water1: led <= led1;
LED_water2: led <= led2;
default : led <= led;
endcase
reg out_en;
always@(posedge clk or negedge rst_n)
if(!rst_n)
begin
out_1 <= 2'b00;
out_en <= 1'b1;
end
else
case(state)
IDLE: begin
out_1 <= 2'b00;
out_en <= 1'b1;
end
mo_0_5: begin
out_1 <= 2'b00;
out_en <= 1'b1;
end
mo_1_0: begin
out_1 <= 2'b00;
out_en <= 1'b1;
end
mo_1_5: begin
out_1 <= 2'b00;
out_en <= 1'b1;
end
mo_2_0: begin
out_1 <= 2'b00;
out_en <= 1'b1;
end
LED_water1: if(out_en)begin
out_1 <= 2'b10;
out_en <= 1'b0;
end
LED_water2: if(out_en)begin
out_1 <= 2'b01;
out_en <= 1'b0;
end
default : begin
out_1 <= 2'b00;
out_en <= 1'b1;
end
endcase
always@(posedge clk or negedge rst_n)
if(!rst_n)
cnt0 <= 28'd0;
else if(rst)
cnt0 <= 28'd0;
else if( cnt0 == cnt_0_5s)
cnt0 <= 28'd0;
else if( cnt_en )
cnt0 <= cnt0 + 1'b1;
reg cnt0_flag;
always@(posedge clk or negedge rst_n)
if(!rst_n)
cnt0_flag <= 1'b0;
else if( cnt0 == cnt_0_5s-1)
cnt0_flag <= 1'b1;
else
cnt0_flag <= 1'b0 ;
reg [4:0]cnt_20;
always@(posedge clk or negedge rst_n)
if(!rst_n)
cnt_20 <= 5'd0;
else if(( cnt_20 == 'd19) || key2_temp || key1_temp)
cnt_20 <= 5'd0;
else if( cnt0_flag )
cnt_20 <= cnt_20 + 1'b1;
always@(posedge clk or negedge rst_n)
if(!rst_n)
cnt_20_flag <= 1'b0;
else if( cnt_20 == 'd18)
cnt_20_flag <= 1'b1;
else
cnt_20_flag <= 1'b0 ;
always@(posedge clk or negedge rst_n)
if(!rst_n) begin
cnt_en <= 1'b0;
end
else if( key2_temp || key1_temp )
cnt_en <= 1'b1 ;
else
cnt_en <= cnt_en;
key_fitter
#(
.cnt_20_ms(cnt_20_ms)
)
Q_0_5
(
.clk(clk),
.rst_n(rst_n),
.key_in(key1),
.led(key1_temp)
);
key_fitter
#(
.cnt_20_ms(cnt_20_ms)
)
Q_1
(
.clk(clk),
.rst_n(rst_n),
.key_in(key2),
.led(key2_temp)
);
water_led
#(
.cnt_0_5s(cnt_0_5s)
)
w0
(
.clk(clk),
.rst_n(rst_n),
.led(led2)
);
water_2_led
#(
.cnt_0_5s(cnt_0_5s)
)
w111
(
.clk(clk),
.rst_n(rst_n),
.led(led1)
);
endmodule