解题思路

采用经典三段式状态机描述,只不过有两个输出,我在此采用了2个always语句。

我只分了两个状态,即饮料机空闲,和饮料机输出饮料B但只投了5块钱,所以输出语句看起来会麻烦一点。

代码实现

`timescale 1ns/1ns

module sale(
   input                clk   ,
   input                rst_n ,
   input                sel   ,
   input          [1:0] din   ,
 
   output   reg  [1:0] drinks_out,
   output	reg        change_out   
);
    reg    [1:0]   state, next_state;
    parameter   IDLE  = 2'b01,
                S_Five= 2'b10;
    always@(posedge clk or negedge rst_n)
        if(!rst_n)
            state <= IDLE;
        else
            state <= next_state;
    
    always@(*)
        case(state)
            IDLE:    next_state = sel ? (din==1 ? S_Five : IDLE) : IDLE;
            S_Five:  next_state = din==0 ? S_Five : IDLE;
            default: next_state = IDLE;
        endcase
    
    always@(posedge clk or negedge rst_n)
        if(!rst_n)
            drinks_out <= 2'd0;
        else if(!sel) begin
            if((state == IDLE && din == 1) || (state == IDLE && din == 2))
                drinks_out <= 2'd1;
            else
                drinks_out <= 2'd0;
        end
        else begin
            if((state == IDLE && din == 2) || (state == S_Five && din == 1) ||(state == S_Five && din == 2))
                drinks_out <= 2'd2;
            else
                drinks_out <= 2'd0;
        end
    
    always@(posedge clk or negedge rst_n)
        if(!rst_n)
            change_out <= 1'b0;
    	else if((sel==1'b0 && state == IDLE && din == 2) || (sel && state == S_Five && din == 2))
            change_out <= 1'b1;
        else 
            change_out <= 1'b0;
    
endmodule