自动贩售机
题目描述:
设计一个自动贩售机,输入货币有三种,为0.5/1/2元,饮料价格是1.5元,要求进行找零,找零只会支付0.5元。
ps:投入的货币会自动经过边沿检测并输出一个在时钟上升沿到1,在下降沿到0的脉冲信号
注意rst为低电平复位
信号示意图:
d1 0.5元
d2 1元
d3 2元
out1 饮料
out2 零钱
这一题第一眼就想到的是状态机,所以先把状态图画出来:
看上去好像有点复杂了。。。 根据状态图写代码就简单很多了。
编译成功的代码详解如下:(但在状态变化那一段有疑惑)
//A:nstate <= (d1)? B:(d2)?C:(d3)?E:nstate;
//这里是不理解的一点,如果把末尾的nstate写成A会报错,out1会丢失一些值,但明明d1d2d3都为0时,就是保持A不变吧,nstate=A也没有问题啊应该。(看到答案才改成的nstate)
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
);
//*************code***********//
//这一题应该用FSM来做
//声明7个状态
parameter A=0,B=1,C=2,D=3,E=4,F=5,G=6;
reg [2:0] state,nstate;
//逻辑变化
always @(*) begin
case(state)
A:nstate <= (d1)? B:(d2)?C:(d3)?E:nstate;
//这里是不理解的一点,如果把末尾的nstate写成A会报错,但明明d1d2d3都为0时,就是保持A不变吧,nstate=A也没有问题啊应该
B:nstate <= (d1)? C:(d2)?D:(d3)?F:nstate;
C:nstate <= (d1)? D:(d2)?E:(d3)?G:nstate;
D:nstate <= A;
E:nstate <= A;
F:nstate <= A;
G:nstate <= A;
default: nstate <= A;
endcase
end
//时序变化
always @(posedge clk or negedge rst)begin
if(!rst) state<=A;
else state<=nstate;
end
//输出判定
always @(*)begin
case(state) //有答案写的上升沿时才输出,并按nstate来进行输出判断
D: begin out1<=1;out2<=0; end
E: begin out1<=1;out2<=1; end
F: begin out1<=1;out2<=2; end
G: begin out1<=1;out2<=3; end
default: begin out1<=0;out2<=0; end
endcase
end
//*************code***********//
endmodule
答案里还看到说用简单的寄存器来进行判定的,即用加法计数来判断,好像也是一种不错的思路,而且代码会简单很多。