项目信息
名称:抢答器计时计分与显示控制 Verilog QuartusII
软件:QuartusII
语言:Verilog
代码功能
该工程实现五路抢答器:按下开始键后进入抢答倒计时,最先按下的选手按键被判定为抢答成功,对应指示灯点亮并输出提示音;若在倒计时内无人抢答则触发超时报警。系统还包含答题计时与分数加减控制,分数与状态信息通过数码管动态显示,形成“抢答-答题-计分-下一轮”的完整实验流程。
相关图片
要求 (1).jpg
要求 (2).jpg
代码实现思路
设计采用多模块协同:首先对关键按键做消抖并提取下降沿,避免机械抖动造成多次触发;核心抢答逻辑由qiangda_ctrl的状态机实现,开始后进入倒计时窗口,优先级按检测顺序锁定首个有效按键,随后进入答题阶段并保持胜出者指示。计时模块jishi提供抢答倒计时与答题计时基准;计分模块score_crtl在允许的状态下响应加分/减分键;显示模块display把倒计时、胜出者编号与各选手分数进行动态刷新。
代码结构
顶层qiangdaqi完成模块例化与信号连线:key_debounce产生开始键与加减分键的稳定触发脉冲;qiangda_ctrl输出系统状态、胜出者与提示信号;jishi根据状态产生倒计时与答题计时;score_crtl维护五路分数寄存器;display将状态、计时、胜出者与分数组织成数码管显示内容。整体数据流为:按键输入→消抖→状态机判定→计时/计分→显示与指示输出。
1、工程文件
2、程序文件
3、程序编译
4、RTL图
5、管脚分配
6、仿真图
整体仿真图
控制模块
分数模块
显示模块
计时模块
按键消抖模块
部分代码
qiangdaqi_bdqiangda_ctrl.v
//抢答控制模块
module qiangda_ctrl(
input clk,
input reset_n,//复位抢答状态
input start_p,//开始控制按键
//5个抢答按键
input key_1,
input key_2,
input key_3,
input key_4,
input key_5,
//5灯指示5个选手
output reg led_1,
output reg led_2,
output reg led_3,
output reg led_4,
output reg led_5,
output reg led_overtime,//超时报警
output [4:0]state_out,//输出状态
input [7:0] time_done,//倒计时
input [7:0] dati_time,//答题时间(30s)
outputreg beep,//抢答成功提示
output [3:0] qiangda//正常抢答
);
parameter s_idle=5'd0;
parameter s_start=5'd1;
parameter s_timedown=5'd2;
parameter s_qianda_1=5'd3;
parameter s_qianda_2=5'd4;
parameter s_qianda_3=5'd5;
parameter s_qianda_4=5'd6;
parameter s_qianda_5=5'd7;
parameter s_overtime=5'd8;
parameter s_dati=5'd9;
reg [4:0] state=5'd0;
assign state_out=state;
always@(posedge clk or negedge reset_n)
if(!reset_n)
state<=s_idle;
else
case(state)
s_idle://空闲状态,还没开始抢答
if(start_p)//开始抢答按键
state<=s_start;
else
state<=s_idle;
s_start:
state<=s_timedown;//开始倒计时
s_timedown:
if(key_1==0)
state<=s_qianda_1;//1号抢答
else if(key_2==0)
state<=s_qianda_2;//2号抢答
else if(key_3==0)
state<=s_qianda_3;//3号抢答
else if(key_4==0)
state<=s_qianda_4;//4号抢答
else if(key_5==0)
state<=s_qianda_5;//5号抢答
else
if(time_done==8'd0)
state<=s_overtime;//超时
else
state<=s_timedown;//倒计时
s_overtime:
state<=s_idle;
s_qianda_1,s_qianda_2,s_qianda_3,s_qianda_4,s_qianda_5:
if(dati_time==8'd30)//答题时间30秒
state<=s_overtime;//超时
else if(start_p)
state<=s_start;
else
state<=state;
default:;
endcase
always@(posedge clk or negedge reset_n)
if(!reset_n)
led_1<=1'd0;
else
if(state==s_qianda_1)//1号抢答
led_1<=1'd1;
else
led_1<=1'd0;
always@(posedge clk or negedge reset_n)
if(!reset_n)
led_2<=1'd0;
else
if(state==s_qianda_2)//2号抢答
led_2<=1'd1;
else
led_2<=1'd0;
always@(posedge clk or negedge reset_n)
if(!reset_n)
led_3<=1'd0;
else
if(state==s_qianda_3)//3号抢答
led_3<=1'd1;
else
led_3<=1'd0;
always@(posedge clk or negedge reset_n)
if(!reset_n)
led_4<=1'd0;
else
if(state==s_qianda_4)//4号抢答
led_4<=1'd1;
else
led_4<=1'd0;
always@(posedge clk or negedge reset_n)
if(!reset_n)
led_5<=1'd0;
else
if(state==s_qianda_5)//5号抢答
led_5<=1'd1;
else
led_5<=1'd0;
//控制超时信号
always@(posedge clk or negedge reset_n)
if(!reset_n)
led_overtime<=0;
else
if(state==s_overtime)
led_overtime<=1;
else if(state==s_start )
led_overtime<=0;
//正常抢答序号 qiangda
reg [3:0] qiangda_buf;
always@(posedge clk or negedge reset_n)
if(!reset_n)
qiangda_buf<=4'd0;
else
if(state==s_qianda_1)
qiangda_buf<=4'd1;
else if(state==s_qianda_2)
qiangda_buf<=4'd2;
else if(state==s_qianda_3)
qiangda_buf<=4'd3;
else if(state==s_qianda_4)
qiangda_buf<=4'd4;
else
qiangda_buf<=4'd0;
assign qiangda=qiangda_buf;
//抢答成功提示
always@(posedge clk or negedge reset_n)
if(!reset_n)
beep<=1'd0;
else
if(state==s_qianda_1 || state==s_qianda_2 || state==s_qianda_3 || state==s_qianda_4)
beep<=1'd1; //抢答成功
else
beep<=1'd0;
endmodule
267