牛客网自动售卖机

1、verilog企业真题LV3

描述:

请设计状态机电路,实现自动售卖机功能,A饮料5元钱,B饮料10元钱,售卖机可接收投币5元钱和10元钱,每次投币只可买一种饮料,考虑找零的情况。

电路的接口如下图所示。sel信号会先于din信号有效,且在购买一种饮料时值不变。

  • sel为选择信号,用来选择购买饮料的种类,sel=0,表示购买A饮料,sel=1,表示购买B饮料;
  • din表示投币输入,din=0表示未投币,din=1表示投币5元,din=2表示投币10元,不会出现din=3的情况;
  • drinks_out表示饮料输出,drinks_out=0表示没有饮料输出,drinks_out=1表示输出A饮料,drinks_out=2表示输出B饮料,不出现drinks_out =3的情况,输出有效仅保持一个时钟周期;
  • change_out表示找零输出,change_out=0表示没有找零,change_out=1表示找零5元,输出有效仅保持一个时钟周期。

接口电路图如下:

输入描述:

   input                clk   ,
   input                rst_n ,
   input                sel   ,//sel=0,5$dranks,sel=1,10&=$drinks
   input          [1:0] din   ,//din=1,input 5$,din=2,input 10$

输出描述:

   output   reg  [1:0] drinks_out,
   output    reg        change_out   

状态机:

代码:

