数字竞赛抢答器课程设计Verilog语言实现Word格式.docx
《数字竞赛抢答器课程设计Verilog语言实现Word格式.docx》由会员分享,可在线阅读,更多相关《数字竞赛抢答器课程设计Verilog语言实现Word格式.docx(9页珍藏版)》请在冰豆网上搜索。
设置抢答按钮K1、K2、K3、K4,主持人复位信号judge,蜂鸣器驱动信号buzzout。
judge=0时,第一信号鉴别、锁存电路、答题计时电路复位,在此状态下,若有抢答按钮按下,鸣笛示警并显示犯规组别;
judge=1时,开始抢答,由第一信号鉴别锁存电路形成第一抢答信号,进行组别显示,控制蜂鸣器发出声响,并启动答题计时电路,若计时时间到,主持人复位信号还没有按下,则由蜂鸣器发出犯规示警声。
计分电路是一个相对独立的模块,采用十进制加/减计数器、数码管数码扫描显示,设置复位信号Reset、加减分信号add_min,加减分状态键key_state,Reset=0时所有得分回到起始分(5分),且加、减分信号无效;
Reset=1时,由第一信号鉴别、锁存电路的输出信号选择进行加减分的组别,当key_state=1时,按一次add_min,第一抢答组加1分;
当key_state=0时,每按一次add_min,则减1分。
以下为每个模块的设计过程。
三、程序及仿真
/******************************************************************
顶层模块信号定义:
clk:
基准时钟输入信号;
k1,k2,k3,k4:
抢答按钮输入信号;
seg:
数码管段输出引脚;
sl:
数码管位输出引脚;
add_min:
加减分按键;
key_state:
加减分模式选择按键;
reset:
初始5分设置键信号;
judge:
裁判员抢答开始键信号;
o5:
超时信号;
o1、o2、o3、o4:
抢答组别LED显示输出信号;
buzz:
示警输出信号;
******************************************************************/
module
qiangdaqi(clk,k1,k2,k3,k4,seg,sl,add_min,key_state,reset,judge,o1,o2,o3,o4,o5,buzz,vg,sel);
inputclk,k1,k2,k3,k4,add_min,key_state,reset,judge;
output[7:
0]seg;
output[3:
0]sl;
outputregsel;
outputo1,o2,o3,o4,o5,vg;
outputbuzz;
reg[3:
0]vg=0010;
wireo1,o2,o3,o4;
wire[3:
0]s1,s2,s3,s4;
/*模块引用*/
selQ1(clk,k1,k2,k3,k4,judge,o1,o2,o3,o4,o5,buzz);
//调用抢答信号锁存显示电路
countQ2(clk,o1,o2,o3,o4,add_min,key_state,reset,s1,s2,s3,s4);
//调用计分电路
dledQ3(seg,sl,s1,s2,s3,s4,clk);
//调用数码管显示电路
endmodule
/****************************************************************
信号锁存电路信号定义:
CLK:
时钟信号;
K1、K2、K3、K4、K5、K6:
抢答按钮信号;
out1、out2、out3、out4、out5、out6:
抢答LED显示信号;
裁判员抢答开始信号;
buzzout:
flag:
答题是否超时的标志;
****************************************************************/
modulesel(clk,k1,k2,k3,k4,judge,out1,out2,out3,out4,out5,buzzout);
inputclk,k1,k2,k3,k4,judge;
outputout1,out2,out3,out4,out5,buzzout;
regout1,out2,out3,out4,out5,block,buzzout;
reg[32:
0]count;
reg[27:
0]counter;
regflag;
always@(posedgeclk)
begincounter=counter+1;
//裁判员发开始抢答信号,初始指示灯灭,蜂鸣器禁声
if(!
judge)begin{out1,out2,out3,out4,out5,block}<
=6'
b111110;
count=0;
flag=0;
end
elsebeginif(!
k1)//第一组别按键是否按下
beginif(!
block)
beginout1=0;
//点亮第一组别指示灯
block=1;
//封锁别组抢答信号
count=1;
//第一组已按下按钮,可启动答题计时器
endend
elseif(!
k2)//第二组别按键是否按下
block)
beginout2=0;
block=1;
end
k3)//第三组别按键是否按下
beginout3=0;
count=1;
k4)//第四组别按键是否按下
beginout4=0;
end/*答题计时开始,并判断是否答题超时*/
if(count!
=0)
beginif(count==32'
hc11e7a00)//如果答题时间到了1分钟,亮犯规灯
begincount=0;
out5<
=0;
flag=1'
b1;
elsebegincount=count+1;
end////蜂鸣器发声
always@(counter[7])
if(flag==1)buzzout=!
(counter[11]&
counter[22]&
counter[27]);
elsebuzzout=1'
b0;
/**************************************************************
去键盘抖动信号定义:
clkin:
clkout:
周期为20ms的信号输出;
*************************************************************/
modulef_1M(clkin,clkout);
Inputclkin;
outputclkout;
regclkout;
reg[18:
always@(negedgeclkin)
if(count==19'
d500000)
begincount<
=19'
d000000;
clkout<
=~clkout;
elsecount<
=count+1'
计分电路信号定义:
c1,c2,c3,c4:
抢答组别输入信号;
加减分按钮;
加减分标志按钮;
初始5分设置信号;
count1:
第一组得分输出;
count2:
第二组得分输出;
count3:
第三组得分输出;
count4:
第四组得分输出;
modulecount(clk,c1,c2,c3,c4,add_min,key_state,reset,count1,count2,count3,count4);
inputclk,c1,c2,c3,c4,add_min,key_state,reset;
0]count1,count2,count3,count4;
reg[3:
wireclk0;
regkeyout;
f_1Mf_1Ma(clk,clk0);
//引用获得20毫秒的子模块
always@(negedgeclk0)
keyout=add_min;
always@(posedgekeyout)//根据相应组别加减分
reset)//初始化各组的起始分数
{count1,count2,count3,count4}=16'
h5555;
key_state)//key_state为低电平,选组别减分模式
c1)//第一组别减1分,最高分为10分,最低分为0分
beginif(count1!
=4'
b0000)count1=count1-1;
c2)//第二组别减1分,最高分为10分,最低分为0分
beginif(count2!
b0000)count2=count2-1;
c3)//第三组别减1分,最高分为10分,最低分为0分
beginif(count3!
b0000)count3=count3-1;
c4)//第四组别减1分,最高分为10分,最低分为0分
beginif(count4!
b0000)count4=count4-1;
endelse//key_state为高电平,选组别加分模式
c1)//第一组别加分,最高分为10分,最低分为0分
beginif(count1>
9)count1=0;
elsecount1=count1+1;
c2)//第二组别加分,最高分为10分,最低分为0分
beginif(count2>
9)count2=0;
elsecount2=count2+1;
c3)//第三组别加分,最高分为10分,最低分为0分
beginif(count3>
9)count3=0;
elsecount3=count3+1;
c4)//第四组别加分,最高分为10分,最低分为0分
beginif(count4>
9)count4=0;
elsecount4=count4+1;
endendend
数码管显示电路信号定义:
score1:
第一组得分输入;
score2:
第二组得分输入;
score3:
第三组得分输入;
score4:
第四组得分输入;
moduledled(seg,sl,score1,score2,score3,score4,clk,vg);
outputreg[3:
inputclk;
input[3:
0]score1,score2,score3,score4;
reg[7:
0]seg_reg;
//定义数码管段输出寄存器
0]sl_reg;
//定义数码管位输出寄存器
0]disp_dat;
//定义显示数据寄存器
reg[16:
//定义计数器寄存器
always@(posedgeclk)//定义clock信号上升沿触发
begincount=count+1;
//计数器值加1
always@(count[14:
13])//定义显示数据触发事件
begincase(count[14:
13])//选择扫描显示数据
2'
h0:
disp_dat=score1;
//在个位数码管上显示第一组别的分数值
h1:
disp_dat=score2;
//在十位数码管上显示第二组别的分数值
h2:
disp_dat=score3;
//在百位数码管上显示第三组别的分数值
h3:
disp_dat=score4;
//在千位数码管上显示第四组别的分数值
endcase
case(count[14:
13])//选择数码管显示位
sl_reg=4'
b1110;
//选择个位数码管
sl_reg=4'
b1101;
//选择十位数码管
b1011;
//选择百位数码管
b0111;
//选择千位数码管
endcaseend
always@(disp_dat)//显示数据的解码过程
begin
case(disp_dat)
4'
seg_reg=8'
h3f;
//显示数据0
h06;
//显示数据1
h5b;
//显示数据2
h4f;
//显示数据3
h4:
h66;
//显示数据4
h5:
h6d;
//显示数据5
h6:
h7d;
//显示数据6
h7:
h07;
//显示数据7
h8:
h7f;
//显示数据8
h9:
h6f;
//显示数据9
ha:
h77;
//显示数据a
hb:
h7c;
//显示数据b
hc:
h39;
//显示数据c
hd:
h51;
//显示数据d
he:
h79;
//显示数据e
hf:
h71;
//显示数据f
assignseg=seg_reg;
//输出数码管解码结果
assignsl=sl_reg;
//输出数码管选择
管脚分配图如下:
四、总结
1、打开QuartusII软件,对该工程文件进行编译处理,若在编译过程中发现错误,找出并更正错误直至成功为止。
2、将CCITCPLD/FGPAJTAG下载电缆的两端分别接到PC机和CCITCPLD/FGPA实验仪上,再打开工作电源,执行下载命令把程序下载到CCITCPLD/FGPA实验仪的EPM1270T144C5N器件中,通过K1~K4抢答按键按下后,由裁判员根答题情况,通过控制add_min和key_state这两个键实现加减分操作,这样大家就可以看到数码管上的分数和LED四盏小灯的变化。
五、心得体会
通过本次课程设计,我学会了综合应用键盘、LED小灯、蜂鸣器、LED数码管等外围接口进行产品设计,掌握了键盘、LED小灯、蜂鸣器、LED数码管等外围接口的Verilog语言编程和各种外围接口的灵活运用。
培养了CPLD的综合开发能力、实验的仿真及下载技能和互帮互助的同学关系,在各种其它能力上也都有了提高。
更重要的是,经过本次课设的反复修改验证及完成,我们学会了很多学习的方法,而这是日后最实用的,真的是感到受益匪浅。
虽然结束了,也留下了很多遗憾,由于时间的紧缺和许多课业的繁忙,并没有做到最好,但是,最起码我们没有放弃,并努力实现它。
相信以后我们会以更加积极地态度对待我们的学习、对待我们的生活。
我们的激情永远不会结束,相反,我们会更加努力,努力的去弥补缺点,发展优点,充实自己!