题解 | #自动售卖机#

自动售卖机

http://www.nowcoder.com/practice/487953e6d3e3434988e0dd6960b6c9f8

解题思路

采用经典三段式状态机描述,只不过有两个输出,我在此采用了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
    
全部评论
当然可以多设置一些状态,如选择10块的饮料,在S_Five再投了5元,进入一个S_Ten,此状态是不稳定的,但也是可以存在于状态图,只是此状态不能再有输入,会自动跳转至稳定的状态,由于状态跳转用的组合逻辑,并无延迟。 这样多一些状态,对于第三段的输出就有一定的书写简化,需要注意的是,对于第三段的输出,若依然使用时序逻辑,需要用next_state来判断是否在那些不稳定的状态,而不是state;组合逻辑使用state来判断。
2 回复 分享
发布于 2022-07-29 11:00

相关推荐

评论
18
4
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务