本文主要是介绍Verilog 每日一题(VL14 自动贩售机1--FSM常见题型),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
自动贩售机
题目描述:
设计一个自动贩售机,输入货币有三种,为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 @(*) begincase(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;endcaseend//时序变化 always @(posedge clk or negedge rst)beginif(!rst) state<=A;else state<=nstate;end//输出判定always @(*)begin case(state) //有答案写的上升沿时才输出,并按nstate来进行输出判断D: begin out1<=1;out2<=0; endE: begin out1<=1;out2<=1; endF: begin out1<=1;out2<=2; endG: begin out1<=1;out2<=3; enddefault: begin out1<=0;out2<=0; endendcaseend
//*************code***********//
endmodule
答案里还看到说用简单的寄存器来进行判定的,即用加法计数来判断,好像也是一种不错的思路,而且代码会简单很多。
这篇关于Verilog 每日一题(VL14 自动贩售机1--FSM常见题型)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!