测试题目“三人抢答器” 要求:
(1)答题开始后,由主持人按下“开始”键后进入抢答环节;
(2)每人一个抢答按钮,有人抢答成功后,其他人再抢答无效;
(3)当某人抢答成功时,抢答器系统发出半秒的低频音,并在数码管上显示该组别序号;
(4)每个人初始分数为 0,抢答成功得到一分,并在数码管上显示 3 人的得分;(每人分配 一个数码管用于显示分数,显示“0~9”)
(5)抢答成功后,10 秒倒计时,并在数码管上显示。倒计时为零,开始下一轮抢答;
(6)当主持人按下“复位”键后,数码管清零,准备开始新一轮抢答;
说明:
(1)2 个拨动开关:“复位”键和“开始”键;注意:“复位”键无效、“开始”键有效,开始抢答。
(2)3 个按键开关:3 个抢答人;
(3)6 个数码管分配:1 个用于显示抢答人序号,3 个用于显示 3 人得分,2 个用于 10 秒 倒计时;
文档要求: (1)良好的编码风格、恰当的注释; (2)系统划分:顶层文件,定义 I/O,高低电平有效;子文件,定义 I/O,高低电平有效。 利用图形展示; (3)功能说明:顶层文件和子文件的功能描述,内部变量定义和说明; (4)管脚分配图; (5)测试结果展示:图片和视频。
主模块:
module fsm_rsp(KEY,CLK,RSTn,Digitron_Out,DigitronCS_Out,Start,key_start,key_right,key_wrong,beep);
input key_start; //主持人所持开始抢答键
input key_right,key_wrong; //正确(或错误)回答键
input [2:0]KEY; //各组所持抢答键
input CLK; //时钟
input RSTn; //总体复位键
input Start; //开关(总)
output beep;
output [7:0]Digitron_Out; //数码管显示
output [5:0]DigitronCS_Out;
parameter S0=1'b0,S1=1'b1;
wire beepon;
reg status; //状态机现时状态S0/S1
reg next_state; //状态机后一状态
wire answer; //按回答键后取1,状态为0时清零
wire KEY_right; //消抖回答键
switch u1(key_right,CLK,KEY_right); //按键消抖
wire [2:0]Q;
latch_key u4(reset,KEY,Q,oe); //锁存键值,oe防止在抢答开始前抢答
buzzer_m1 bee(CLK,beepon,beep); //抢答后蜂鸣器响应
assign beepon = Q[0]|Q[1]|Q[2];
wire [11:0]Score; //各小组分数
wire [3:0]Group; //各小组组号
recorder u5(status,RSTn,Q,Score,Group,KEY_right,answer); //记录得分和组号
numdisplay u6(CLK,countdown_num,Digitron_Out,DigitronCS_Out,Score,Group);//数码管显示
reg [3:0]countdown_num; //倒计时数字(显示数码管)
wire [3:0]countdown_num0; //三个计时器的倒计时数字
wire [3:0]countdown_num1;
wire [3:0]countdown_num2;
wire flag0; //计时器进位信号
wire flag1;
wire flag2;
reg counter_clr0; //计时器复位信号
reg counter_clr1; //S0状态时计时器2,3复位,计时器1在按下key—start后开始计时(不按为复位状态)
reg counter_clr2;
wire startcounter0;
wire startcounter1;
wire startcounter2;
assign startcounter0 = (~status) & Start; //开始条件
assign startcounter1 = status & Start;
assign startcounter2 = (~key_wrong|answer) & Start;
counter_ten u7(CLK,startcounter0,counter_clr0,countdown_num0,flag0); //准备抢答 倒计时
counter_ten u8(CLK,startcounter1,counter_clr1,countdown_num1,flag1); //答题倒计时
counter_ten u9(CLK,startcounter2,counter_clr2,countdown_num2,flag2); //答题后等待进入下一轮
always @ (posedge CLK or negedge RSTn) //三段式
begin
if(!RSTn)begin
status<=S0;
end
else status<=next_state;
end
always @ (status or Q or flag1 or flag2 or flag0) //define state of fsm
begin
case(status)
S0:
begin
if(Q) next_state = S1;
else next_state = S0;
end
S1:
begin
if(flag1|flag2) next_state= S0;
else next_state = S1;
end
default: next_state= S0;
endcase
end
always @ (*) //define output of fsm
begin
case(status)
S0:
begin
countdown_num<=countdown_num0;
counter_clr1<=1;
counter_clr2<=1; //将其余两个钟复位
if(oe) counter_clr0<=0;
else counter_clr0 <= 1;
end
S1:
begin
counter_clr0<=1; //复位第一个钟
counter_clr2<=0;
if(!answer) //按下正确的答题键
begin
countdown_num<=countdown_num1;
counter_clr1<=0;
end
else
begin
countdown_num<=countdown_num2;
counter_clr1<=1;
end
end
default:
begin
countdown_num<=4'b0;
end
endcase
end
assign reset = flag1|flag2|~RSTn; //锁存器复位信号
reg oe;
always@(negedge key_start or negedge RSTn or posedge flag1 or posedge flag2 or posedge flag0) //主持人抢答开始
begin
if(!RSTn)
oe<=0;
else
begin
if(flag1|flag0|flag2) //计时器进位信号到来时复位
oe<=0;
else
oe<=1;
end
end
endmodule
数码管显示模块:
module numdisplay(CLK, countdown, Digitron_Out, DigitronCS_Out,score,group);
input CLK;
input [3:0]countdown;
input [11:0]score;
input [3:0]group;
output [7:0]Digitron_Out;
output [5:0]DigitronCS_Out;
reg [3:0]Result1;
reg [3:0]Result2;
reg [7:0]Count;
reg [3:0]SingleNum;
reg [7:0]W_Digitron_Out;
reg [5:0]W_DigitronCS_Out;
parameter _0 = 8'b00111111, _1 = 8'b00000110, _2 = 8'b01011011,
_3 = 8'b01001111, _4 = 8'b01100110, _5 = 8'b01101101,
_6 = 8'b01111101, _7 = 8'b00000111, _8 = 8'b01111111,
_9 = 8'b01101111;
parameter Timex = 8'd200; //divide frequency for select_signal(wei)
always @ ( posedge CLK )
begin
if( Count == Timex ) //this is also clock'count',its frequency is very fast
begin //controls the transfrom of select_signal
Count <= 8'd0;
case(W_DigitronCS_Out)
6'b111110:W_DigitronCS_Out<=6'b111101;
6'b111101:W_DigitronCS_Out<=6'b111011;
6'b111011:W_DigitronCS_Out<=6'b110111;
6'b110111:W_DigitronCS_Out<=6'b101111;
6'b101111:W_DigitronCS_Out<=6'b011111;
6'b011111:W_DigitronCS_Out<=6'b111110;
default:W_DigitronCS_Out<=6'b111110;
endcase
end
else
Count <= Count + 1'b1;
end
assign Digitron_Out = W_Digitron_Out;
assign DigitronCS_Out = W_DigitronCS_Out;
always @ (*)
begin
if(countdown==4'd10)
begin
Result1<=4'd1;
Result2<=4'b0;
end
else
begin
Result1<=4'd0;
Result2<=countdown;
end
end
always@ (*)
begin
case(SingleNum)
4'd0: W_Digitron_Out = _0;
4'd1: W_Digitron_Out = _1;
4'd2: W_Digitron_Out = _2;
4'd3: W_Digitron_Out = _3;
4'd4: W_Digitron_Out = _4;
4'd5: W_Digitron_Out = _5;
4'd6: W_Digitron_Out = _6;
4'd7: W_Digitron_Out = _7;
4'd8: W_Digitron_Out = _8;
4'd9: W_Digitron_Out = _9;
default: W_Digitron_Out = _0;
endcase
end
always@ (*)
begin
case(W_DigitronCS_Out)
6'b101111: SingleNum = Result2; //Display Result and record
6'b011111: SingleNum = Result1;
6'b110111: SingleNum = score[11:8];
6'b111011: SingleNum = score[7:4];
6'b111101: SingleNum = score[3:0];
6'b111110: SingleNum = group;
default: SingleNum = 4'd0;
endcase
end
endmodule
计分模块:
module recorder(status,RSTn,key_latched,score,group,key_right,answer);
input status;
input key_right;
input RSTn;
input [2:0]key_latched;
output reg answer;
output [11:0]score; //record the scores
output [3:0]group;
reg [3:0]score_1;
reg [3:0]score_2;
reg [3:0]score_3;
reg [3:0]group_number;
always @ (*)
begin
case(key_latched)
3'b001:group_number<=4'd1;
3'b010:group_number<=4'd2;
3'b100:group_number<=4'd3;
default:group_number<=4'd0;
endcase
end
always @ (posedge key_right or negedge RSTn)
begin
if(!RSTn)
begin
score_1<=0;
score_2<=0;
score_3<=0;
end
else
case(key_latched)
3'b001:score_1<=score_1+4'd1;
3'b010:score_2<=score_2+4'd1;
3'b100:score_3<=score_3+4'd1;
default:begin
score_1<=score_1;
score_2<=score_2;
score_3<=score_3;
end
endcase
end
always @ (posedge key_right or negedge RSTn or negedge status) //答题键
begin
if(!RSTn|~status) //在加入key_wrong键时逻辑无法实现
answer<=0;
else
answer<=1;
end
assign score = {score_1,score_2,score_3};
assign group = group_number;
endmodule
按键模块:
module switch(input key_in,
input CLK,
output reg key_out); //delay to avoid keys' bounce
wire clk_use;
reg [7:0]counter;
assign clk_use = counter[7];
always @ (posedge CLK)
counter <= counter + 1'b1;
always @ (posedge clk_use)
key_out <= key_in;
endmodule
锁存按键模块:
module latch_key(input rst,
input [2:0]key,
output reg[2:0]q=3'b0,
input start); //latch for key(oe change with fsm)
wire le;
always @ (~key[0] or ~key[1] or ~key[2])
begin
if(rst)
begin
q<=3'b0;
end
else
begin
if(start)
begin
if(le)
q<={~key[2],~key[1],~key[0]};
else
q<=q;
end
else q<=3'b0;
end
end
assign le = (!q);
endmodule
计数器基础计时模块:
module counter_ten(CLK,start_impulse,CLR,countdown_num,flag);
input CLR;
input start_impulse;
input CLK;
output [3:0]countdown_num;
output reg flag=0;
wire clk_1hz;
reg [3:0]counter_10=4'd10;
clk50mto1 clk1hz_ist(CLK,clk_1hz);
always @ (posedge clk_1hz or posedge CLR)
begin
if(CLR)
begin
counter_10<=4'd10;
flag<=0;
end
else
begin
if(start_impulse)
begin
if(counter_10==0)
flag<=1;
else
counter_10 <= counter_10 - 1'b1;
end
else counter_10 <= counter_10;
end
end
assign countdown_num = counter_10;
endmodule
蜂鸣器模块(有误):
module buzzer_m1(
input CLK,
input on,
output reg beep
);
reg en=1;
wire clk_1hz;
reg [19:0] cnt; //20 bit get the maximum number of 1048575;
reg [3:0] clk_1hz_cnt;
//计数模块,计数达到100 000次,计数器清零
always @ (posedge CLK or negedge on)
begin
if(!on)
begin
cnt <= 20'b0;
end
else
begin
if(!en)
cnt <= 20'b0;
else if(cnt < 20'd500000)
cnt <= cnt + 1'b1;
else
cnt <= 20'b0;
end
end
always @ (posedge CLK or negedge on)
begin
if(!on)
beep <= 1'b0;
else if(cnt < 20'd250000)
beep <= 1'b1;
else
beep <= 1'b0;
end
clk50mto1 beep2s(CLK,clk_1hz);
always @ (posedge clk_1hz or negedge on)
begin
if(!on)
clk_1hz_cnt <= 4'd1;
else if(clk_1hz_cnt > 0)
clk_1hz_cnt <= clk_1hz_cnt -4'd1;
else
begin
clk_1hz_cnt <= 4'd1;
en<=0;
end
end
endmodule
文章来源:https://www.toymoban.com/news/detail-758794.html
文章来源地址https://www.toymoban.com/news/detail-758794.html
到了这里,关于用FPGA实现多人抢答器的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!