牛客网自动售卖机
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$
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
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