链接: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;
.