摘要:
设计一个自动饮料售卖机,共有two water,其中waterA/10分钱,waterB/5分钱,coin有5分和10分两种,并考虑找零。要求用状态机实现,定义状态,画出状态转移图,并用Verilog完整描述该模块
解析:
a=1表示投5分,b=1表示投10分,c=0买waterA,c=1买waterB;
y=1出水,z=1找零
定义两个状态,初始态S0和转移态S1,到达转移态S1的条件是选择的饮料种类的价格比第一次投入的硬币的面值大
代码实现:

module lexin_sell( clk, rst_n, a,//投5分 b,//投10分 c,//选饮料,c=0选5分的饮料,c=1选十分的饮料 y,//出饮料 z//找零 ); input clk; input rst_n; input a; input b; input c; output reg y; output reg z; parameter s0=0,s1=1; reg current_state,nex_state; always@(posedge clk or negedge rst_n) if(!rst_n) current_state<=s0; else current_state<=nex_state; always@(*) if(!rst_n)begin y<=0; z<=0; end else begin case(current_state) s0:if(a&(!b)&c)begin y<=0; z<=0; nex_state<=s1; end else if(a&(!b)&(!c))begin y<=1; z<=0; nex_state<=s0; end else if((!a)&b&(!c))begin y<=1; z<=1; nex_state<=s0; end else if((!a)&b&c)begin y<=1; z<=0; nex_state<=s0; end else begin y<=0; z<=0; nex_state<=s0; end s1:begin if(a&(!b)&c)begin y<=1; z<=0; nex_state<=s0; end else if((!a)&b&c)begin y<=1; z<=1; nex_state<=s0; end else begin y<=0; z<=0; nex_state<=s0; end end default:begin y<=0; z<=0; nex_state<=s0; end endcase end endmodule
tb:

`timescale 1ns/1ns module lexin_sell_tb; reg clk; reg rst_n; reg a; reg b; reg c; wire y; wire z; lexin_sell lexin_sell( .clk(clk), .rst_n(rst_n), .a(a),//投5分 .b(b),//投10分 .c(c),//选饮料,c=0选5分的饮料,c=1选十分的饮料 .y(y),//出饮料 .z(z)//找零 ); initial clk=0; always #10 clk=~clk; initial begin rst_n=0; a=0; b=0; c=0; #21; rst_n=1; #60; @(posedge clk)#1 a=1; b=0; c=1; @(posedge clk)#1 a=1; b=0; c=1; @(posedge clk)#1 a=1; b=0; c=1; @(posedge clk)#1 a=0; b=1; c=1; #50; $stop; end endmodule
波形: