/******************************************************************
顶层模块信号定义:
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);
input clk,k1,k2,k3,k4,add_min,key_state,reset,judge;
output[7:0] seg;
output[3:0] sl;
output reg sel;
output o1,o2,o3,o4,o5,vg;
output buzz;
reg [3:0] vg=0010;
wire o1,o2,o3,o4;
wire[3:0] s1,s2,s3,s4;
/* 模块引用*/
sel Q1(clk,k1,k2,k3,k4,judge,o1,o2,o3,o4,o5,buzz); //调用抢答信号锁存显示电路
count Q2(clk,o1,o2,o3,o4,add_min,key_state,reset,s1,s2,s3,s4); //调用计分电路
dled Q3(seg,sl,s1,s2,s3,s4,clk); //调用数码管显示电路
endmodule
/****************************************************************
信号锁存电路信号定义:CLK:时钟信号;K1、K2、K3、K4、K5、K6:抢答按钮信号;out1、out2、out3、out4、out5、out6:抢答LED显示信号;judge:裁判员抢答开始信号;buzzout:示警输出信号;flag:答题是否超时的标志;
***************************************************************/
module sel(clk,k1,k2,k3,k4,judge,out1,out2,out3,out4,out5,buzzout);
input clk,k1,k2,k3,k4,judge;
output out1,out2,out3,out4,out5,buzzout;
reg out1,out2,out3,out4,out5,block,buzzout;
reg[32:0] count;
reg[27:0] counter;
reg flag;
always@(posedge clk )
begin counter=counter+1; //裁判员发开始抢答信号,初始指示灯灭,蜂鸣器禁声
if(!judge)
begin {out1,out2,out3,out4,out5,block}<=6'b111110;
count=0;
flag=0;
end else begin if(!k1) //第一组别按键是否按下
begin if(!block)
begin out1=0; //点亮第一组别指示灯
block=1; //封锁别组抢答信号
count=1; //第一组已按下按钮,可启动答题计时器
end
end
else if(!k2) //第二组别按键是否按下下载文档到电脑,查找使用更方便2下载券 70人已下载
下载还剩4页未读,继续阅读
begin if(!block) begin out2=0;
block=1;count=1;
end
end
else if(!k3) //第三组别按键是否按下
begin if(!block) begin out3=0;
block=1; count=1;
end
end
else if(!k4) //第四组别按键是否按下
begin if(!block) begin out4=0;
block=1; count=1;
end
end
end /*答题计时开始,并判断是否答题超时*/
if(count!=0)
begin if(count==32'hc11e7a00) //如果答题时间到了1分钟,亮犯规灯
begin count=0;
out5<=0;
flag=1'b1;
end
else
begin count=count+1;
end
end
end ////蜂鸣器发声
always@(counter[7])
if(flag==1)
buzzout=!(counter[11]&counter[22]&counter[27]);
else buzzout=1'b0;
endmodule
/**************************************************************
去键盘抖动信号定义:clkin:基准时钟输入信号;clkout:周期为20ms的信号输出;
*************************************************************/
module f_1M(clkin,clkout);
Input clkin;
output clkout;
reg clkout;
reg[18:0] count;
always @(negedge clkin)
if(count==19'd500000)
begin count<=19'd000000;
clkout<=~clkout;
end
else count<=count+1'b1;
endmodule
/**************************************************************
计分电路信号定义:clk:时钟信号;c1,c2,c3,c4:抢答组别输入信号;add_min:加减分按钮;key_state:加减分标志按钮;reset:初始5分设置信号;count1:第一组得分输出;count2:第二组得分输出;count3:第三组得分输出;count4:第四组得分输出;
*************************************************************/
module count(clk,c1,c2,c3,c4,add_min,key_state,reset,count1,count2,count3,count4);
input clk,c1,c2,c3,c4,add_min,key_state,reset;
output[3:0] count1,count2,count3,count4;
reg[3:0] count1,count2,count3,count4;
wire clk0;
reg keyout;
f_1M f_1Ma(clk,clk0); //引用获得20毫秒的子模块
always @(negedge clk0) keyout=add_min;
always @(posedge keyout) //根据相应组别加减分
begin if(!reset) //初始化各组的起始分数
{count1,count2,count3,count4}=16'h5555;
if(!key_state) // key_state为低电平,选组别减分模式
begin
if(!c1) //第一组别减1分,最高分为10分,最低分为0分
begin
if(count1!=4'b0000) count1=count1-1;
end if(!c2) //第二组别减1分,最高分为10分,最低分为0分
begin
if(count2!=4'b0000) count2=count2-1;
end
if(!c3) //第三组别减1分,最高分为10分,最低分为0分
begin if(count3!=4'b0000) count3=count3-1;
end
if(!c4) //第四组别减1分,最高分为10分,最低分为0分
begin if(count4!=4'b0000) count4=count4-1;
end
end
else // key_state为高电平,选组别加分模式
begin
if(!c1) //第一组别加分,最高分为10分,最低分为0分
begin
if(count1>9) count1=0;
else count1=count1+1;
end
if(!c2) //第二组别加分,最高分为10分,最低分为0分
begin
if(count2>9) count2=0;
else count2=count2+1;
end
if(!c3) //第三组别加分,最高分为10分,最低分为0分
begin
if(count3>9) count3=0;
else count3=count3+1;
end
if(!c4) //第四组别加分,最高分为10分,最低分为0分
begin
if(count4>9) count4=0;
else count4=count4+1;
end
end
end
endmodule
/******************************************************************
数码管显示电路信号定义:clk:时钟信号;seg:数码管段输出引脚;sl:数码管位输出引脚;score1:第一组得分输入;score2:第二组得分输入;score3:第三组得分输入;score4:第四组得分输入;
******************************************************************/
module dled (seg,sl,score1,score2,score3,score4,clk,vg);
output[7:0] seg;
output[3:0] sl;
output reg [3:0] vg=0010;
input clk;
input[3:0] score1,score2,score3,score4;
reg[7:0] seg_reg; //定义数码管段输出寄存器
reg[3:0] sl_reg; //定义数码管位输出寄存器
reg[3:0] disp_dat; //定义显示数据寄存器
reg[16:0] count; //定义计数器寄存器5
always@(posedge clk) //定义clock信号上升沿触发
begin count=count+1; //计数器值加1
end
always@(count[14:13]) //定义显示数据触发事件
begin case(count[14:13]) //选择扫描显示数据
2'h0:disp_dat=score1; //在个位数码管上显示第一组别的分数值2'h1:disp_dat=score2; //在十位数码管上显示第二组别的分数值2'h2:disp_dat=score3; //在百位数码管上显示第三组别的分数值2'h3:disp_dat=score4; //在千位数码管上显示第四组别的分数值endcase case(count[14:13]) //选择数码管显示位
2'h0:sl_reg=4'b1110; //选择个位数码管
2'h1:sl_reg =4'b1101; //选择十位数码管
2'h2:sl_reg =4'b1011; //选择百位数码管
2'h3:sl_reg =4'b0111; //选择千位数码管
endcase
end
always@(disp_dat) //显示数据的解码过程
begin
case(disp_dat)
4'h0:seg_reg=8'h3f; //显示数据0
4'h1:seg_reg=8'h06; //显示数据1
4'h2:seg_reg=8'h5b; //显示数据2
4'h3:seg_reg=8'h4f; //显示数据3
4'h4:seg_reg=8'h66; //显示数据4
4'h5:seg_reg=8'h6d; //显示数据5
4'h6:seg_reg=8'h7d; //显示数据6
4'h7:seg_reg=8'h07; //显示数据7
4'h8:seg_reg=8'h7f; //显示数据8
4'h9:seg_reg=8'h6f; //显示数据9
4'ha:seg_reg=8'h77; //显示数据a
4'hb:seg_reg=8'h7c; //显示数据b
4'hc:seg_reg=8'h39; //显示数据c
4'hd:seg_reg=8'h51; //显示数据d
4'he:seg_reg=8'h79; //显示数据e
4'hf:seg_reg=8'h71; //显示数据f
endcase
end
assign seg=seg_reg; //输出数码管解码结果
assign sl=sl_reg; //输出数码管选择
endmodule
把各个模块分别用Quartus II 5.0 仿真出来。
得到这样的波形图