题解 | #自动贩售机1#

自动贩售机1

https://www.nowcoder.com/practice/dcf59e6c51f6489093495acb1bc34dd8

`timescale 1ns/1ns
module seller1(
    input wire clk  ,
    input wire rst  ,
    input wire d1   ,   // 0.5元
    input wire d2   ,   // 1元
    input wire d3   ,   // 2元

    output reg out1,    // 1.5元
    output reg [1:0]out2    // 零钱
);
//*************code***********//

parameter   P_ST_IDLE   = 3'd0  ,
            P_ST_0Y5    = 3'd1  ,
            P_ST_1Y     = 3'd2  ,
            P_ST_1Y5    = 3'd3  ,
            P_ST_2Y     = 3'd4  ,
            P_ST_2Y5    = 3'd5  ,
            P_ST_3Y     = 3'd6  ;

reg [2 :0]      r_curr_state    ;
reg [2 :0]      r_next_state    ;

always @(posedge clk, negedge rst) begin
    if(!rst)
        r_curr_state <= P_ST_IDLE;
    else 
        r_curr_state <= r_next_state;
end

always @(*) begin
    if(!rst)
        r_next_state = P_ST_IDLE;
    else
        case (r_curr_state)
            P_ST_IDLE : r_next_state =  d1  ?   P_ST_0Y5    :
                                        d2  ?   P_ST_1Y     :
                                        d3  ?   P_ST_2Y     :
                                        r_next_state    ;
            P_ST_0Y5  : r_next_state =  d1  ?   P_ST_1Y     :
                                        d2  ?   P_ST_1Y5    :
                                        d3  ?   P_ST_2Y5    :
                                        r_next_state    ;
            P_ST_1Y   : r_next_state =  d1  ?   P_ST_1Y5    :
                                        d2  ?   P_ST_2Y     :
                                        d3  ?   P_ST_3Y     :
                                        r_next_state    ;
            P_ST_1Y5  : r_next_state =  P_ST_IDLE   ;
            P_ST_2Y   : r_next_state =  P_ST_IDLE   ;
            P_ST_2Y5  : r_next_state =  P_ST_IDLE   ;
            P_ST_3Y   : r_next_state =  P_ST_IDLE   ;
            default   : r_next_state =  P_ST_IDLE   ;
        endcase
    end

always @(*) begin
    if(!rst)
        out1 <= 1'd0;
    else if(r_curr_state >= P_ST_1Y5)
        out1 <= 1'd1;
    else
        out1 <= 1'd0;
end

always @(*) begin
    if(!rst)
        out2 <= 2'd0;
    else if(r_curr_state == P_ST_1Y5)
        out2 <= 2'd0;
    else if(r_curr_state == P_ST_2Y)
        out2 <= 2'd1;
    else if(r_curr_state == P_ST_2Y5)
        out2 <= 2'd2;
    else if(r_curr_state == P_ST_3Y)
        out2 <= 2'd3;
    else
        out2 <= 2'd0;
end

// always @(*) begin
//     if(!rst)
//         out2 = 2'd0;
//     else
//         case (r_curr_state)
//             P_ST_2Y  : out2 = 1;
//             P_ST_2Y5 : out2 = 2;
//             P_ST_3Y  : out2 = 3;
//             default  : out2 = 0;
//         endcase
// end

//*************code***********//
endmodule

这个题还挺坑人的,最开始调试了好几次都通过不了

P_ST_IDLE : r_next_state = d1 ? P_ST_0Y5 : d2 ? P_ST_1Y : d3 ? P_ST_2Y : r_next_state ;

这里最后必须是 r_next_state,而不能是 P_ST_IDLE(包括下面一样的处理方式) ,因为输入数据是只有半个周期,在上升沿的时候拉高,下降沿就拉低了,而r_next_state 因为是组合逻辑,因此会根据输入数据的拉低而同步变化,导致状态机不会发生跳转,下面是错误的仿真图与正确的波形图对比

错误的波形图

正确的波形图

这里选择让r_next_state进行自保持就能得到我们想要的波形图了,也怪自己仿真文件写错了,一直觉得自己的调试没问题,后面看了别人也遇到了类似的问题才发现是我弄错了。记录一下,也防止别人踩坑

全部评论

相关推荐

1 收藏 评论
分享
牛客网
牛客企业服务