简析

输入:d1, d2, sel
输出: out1, out2, out3
自动贩售机1相比多了选择饮料的功能,但少了一种货币,总体上难度相似。

首先自动贩售机中可能存在的几种金额:0,0.5,1,1.5,2,2.5,3。然后直接将其作为状态机的几种状态,并根据投币面额确定状态转移。当贩售机内金额大于等于1.5时,也就是S1_5及以后的状态,还应根据饮料种类做判断。如果选择的是饮料1,sel=0,则返回S0状态;如果选择的是饮料2,sel=1,则根据投入的货币继续向下转移状态。当贩售机内金额大于等于2.5时,也就是S2_5及以后的状态,肯定足够购买饮料,状态机直接返回S0,并根据情况找零。

代码

`timescale 1ns/1ns

module seller2(
	input wire clk  ,
	input wire rst  ,
	input wire d1 ,
	input wire d2 ,
	input wire sel ,
	
	output reg out1,
	output reg out2,
	output reg out3
);
//*************code***********//

    parameter S0=0, S0_5=1, S1=2, S1_5=3, S2=4, S2_5=5, S3=6;
    reg[2:0] state, nstate;
    
    always@(posedge clk or negedge rst) begin
        if(~rst)
            state <= 0;
        else
            state <= nstate;
    end
    
    always@(*) begin
        case(state)
            S0     : nstate = d1? S0_5:
                              d2? S1:
                              nstate;
            S0_5   : nstate = d1? S1:
                              d2? S1_5:
                              nstate;
            S1     : nstate = d1? S1_5:
                              d2? S2:
                              nstate;
            S1_5   : nstate = ~sel? S0:
                              d1? S2:
                              d2? S2_5:
                              nstate;
            S2     : nstate = ~sel? S0:
                              d1? S2_5:
                              d2? S3:
                              nstate;
            default: nstate = S0;
        endcase
    end
    
    always@(*) begin
        if(~rst) begin
            {out1, out2, out3} = 3'b000;
        end
        else begin
            case(state)
                S0, S0_5, S1: {out1, out2, out3} = 0;
                S1_5        : {out1, out2, out3} = ~sel? 3'b100: 3'b000;
                S2          : {out1, out2, out3} = ~sel? 3'b101: 3'b000;
                S2_5        : {out1, out2, out3} = ~sel? 3'b101: 3'b010;
                S3          : {out1, out2, out3} = ~sel? 3'b101: 3'b011;
                default     : {out1, out2, out3} = 3'b000;
            endcase
        end
    end
//*************code***********//
endmodule