(1) 主程序代码:
module who_is_the_best(clk,rset,start,rusher1,rusher2,rusher3,rusher4,rusher5,rusher6,time_outA,time_outB,who,warn_buzzer,remind_buzzer);
input clk,rset,start;//声明输入端口
input rusher1,rusher2,rusher3,rusher4,rusher5,rusher6;
output[3:0] time_outA,time_outB;//声明输出端口
output reg[2:0] who;
output reg warn_buzzer,remind_buzzer;
reg[4:0] count_down;//声明程序之中必要的寄存器变量
reg time_length,flag;
reg come_on;
reg[2:0] which_one;
always @(posedge clk)//设置触发方式,使用时钟的上升沿触发
begin
if(!rset)//rset是复位端,我采取低电平作用
begin
count_down<=19;//将所有的寄存器变量赋初值
who<=0;
flag<=0;
time_length<=0;
come_on<=0;
which_one<=0;
end
else
if(!flag&&come_on)//只有come_on为1和flag为0时,才执行下列操作
begin
if(count_down==0)//如果倒计时记到0,就停在0,不再变化
count_down<=0;
else
count_down<=count_down-1;//如果倒计时没有记到9,就继续倒计时操作
end
end
assign time_outA=count_down/10;//取寄存器变量的高位写入输出端口time_outA
assign time_outB=count_down;//取寄存器变量的低位写入输出端口time_outB
always @(posedge clk)
begin
case(which_one)//对which_one设置switch语句
1: if(!rusher1) begin if(come_on) time_length<=0; else time_length<=1; end
2: if(!rusher2) begin if(come_on) time_length<=0; else time_length<=1; end
3: if(!rusher3) begin if(come_on) time_length<=0; else time_length<=1; end
4: if(!rusher4) begin if(come_on) time_length<=0; else time_length<=1; end
5: if(!rusher5) begin if(come_on) time_length<=0; else time_length<=1; end
6: if(!rusher6) begin if(come_on) time_length<=0; else time_length<=1; end
endcase
end
always @(posedge clk)
begin
if(rusher1==1&&(!flag))//rusher1号选手按下了抢答键同时别人还没有按的时候,执行下列操作
begin
who<=1;
which_one<=1;
time_length<=1;
flag<=1;
end
end
always @(posedge clk)//之后的这几个模块是类似的
begin
if(rusher2==1&&(!flag))
begin
who<=2;
which_one<=2;
time_length<=1;
flag<=1;
end
end
always @(posedge clk)
begin
if(rusher3==1&&(!flag))
begin
who<=3;
which_one<=3;
time_length<=1;
flag<=1;
end
end
always @(posedge clk)
begin
if(rusher4==1&&(!flag))
begin
who<=4;
which_one<=4;
time_length<=1;
flag<=1;
end
end
always @(posedge clk)
begin
if(rusher5==1&&(!flag))
begin
who<=5;
which_one<=5;
time_length<=1;
flag<=1;
end
end
always @(posedge clk)
begin
if(rusher6==1&&(!flag))
begin
who<=6;
which_one<=6;
time_length<=1;
flag<=1;
end
end
always @(posedge time_length)//根据time_length的上升沿来判断
begin
if(come_on)//如果这个时候come_on为1,说明按下了开始start键
remind_buzzer<=1;
end
always @(negedge time_length)//声明time_Length的下降沿有效
begin
remind_buzzer<=0;//下降沿来的时候都回到初值
warn_buzzer<=0;
end
always @(posedge clk)
begin
if(start)
come_on<=1; //开始的同时给寄存器变量come_on赋值
end
always @(posedge start)//检测start的上升沿的时候的相关寄存器值
begin
if(time_length)//开始的时候,如果time_length已经不为1,说明超前抢答
warn_buzzer<=1;
end
always @(negedge start)//检测start的下降沿
begin
if(warn_buzzer)
warn_buzzer<=0;//至此警告蜂鸣器的持续时间就是start维持为高电平的时间
end
endmodule
(2)测试代码
module who_is_the_best_tb;
// Inputs
reg clk;
reg rset;
reg start;
reg rusher1;
reg rusher2;
reg rusher3;
reg rusher4;
reg rusher5;
reg rusher6;
// Outputs
wire [3:0] time_outA;
wire [3:0] time_outB;
wire [2:0] who;
wire warn_buzzer;
wire remind_buzzer;
// Instantiate the Unit Under Test (UUT)
who_is_the_best uut (
.clk(clk),
.rset(rset),
.start(start),
.rusher1(rusher1),
.rusher2(rusher2),
.rusher3(rusher3),
.rusher4(rusher4),
.rusher5(rusher5),
.rusher6(rusher6),
.time_outA(time_outA),
.time_outB(time_outB),
.who(who),
.warn_buzzer(warn_buzzer),
.remind_buzzer(remind_buzzer)
);
parameter DELY=100;
always #(DELY/2) clk=~clk;
initial begin
// Initialize Inputs
clk = 0;
rset = 0;
start = 0;
rusher1 = 0;
rusher2 = 0;
rusher3 = 0;
rusher4 = 0;
rusher5 = 0;
rusher6 = 0;
// Wait 100 ns for global reset to finish
#100;
#DELY rset=1;
#(DELY*2) rusher1=1;
#DELY rusher1=0;rusher2=1;
#DELY rusher2=0;rusher3=1;
#DELY rusher3=0;rusher4=1;
#DELY rusher4=0;rusher5=1;
#DELY rusher5=0;rusher6=1;
#DELY rusher6=0;
#DELY start=1;
#DELY start=0;
#(DELY*3) rset=0;
#DELY rset=1;
#DELY start=1;
#DELY start=0;
#(DELY*15) rusher1=1;
#(DELY*30) rusher1=0;rusher2=1;
#(DELY*2) rusher3=1;rusher4=1;rusher5=1;
#DELY rusher1=0;rusher2=0;rusher3=0;rusher4=0;rusher5=0;rusher6=0;
#(DELY*10) rset=0;
#100;
#DELY rset=1;
#(DELY*2) rusher1=1;
#DELY rusher1=0;rusher2=1;
#DELY rusher2=0;rusher3=1;
#DELY rusher3=0;rusher4=1;
#DELY rusher4=0;rusher5=1;
#DELY rusher5=0;rusher6=1;
#DELY rusher6=0;
#DELY start=1;
#DELY start=0;
#(DELY*3) rset=0;
#DELY rset=1;
#DELY start=1;
#DELY start=0;
#(DELY*2) rusher1=1;
#(DELY*3) rusher1=0;rusher2=1;
#(DELY*2) rusher3=1;rusher4=1;rusher5=1;
#DELY rusher1=0;rusher2=0;rusher3=0;rusher4=0;rusher5=0;rusher6=0;
#(DELY*4) rset=0;
//尝试既有提前抢答,又有正规抢答
#(DELY*3) rset=0;
#DELY rset=1;
#(DELY*2) rusher1=1;
#(DELY*3) rusher1=0;
#DELY start=1;
#DELY start=0;
#(DELY*2) rusher3=1;rusher4=1;rusher5=1;
#DELY rusher1=0;;rusher3=0;rusher4=0;rusher5=0;rusher6=0;
#(DELY*2) rset=0;
//尝试抢答信号长按跨过开始
#100;
#DELY rset=1;
#(DELY*2) rusher1=1;
#DELY start=1;
#DELY start=0;
#DELY rusher1=0;
#(DELY*5) rset=0;
// Add stimulus here
end
endmodule