简析

输入:d1,d2,d3
输出:out1,out2[1:0]
d1d2d3拉高半个周期时分别表示自动贩售机投入了0.5元、1元和2元。out1表示是否找零,out2表示找零的数额。此外,自动贩售机每次只允许投入一枚货币。

首先自动贩售机中可能存在的几种金额:0,0.5,1,1.5,2,2.5,3。然后直接将其作为状态机的几种状态,并根据投币面额确定状态转移。

代码

`timescale 1ns/1ns
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***********//
    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 <= S0;
        else
            state <= nstate;
    end
    
    always@(*) begin
        case(state)
            S0                : nstate = d1? S0_5:
                                         d2? S1  :
                                         d3? S2  :
                                         nstate;
            S0_5              : nstate = d1? S1  :
                                         d2? S1_5:
                                         d3? S2_5:
                                         nstate;
            S1                : nstate = d1? S1_5:
                                         d2? S2  :
                                         d3? S3  :
                                         nstate;
            S1_5, S2, S2_5, S3: nstate = S0;
            default           : nstate = S0;
        endcase
    end
    
    always@(*) begin
        if(~rst)
            out1 = 0;
        else
            out1 = state==S1_5||state==S2||state==S2_5||state==S3;
    end
    
    always@(*) begin
        if(~rst)
            out2 <= 0;
        else
            case(state)
                S0, S0_5, S1, S1_5: out2 <= 0;
                S2                : out2 <= 1;
                S2_5              : out2 <= 2;
                S3                : out2 <= 3;
                default           : out2 <= 0;
            endcase
    end
//*************code***********//
endmodule