有限状态机-----自动售货机
假设自动售货机的投币口可以投10元,20元和50元。商品价格为80元
RTL代码
module DRINK_STAUTS_MOORE #(
parameter CHARGE_WIDTH = 6
)
(
input clk,
input rst_n,
input ten,
input twenty,
input fifty,
output reg out,
output reg [CHARGE_WIDTH-1 : 0] charge
);
localparam FSM_WIDTH = 4;
localparam IDLE = 4'd0,
TEN_ST = 4'd10,
TWENTY_ST = 4'd20,
THIRTY_ST = 4'd30,
FOURTY_ST = 4'd40,
FIFTY_ST = 4'd50,
SIXTY_ST = 4'd60,
SEVENTY_ST = 4'd70,
EIGHTY_ST = 4'd80,
NINETY_ST = 4'd90,
HUND_ST = 4'd100,
HUND_TEN_ST = 4'd110,
HUND_TWENTY_ST = 4'd120;
reg [FSM_WIDTH-1 , 0 ] curr_state;
reg [FSM_WIDTH-1 , 0 ] next_state;
always @ (posedge clk , negedge rst_n ) begin
if (rst_n==0) begin
curr_state <= IDLE;
end
else begin
curr_state <= next_state;
end
end
always @ (*) begin
case(curr_state)
IDLE : begin
if (ten == 1'b1) begin
next_state = TEN_ST ;
end
if else (twenty == 1'b1) begin
next_state = TWENTY_ST ;
end
if else (fifty == 1'b1) begin
next_state = FIFTY_ST ;
end
else begin
next_state = IDLE_ST ;
end
end
TENTY_ST : begin
if (ten == 1'b1) begin
next_state = TWENTY_ST ;
end
if else (twenty == 1'b1) begin
next_state = THIRTY_ST ;
end
if else (fifty == 1'b1) begin
next_state = SIXTY_ST ;
end
else begin
next_state = TWENTY_ST ;
end
end
THIRTY_ST : begin
if (ten == 1'b1) begin
next_state = FOURTY_ST ;
end
if else (twenty == 1'b1) begin
next_state = FIFTY_ST ;
end
if else (fifty == 1'b1) begin
next_state = EIGHTY_ST ;
end
else begin
next_state = THIRTY_ST ;
end
end
FOURTY_ST : begin
if (ten == 1'b1) begin
next_state = FIFTY_ST ;
end
if else (twenty == 1'b1) begin
next_state = SIXTY_ST ;
end
if else (fifty == 1'b1) begin
next_state = NINETY_ST ;
end
else begin
next_state = FOURTY_ST ;
end
end
FIFTY_ST : begin
if (ten == 1'b1) begin
next_state = SIXTY_ST ;
end
if else (twenty == 1'b1) begin
next_state = SEVENTY_ST ;
end
if else (fifty == 1'b1) begin
next_state =HUND_ST ;
end
else begin
next_state = FIFTY_ST ;
end
end
SIXTY_ST : begin
if (ten == 1'b1) begin
next_state = SEVENTY_ST ;
end
if else (twenty == 1'b1) begin
next_state = EIGHTY_ST ;
end
if else (fifty == 1'b1) begin
next_state =HUND_TEN_ST ;
end
else begin
next_state = FIFTY_ST ;
end
end
SEVENTY_ST : begin
if (ten == 1'b1) begin
next_state = EIGHTY_ST ;
end
if else (twenty == 1'b1) begin
next_state = NINETY_ST ;
end
if else (fifty == 1'b1) begin
next_state =HUND_TWENTY_ST ;
end
else begin
next_state = FIFTY_ST ;
end
end
EIGHTY_ST : begin
next_state = IDLE;
end
NINETY_ST : begin
next_state = IDLE;
end
HUND_ST : begin
next_state = IDLE;
end
HUND__TEN_ST : begin
next_state = IDLE;
end
HUND_TWENTY_ST : begin
next_state = IDLE;
end
default : next_state = IDLE;
endcase
//找钱和输出商品
always @ (*) begin
if ((curr_state ==EIGHTY_ST) || (curr_state ==NINETY_ST) || (curr_state ==HUND_ST) || (curr_state ==HUND_TEN_ST) || (curr_state ==HUND_TWENTY_ST)) begin
out = 1'b1;
end
else begin
out = 1'b0;
end
end
always @ (*) begin
if (curr_state ==NINETY_ST) begin
charge = 6'd10;
end
else if (curr_state ==HUND_ST) begin
charge = 6'd20;
end
else if (curr_state ==HUND_TEN_ST) begin
charge = 6'd30;
end
else if (curr_state ==HUND_TWENTY_ST) begin
charge = 6'd40;
end
else begin
charge = 6'd0;
end
end
endmodule