vending machine
if naive method
One idea is to use the register cnt to record the existing smallest unit currency amount, here it is 0.5
When d1, cnt+1; when d2, cnt+2; when d3, cnt+4;
`timescale 1ns/1ns
module seller1(
input wire clk ,
input wire rst ,
input wire d1 ,
input wire d2 ,
input wire d3 ,
output reg out1,
output reg [1:0]out2
);
reg[2:0]cnt;
always@(posedge clk,negedge rst)begin
if(!rst)begin
cnt<=0;
out1<=0;
out2<=0;
end
else begin
if(d1)cnt<=cnt+1;
else if(d2)cnt<=cnt+2;
else if(d3)cnt<=cnt+4;
else if(cnt>=3)begin
out1<=1;
out2<=cnt-3;
cnt<=0;//记得复位为0,表示一个过程的结束
end
else begin
out1<=0;
out2<=0;
end//这里需要注意一定需要这一步,不然在不复位时,将保持一直输出1的状态
end
end
endmodule
Note here that d1, d2, and d3 are all in the form of pulses, that is, they will only be accepted in one time step, and the detection is also
`timescale 1ns/1ns
module seller1(
input wire clk ,
input wire rst ,
input wire d1 ,
input wire d2 ,
input wire d3 ,
output reg out1,
output reg [1:0]out2
);
parameter S0 = 'd0, S1 = 'd1, S2 = 'd2, S3 = 'd3 , S4 = 'd4, S5 = 'd5 , S6 = 'd6;
reg [2:0] current_state;
reg [2:0] next_state;
wire [2:0] input_state;//将输入组合起来
assign input_state = {d1,d2,d3};
always@(posedge clk or negedge rst)begin
if(rst == 1'b0)begin
current_state <= S0;
end
else begin
current_state <= next_state;
end
end
always@(*)begin
case(current_state)
S0:begin
case(input_state)
3'b100:next_state = S1 ;
3'b010:next_state = S2 ;
3'b001:next_state = S4 ;
default:next_state = next_state;
endcase
end
S1:begin
case(input_state)
3'b100:next_state = S2 ;
3'b010:next_state = S3 ;
3'b001:next_state = S5 ;
default:next_state = next_state;
endcase
end
S2:begin
case(input_state)
3'b100:next_state = S3 ;
3'b010:next_state = S4 ;
3'b001:next_state = S6 ;
default:next_state = next_state;
endcase
end
default:begin
next_state = S0;
end
endcase
end
always@(posedge clk or negedge rst)begin
if(rst == 1'b0)begin
out1 <= 1'b0;
out2 <= 2'b0;
end
else begin
case(next_state)
S3: begin out1 <= 1'b1;out2 <= 2'b0; end
S4: begin out1 <= 1'b1;out2 <= 2'b1; end
S5: begin out1 <= 1'b1;out2 <= 2'b10; end
S6: begin out1 <= 1'b1;out2 <= 2'b11; end
default: begin out1 <= 1'b0;out2 <= 2'b0; end
endcase
end
end
endmodule
State machine method
Using MOORE state machine, that is, the output is only related to the state and has nothing to do with the current input signal
The state machine method can support inserting multiple coins at one time
MOORE three sections
The first paragraph: signal declaration, state definition, state transition
Second paragraph: From the current state, determine the next state based on the input signal
It can be seen here that if multiple coins are invested at one time, transfer and judgment can be performed. Just add judgment in the case.
Section 3: Determine the output signal based on the secondary state
Vending machine (supports multi-item vending)
When sel is 0, buy one dollar and a half, which is the fourth state, s3; when sel is 1, buy two yuan and a half, which is the sixth state, s5.
state machine
`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, S0_5=1, S1=2, S1_5=3, S2=4, S2_5=5, S3=6;
reg[2:0] state, nstate;
always@(posedge clk or negedge rst) begin
if(~rst)
state <= 0;
else
state <= nstate;
end
always@(*) begin
case(state)
S0 : nstate = d1? S0_5:
d2? S1:
nstate;
S0_5 : nstate = d1? S1:
d2? S1_5:
nstate;
S1 : nstate = d1? S1_5:
d2? S2:
nstate;
S1_5 : nstate = ~sel? S0:
d1? S2:
d2? S2_5:
nstate;
S2 : nstate = ~sel? S0:
d1? S2_5:
d2? S3:
nstate;
default: nstate = S0;
endcase
end
always@(*) begin
if(~rst) begin
{out1, out2, out3} = 3'b000;
end
else begin
case(state)
S0, S0_5, S1: {out1, out2, out3} = 0;
S1_5 : {out1, out2, out3} = ~sel? 3'b100: 3'b000;
S2 : {out1, out2, out3} = ~sel? 3'b101: 3'b000;
S2_5 : {out1, out2, out3} = ~sel? 3'b101: 3'b010;
S3 : {out1, out2, out3} = ~sel? 3'b101: 3'b011;
default : {out1, out2, out3} = 3'b000;
endcase
end
end
//*************code***********//
endmodule
The above is a mealy state machine, that is, the output depends on the current state and the input signal
`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
);
parameter S0 = 'd0, S1 = 'd1, S2 = 'd2, S3 = 'd3 , S4 = 'd4, S5 = 'd5, S6 = 'd6;
reg [2:0] current_state;
reg [2:0] next_state;
wire [1:0] input_state;
assign input_state = {d1,d2};
always@(posedge clk or negedge rst)begin
if(rst == 1'b0)begin
current_state <= S0;
end
else begin
current_state <= next_state;
end
end
always@(*)begin
if (!sel) begin
case(current_state)
S0:begin
case(input_state)
2'b10 :next_state = S1 ;
2'b01 :next_state = S2 ;
default:next_state = next_state;
endcase
end
S1:begin
case(input_state)
2'b10 :next_state = S2 ;
2'b01 :next_state = S3 ;
default:next_state = next_state;
endcase
end
S2:begin
case(input_state)
2'b10 :next_state = S3 ;
2'b01 :next_state = S4 ;
default:next_state = next_state;
endcase
end
default: next_state = S0;
endcase
end
else begin
case(current_state)
S0:begin
case(input_state)
2'b10 :next_state = S1 ;
2'b01 :next_state = S2 ;
default:next_state = next_state;
endcase
end
S1:begin
case(input_state)
2'b10 :next_state = S2 ;
2'b01 :next_state = S3 ;
default:next_state = next_state;
endcase
end
S2:begin
case(input_state)
2'b10 :next_state = S3 ;
2'b01 :next_state = S4 ;
default:next_state = next_state;
endcase
end
S3:begin
case(input_state)
2'b10 :next_state = S4 ;
2'b01 :next_state = S5 ;
default:next_state = next_state;
endcase
end
S4:begin
case(input_state)
2'b10 :next_state = S5 ;
2'b01 :next_state = S6 ;
default:next_state = next_state;
endcase
end
default: next_state = S0;
endcase
end
end
always@(posedge clk or negedge rst)begin
if(rst == 1'b0)begin
out1 <= 1'b0;
out2 <= 1'b0;
out3 <= 1'b0;
end
else begin
if(!sel)begin
case (next_state)
S3: begin out1 <= 1'b1;out2 <= 1'b0;out3 <= 1'b0;end
S4: begin out1 <= 1'b1;out2 <= 1'b0;out3 <= 1'b1;end
default:begin out1 <= 1'b0;out2 <= 1'b0;out3 <= 1'b0;end
endcase
end
else begin
case (next_state)
S5: begin out1 <= 1'b0;out2 <= 1'b1;out3 <= 1'b0;end
S6: begin out1 <= 1'b0;out2 <= 1'b1;out3 <= 1'b1;end
default:begin out1 <= 1'b0;out2 <= 1'b0;out3 <= 1'b0;end
endcase
end
end
end
endmodule
The above is the standard MOORE state machine code, that is, the output is only related to the secondary state.
During state transition, be sure to remember to write
That is equivalent to the subsequent reset, otherwise there is no way to reset