4人抢答器----基于Step MAX10小脚丫开发板

设计任务

1、四人通过按键抢答,最先按下按键的人抢答成功,此后其他人抢答无效,抢答成功的人对应的LED灯亮。
2、每次只有一人可获得抢答资格,一次抢答完后主持人通过复位按键复位,选手再从新抢答。
3、有重新开始游戏按键,游戏从新开始时每位选手有5分的初始分,答对加1分,答错扣1分,最高分不能超过9分,最低为0分。
4、每位选手和主持人共有30秒时间进行回答和加减分,在此期间,RGB为蓝色灯;超过30秒,RGB变为红色,即报警;未开始抢答,则RGB灯为绿色。
5、选手抢答成功时通过数码管显示其对应的分数。

代码分析

  1. 本次设计共有7个模块:
模块功能
common.v头文件
devide.v用来对时钟进行分频
counter.v计时30秒
debounce.v按键消抖
segment.v数码管显示
snatch.v抢答,定义了抢答规则,并开始计时30s
score.v分数,用来对选手加分减分等
qiangdaqi.v顶层文件
  1. 设计代码
  • common.v
//*************************************************************
//
//*@File name: common.v
//
//*@File type: verilog
//
//*@Version  : 0.0.1
//
//*@Author   : Zehua Dong, HITWH
//
//*@E-mail   : hitdongzh@163.com
//
//*@Date     : 2020-12-07 11:26:28
//
//*@Function : Some Macros.
//
//*************************************************************

/* Used in unblocking */
/* Just to be convenient to watch the waves in RTL level */

`define DEL 1

/* Define your own macro here */
`define SIM 1
  • devide.v
// ********************************************************************
// File name    : divide.v
// Module name  : divide
// Author       : 
// Description  : clock divider
// Module Function:任意整数时钟分频
// ********************************************************************
 
module divide (	clk,rst_n,clkout);
 
  input 	clk,rst_n;       //输入信号,其中clk连接到FPGA的C1脚,频率为12MHz
  output	clkout;          //输出信号,可以连接到LED观察分频的时钟
 
	parameter	WIDTH	= 24;     //计数器的位数,计数的最大值为 2**WIDTH-1
	parameter	N	= 12000000;         //分频系数,请确保 N < 2**WIDTH-1,否则计数会溢出
 
	reg 	[WIDTH-1:0]	cnt_p,cnt_n;     //cnt_p为上升沿触发时的计数器,cnt_n为下降沿触发时的计数器
	reg			clk_p,clk_n;     //clk_p为上升沿触发时分频时钟,clk_n为下降沿触发时分频时钟
 
	//上升沿触发时计数器的控制
	always @ (posedge clk or negedge rst_n )   //posedge和negedge是verilog表示信号上升沿和下降沿
                                             //当clk上升沿来临或者rst_n变低的时候执行一次always里的语句
		begin
			if(!rst_n)
				cnt_p<=0;
			else if (cnt_p==(N-1))
				cnt_p<=0;
			else cnt_p<=cnt_p+1;             //计数器一直计数,当计数到N-1的时候清零,这是一个模N的计数器
		end
 
   //上升沿触发的分频时钟输出,如果N为奇数得到的时钟占空比不是50%;如果N为偶数得到的时钟占空比为50%
   always @ (posedge clk or negedge rst_n)
		begin
			if(!rst_n)
				clk_p<=0;
			else if (cnt_p<(N>>1))          //N>>1表示右移一位,相当于除以2去掉余数
				clk_p<=0;
			else 
				clk_p<=1;               //得到的分频时钟正周期比负周期多一个clk时钟
		end
 
   //下降沿触发时计数器的控制        	
	 always @ (negedge clk or negedge rst_n)
		 begin
		 	 if(!rst_n)
		 	  	cnt_n<=0;
		 	 else if (cnt_n==(N-1))
		 	 	 cnt_n<=0;
		 	 else cnt_n<=cnt_n+1;
		 end
 
  //下降沿触发的分频时钟输出,和clk_p相差半个时钟
	always @ (negedge clk)
		begin
			if(!rst_n)
				clk_n<=0;
			else if (cnt_n<(N>>1))  
				clk_n<=0;
			else 
				clk_n<=1;                //得到的分频时钟正周期比负周期多一个clk时钟
		end
 
  assign clkout = (N==1)?clk:(N[0])?(clk_p&clk_n):clk_p;//条件判断表达式
                                                        //当N=1时,直接输出clk
                                                        //当N为偶数也就是N的最低位为0,N(0)=0,输出clk_p
                                                        //当N为奇数也就是N最低位为1,N(0)=1,输出clk_p&clk_n。正周期多所以是相与
