题解 | 自动贩售机2
同样考虑连续投币问题:
`timescale 1ns/1ns
module seller2(
input wire clk ,
input wire rst ,
input wire d1 ,
input wire d2 ,
input wire sel ,
output reg out1,
output reg out2,
output reg out3
);
//*************code***********//
parameter S0=0,S05=1,S10=2,S15=3,S20=4,S25=5,S30=6;
reg [2:0]state,next;
reg d1r,d2r;
always@(posedge clk or negedge rst)
if (~rst)
state <= S0;
else
state <= next;
always@(posedge clk or negedge rst)
if (~rst) begin
d1r <= 0;
d2r <= 0;
end
else begin
d1r <= d1;
d2r <= d2;
end
always@(*)
if (~rst)
next = S0;
else begin
case(state)
S0 : next = {d1r,d2r}==2'b10 ? S05: //0
{d1r,d2r}==2'b01 ? S10: state;
S05: next = {d1r,d2r}==2'b10 ? S10: //0.5
{d1r,d2r}==2'b01 ? S15: state;
S10: next = {d1r,d2r}==2'b10 ? S15: //1.0
{d1r,d2r}==2'b01 ? S20: state;
S15: next = ~sel? ({d1r,d2r}==2'b10 ? S05:
{d1r,d2r}==2'b01 ? S10:
{d1r,d2r}==2'b00 ? S0 :next):
({d1r,d2r}==2'b10 ? S20:
{d1r,d2r}==2'b01 ? S25:next);
S20: next = ~sel? ({d1r,d2r}==2'b10 ? S05:
{d1r,d2r}==2'b01 ? S10:
{d1r,d2r}==2'b00 ? S0 :next):
({d1r,d2r}==2'b10 ? S25: //2.0
{d1r,d2r}==2'b01 ? S30:next);
S25: next = {d1r,d2r}==2'b10 ? S05: //2.5
{d1r,d2r}==2'b01 ? S10:
{d1r,d2r}==2'b00 ? S0 :next;
S30: next = {d1r,d2r}==2'b10 ? S05: //3.0
{d1r,d2r}==2'b01 ? S10:
{d1r,d2r}==2'b00 ? S0 :next;
default: next = S0;
endcase
end
always@(posedge clk or negedge rst)
if (~rst) begin
out1 <= 1'b0;
out2 <= 1'b0;
out3 <= 1'b0;
end
else begin
case (next)
S15:
begin
if (~sel) begin
out1 <= 1'b1;
out3 <= 1'b0;
end
end
S20:
begin
if (~sel) begin
out1 <= 1'b1;
out3 <= 1'b1;
end
end
S25:
begin
out2 <= 1'b1;
out3 <= 1'b0;
end
S30:
begin
out2 <= 1'b1;
out3 <= 1'b1;
end
default: begin out1 <= 1'b0; out2 <= 1'b0; out3 <= 1'b0;end
endcase
end
//*************code***********//
endmodule
`timescale 1ns/1ns
module seller2_tb();
reg clk ;
reg rst ;
reg d1 ;
reg d2 ;
reg sel ;
wire out1 ;
wire out2 ;
wire out3 ;
seller2 sss(
.clk (clk) ,
.rst (rst) ,
.d1 (d1) ,
.d2 (d2) ,
.sel (sel) ,
.out1 (out1) ,
.out2 (out2) ,
.out3 (out3)
);
initial begin
clk=0;
end
always#10 clk=~clk;
// 测试主程序
initial begin
#10;
rst = 1'b1;
{d1,d2}=2'b00;
#20;
sel =1'b0;
#20;
@ (posedge clk) ; {d1,d2}=2'b10;
@ (negedge clk) ; {d1,d2}=2'b00;
#20;
@ (posedge clk) ; {d1,d2}=2'b01;
@ (negedge clk) ; {d1,d2}=2'b00;
#5;
@ (posedge clk) ; {d1,d2}=2'b01;
@ (negedge clk) ; {d1,d2}=2'b00;
#20;
@ (posedge clk) ; {d1,d2}=2'b01;
@ (negedge clk) ; {d1,d2}=2'b00;
#5;
@ (posedge clk) ; {d1,d2}=2'b01;
@ (negedge clk) ; {d1,d2}=2'b00;
#20;
sel = 1'b1;
#20;
@ (posedge clk) ; {d1,d2}=2'b10;
@ (negedge clk) ; {d1,d2}=2'b00;
#20;
@ (posedge clk) ; {d1,d2}=2'b01;
@ (negedge clk) ; {d1,d2}=2'b00;
#5;
@ (posedge clk) ; {d1,d2}=2'b01;
@ (negedge clk) ; {d1,d2}=2'b00;
#20;
@ (posedge clk) ; {d1,d2}=2'b01;
@ (negedge clk) ; {d1,d2}=2'b00;
#20;
@ (posedge clk) ; {d1,d2}=2'b01;
@ (negedge clk) ; {d1,d2}=2'b00;
#20;
@ (posedge clk) ; {d1,d2}=2'b01;
@ (negedge clk) ; {d1,d2}=2'b00;
#20;
@ (posedge clk) ; {d1,d2}=2'b01;
@ (negedge clk) ; {d1,d2}=2'b00;
#20;
#200 $finish;
end
endmodule