三种类型自助售货机Verilog描述
最近遇到该类题目一共三种形式,在解决过程中发现暂且在理想状态下设计,如果在实际情况下还需要再深入思考。
1.两种面值5分、10分;货物价格10分;考虑有找零。
此种情形在此使用2个状态,两段式描述(也可考虑3个状态)
module zzshj1(
input clk,
input rst,
input A, //投入5分
input B, //投入10分
output reg out,
output reg change
);
parameter s0=1'b0,s1=1'b1;
reg current_state,next_state; //中间变量声明
always@(posedge clk or negedge rst) //状态转换
begin
if(!rst)
current_state<=s0;
else
current_state<=next_state;
end
always@(current_state or A or B) //输出逻辑和次态逻辑描述
begin
out=1'b0;
change=1'b0;
case(current_state)
s0: begin
if(A==1&&B==0)
next_state=s1;
else if(A==0&&B==1)
begin
next_state=s0;
out=1'b1;
end
else
next_state=s0;
end
s1: begin
if(A==1&&B==0)
begin
next_state=s0;
out=1'b1;
end
else if(A==0&&B==1)
begin
next_state=s0;
out=1'b1;
change=1'b1;
end
else
next_state=s0;
end
default:next_state=s0;
endcase
end
endmodule
2.两种面值5分、10分;货物价格15分;考虑有找零。
module zzshj2(
input clk,
input rst,
input A, //投入5分
input B, //投入10分
output reg out,
output reg change
);
parameter s0=2'b00,s1=2'b01,s2=2'b10;
reg [1:0] current_state,next_state; //中间变量声明
always@(posedge clk or negedge rst) //状态转换
begin
if(!rst)
current_state<=s0;
else
current_state<=next_state;
end
always@(current_state or A or B) //输出逻辑和次态逻辑描述
begin
out=1'b0;
change=1'b0;
case(current_state)
s0: begin
if(A==1&&B==0)//5
next_state=s1;
else if(A==0&&B==1)//10
next_state=s2;
else
next_state=s0;
end
s1: begin
if(A==1&&B==0)//5
next_state=s2;
else if(A==0&&B==1)//10
begin
next_state=s0;
out=1'b1;
end
else
next_state=s1;
end
s2: begin
if(A==1&&B==0)//5
begin
next_state=s0;
out=1'b1;
end
else if(A==0&&B==1)//10
begin
next_state=s0;
out=1'b1;
change=1'b1;
end
else
next_state=s2;
end
default:next_state=s0;
endcase
end
endmodule
综合后状态机视图
仿真结果图
3.三种面值1分、2分、5分;货物价格5分;考虑找零一分。
对于此种情形在设计过程中暂时未考虑:投入2分再投5分、投入已3分再投5分诸如此类,因为要求找零一分。如果只考虑找零,不考虑找零多少,只是产生找零信号,那么可以考虑以上情况。
module zzshj3(
input clk,
input rst,
input A, //投入1fen
input B, //2fen
input C, //5fen
output reg out, //出饮料
output reg change //找零一分
);
parameter s0=5'b0_0001,s1=5'b0_0010,s2=5'b0_0100,s3=5'b0_1000,s4=5'b1_0000;
reg [4:0] state; //中间变量声明
always@(posedge clk or negedge rst)
begin
if(!rst)
begin
out<=1'b0;
change<=1'b0;
state<=s0;
end
else begin
out<=1'b0;
change<=1'b0;
case(state)
s0: begin
if(A==1&&B==0&&C==0) //1
state<=s1;
else if(A==0&&B==1&&C==0)//2
state<=s2;
else if(A==0&&B==0&&C==1)//5
begin
state<=s0;
out<=1'b1;
end
else if(A==0&&B==0&&C==0)
state<=s0;
end
s1: begin
if(A==1&&B==0&&C==0)//1
state<=s2;
else if(A==0&&B==1&&C==0)//2
state<=s3;
else if(A==0&&B==0&&C==0)
state<=s1;
end
s2: begin
if(A==1&&B==0&&C==0)//1
state<=s3;
else if(A==0&&B==1&&C==0)//2
state<=s4;
else if(A==0&&B==0&&C==0)
state<=s2;
end
s3: begin
if(A==1&&B==0&&C==0)//1
state<=s4;
else if(A==0&&B==1&&C==0)//2
begin
state<=s0;
out<=1'b1;
end
else if(A==0&&B==0&&C==0)
state<=s3;
end
s4: begin
if(A==1&&B==0&&C==0)//1
begin
state<=s0;
out<=1'b1;
end
else if(A==0&&B==1&&C==0)//2
begin
state<=s0;
out<=1'b1;
change<=1'b1;
end
else if(A==0&&B==0&&C==0)
state<=s4;
end
default:state<=s0;
endcase
end
end
endmodule
综合后状态机视图
仿真结果图(红线分割区间分别为连续输入5分、连续输入2分、连续输入1分)
总结:对于以上分析设计存在瑕疵,欢迎有兴趣的与我交流改正。