三、设计一个自动饮料售卖机,共有两种饮料,其中饮料A每个10分钱,饮料B每个5分钱,硬币有5分和10分两种,并考虑找零。要求用状态机实现,定义状态,画出状态转移图,并用Verilog完整描述该模块
Verilog如下
module outab(
input clk,
input rst_n,
input [1:0] want,
input [1:0] money, //2'b10: 10 cents 2'b01: 5 cents
output reg [1:0] ab, //2'b10:a 2'b01:b
output reg [1:0] remain);
// 状态:空闲态,等待投钱状态,钱够了(完成状态)
parameter
idle=2'b00,
invest=2'b01,
complete=2'b10;
reg [1:0] state;
reg [1:0] total; //统计总钱
reg [1:0] want_r; //暂存想要饮料的价格
always@(posedge clk)
if(!rst_n)
begin
total<=0;
state<=idle;
want_r<=0;
remain<=0;
ab<=0;
end
else
case(state)
idle: begin
total<=total+money; //每个状态都加money了,允许先投钱再输入想要饮料
remain<=0;
ab<=0;
if(want==2'b01 || want==2'b10)
begin state<=invest;
want_r<=want;
end
end
invest: if(total>=want_r)
begin state<=complete;
total<=total+money;
end
else begin
state<=invest;
total<=total+money;
end
complete: begin state<=idle;
remain<=total+money-want_r;
total<=0;
if(want_r==2'b01) ab=2'b01;
else ab=2'b10;
end
endcase
endmodule
tb(sv)
module tb( );
logic clk, rst_n;
logic [1:0] ab, want, remain, money;
outab outab(clk, rst_n, want, money, ab, remain);
initial
begin clk=0; forever #5 clk=~clk; end
initial
begin rst_n=0; #30 rst_n=1; end
initial
begin
#30
want=2'b01;
money=2'b10;
#10
want=0;
money=0;
#30
want=2'b10;
#10
money=2'b01;
#10
money=2'b10;
#10
money=0;
end
endmodule
四、请实现对(1011001)2的序列检测功能,模块每拍并行输入2bit,且顺序为高位先输入,当检测到序列,输出一拍高电平脉冲。请用Verilog描述该模块
verilog如下
//1011001
module seqdet2(
input clk,
input rst_n,
input [1:0] data,
output reg det);
//状态总数和单比特输入序列检查一致;状态转移分成1bit检测和2bit检测了;
parameter
idle=4'b000,
s1=4'b0001,
s2=4'b0010,
s3=4'b0011,
s4=4'b0100,
s5=4'b0101,
s6=4'b0110,
s7=4'b0111;
reg [3:0] state, nstate;
always@(posedge clk)
if(!rst_n)
state<=idle;
else state<=nstate;
always@(*)
begin det=0; nstate=idle;
case(state)
idle: if(data==2'b10) nstate=s2; else if(data[0]==1) nstate=s1; else nstate=idle;
s1: if(data==2'b01) nstate=s3; else if(data==2'b10) nstate=s2; else if(data[0]==1) nstate=s1; else nstate=idle;
s2: if(data==2'b11) nstate=s4; else if(data==2'b10) nstate=s2; else if(data[0]==1) nstate=s1; else nstate=idle;
s3: if(data==2'b10) nstate=s5; else if(data==2'b10) nstate=s2; else if(data[0]==1) nstate=s1; else nstate=idle;
s4: if(data==2'b00) nstate=s6; else if(data==2'b10) nstate=s2; else if(data[0]==1) nstate=s1; else nstate=idle;
s5: if(data==2'b01) nstate=s7; else if(data==2'b10) nstate=s2; else if(data[0]==1) nstate=s1; else nstate=idle;
s6: begin if(data[1]==1) begin det=1; if (data[0]==1) nstate=s1; else nstate=idle; end
else begin det=0;
if(data==2'b10) nstate=s2; else if(data[0]==1) nstate=s1; else nstate=idle; end
end
s7: begin det=1;if(data==2'b10) nstate=s2; else if(data[0]==1) nstate=s1; else nstate=idle; end
endcase
//s6和s7都有可能输出det为1;
end
endmodule
tb(sv)
class datarand;
rand bit [1:0] data;
endclass
module tb( );
logic clk, rst_n, det;
logic [1:0] data;
seqdet2 seqdet2(clk, rst_n, data, det);
initial begin clk=0; forever #5 clk=~clk; end
initial begin rst_n=0; #30 rst_n=1; end
datarand p;
initial
begin
#28 p=new();
for(int i=0; i<300; i++)
begin #10 assert(p.randomize());
data=p.data;
end
end
endmodule
五、请基于f = 100Hz的Clock设计一个数字时钟,用Verilog实现以下功能
1、产生时、分、秒的计时(Hour, minute, second)
2、可通过3个按键来设置时、分、秒值
Verilog如下
//100HZ
//hour minute second
module hourminutesecond(
input clk,
input rst_n,
input [5:0] hour_rst,
input [5:0] minute_rst,
input [5:0] second_rst,
output reg [5:0] hour,
output reg [5:0] minute,
output reg [5:0] second);
reg [7:0] cnt;
always@(posedge clk)
if(!rst_n)
cnt<=0;
else if(cnt==99) cnt<=0;
else cnt<=cnt+1;
always@(posedge clk)
if(!rst_n)
second<=second_rst;
else if(cnt==99) if(second==59) second<=0; else second<=second+1;
always@(posedge clk)
if(!rst_n)
minute<=minute_rst;
else if(second==59 && cnt==99) if(minute==59) minute<=0; else minute<=minute+1;
always@(posedge clk)
if(!rst_n)
hour<=hour_rst;
else if(minute==59 && second==59 && cnt==99) if (hour==23) hour<=0; else hour<=hour+1;
endmodule
tb(sv)
module tb( );
logic clk, rst_n;
logic[5:0] hour_rst, minute_rst, second_rst, hour, minute, second;
hourminutesecond hms(clk, rst_n, hour_rst, minute_rst, second_rst, hour, minute, second);
initial begin clk=0; forever #5 clk=~clk; end
initial begin rst_n=0; #30 rst_n=1; end
initial begin
hour_rst=0;
minute_rst=0;
second_rst=0;
end
endmodule
原文参考
https://blog.csdn.net/buzhiquxiang/article/details/106642189