设计一个自动饮料售卖机,共有两种饮料,其中饮料 A 每个 10 分钱,饮料 B 每个 5 分钱,硬币有 5 分和 10 分两种,并考虑找零。
要求用状态机实现,定义状态,画出状态转移图,并用 Verilog 完整描述该识别模块。
// input:
// select=1表示买A,select=0表示买B
// money=1: 投入10分钱,money=0: 投入5分钱
// output:
// out=00表示不出饮料,out=01表示出饮料A,out=10表示出饮料B
// change=01表示退5分钱,change=10表示退10分钱,change=00表示不退钱
S0:交易完成状态
S1: 交易未完成状态(机器内尚有5分钱)
module sell(
clk,
rst_n,
select,
money,
out,
change
);
input clk,rst_n,select,money;
output out,change;
reg [1:0] out,change;
reg CS, NS;
wire cond0,cond1,cond2,cond3;
assign cond0 = (!money)&&(!select);
assign cond1 = (money)&&(!select);
assign cond2 = (!money)&&(select);
assign cond3 = (money)&&(select);
parameter S0 = 1'b0,
S1 = 1'b1;
always@(posedge clk or negedge rst_n) begin
if(!rst_n)
CS <= S0;
else
CS <= NS;
end
always@(rst_n or money or select or CS) begin
case (CS)
S0: begin
if(cond0 || cond2 || cond3)
NS <= S0;
else if( cond1 )
NS <= S1;
end
S1: begin
if(cond0 || cond1 || cond2 || cond3)
NS <= S0;
end
default: begin
NS <= S0;
end
end
always@(posedge clk or negedge rst_n) begin
if(!rst_n) begin
out <= 2'b00;
change <= 2'b00;
end
else begin
case(CS)
S0:
if(cond0) begin
out <= 2'b10;
change <= 2'b00;
end
else if(cond2) begin
out <= 2'b10;
change <= 2'b01;
end
else if(cond3) begin
out <= 2'b01;
change <= 2'b00;
end
else if(cond1) begin
out <= 2'b00;
change <= 2'b00;
end
S1: if(cond0) begin
out <= 2'b10;
change <= 2'b01;
end
else if(cond2) begin
out <= 2'b10;
change <= 2'b10;
end
else if(cond3) begin
out <= 2'b01;
change <= 2'b01;
end
else if(cond1) begin
out <= 2'b01;
change <= 2'b00;
end
default: begin
out <= 2'b00;
change <= 2'b00;
end
end
end
endmodule