基于FPGA的多路抢答器设计程序代码与测试代码

(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%10;//取寄存器变量的低位写入输出端口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

你可能感兴趣的:(Verilog,HDL,数字设计与综合)