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