基于FPGA的智力抢答器Verilog仿真设计

链接:https://pan.baidu.com/s/1sGmJE7ZeHCYwGkIet33zLQ
提取码:1234

部分代码:

//synopsys translate_off
`timescale 10 ns/ 1 ps
//synopsys translate_on
module display(
    clk,            
	rst_n,
    duan,           
    wei,            
    start,
	choose,
	num_choose,
    display_score_ge,
    display_score_shi,
    start_en,
    start_falling_edge,
    time_over
	);
	
	input           clk;												// 系统时钟 100MHz
	input 			rst_n;												// 复位信号 低电平有效
	input           choose;												// 抢答完成信号
	input  [2:0]    num_choose;											// 抢答者号码
	input			start;												// 抢答开始按键
    input           start_en;  //开始使能信号
    input           start_falling_edge;//开始按键下降沿检测
    
    input [3:0]     display_score_ge;// 分数个位
    input [3:0]     display_score_shi;// 分数十位
    output [7:0]    duan;												// 数码管段选
	output [7:0]    wei;												// 数码管位选
    output  reg     time_over;
	//------------------------------------------------------------------
			
	//------------------------------------------------------------------
	reg  start_sign;													// 开始抢答标志
	
	always@(negedge start or negedge rst_n)
	begin
		if(rst_n == 1'b0)
			start_sign <=   1'b0;
		else
			start_sign <=   1'b1;
	end
	//------------------------------------------------------------------
	reg [25:0] count;      												// 1HZ时钟计数器
	reg        clk_1hz;    												// 1HZ时钟信号
	
	always@(posedge clk or negedge rst_n)							// 计数 用于分频
	begin
		if(rst_n == 1'b0)
			count <=   26'b0;
		else
		begin
			if(count == 26'd49999999)
				count <=   26'b0;
			else
				count <=   count + 1'b1;
		end
	end
	
	always@(posedge clk or negedge rst_n)							// 产生一个1Hz的时钟
	begin
		if(rst_n == 1'b0)
			clk_1hz <=   1'b0;
		else
		begin
		    if(count == 26'd49999999)
				clk_1hz <=   1'b1;
			else
				clk_1hz <=   1'b0;	 
		end
	end
	//------------------------------------------------------------------
	
	//------------------------------------------------------------------
	reg [3:0] ge;        												// 数码管显示倒计时个位
	reg [1:0] shi;       												// 数码管显示倒计时十位
	reg [2:0] num;														// 数码管显示抢答号
	
	always@(posedge clk or negedge rst_n)							// 数码管个位显示
	begin
		if(rst_n == 1'b0)
        begin
			ge <= 4'd0;
            time_over <= 1'd0;
        end
		else
		begin
            if(start_falling_edge == 1'b1)
            begin
                ge <= 4'd0;
                time_over <= 1'b0;
            end
            else if(clk_1hz == 1'b1)
            begin
                if((start_sign == 1'b1) && (choose == 1'b0))
                begin
                    if(ge == 4'b1010)
                        ge <= 4'b0000;
                    else if((ge == 4'b0000)&&(shi != 2'b00))
                        ge <= 4'b1001;
                    else if((ge == 4'b0000)&&(shi == 2'b00))				// 30s倒计时完毕
                    begin
                        ge <= 4'b0000;
                        time_over <= 1'b1;
                    end
                    else
                        ge <= ge - 1'b1;
                end
                else
                    ge <= ge;
            end
		end
	end
	
	always@(posedge clk or negedge rst_n)							// 数码管十位显示
	begin
		if(rst_n == 1'b0)
			shi <=   2'b11;
		else
		begin
            if(start_falling_edge == 1'b1)
            begin
                shi <= 2'b11;
            end
           else if(clk_1hz == 1'b1)
           begin
                if((start_sign == 1'b1) && (choose == 1'b0))
                begin
                    if(ge == 4'b1010)
                        shi <=   2'b11;
                    else if(ge == 4'b0000)
                    begin
                        if(shi == 2'b00)									// 30s倒计时完毕
                        shi <= 2'b00;
                        else
                        shi <= shi - 1'b1;
                    end
                    else
                    shi <= shi;
                end
                else
                shi <= shi;
           end
		end
	end
	
	always@(posedge clk or negedge rst_n)							// 数码管抢答号显示
	begin
		if(rst_n == 1'b0)
			num <=   3'b0;
		else
		begin
            if(start_falling_edge == 1'b1)
                num <=   3'b0;
            else
                if(choose == 1'b1)
                    num <=   num_choose;
                else
                    num <=   num;		
		end	
	end
	/***********************数码管显示原理***************************/
    // 功能:数码管显示原理
    // 说明:
    //  功能描述:
    // 动态显示原理:
    // 由于LED静态显示需要占用较多的I/O口,且功耗较大,因此在大多数场合通常不采用静态显示,
    // 而采用动态扫描的方法来控制LED数码管的显示。动态显示的特点是将8位数码管的
    // 段选线并联在一起,由位选线控制是哪一位数码管有效。点亮数码管采用动态扫描显示。

    // 动态扫描显示原理:
    // 动态扫描显示即轮流向各位数码管送出字形码和相应的位选,只要扫描显示速度够快,
    // 利用发光管的余辉和人眼视觉暂留作用,使人的感觉好像各位数码管同时都在显示。
    // 动态显示的亮度比静态显示要差一些,所以在选择限流电阻时应略小于静态显示电路中的。
    // 动态扫描显示时刷新频率最好大于50HZ,即显示一轮的时间不超过20ms,本设计采用1000HZ的频率进行扫描显示,
    // 也就是数码管的刷新频率,每个数码管显示
    // 时间不能太长也不能太短,时间太长会影响刷新率,导致总体显示呈现闪烁的现象,时间
    // 太短发光二极管的电流导通时间也就短,会影响总体的显示亮度。一般控制在1ms左右最佳。
    // ***********************************************************
   
    /***********************位选时钟***************************/
    // 功能:产生1000Hz的位选时钟
    // 说明:
        // 对于分频系数为24999的分频器,本例的输入时钟系统50M时钟(clk_50M),
        // 输出为24999分频时钟(f_50)。设计方法为,通过设置一个10位的计数寄存器(cnt)
        // 来实现,每种系统时钟周期的上升沿计数一次,当计数寄存器数到999的时候,
        // 将输出分频信号取反即可得到24999分频的输出1000Hz的位选时钟。
    // ***********************************************************
	reg    [14:0]   count2;												// 1KHZ时钟计数器
	reg 	        clk_1k;												// 1KHZ时钟信号
	
	always@(posedge clk or negedge rst_n)							// 计数 用于分频
	begin
		if(rst_n == 1'b0)
			count2 <=   15'b0;
		else
		begin
			if(count2 == 15'd24999)
				count2 <=   15'b0;
			else
				count2 <=   count2 + 1'b1;
		end
	end
	
	always@(posedge clk or negedge rst_n)							// 数码管扫描时钟 1KHz
	begin
		if(rst_n == 1'b0)
			clk_1k <=   1'b0;
		else
		begin
		    if(count2 == 15'd24999)
				clk_1k <=   1'b1;
			else
				clk_1k <=   1'b0;	 
		end
	end
    /***********************数码管位选信号产生***************************/
    // 功能:数码管位选信号产生
    // 说明:
    // 本设计采用共阳数码管,即位选低电平有效,需要使用2位数码管显示速度档位,
    // 所以需要位宽为2bit的位选信号,并且将位选信号设置为低电平;
    // ***********************************************************
	reg [2:0] clk_scan; 
	
	always@(posedge clk_1k or negedge rst_n)
	begin
		if(rst_n == 1'b0)
			clk_scan <=   1'b0;
		else 
		begin
			if(clk_scan == 3'd4)
				clk_scan <=   1'b0;
			else
				clk_scan <=   clk_scan + 1'b1;
		end
	end
	//------------------------------------------------------------------
	
	//------------------------------------------------------------------
	reg [7:0] duan;
	reg [7:0] wei;

.

  • 5
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值