智能抢答器项目设计
功能如下:
1.主持人按下清零键,可清除所有信息
2.两位选手进行抢答,当一位选手按下抢答键,其他选手再按无效,数码管显示选手序号。
3.当剩余时间15s时,开始倒计时,剩余时间为0的时候,表示回答时间到
4.当时间到时,蜂鸣器响5s表示时间到,进行下一轮抢答。
此项目分为四个模块,分别是按键消抖模块、数据处理模块、倒计时模块、数码管显示模块**
数据处理模块是用来产生start信号,通知倒计时模块,开始倒计时,同时数据处理模块要输出当前抢答者的序号,倒计时模块的输入信号为start信号,输出倒计时的时间,同时对蜂鸣器进行处理,数码管显示模块显示当前序号以及倒计时时间。
如下是源代码:
顶层模块
> module
> zhinengqiangdaqi(clk,rst_n,clear,key1,key2,
> seg_sel,seg_led,beep);
> input clk,rst_n;
> input clear;
> input key1,key2;
> output beep;
> output [7:0] seg_led;
> output [3:0] seg_sel;
> wire clear_value,key1_value,key2_value;
> wire start;
> wire [3:0] xuhao_1;
> wire [3:0] xuhao_2;
> wire beep;
> wire [3:0] xianshi_1;
> wire [3:0] xianshi_2;
>
> anjian inst1(
> .clk(clk),
> .rst_n(rst_n),
> .key(clear),
> .key_value(clear_value)
> );
> anjian inst2(
> .clk(clk),
> .rst_n(rst_n),
> .key(key1),
> .key_value(key1_value)
> );
> anjian inst3(
> .clk(clk),
> .rst_n(rst_n),
> .key(key2),
> .key_value(key2_value)
> );
>
> shujuchuli u2(
> .clk(clk),
> .rst_n(rst_n),
> .clear(clear_value),
> .key1(key1_value),
> .key2(key2_value),
> .start(start),
> .xuhao_1(xuhao_1),
> .xuhao_2(xuhao_2)
> );
>
> daojishi u3(
> .clk(clk),
> .rst_n(rst_n),
> .start(start),
> .beep(beep),
> .xianshi_1(xianshi_1),
> .xianshi_2(xianshi_2)
> );
> shumaxianshi u4(
> .clk(clk),
> .rst_n(rst_n),
> .xianshi_1(xianshi_1),
> .xianshi_2(xianshi_2),
> .xuhao_1(xuhao_1),
> .xuhao_2(xuhao_2),
> .seg_sel(seg_sel),
> .seg_led(seg_led)
> );
> endmodule
按键消抖模块
> module anjian(clk,rst_n,key,key_value);
> input clk,rst_n;
> input key;
> output reg key_value;
> reg key_reg;
> reg [20:0] cnt; //1000000100
> always @(posedge clk or negedge rst_n) begin
> if(!rst_n)
> key_reg <= 0;
> else
> key_reg <= key;
> end
>
> always @(posedge clk or negedge rst_n) begin
> if(!rst_n)
> cnt <= 0;
> else begin
> if(key!=key_reg)
> cnt <= 1000000;
> else begin
> if(cnt>0)
> cnt <= cnt-1;
> else
> cnt <= cnt;
> end
> end
> end
> //key_value
> always @(posedge clk or negedge rst_n) begin
> if(!rst_n)
> key_value <= 1;
> else begin
> if(cnt==1)
> key_value <= key;
> else
> key_value <= key_value;
> end
> end
> endmodule
数据处理模块
> module shujuchuli(clk,rst_n,clear,key1,key2,
> start,xuhao_1,xuhao_2);
> input clk,rst_n;
> input clear,key1,key2;
> output reg start;
> output reg [3:0] xuhao_1;
> output reg [3:0] xuhao_2;
> reg block;
> always @(posedge clk or negedge rst_n) begin
> if(!rst_n)
> begin
> start <= 0;
> block <= 0;
> end
> else begin
> if(clear==0)
> > begin
> > start <= 0;
> block <= 0;
> end
> else if(key1==0)
> > begin
> > start <= 1;
> > block <= 1;
> > end
> else if(key2==0)
> > begin
> > start <= 1;
> > block <= 1;
> > end
> end
> end
> >
> > always @(posedge clk or negedge rst_n)
> begin
> if(!rst_n)
> begin
> > xuhao_1 <= 0;
> > xuhao_2 <= 0;
> end
> else begin
> if(clear==0)
> > begin
> > xuhao_1 <= 4'd15;
> > xuhao_2 <= 4'd15;
> end
> else if(key1==0)
> > begin
> > if(block==0)
> > begin
> > xuhao_1 <= 1;
> > xuhao_2 <= 5;
> > end
> > else
> > begin
> > xuhao_1 <= xuhao_1;
> > xuhao_2 <= xuhao_2;
> > end
> end
> > else if(key2==0)
> > begin
> > if(block==0)
> > begin
> > xuhao_1 <= 1;
> > xuhao_2 <= 6;
> > end
> > else
> > begin
> > xuhao_1 <= xuhao_1;
> > xuhao_2 <= xuhao_2;
> > end
> > end
> > end
> > end
> > endmodule
倒计时模块
> module daojishi(clk,rst_n,start,beep,xianshi_1,xianshi_2);
> input clk,rst_n,start;
> output reg beep; //蜂鸣器响5s
> output reg [3:0] xianshi_1;
> output reg [3:0] xianshi_2;
> reg flag; //1s定时标志
> reg [25:0] cnt; //50_000_000
> reg [5:0] count; //倒计时
> reg [2:0] beep_cnt; //倒计时5s
> always @(posedge clk or negedge rst_n) begin
> if(!rst_n)
> cnt <= 0;
> else begin
> if(start==1)
> begin
> if(cnt==0)
> cnt <= 50000000;
> else
> cnt <= cnt-1;
> end
> else
> cnt <= 50000000; //start为0的时候,cnt为500
> end
> end
>
> // 1s定时标志
> always @(posedge clk or negedge rst_n) begin
> if(!rst_n)
> flag <= 0;
> else begin
> if(start==1)
> begin
> if(cnt==1)
> flag <= 1;
> else
> flag <= 0;
> end
> else
> flag <= 0;
> end
> end
>
> //倒计时 always @(posedge clk or negedge rst_n) begin
> if(!rst_n)
> count <= 0;
> else begin
> if(start==1)
> begin
> if(flag==1) begin
> if(count==0)
> count <= 0;
> else
> count < =count-1;
> end
> else
> count <= count;
> end
> else
> count <= 30;
> end
> end
>
> //xianshi 15s计时
> always @(posedge clk or negedge rst_n) begin
> if(!rst_n)
> begin
> xianshi_1 <= 0;
> xianshi_2 <= 0;
> end
> else begin
> if(count>0 && count<15)
> begin
> xianshi_1 <= count/10;
> xianshi_2 <= count%10;
> end
> else
> begin
> xianshi_1 <= 0;
> xianshi_2 <= 0;
> end
> end
> end
>
>
> //beep_cnt
> always @(posedge clk or negedge rst_n) begin
> if(!rst_n)
> beep_cnt <= 0;
> else begin
> if(start==1)
> if(flag==1)
> if(count==0)
> if(beep_cnt==0)
> beep_cnt <= 0;
> else
> beep_cnt <= beep_cnt-1;
> else
> beep_cnt <= beep_cnt;
> else
> beep_cnt <= beep_cnt;
> else
> beep_cnt < =6;
> end
> end
>
> //beep
> always @(posedge clk or negedge rst_n) begin
> if(!rst_n)
> beep <= 1;
> else begin
> if(beep_cnt > 0&&beep_cnt <= 5)
> beep <= 0;
> else
> beep <= 1;
> end
> end
> endmodule
数码管显示模块
> module
> shumaxianshi(clk,rst_n,xianshi_1,xianshi_2,
> xuhao_1,xuhao_2,seg_sel,seg_led);
> input clk,rst_n;
> input [3:0] xianshi_1;
> input [3:0] xianshi_2;
> input [3:0] xuhao_1;
> input [3:0] xuhao_2;
> output reg [3:0] seg_sel;
> output reg [7:0] seg_led;
> parameter TIME_1ms=50000; //50000
> reg clk_1ms;
> reg [15:0] cnt;
> reg [3:0] data;
> reg [1:0] cnt_sel;
> always @(posedge clk or negedge rst_n)
> begin
> if(!rst_n)
> cnt <= 0;
> else begin
> if(cnt==TIME_1ms/2-1)
> cnt <= 0;
> else
> cnt <= cnt+1;
> end
> end
> //降低频率
> always @(posedge clk or negedge rst_n) begin
> if(!rst_n)
> clk_1ms <= 0;
> else begin
> if(cnt==TIME_1ms/2-1)
> clk_1ms <= ~clk_1ms;
> else
> clk_1ms <= clk_1ms;
> end
> end
>
> //扫描数码管
> always @(posedge clk_1ms or negedge rst_n) begin
> if(!rst_n)
> cnt_sel <= 0;
> else begin
> if(cnt_sel==3)
> cnt_sel <= 0;
> else
> cnt_sel <= cnt_sel+1;
> end
> end
>
> always @(posedge clk or negedge rst_n) begin
> if(!rst_n)
> seg_sel <= 4'b1111;
> else
> case(cnt_sel)
> 4'd0: seg_sel <= 4'b1110;
> 4'd1: seg_sel <= 4'b1101;
> 4'd2: seg_sel <= 4'b1011;
> 4'd3: seg_sel <= 4'b0111;
> endcase
> end
>
> //给段选数据
> always @(posedge clk or negedge rst_n) begin
> if(!rst_n)
> data <= 4'b0000;
> else begin
> case(seg_sel)
> 4'b1110: data <= xianshi_1;
> 4'b1101: data <= xianshi_2;
> 4'b1011: data <= xuhao_1;
> 4'b0111: data <= xuhao_2;
> endcase
> end
> end
> //译码模块
> always@(posedge clk or negedge rst_n) begin
> if(!rst_n)
> seg_led <= 8'd0;
> else begin
> case (data)
> 4'h0:seg_led <= 8'b11000000;
> 4'h1:seg_led <= 8'b11111001;
> 4'h2:seg_led <= 8'b10100100;
> 4'h3:seg_led <= 8'b10110000;
> 4'h4:seg_led <= 8'b10011001;
> 4'h5:seg_led <= 8'b10010010;
> 4'h6:seg_led <= 8'b10000010;
> 4'h7:seg_led <= 8'b11111000;
> 4'h8:seg_led <= 8'b10000000;
> 4'h9:seg_led <= 8'b10010000;
> 4'ha:seg_led <= 8'b10001000;
> 4'hb:seg_led <= 8'b10000011;
> 4'hc:seg_led <= 8'b11000110;
> 4'hd:seg_led <= 8'b10100001;
> 4'he:seg_led <= 8'b10000110;
> 4'hf:seg_led <= 8'b10001110;
> endcase
> end
> end
> endmodule
测试代码:
> `timescale 1ns/1ns
> module zhinengqiangdaqi_tb;
> reg clk,rst_n;
> reg clear,key1,key2;
> wire start;
> wire [3:0] xuhao_1;
> wire [3:0] xuhao_2;
> always #10 clk=~clk;
> initial begin
> clk=0;
> rst_n=0;
> #100
> rst_n=1;
> #400
> clear=0;
> key1=1;
> key2=1;
> #400
> clear=1;
> key1=0;
> key2=1;
> #600
> clear=1;
> key1=1;
> key2=0;
> #600 clear=0; key1=1; key2=1;
> #600 clear=1; key1=1; key2=0;
> #600 clear=1; key1=0; key2=1;
> #2000
> $stop;
> end
> zhili inst(.clk(clk),
> .rst_n(rst_n),
> .clear(clear),
> .key1(key1),
> .key2(key2),
> .start(start),
> .xuhao_1(xuhao_1),
> .xuhao_2(xuhao_2)
> );
> endmodule
经过上板验证后成功!!!