Verilog实现八人抢答器

一设计需求

抢答器由FPGA中verilog语言编写,一共有六个模块,分别为:daojishi,divscandisplay,fmq2,shuju,qqddqq组成,可实现八人抢答功能,并实现30s倒计时,当倒计时时间为0时无人抢答会使蜂鸣器报警,当有人成功抢答时会显示抢答选手序号并产生报警。qqddqq为顶层文件,级联各个模块

二模块划分和代码

1、抢答模块

为实现八人抢答功能模块,选手成功抢答会显示序号并产生报警

module shuju(clk,start,xuan,answer,EnFlat);
input start,clk;
input[7:0] xuan;
output reg EnFlat;
output reg [3:0] answer;

always@(posedge clk)
begin
	if(start==1'b0)
	begin
	EnFlat=1'b1;//锁存置高
	end
	else if(EnFlat)
	begin
		case(xuan)//选手抢答,选手按下时输出自己序号,并使锁存置0达到锁存效果
		8'b00000001:
			begin
				EnFlat<=1'b0;
				answer<=8'b00000001;
			end
		8'b00000010:
			begin
				EnFlat<=1'b0;
				answer<=8'b00000010;
			end
		8'b00000100:
			begin
				EnFlat<=1'b0;
				answer<=8'b00000011;
			end
		8'b00001000:
			begin
				EnFlat<=1'b0;
				answer<=8'b00000100;
			end
		8'b00010000:
			begin
				EnFlat<=1'b0;
				answer<=8'b00000101;
			end
		8'b00100000:
			begin
				EnFlat<=1'b0;
				answer<=8'b00000110;
			end
		8'b01000000:
			begin
				EnFlat<=1'b0;
				answer<=8'b00000111;
			end
		8'b10000000:
			begin
				EnFlat<=1'b0;
				answer<=8'b00001000;
			end
				default:answer<=0;
		  endcase
	end
end
endmodule

2、倒计时模块

实现30s倒计时模块

module daojishi (q,qout,reset,cout,clk);
output reg [7:0] qout;
output cout;
reg cout;
input reset,clk,q;
always@(posedge clk or negedge reset )

begin
	if(!reset) begin
	qout <= 8'h30;
	cout <=0;
	end
	else if(q)
	begin
		if(qout[3:0]==0) //判断十位是否为0
		begin
			if(qout[7:4]==0)	//判断个位是否为0
			begin
				cout <=1;//全为0时给一个cout信号给蜂鸣器
				qout <=0;//使倒计时一直为0
			end
			else
			begin
			qout[3:0]<=9;//个位为0,十位不为0,让个位为9
			qout[7:4]<=qout[7:4]-1;//让十位减一
			end
		end
		else 
		begin
			qout[3:0]<= qout[3:0]-1;//若都不为0,让个位减1
		end
	end
end
endmodule
		

3、分频模块

module div(rst_n,clk_in,clk_out);
    parameter period=5,duty=2;
	 input rst_n,clk_in;
	 output reg clk_out;
	 
reg [25:0] counter;

always@(posedge clk_in or negedge rst_n)
 begin
  if(!rst_n)
  begin
    counter<=0;
	 clk_out<=0;
  end
  else  
  begin
    if(counter>=period)
	    counter<=0;
	 else
	    counter<=counter+1;
		
	 if(counter>duty)
	    clk_out<=1;
	 else
	    clk_out<=0;
	 end

  end
endmodule

4、扫描显示模块

为扫描显示模块,一个用了四个数码管显示,一个显示选手抢答序号,两个分别显示倒计时十位和个位,一个显示横杠分开选手序号和倒计时

module scandisplay(clk,mdata0,ddata0,ddata1,seg_sel,seg7);
   input clk;
	input[3:0]mdata0,ddata1,ddata0;
	output reg[2:0] seg_sel;
	output reg[7:0] seg7;
	reg[3:0] data;
	reg cnt;
	always@(posedge clk)
	begin
	    if(seg_sel<3)
         seg_sel<=seg_sel+1;
		else
		    seg_sel<=0;
			 end
			 always@(seg_sel)
			 begin
		case(seg_sel)
		0:  data<=ddata0;//显示倒计时的个位
		1:  data<=ddata1;//显示倒计时的十位
		2:  data<=11;//一个横杆
		3:  data<=mdata0;//选手号码
		default:data<=0;
		endcase
   end
	always@(data)
	begin
	  case(data)
	  0:seg7<=8'b00111111;
	  1:seg7<=8'b00000110;	  
	  2:seg7<=8'b01011011;
	  3:seg7<=8'b01001111;
	  4:seg7<=8'b01100110;
	  5:seg7<=8'b01101101;
	  6:seg7<=8'b01111101;
	  7:seg7<=8'b00000111;
	  8:seg7<=8'b01111111;
	  9:seg7<=8'b01101111;
	  default:seg7<=8'b01000000;
	endcase
	end
	endmodule

5、蜂鸣器

module fmq2(q,clk,cout,beep);
input clk,q;	
input cout;
output reg beep;

always @ (posedge clk)
	begin
		if(cout==1||q==1) beep=0;//蜂鸣器为低时响

		else beep=1;
	end
endmodule

三、顶层

请添加图片描述

四、一些问题及总结

1、第一次完成fpga编写,完成八人抢答器,其中一些变量命名中英文混合,可能看的有点恶心。
2、写代码时一些逻辑问题经过多次改进才最终实现目标。

  • 20
    点赞
  • 172
    收藏
    觉得还不错? 一键收藏
  • 26
    评论
评论 26
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值