endmodule   

  • counter.v
//*************************************************************
//
//*@File name: counter.v
//
//*@File type: verilog
//
//*@Version  : 0.0.1
//
//*@Author   : Zehua Dong, HITWH
//
//*@E-mail   : hitdongzh@163.com
//
//*@Date     : 2020-12-07 11:22:56
//
//*@Function : Count 30s
//
//*************************************************************
//
// Head files
`include "common.v"
//
// Module definition
module counter(
  clk        ,                
  rst_n      ,        
  start      ,       
  valid         
);

  input                     clk   ;                  
  input                     rst_n ;  
  input                     start ;  
  output                    valid ;  

  reg                       valid ;

  //
  // Generate the 1Hz clock
  wire                      clkout_1hz;
  `ifdef SIM
    // 12Mhz in simulation mode, just to reduce sim time
    divide #(.N(1)) devide_u1 (	
      .clk   ( clk    ) ,
      .rst_n ( rst_n  ) ,
      .clkout( clkout_1hz ) 
    ); 
  `else 
    // 1Hz in real mode
    divide devide_u1(	
      .clk   ( clk    ) ,
      .rst_n ( rst_n  ) ,
      .clkout( clkout_1hz ) 
    ); 
  `endif

  /
  //*Function Description:
  //*  Detect the rise edge of clkout_1hz as enable signal
  //*  
  /
  //
  reg     clkout_1hz_q;
  wire    clkout_1hz_flag;

  always @( posedge clk or negedge rst_n ) begin
    if( ~rst_n ) begin
      clkout_1hz_q <= #`DEL 1'b0;
    end
    else begin
      clkout_1hz_q <= #`DEL clkout_1hz;
    end
  end
  assign clkout_1hz_flag = ( ~clkout_1hz_q ) && ( clkout_1hz );


  //
  // Delay of start
  reg start_dly;
  reg [4:0] cnt_1s;

  always @( posedge clk or negedge rst_n ) begin
    if( ~rst_n ) begin
      start_dly <= #`DEL 1'b0;
    end
    else if( start ) begin
      start_dly <= #`DEL 1'b1;
    end
    else if( cnt_1s == 5'd29 ) begin
      start_dly <= #`DEL 1'b0;
    end
  end      


  // 
  // Count by 1s

  always @( posedge clk or negedge rst_n ) begin
    if( ~rst_n ) begin
      cnt_1s <= #`DEL 5'd0;
    end
    else if( start_dly ) begin
      if( clkout_1hz_flag ) begin
        cnt_1s <= #`DEL cnt_1s + 1'b1;
      end
    end
    else begin
      cnt_1s <= #`DEL 5'd0;
    end
  end   

  //
  // Generate the end signal: valid
  always @( posedge clk or negedge rst_n ) begin
    if( ~rst_n ) begin
      valid <= #`DEL 1'b0;
    end
    else if( cnt_1s == 5'd29 ) begin
      valid <= #`DEL 1'b1;
    end
    else begin
      valid <= #`DEL 1'b0;
    end
  end      


endmodule


  • debounce.v
// ********************************************************************
// File name    : debounce.v
// Module name  : debounce
// Description  : 
// Module Function:按键消抖
// ********************************************************************
`include "common.v"
module debounce (clk,rst,key,key_pulse);
 
	parameter       N  =  1;         //要消除抖动的按键的数量
 
	input             clk;
	input             rst;
	input 	[N-1:0]   key;           //输入的按键					
	output  [N-1:0]   key_pulse;     //按键动作产生的脉冲一个时钟周期高电平	
 
	reg     [N-1:0]   key_rst_pre;   //定义一个寄存器型变量存储上一个触发时的按键值
	reg     [N-1:0]   key_rst;       //定义一个寄存器变量储存储当前时刻触发的按键值
 
	wire    [N-1:0]   key_edge;      //检测到按键由高到低变化时产生一个高脉冲
 
	//利用非阻塞赋值特点,将两个时钟触发时按键状态存储在两个寄存器变量中
	always @(posedge clk  or  negedge rst)
		begin
			if (!rst) begin
				key_rst <= {N{1'b1}};       //初始化时给key_rst赋值全为1,{}中表示N个1
				key_rst_pre <= {N{1'b1}};
				end
			else begin
				key_rst <= key;             //第一个时钟上升沿触发之后key的值赋给key_rst,同时key_rst的值赋给key_rst_pre
				key_rst_pre <= key_rst;     //非阻塞赋值。相当于经过两个时钟触发,key_rst存储的是当前时刻key的值,key_rst_pre存储的是前一个时钟的key的值
				end    
		end
 
	//脉冲边沿检测。当key检测到下降沿时,key_edge产生一个时钟周期的高电平
	assign  key_edge = key_rst_pre & (~key_rst);
	reg	[17:0]	  cnt;                       //产生延时所用的计数器,系统时钟12MHz,要延时20ms左右时间,至少需要18位计数器     
 
	//产生20ms延时,当检测到key_edge有效是计数器清零开始计数
	always @(posedge clk or negedge rst)
		begin
			if(!rst)
				cnt <= 18'h0;
			else if(key_edge)
				cnt <= 18'h0;
			else
				cnt <= cnt + 1'h1;
			end  
 
	reg     [N-1:0]   key_sec_pre;                //延时后检测电平寄存器变量
	reg     [N-1:0]   key_sec;                    
 
 
	//延时后检测key,如果按键状态变低产生一个时钟的高脉冲。如果按键状态是高的话说明按键无效
	  always @(posedge clk  or  negedge rst)
	  	begin
	  		if (!rst) 
	  			key_sec <= {N{1'b1}};                
	  		else if (cnt==18'h3ffff)
	  			key_sec <= key;  
	  	end
	  always @(posedge clk  or  negedge rst)
	  	begin
	  		if (!rst)
	  			key_sec_pre <= {N{1'b1}};
	  		else                   
	  			key_sec_pre <= key_sec;             
	  		end      
	  assign  key_pulse = key_sec_pre & (~key_sec);     
 
endmodule

  • segment.v
// ********************************************************************
// File name    : segment.v
// Module name  : segment
// Description  : segment initial
// Module Function:数码管的译码模块初始化
// ********************************************************************
 
module segment (seg_data_1,seg_data_2,seg_led_1,seg_led_2);
 
	input  [3:0] seg_data_1;  //数码管需要显示0~9十个数字,所以最少需要4位输入做译码
	input  [3:0] seg_data_2;  //小脚丫上第二个数码管
	output [8:0] seg_led_1;		//在小脚丫上控制一个数码管需要9个信号 MSB~LSB=DIG、DP、G、F、E、D、C、B、A
	output [8:0] seg_led_2;		//在小脚丫上第二个数码管的控制信号  MSB~LSB=DIG、DP、G、F、E、D、C、B、A
 
  reg [8:0] seg [9:0];   	  //定义了一个reg型的数组变量,相当于一个10*9的存储器,
								
  initial 	begin
		seg[0] = 9'h3f;         //对存储器中第一个数赋值9'b00_0011_1111,相当于共阴极接地,DP点变低不亮,7段显示数字  0
		seg[1] = 9'h06;         //7段显示数字  1
		seg[2] = 9'h5b;         //7段显示数字  2
		seg[3] = 9'h4f;         //7段显示数字  3
		seg[4] = 9'h66;         //7段显示数字  4
		seg[5] = 9'h6d;         //7段显示数字  5
		seg[6] = 9'h7d;         //7段显示数字  6
		seg[7] = 9'h07;         //7段显示数字  7
		seg[8] = 9'h7f;         //7段显示数字  8
		seg[9] = 9'h6f;         //7段显示数字  9
  end
 
	assign seg_led_1 = seg[seg_data_1];      //连续赋值,这样输入不同四位数,
	assign seg_led_2 = seg[seg_data_2];      //就能输出对于译码的9位输出
 
endmodule

  • snatch.v
//*************************************************************
//
//*@File name: snatch.v
//
//*@File type: verilog
//
//*@Version  : 0.0.1
//
//*@Author   : Zehua Dong, HITWH
//
//*@E-mail   : hitdongzh@163.com
//
//*@Date     : 2020-12-07 21:00:41
//
//*@Function : Detect the key pressed
//
//*************************************************************
//
// Head files
`include "common.v"
//
//  Module definition
//
module snatch(
  clk    ,              
  rst_n  ,          
  key    ,  
  reload ,   // Connect to the 3rd switch 
  led    ,    
  valid_dly,
  debug_key_pulse_reg,      
  debug_valid_dly,
  debug_lock,
  rgb    
);

  //
  // Input and output signals
  input                     clk    ;                 
  input                     rst_n  ;              
  input      [3:0]          key    ;   
  input                     reload ;  
  output     [3:0]          led    ;        
  output     [2:0]          rgb    ;     
  output                    valid_dly    ;  


  reg        [3:0]          led    ;      
  reg        [2:0]          rgb    ;     
  reg                       valid_dly; 

  //
  // Debug signal
  output     [3:0]          debug_key_pulse_reg    ;  
  output                    debug_valid_dly    ;        
  output                    debug_lock    ;   

  // 
  // Key debounce instantiation
  wire [3:0] key_pulse;
  debounce #(.N(4)) debounce_u1(
    .clk      ( clk       ) ,
    .rst      ( rst_n     ) ,
    .key      ( key       ) ,
    .key_pulse( key_pulse )    
  );

  // 
  // Used to store the key_pulse for long
  reg [3:0] key_pulse_reg;
  always @( posedge clk or negedge rst_n ) begin
    if( ~rst_n ) begin
      key_pulse_reg <= #`DEL 4'b0000;
    end
    else if( |key_pulse & ~lock ) begin
      key_pulse_reg <= #`DEL key_pulse;
    end
    else if( reload ) begin
      key_pulse_reg <= #`DEL 4'd0;
    end
  end      
  
  assign debug_key_pulse_reg = key_pulse_reg;


  // 
  // Judge player
  always @( posedge clk or negedge rst_n ) begin
    if( ~rst_n ) begin
      led <= #`DEL 4'b1111;
    end
    else if( key_pulse_reg[3] ) begin
      led <= #`DEL 4'b0111;
    end
    else if( key_pulse_reg[2] ) begin
      led <= #`DEL 4'b1011;
    end
    else if( key_pulse_reg[1] ) begin
      led <= #`DEL 4'b1101;
    end
    else if( key_pulse_reg[0] ) begin
      led <= #`DEL 4'b1110;
    end
    else begin
      led <= #`DEL 4'b1111;
    end
  end      

  // 
  // Signal: lock
  // The key was pressed, the lock is valid
  // Then the value of key is invalid until the reload coming
  reg lock;
  always @( posedge clk or negedge rst_n ) begin
    if( ~rst_n ) begin
      lock <= #`DEL 1'b0;
    end
    else if( reload ) begin
      lock <= #`DEL 1'b0;
    end
    else if( key_pulse_reg[3] || key_pulse_reg[2] || key_pulse_reg[1] || key_pulse_reg[0] ) begin
      lock <= #`DEL 1'b1;
    end
    else begin
      lock <= #`DEL lock;
    end
  end
  assign debug_lock = ~lock;

  //
  // Detect the rise edge of lock
  reg     lock_q;
  wire    lock_flag;

  always @( posedge clk or negedge rst_n ) begin
    if( ~rst_n ) begin
      lock_q <= #`DEL 1'b0;
    end
    else begin
      lock_q <= #`DEL lock;
    end
  end
  assign lock_flag = ( ~lock_q ) && ( lock );


  // 
  // Counter instantiation
  // When detect the rise edge of lock, then begin to count
  counter counter_u1(
    .clk   ( clk       )     ,                
    .rst_n ( rst_n     )     ,        
    .start ( lock_flag )     ,       
    .valid ( valid     )        
  ); 

  // 
  // valid is a pulse signal, so there need a delay of valid
  always @( posedge clk or negedge rst_n ) begin
    if( ~rst_n ) begin
      valid_dly <= #`DEL 1'b0;
    end
    else if( valid ) begin
      valid_dly <= #`DEL 1'b1;
    end
    else if( reload ) begin
      valid_dly <= #`DEL 1'b0;
    end
  end    

  assign debug_valid_dly = ~valid_dly;

  // 
  // RGB display
  // if lock  == 0, green
  // if lock  == 1, blue
  // if valid == 1, red
  always @( posedge clk or negedge rst_n ) begin
    if( ~rst_n ) begin
      rgb <= #`DEL 3'b111;
    end
    else if( valid_dly ) begin 
      rgb <= #`DEL 3'b011;
    end
    else if( ~lock ) begin
      rgb <= #`DEL 3'b101;
    end
    else if( lock ) begin
      rgb <= #`DEL 3'b110;
    end
  end      

endmodule


  • score.v
//*************************************************************
//
//*@File name: score.v
//
//*@File type: verilog
//
//*@Version  : 0.0.1
//
//*@Author   : Zehua Dong, HITWH
//
//*@E-mail   : hitdongzh@163.com
//
//*@Date     : 2020-12-08 08:41:02
//
//*@Function : Describe the score of players
//
//*************************************************************
//
// Head files
`include "common.v"
//
//  Module definition
//
module score(
  clk       ,           
  rst_n     ,       
  add_score ,              
  sub_score ,     
  led       ,        
  lock      ,
  end_score         
  );

  //===========================================================
  //* Input and output signals
  //===========================================================
  input                     clk        ;             
  input                     rst_n      ;          
  input                     add_score  ;              
  input                     sub_score  ;      
  input                     lock       ;                
  input     [3:0]           led        ;        
  output    [3:0]           end_score  ;              

  wire      [3:0]           end_score  ;              

  //===========================================================
  //* Internal signals
  //===========================================================
  reg  [3:0] score_player[0:3];

  // 
  // Switch debounce instantiation
  wire [1:0] switch_pulse;
  debounce #(.N(2)) debounce_u1(
    .clk      ( clk       ) ,
    .rst      ( rst_n     ) ,
    .key      ( {add_score,sub_score} ) ,
    .key_pulse( switch_pulse )    
  );
  
  wire add_score_flag, sub_score_flag;
  assign {add_score_flag, sub_score_flag} = switch_pulse;
  
  /
  //*Function Description:
  //*  Display the initial score
  //*  Add or sub one score at the same time
  /
  //
  always @( posedge clk or negedge rst_n ) begin
    if( ~rst_n ) begin
      score_player[0] <= #`DEL 4'd5;
      score_player[1] <= #`DEL 4'd5;
      score_player[2] <= #`DEL 4'd5;
      score_player[3] <= #`DEL 4'd5;
    end
    else if( ~&led && ~lock ) begin
      case(1'b1)
        ~led[0]:begin
          if( add_score_flag ) begin
            if( score_player[0] < 4'd9 ) begin
              score_player[0] <= #`DEL score_player[0] + 1'b1;
            end
          end
          else if( sub_score_flag ) begin
            if( |score_player[0] ) begin
              score_player[0] <= #`DEL score_player[0] - 1'b1;
            end
          end
        end
        ~led[1]:begin
          if( add_score_flag ) begin
            if( score_player[1] < 4'd9 ) begin
              score_player[1] <= #`DEL score_player[1] + 1'b1;
            end
          end
          else if( sub_score_flag ) begin
            if( |score_player[1] ) begin
              score_player[1] <= #`DEL score_player[1] - 1'b1;
            end
          end
        end
        ~led[2]:begin
          if( add_score_flag ) begin
            if( score_player[2] < 4'd9 ) begin
              score_player[2] <= #`DEL score_player[2] + 1'b1;
            end
          end
          else if( sub_score_flag ) begin
            if( |score_player[2] ) begin
              score_player[2] <= #`DEL score_player[2] - 1'b1;
            end
          end
        end
        ~led[3]:begin
          if( add_score_flag ) begin
            if( score_player[3] < 4'd9 ) begin
              score_player[3] <= #`DEL score_player[3] + 1'b1;
            end
          end
          else if( sub_score_flag ) begin
            if( |score_player[3] ) begin
              score_player[3] <= #`DEL score_player[3] - 1'b1;
            end
          end
        end
      endcase
    end
  end     

  assign end_score = &led ? 4'd0 : 
                     (~led[0] ? score_player[0] : 
                     (~led[1] ? score_player[1] :
                     (~led[2] ? score_player[2] :
                     (~led[3] ? score_player[3] : 
                     4'd0))));

endmodule


  • qiangdaqi.v
//*************************************************************
//
//*@File name: qiangdaqi.v
//
//*@File type: verilog top module
//
//*@Version  : 0.0.1
//
//*@Author   : Zehua Dong, HITWH
//
//*@E-mail   : hitdongzh@163.com
//
//*@Date     : 2020-12-08 11:11:08
//
//*@Function : 
//
//*************************************************************
//
//  Module definition
//
module qiangdaqi(
  clk       ,             
  rst_n     ,         
  switch    ,       
  key       ,          
  led       ,        
  rgb       ,
  seg_led_1       
  );

  //===========================================================
  //* Input and output signals
  //===========================================================
  //
  input                     clk       ;              
  input                     rst_n     ;           
  input     [2:0]           switch    ; 
  input     [3:0]           key       ;
  output    [3:0]           led       ;
  output    [2:0]           rgb       ;
  output    [8:0]           seg_led_1 ;   

  /
  //*Function Description:
  //* Module instantiation 
  //*  
  /
  //
  snatch snatch_u1(
    .clk    ( clk    ),              
    .rst_n  ( rst_n  ),          
    .key    ( key    ),             
    .reload ( ~switch[2] ),   // Connect to the 3rd switch 
    .led    ( led    ),      
    .valid_dly( valid_dly     ) ,
    .rgb    ( rgb    )
  );
  
  wire [3:0] end_score;
  score score_u1(
    .clk       ( clk       ),           
    .rst_n     ( rst_n     ),       
    .add_score ( switch[0] ),              
    .sub_score ( switch[1] ),
    .lock      ( valid_dly ),
    .led       ( led       ),        
    .end_score ( end_score )        
  );
  
  segment segment_u1(
    .seg_data_1  ( end_score )       ,
    .seg_data_2  (  )       ,
    .seg_led_1   ( seg_led_1  )       ,
    .seg_led_2   (  )         
  );

endmodule


  1. 仿真文件
  • counter_tb.v
module counter_tb();

  reg                 tb_clk  ;                       
  reg                 tb_rst_n;                
  reg                 tb_start;                
  wire                tb_valid;                

  // 
  // Task of delay
  task delay;
    input [31:0] num;
    begin
      repeat(num) @(posedge tb_clk);
      #1;
    end
  endtask

  // 
  // Generate tb_clock
  initial begin
    tb_clk = 0;
  end
  always #10 tb_clk = ~tb_clk;

  // 
  // Generate tb_reset 
  initial begin
    tb_rst_n = 1;
    delay(1);
    tb_rst_n = 0;
    delay(1);
    tb_rst_n = 1;
  end

  // 
  // Dump file
  initial begin
    $dumpfile(" counter_tb.vcd ");
    $dumpvars();
  end

  // 
  // Others signals
  initial begin
    tb_start = 1'b0;
    // After reset
    delay(3);
    tb_start = 1'b1;
    delay(1);
    tb_start = 1'b0;
    delay(40);
    $finish;
  end

  //
  // Instantiation
  counter counter_u1(
    .clk   ( tb_clk   )     ,                
    .rst_n ( tb_rst_n )     ,        
    .start ( tb_start )     ,       
    .valid ( tb_valid )        
  );

endmodule


  • snatch_tb.v
//*************************************************************
//
//*@File name: snatch_tb.v
//
//*@File type: testbench
//
//*@Version  : 0.0.1
//
//*@Author   : Zehua Dong, HITWH
//
//*@E-mail   : hitdongzh@163.com
//
//*@Date     : 2020-12-07 21:12:51
//
//*@Function : 
//
//*************************************************************
//
// Head files
// `include "common.v"
//
//  Module definition
//
module snatch_tb();

  reg                 tb_clk    ;                     
  reg                 tb_rst_n  ;              
  reg     [3:0]       tb_key    ;                     
  reg                 tb_reload ;               
  wire    [3:0]       tb_led    ;                     
  wire    [2:0]       tb_rgb    ;            

  task delay;
    input [31:0] num;
    begin
      repeat(num) @(posedge tb_clk);
      #1;
    end
  endtask

  initial begin
    tb_clk = 0;
  end
  always #10 tb_clk = ~tb_clk;

  initial begin
    tb_rst_n = 1;
    delay(1);
    tb_rst_n = 0;
    delay(1);
    tb_rst_n = 1;
  end

  initial begin
    $dumpfile(" snatch_tb.vcd ");
    $dumpvars();
  end

  initial begin
    tb_key = 4'b1111;
    tb_reload = 1'b0;
    delay(5);         // rgb is green
    tb_key = 4'b1100; // 3
    delay(15);        // rgb is bule
    tb_reload = 1'b1;
    delay(1);
    tb_reload = 1'b0;

    tb_key = 4'b0111; // 1
    delay(40);        // rgb is red, time out
    tb_reload = 1'b1;
    delay(1);
    tb_reload = 1'b0;
    
    tb_key = 4'b1010; // 1
    delay(20);        // rgb is blue
    tb_reload = 1'b1;
    delay(1);
    tb_reload = 1'b0;
    delay(5);         // rgb is green
    $finish;
  end

  snatch snatch_u1(
    .clk   ( tb_clk    ) ,              
    .rst_n ( tb_rst_n  ) ,          
    .key   ( tb_key    ) ,             
    .reload( tb_reload ) ,   // Connect to the 3rd switch 
    .led   ( tb_led    ) ,         
    .rgb   ( tb_rgb    )  
  );

endmodule


  • score_tb.v
//*************************************************************
//
//*@File name: score_tb.v
//
//*@File type: testbench
//
//*@Version  : 0.0.1
//
//*@Author   : Zehua Dong, HITWH
//
//*@E-mail   : hitdongzh@163.com
//
//*@Date     : 2020-12-08 09:44:40
//
//*@Function : 
//
//*************************************************************
//
// Head files
// `include "common.v"
//
//  Module definition
//
module score_tb();

  reg                 tb_clk       ;                  
  reg                 tb_rst_n     ;           
  reg                 tb_add_score ;               
  reg                 tb_sub_score ;               
  reg  [3:0]          tb_led       ;               
  wire [3:0]          tb_end_score ;               

  task delay;
    input [31:0] num;
    begin
      repeat(num) @(posedge tb_clk);
      #1;
    end
  endtask

  initial begin
    tb_clk = 0;
  end
  always #10 tb_clk = ~tb_clk;

  initial begin
    tb_rst_n = 1;
    delay(1);
    tb_rst_n = 0;
    delay(1);
    tb_rst_n = 1;
  end

  initial begin
    $dumpfile(" score_tb.vcd ");
    $dumpvars();
  end

  initial begin
    tb_add_score = 1'b0;
    tb_sub_score = 1'b0;
    tb_led = 4'b1111;      // Display 0
    delay(3);

    tb_led = 4'b1011;      // Display 5  
    delay(5);
    tb_add_score = 1'b1;   // Display 6
    delay(2);
    tb_add_score = 1'b0;
    delay(5);
    
    tb_led = 4'b0111;      // Display 5
    delay(5);
    tb_sub_score = 1'b1;   // Display 4
    delay(2);
    tb_sub_score = 1'b0;
    delay(5);
    $finish;
  end

  score score_u1(
    .clk      ( tb_clk       ) ,           
    .rst_n    ( tb_rst_n     ) ,       
    .add_score( tb_add_score ) ,              
    .sub_score( tb_sub_score ) ,     
    .led      ( tb_led       ) ,        
    .end_score( tb_end_score )         
  );

endmodule


  • qiangdaqi_tb.v
module qiangdaqi_tb();

  reg                 tb_clk      ;                   
  reg                 tb_rst_n    ;            
  reg    [2:0]        tb_switch   ;                
  reg    [3:0]        tb_key      ;                
  wire   [3:0]        tb_led      ;                
  wire   [2:0]        tb_rgb      ;                
  wire   [8:0]        tb_seg_led_1;                

  task delay;
    input [31:0] num;
    begin
      repeat(num) @(posedge tb_clk);
      #1;
    end
  endtask

  initial begin
    tb_clk = 0;
  end
  always #10 tb_clk = ~tb_clk;

  initial begin
    tb_rst_n = 1;
    delay(1);
    tb_rst_n = 0;
    delay(1);
    tb_rst_n = 1;
  end

  initial begin
    $dumpfile(" qiangdaqi_tb.vcd ");
    $dumpvars();
  end

  initial begin
    tb_switch = 3'd0;
    tb_key = 4'b1111;  // green
    delay(3);

    tb_key = 4'b1001;  // 2hao
    delay(10);         // blue
    tb_switch = 3'b001;// 6 score
    delay(1);
    tb_switch = 3'b100;// reload
    delay(1);
    tb_switch = 3'b000;
    delay(5);

    tb_key = 4'b0111;  // 1hao
    delay(10);         // blue
    tb_switch = 3'b010; // 4 score
    delay(1);
    tb_switch = 3'b100;// reload
    delay(1);
    tb_switch = 3'b000;
    delay(5);

    tb_key = 4'b1110;  // 4hao
    delay(40);         // red
    tb_switch = 3'b100;// reload
    delay(1);
    tb_switch = 3'b000;
    delay(10);
    
    $finish;
  end

qiangdaqi qiangdaqi_u1(
  .clk       ( tb_clk       ),             
  .rst_n     ( tb_rst_n     ),         
  .switch    ( tb_switch    ),       
  .key       ( tb_key       ),          
  .led       ( tb_led       ),        
  .rgb       ( tb_rgb       ),     
  .seg_led_1 ( tb_seg_led_1 )      
);

endmodule


  1. 仿真结果
  • modelsim编译结果是没问题的,有几个warning无伤大雅,用来调试的
    在这里插入图片描述
  1. 上板
    工程是在QuartusII15.0中建立的
  • RTL视图
    • 顶层qiangdaqi视图
      在这里插入图片描述

    • score视图
      在这里插入图片描述

    • snatch视图
      在这里插入图片描述

    • 引脚分配
      在这里插入图片描述
      在这里插入图片描述

  • 上板验证
    • 上电后
      在这里插入图片描述
    • 正常抢答状态,rgb为蓝色,初始分数5分
      在这里插入图片描述
    • 超过30秒后,rgb变为红色,此时加分减分按键不起作用

在这里插入图片描述
- 减一分
在这里插入图片描述
- 加一分
在这里插入图片描述

  • 9
    点赞
  • 63
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: 基于小脚丫FPGA开发板的交通灯设计可以通过使用FPGA芯片的可编程性和并行处理能力来实现交通灯的各种功能和状态转换。 首先,我们可以将FPGA开发板中的IO口连接到交通灯的灯光控制部分。通过编程FPGA芯片,我们可以实现不同颜色灯光的控制和状态转换。例如,可以使用FPGA开发板的GPIO接口控制交通灯的红、黄、绿三种颜色的灯光。 其次,我们可以利用FPGA芯片的并行处理能力,通过同时处理多个输入和输出信号来实现交通灯的时序控制。例如,可以使用FPGA开发板的定时器模块来控制交通灯的时间间隔和状态转换。通过编程FPGA芯片,我们可以实现交通灯的定时控制和状态切换,并可以根据实际交通流量和需求进行灵活调整。 此外,FPGA开发板还可以用于其他与交通灯相关的功能设计。例如,可以使用FPGA芯片来识别交通流量,通过连接传感器和视频输入接口,实时采集和处理交通流量信息,并根据需求调整交通灯的控制策略。同时,还可以利用FPGA的可编程性,设计并实现智能交通系统,如车辆识别、自动控制等功能。 总之,基于小脚丫FPGA开发板的交通灯设计可以利用其可编程性和并行处理能力,实现交通灯的各种功能和状态转换,并可以扩展到其他与交通灯相关的智能交通系统设计中。 ### 回答2: 基于小脚丫FPGA开发板的交通灯设计是一种通过FPGA(可编程逻辑门阵列)实现的交通信号灯控制系统。这种设计可以模拟真实交通环境中的交通信号灯,并且具有高度可编程性和灵活性。 在这个设计中,首先需要使用FPGA开发板上的I/O接口连接LED灯,模拟交通信号灯的红、黄、绿三种状态。使用FPGA的开发软件,在开发板上进行编程,设置不同的状态和时间间隔,以模拟交通信号灯的工作逻辑。 通过编程,可以实现以下功能: 1. 设置交通信号灯的状态:红灯、黄灯和绿灯。每个状态可以通过不同颜色的LED灯显示。 2. 设置交通信号灯的时间间隔:红灯、黄灯和绿灯的时间可以根据实际需要进行调整。 3. 实现交通信号灯的循环:根据设置的时间间隔,交通信号灯可以按照规定的顺序进行循环切换。 此外,还可以实现其他功能,例如: 1. 增加行人过马路的信号:可以设置一个行人过马路的信号灯,通过另一个LED灯来表示行人的状态。 2. 添加传感器控制:可以使用FPGA开发板上的传感器接口,通过感应车辆或行人的存在,实现交通信号灯自动切换功能。 这种基于小脚丫FPGA开发板的交通灯设计,可以实现交通信号灯的模拟,具有高度可编程性,可以根据实际需要进行各种设置和调整,使得交通灯的控制更加灵活和智能化。同时,这种设计也有助于更好地理解和研究交通信号灯的工作原理和控制逻辑。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值