`timescale 1ns/1ns

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

 

 2、Verilog进阶挑战LV14自动贩售机1

描述:

设计一个自动贩售机,输入货币有三种,为0.5/1/2元,饮料价格是1.5元,要求进行找零,找零只会支付0.5元。

ps:

  • 投入的货币会自动经过边沿检测并输出一个在时钟上升沿到1,在下降沿到0的脉冲信号
  • 注意rst为低电平复位

信号示意图:

  • d1   0.5元
  • d2   1元
  • d3   2元
  • out1 饮料
  • out2 零钱

波形示意图:

状态机:

代码:

`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 IDLE=3'b001,S0=3'b010,S1=3'b100;
    reg [2:0] state,next_state;
    
    always@(posedge clk or negedge rst)
        begin
            if(!rst)
                state<=IDLE;
            else
                state<=next_state;
        end
    
    always@(d1,d2,d3,rst)
        begin
            if(!rst)
                next_state=IDLE;
            else
            case(state)
                IDLE:
                    case({d1,d2,d3})
                        3'b000:next_state=next_state;
                        3'b100:next_state=S0;
                        3'b010:next_state=S1;
                        3'b001:next_state=IDLE;
                        default:next_state=IDLE;
                    endcase
                S0:
                    case({d1,d2,d3})
                        3'b000:next_state=next_state;
                        3'b100:next_state=S1;
                        3'b010:next_state=IDLE;
                        3'b001:next_state=IDLE;
                        default:next_state=IDLE;
                    endcase
                S1:
                    case({d1,d2,d3})
                        3'b000:next_state=next_state;
                        3'b100:next_state=IDLE;
                        3'b010:next_state=IDLE;
                        3'b001:next_state=IDLE;
                        default:next_state=IDLE;
                    endcase
                default:
                    if({d1,d2,d3}==3'b000)
                        next_state=next_state;
                    else
                        next_state=IDLE;
            endcase
        end
    
    reg out1_reg;
    reg[1:0] out2_reg;
    always@(posedge clk or negedge rst)
        begin
            if(!rst) begin
                out1_reg<=1'b0;
                out2_reg<=2'd0;
            end
            else
                case(state)
                    IDLE:
                        if({d1,d2,d3}==3'b001) begin
                            out1_reg<=1'b1;
                            out2_reg<=2'd1;
                        end
                        else begin
                            out1_reg<=1'b0;
                            out2_reg<=2'd0;
                        end
                    S0:
                        if({d1,d2,d3}==3'b001) begin
                            out1_reg<=1'b1;
                            out2_reg<=2'd2;
                        end
                        else if({d1,d2,d3}==3'b010) begin
                            out1_reg<=1'b1;
                            out2_reg<=2'd0;
                        end
                        else begin
                            out1_reg<=1'b0;
                            out2_reg<=2'd0;
                        end
                    S1:
                        if({d1,d2,d3}==3'b001) begin
                            out1_reg<=1'b1;
                            out2_reg<=2'd3;
                        end
                        else if({d1,d2,d3}==3'b010) begin
                            out1_reg<=1'b1;
                            out2_reg<=2'd1;
                        end
                        else if({d1,d2,d3}==3'b100) begin
                            out1_reg<=1'b1;
                            out2_reg<=2'd0;
                        end
                        else begin
                            out1_reg<=1'b0;
                            out2_reg<=2'd0;
                        end
                    default:begin
                            out1_reg<=1'b0;
                            out2_reg<=2'd0;
                    end
                endcase
        end
    
    always@(posedge clk or negedge rst)
        begin
            if(!rst)
                begin
                    out1<=1'b0;
                    out2<=2'd0;
                end
            else
                begin
                    out1<=out1_reg;
                    out2<=out2_reg;
                end
        end


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

 

3、Verilog进阶挑战LV15自动贩售机2

描述:    

设计一个自动贩售机,输入货币有两种,为0.5/1元,饮料价格是1.5/2.5元,要求进行找零,找零只会支付0.5元。

ps:

  • 投入的货币会自动经过边沿检测并输出一个在时钟上升沿到1,在下降沿到0的脉冲信号
  • 此题忽略出饮料后才能切换饮料的问题

注意rst为低电平复位

信号示意图:

  • d1 0.5
  • d2 1
  • sel  选择饮料
  • out1 饮料1
  • out2 饮料2
  • out3 零钱
 

状态机:

先只买2.5元的饮料

 

再考虑只买1.5元的饮料

 

再合并

代码:

`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 IDLE=7'b0000001;
    parameter S05=7'b0000010;
    parameter S10=7'b0000100;
    parameter S15=7'b0001000;
    parameter S20=7'b0010000;
    parameter S25=7'b0100000;
    parameter S30=7'b1000000;
    reg [6:0] state,next_state;
    
    always@(posedge clk or negedge rst)
        begin
            if(!rst)
                state<=IDLE;
            else
                state<=next_state;
        end
    
    always@(*)
        begin
            case(state)
                IDLE:
                    case({d1,d2})
                        2'b10:next_state=S05;
                        2'b01:next_state=S10;
                        default:next_state=next_state;
                    endcase
                S05:
                    case({d1,d2})
                        2'b10:next_state=S10;
                        2'b01:next_state=S15;
                        default:next_state=next_state;
                    endcase
                S10:
                    case({d1,d2})
                        2'b10:next_state=S15;
                        2'b01:next_state=S20;
                        default:next_state=next_state;
                    endcase
                S15:
                    if(sel==1'b0)
                        next_state=IDLE;
                    else
                        case({d1,d2})
                            2'b10:next_state=S20;
                            2'b01:next_state=S25;
                            default:next_state=next_state;
                        endcase
                S20:
                    if(sel==1'b0)
                        next_state=IDLE;
                    else
                        case({d1,d2})
                            2'b10:next_state=S25;
                            2'b01:next_state=S30;
                            default:next_state=next_state;
                        endcase
                S25:next_state=IDLE;
                S30:next_state=IDLE;
                default:next_state=IDLE;
            endcase
        end
    
    always@(posedge clk or negedge rst)
        begin
            if(!rst)
                begin
                    out1<=1'b0;
                    out2<=1'b0;
                    out3<=1'b0;
                end
            else
                begin
                    case(next_state)
                        IDLE:begin
                            out1<=1'b0;
                            out2<=1'b0;
                            out3<=1'b0;
                        end
                        S05:begin
                            out1<=1'b0;
                            out2<=1'b0;
                            out3<=1'b0;
                        end
                        S10:begin
                            out1<=1'b0;
                            out2<=1'b0;
                            out3<=1'b0;
                        end
                        S15:
                            if(sel==1'b0) begin
                                out1<=1'b1;
                                out2<=1'b0;
                                out3<=1'b0;
                            end
                            else begin
                                out1<=1'b0;
                                out2<=1'b0;
                                out3<=1'b0;
                            end
                        S20:
                            if(sel==1'b0) begin
                                out1<=1'b1;
                                out2<=1'b0;
                                out3<=1'b1;
                            end
                            else begin
                                out1<=1'b0;
                                out2<=1'b0;
                                out3<=1'b0;
                            end
                        S25:begin
                            out1<=1'b0;
                            out2<=1'b1;
                            out3<=1'b0;
                        end
                        S30:begin
                            out1<=1'b0;
                            out2<=1'b1;
                            out3<=1'b1;
                        end
                        default:begin
                            out1<=1'b0;
                            out2<=1'b0;
                            out3<=1'b0;
                        end
                    endcase
                end
        end


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

 

 
posted @ 2022-05-31 15:43  super_sweet  阅读(569)  评论(0编辑  收藏  举报