FPGA-篮球计分计时器的设计

简介: FPGA-篮球计分计时器的设计

这次的任务相对上次来说代码书写的更为规范和简洁

任务一、篮球计分器


功能:按照篮球赛赛制进行设计。须具有24秒倒计时功能,十二分钟计时功能,暂停功能,进球计分功能(1分,2分,3分)等。可再自由发挥。

要求:比分与计时须在数码管实时显示,显示状态可通过按键或者拨码开关切换,计分可通过按键进行设计(不限制)。

设计:

sw1  暂停

sw2  24秒倒计时

sw3  显示计时或者得分

key0 1分

key1 2分

key2 3分

key4计分切换

顶层模块:

moduletop(ext_clk_25m,ext_rst_n,
switch1,switch2,switch3,
key_left,key_entr,key_righ,key_down,
dtube_cs_n,dtube_data,led    );
inputext_clk_25m     ;//输入时钟inputext_rst_n       ;//复位信号inputswitch1         ;//暂停开关inputswitch2         ;//24s使能开关inputswitch3         ;//显示切换位inputkey_left        ;//1分inputkey_entr        ;//2分inputkey_righ        ;//3分inputkey_down        ;//切换记分output  [3:0] dtube_cs_n      ;//位选数据位output  [6:0] dtube_data      ;//段选数据位output  [3:0] led             ; 
wireclk             ;//中间变量wire   [15:0] times_24s       ;
wire   [15:0] times_12m       ;
wire   [15:0] times_sore      ;
wireen_cnt          ;
wireen_seg          ;
wireen_24s          ;
wireen_sor          ;
//分频25MHZ变为1HZdivd1(
    .ext_clk_25m(ext_clk_25m),
    .ext_rst_n(ext_rst_n),
    .mclk(clk)
    );
//控制电路controlcon1(
    .ext_clk_25m(ext_clk_25m),
    .ext_rst_n(ext_rst_n),
    .switch1(switch1),
    .switch2(switch2),
    .switch3(switch3),
    .en_cnt(en_cnt),
    .en_seg(en_seg),
    .en_24s(en_24s),
    .en_sore(en_sor)
    );
//计分模块soringso1(
    .ext_clk_25m(ext_clk_25m),
    .ext_rst_n(ext_rst_n),
    .key_down(key_down),
    .key_left(key_left),
    .key_entr(key_entr),
    .key_righ(key_righ),
    .en_sore(en_sor),
    .sore(times_sore),
    .led(led[3:2])
    );
//12分钟倒计时模块counter_12minc1(
    .ext_clk_25m(ext_clk_25m),
    .mclk(clk),
    .ext_rst_n(ext_rst_n),
    .en_24s(en_24s),
    .en_cnt(en_cnt),
    .times_12m(times_12m),
    .led(led[0])
    );
//24分钟倒计时模块counter_24c2(
    .ext_clk_25m(ext_clk_25m),
    .mclk(clk),
    .ext_rst_n(ext_rst_n),
    .en_24s(en_24s),
    .en_cnt(en_cnt),
    .times_24s(times_24s),
    .led(led[1])
    );
//数码管显示模块segs1(
    .ext_clk_25m(ext_clk_25m),
    .ext_rst_n(ext_rst_n),
    .times_24s(times_24s),
    .times_12m(times_12m),
    .times_sore(times_sore),
    .en_24s(en_24s),
    .en_seg(en_seg),
    .en_sore(en_sor),
    .dtube_cs_n(dtube_cs_n),
    .dtube_data(dtube_data) 
    );
modulecontrol(ext_clk_25m,ext_rst_n,switch1,switch2,switch3,en_cnt,en_seg,en_24s,en_sore    );
inputext_clk_25m;        //输入时钟inputext_rst_n  ;        //复位信号inputswitch1    ;        //暂停开关inputswitch2    ;        //24s使能开关inputswitch3    ;        //显示切换位outputregen_cnt     ;        //暂停计数使能位outputregen_seg     ;        //数码管显示使能位outputregen_24s     ;        //24s使能位outputregen_sore    ;        //计分使能位reg  [24:0] cnt        ;        //存放计数器的值parameterTIME=25'd2500_0000;//数码管特殊状态闪烁计数器模块always@(posedgeext_clk_25mornegedgeext_rst_n)beginif(ext_rst_n==1'b0)begincnt<=25'd0;endelseif(cnt==TIME-1'b1)begincnt<=1'b0;endelsebegincnt<=cnt+1'b1;endend//数码管闪烁模块always@(posedgeext_clk_25mornegedgeext_rst_n)beginif(ext_rst_n==1'b0)beginen_seg<=1'b0;endelseif(switch1==1'b0)beginif(cnt<(TIME/2-1'b1))beginen_seg<=1'b1;endelsebeginen_seg<=1'b0;endendelsebeginen_seg<=1'b0;endend//停止计数器计时模块always@(posedgeext_clk_25mornegedgeext_rst_n)beginif(ext_rst_n==1'b0)beginen_cnt<=1'b0;endelseif(switch1==1'b0)beginen_cnt<=1'b1;endelsebeginen_cnt<=1'b0;endend//开启24s倒计时always@(posedgeext_clk_25mornegedgeext_rst_n)beginif(ext_rst_n==1'b0)beginen_24s<=1'b0;endelseif(switch2==1'b0)beginen_24s<=1'b1;endelsebeginen_24s<=1'b0;endend//计分和计时显示切换always@(posedgeext_clk_25mornegedgeext_rst_n)beginif(ext_rst_n==1'b0)beginen_sore<=1'b0;endelseif(switch3==1'b0)beginen_sore<=1'b1;endelsebeginen_sore<=1'b0;endendendmodule
modulediv(ext_clk_25m,ext_rst_n,mclk    );
inputext_clk_25m    ;//输入时钟inputext_rst_n      ;//复位端口outputregmclk           ;//输出1Hzreg      [23:0] cnt            ;//存放计数器的值parameterTIME=24'd1250_0000;//时钟25MHz//分频模块,使得输入时钟为25MHz输出时钟为1Hzalways@ (posedgeext_clk_25mornegedgeext_rst_n)beginif(!ext_rst_n)beginmclk<=1'b0;cnt<=24'd0;endelseif(cnt==TIME-1'b1)beginmclk<=~mclk;
cnt<=1'b0;endelsebegincnt<=cnt+1'b1;endendendmodule
modulecounter_24(ext_clk_25m,mclk,ext_rst_n,en_24s,en_cnt,times_24s,led    );
inputext_clk_25m       ;//系统时钟inputmclk              ;//时钟信号inputext_rst_n         ;//复位信号inputen_24s            ;//24s使能位inputen_cnt            ;//计数器停止使能位outputreg [15:0] times_24s         ;
outputled               ;//led指示状态assignled=(times_24s==16'h0000);reg      [24:0] cnt            ;//存放计数器的值parameterTIME=25'd2500_0000;always@ (posedgeext_clk_25mornegedgeext_rst_n)beginif(!ext_rst_n)begincnt<=25'd0;endelseif(cnt==TIME-1'b1)begincnt<=1'b0;endelsebegincnt<=cnt+1'b1;endend//计数器模块高位 秒计时(99)always@(posedgeext_clk_25mornegedgeext_rst_n)beginif(!ext_rst_n)begintimes_24s[7:4] <=4'h9;      endelseif(en_24s==1'b0)begintimes_24s[7:4] <=4'h9;endelseif(en_cnt==1'b1)begintimes_24s[7:4] <=times_24s[7:4];
endelseif(cnt%25'd25_0000==0)beginif({times_24s[7:4],times_24s[3:0]}==8'h00)beginif({times_24s[15:12],times_24s[11:8]}==8'h00)begintimes_24s[7:4] <=4'h0; endelsebegintimes_24s[7:4] <=4'h9;endendelseif(times_24s[3:0]==4'h0)begintimes_24s[7:4] <=times_24s[7:4]-1'b1;endelsebegintimes_24s[7:4] <=times_24s[7:4];
endendelsebegintimes_24s[7:4] <=times_24s[7:4];
endend//计数器模块低位 秒计时(99)always@(posedgeext_clk_25mornegedgeext_rst_n)beginif(!ext_rst_n)begintimes_24s[3:0] <=4'h9;endelseif(en_24s==1'b0)begintimes_24s[3:0] <=4'h9;endelseif(en_cnt==1'b1)begintimes_24s[3:0] <=times_24s[3:0];
endelseif(cnt%25'd25_0000==0)beginif({times_24s[7:4],times_24s[3:0]}==8'h00) beginif({times_24s[15:12],times_24s[11:8]}==8'h00)begintimes_24s[3:0] <=4'h0; endelsebegintimes_24s[3:0] <=4'h9;endendelseif(times_24s[3:0]==4'h0)begintimes_24s[3:0] <=4'h9;endelsebegintimes_24s[3:0] <=times_24s[3:0]-1'b1;endendelsebegintimes_24s[3:0] <=times_24s[3:0];
endend//计数器模块高位 秒计时always@(posedgemclkornegedgeext_rst_n)
beginif(!ext_rst_n)begintimes_24s[15:12] <=4'h2;        endelseif(en_24s==1'b0)begintimes_24s[15:12] <=4'h2;endelseif(en_cnt==1'b1)begintimes_24s[15:12] <=times_24s[15:12];
endelseif({times_24s[15:12],times_24s[11:8]}==8'h00)begintimes_24s[15:12] <=4'h0; endelseif(times_24s[11:8]==4'h0)begintimes_24s[15:12] <=times_24s[15:12]-1'b1;endelsebegintimes_24s[15:12] <=times_24s[15:12];
endend//计数器模块低位 秒计时always@(posedgemclkornegedgeext_rst_n)beginif(!ext_rst_n)begintimes_24s[11:8] <=4'h3;endelseif(en_24s==1'b0)begintimes_24s[11:8] <=4'h3;endelseif(en_cnt==1'b1)begintimes_24s[11:8] <=times_24s[11:8];
endelseif({times_24s[15:12],times_24s[11:8]}==8'h00) begintimes_24s[11:8] <=4'h0;endelseif(times_24s[11:8]==4'h0)begintimes_24s[11:8] <=4'h9;endelsebegintimes_24s[11:8] <=times_24s[11:8]-1'b1;endendendmodule
modulecounter_12min(ext_clk_25m,mclk,ext_rst_n,en_24s,en_cnt,times_12m,led    );
inputext_clk_25m       ;//系统时钟inputmclk              ;//时钟信号inputext_rst_n         ;//复位信号inputen_24s            ;//24s使能位inputen_cnt            ;//计数器停止使能位outputreg[15:0]times_12m         ;//15-12分高位 11-8 分低位 7-4秒高位 3-0秒低位outputled               ;//led指示状态assignled=(times_12m==16'h0000);//计数器模块高位 分钟计时always@(posedgemclkornegedgeext_rst_n)beginif(!ext_rst_n)begintimes_12m[15:12] <=4'h1;        endelseif(en_24s==1'b1)begintimes_12m[15:12] <=4'h1;endelseif(en_cnt==1'b1)begintimes_12m[15:12] <=times_12m[15:12];
endelseif({times_12m[15:12],times_12m[11:8]}==8'h00)begintimes_12m[15:12] <=4'h0; endelseif({times_12m[7:4],times_12m[3:0]}==8'h00) beginif(times_12m[11:8]==4'h0)begintimes_12m[15:12] <=times_12m[15:12]-1'b1;endelsebegintimes_12m[15:12] <=times_12m[15:12];
endendelsebegintimes_12m[15:12] <=times_12m[15:12];
endend//计数器模块低位 分钟计时always@(posedgemclkornegedgeext_rst_n)beginif(!ext_rst_n)begintimes_12m[11:8] <=4'h1;    endelseif(en_24s==1'b1)begintimes_12m[11:8] <=4'h1;endelseif(en_cnt==1'b1)begintimes_12m[11:8] <=times_12m[11:8];
endelseif({times_12m[15:12],times_12m[11:8]}==8'h00)begintimes_12m[11:8] <=4'h0; endelseif({times_12m[7:4],times_12m[3:0]}==8'h00) beginif(times_12m[11:8]==4'h0)begintimes_12m[11:8] <=4'h9;endelsebegintimes_12m[11:8] <=times_12m[11:8]-1'b1;endendelsebegintimes_12m[11:8] <=times_12m[11:8];
endend//计数器模块高位 秒计时always@(posedgemclkornegedgeext_rst_n)
beginif(!ext_rst_n)begintimes_12m[7:4] <=4'h5;  endelseif(en_24s==1'b1)begintimes_12m[7:4] <=4'h5;endelseif(en_cnt==1'b1)begintimes_12m[7:4] <=times_12m[7:4];
endelseif({times_12m[7:4],times_12m[3:0]}==8'h00)beginif({times_12m[15:12],times_12m[11:8]}==8'h00)begintimes_12m[7:4] <=4'h0;endelsebegintimes_12m[7:4] <=4'h5;endendelseif(times_12m[3:0]==4'h0)begintimes_12m[7:4] <=times_12m[7:4]-1'b1;endelsebegintimes_12m[7:4] <=times_12m[7:4];
endend//计数器模块低位 秒计时always@(posedgemclkornegedgeext_rst_n)beginif(!ext_rst_n)begintimes_12m[3:0] <=4'h9;    endelseif(en_24s==1'b1)begintimes_12m[3:0] <=4'h9;endelseif(en_cnt==1'b1)begintimes_12m[3:0] <=times_12m[3:0];
endelseif({times_12m[7:4],times_12m[3:0]}==8'h00) beginif({times_12m[15:12],times_12m[11:8]}==8'h00)begintimes_12m[3:0] <=4'h0;endelsebegintimes_12m[3:0] <=4'h9;endendelseif(times_12m[3:0]==4'h0)begintimes_12m[3:0] <=4'h9;endelsebegintimes_12m[3:0] <=times_12m[3:0]-1'b1;endendendmodule
modulesoring(ext_clk_25m,ext_rst_n,key_down,key_left,key_entr,key_righ,en_sore,sore,led    );
inputext_clk_25m   ;//时钟信号inputext_rst_n     ;//复位信号inputkey_down      ;//切换记分inputkey_left      ;//1分inputkey_entr      ;//2分inputkey_righ      ;//3分inputen_sore       ;//积分使能位output     [15:0] sore          ;//15-8 7-0分别为两个队的分数outputreg  [1:0] led           ;////按键抖动判断逻辑wirekey;  //所有的按键相与的结果,用于按键触发判断reg[3:0]keyr ; //按键值key的缓冲寄存器assignkey=key_down&key_entr&key_left&key_righ;
always@(posedgeext_clk_25mornegedgeext_rst_n)beginif(!ext_rst_n)beginkeyr<=4'b1111;endelsebeginkeyr<={keyr[2:0],key};
endendwirekey_neg;
wirekey_pos;
assignkey_neg=~keyr[2] &keyr [3];//有按键被按下assignkey_pos=keyr[2] &~keyr [3];//有按键被释放//定时器计数逻辑,用于对按键的消抖的判断reg [19:0] cnt;
always@(posedgeext_clk_25mornegedgeext_rst_n)beginif(!ext_rst_n)begincnt<=20'd0;endelseif(key_pos||key_neg)begincnt<=20'd0;endelseif(cnt<20'd999_999)begincnt<=cnt+1'b1;endelsebegincnt<=20'd0;endendreg[3:0]key_value_c;
reg[3:0]key_value_n;
//定时采取按键值always@(posedgeext_clk_25mornegedgeext_rst_n)beginif(!ext_rst_n)beginkey_value_c<=4'b1111;key_value_n<=4'b1111;endelsebeginif(cnt==20'd999_999)beginkey_value_c<={key_down,key_righ,key_entr,key_left};
endelsebeginkey_value_n<=key_value_c;
endendendwire [3:0]key_press=key_value_n&~key_value_c;
//计分标志模块regsore_f;
always@(posedgeext_clk_25mornegedgeext_rst_n)beginif(ext_rst_n==1'b0)beginsore_f<=1'b0;endelseif(en_sore==1'b0)beginsore_f<=1'b0;endelseif(key_press[3]==1'b1)beginsore_f<=~sore_f;
endelsebeginsore_f<=sore_f;
endend//led指示模块always@(posedgeext_clk_25mornegedgeext_rst_n)beginif(ext_rst_n==1'b0)beginled<=2'b11;endelseif(en_sore==1'b0)beginled<=led;
endelseif(sore_f==1'b0)beginled<=2'b10;endelsebeginled<=2'b01;endend//第一队比分reg [7:0] sore_1;
assignsore[15:12]=sore_1/10;
assignsore[11:8]=sore_1%10;
always@(posedgeext_clk_25mornegedgeext_rst_n)beginif(ext_rst_n==1'b0)beginsore_1<=8'h00;endelseif(en_sore==1'b0)beginsore_1<=sore_1;
endelseif(sore_1==8'd99)beginsore_1<=8'h00;endelseif(key_press[0]==1'b1&&sore_f==1'b0)beginsore_1<=sore_1+1'b1;endelseif(key_press[1]==1'b1&&sore_f==1'b0)beginsore_1<=sore_1+2'b10;endelseif(key_press[2]==1'b1&&sore_f==1'b0)beginsore_1<=sore_1+2'b11;endelsebeginsore_1<=sore_1;
endend//第二队比分reg [7:0] sore_2;
assignsore[7:4]=sore_2/10;
assignsore[3:0]=sore_2%10;
always@(posedgeext_clk_25mornegedgeext_rst_n)beginif(ext_rst_n==1'b0)beginsore_2<=8'h00;endelseif(en_sore==1'b0)beginsore_2<=sore_2;
endelseif(sore_2==8'd99)beginsore_2<=8'h00;endelseif(key_press[0]==1'b1&&sore_f==1'b1)beginsore_2<=sore_2+1'b1;endelseif(key_press[1]==1'b1&&sore_f==1'b1)beginsore_2<=sore_2+2'b10;endelseif(key_press[2]==1'b1&&sore_f==1'b1)beginsore_2<=sore_2+2'b11;endelsebeginsore_2<=sore_2;
endendendmodule
moduleseg( ext_clk_25m,ext_rst_n,
times_24s,times_12m,times_sore,
en_24s,en_seg,en_sore,
dtube_cs_n,dtube_data        );
inputext_clk_25m    ;//时钟信号25MHzinputext_rst_n      ;//复位信号input    [15:0] times_24s      ;//24秒倒计时显示位input    [15:0] times_12m      ;//12分倒计时显示位input    [15:0] times_sore     ;//分数显示数据inputen_24s         ;//24秒倒计时使能端inputen_seg         ;//显示使能端inputen_sore       ;//积分使能端output   [ 3:0] dtube_cs_n     ;//段选数据位output   [ 6:0] dtube_data     ;//位选数据位reg      [ 3:0] dtube_cs_n     ;
reg      [ 6:0] dtube_data     ;
reg      [ 3:0] display_num    ;//当前显示数据reg      [16:0] div_cnt        ;//延时计数器计数位//延时计数器模块always@ (posedgeext_clk_25mornegedgeext_rst_n)beginif(!ext_rst_n) begindiv_cnt<=8'd0;endelseif(div_cnt==17'd80000)begindiv_cnt<=8'd0;        endelsebegindiv_cnt<=div_cnt+1'b1;endend//显示当前的数据模块always@(posedgeext_clk_25mornegedgeext_rst_n)beginif(!ext_rst_n)begindisplay_num<=4'h0;endelseif(div_cnt<17'd20000)beginif(en_24s==1'b1)begindisplay_num<=times_24s[3:0];
endelseif(en_sore==1'b1)begindisplay_num<=times_sore[3:0];
endelsebegindisplay_num<=times_12m[3:0];
endendelseif((div_cnt>17'd20000)&(div_cnt <17'd40000))beginif(en_24s==1'b1)begindisplay_num<=times_24s[7:4];
endelseif(en_sore==1'b1)begindisplay_num<=times_sore[7:4];
endelsebegindisplay_num<=times_12m[7:4];
endendelseif((div_cnt>17'd40000)&(div_cnt < 17'd60000))beginif(en_24s==1'b1)begindisplay_num<=times_24s[11:8];
endelseif(en_sore==1'b1)begindisplay_num<=times_sore[11:8];
endelsebegindisplay_num<=times_12m[11:8];
endendelsebeginif(en_24s==1'b1)begindisplay_num<=times_24s[15:12];
endelseif(en_sore==1'b1)begindisplay_num<=times_sore[15:12];
endelsebegindisplay_num<=times_12m[15:12];
endendend//段选数据译码模块(共阴数码管)always@(*)beginif(!ext_rst_n)begindtube_data<=8'h00;endelsebegincase(display_num) 
4'h0: dtube_data <= 8'h3f;
4'h1: dtube_data <= 8'h06;
4'h2: dtube_data <= 8'h5b;
4'h3: dtube_data <= 8'h4f;
4'h4: dtube_data <= 8'h66;
4'h5: dtube_data <= 8'h6d;
4'h6: dtube_data <= 8'h7d;
4'h7: dtube_data <= 8'h07;
4'h8: dtube_data <= 8'h7f;
4'h9: dtube_data <= 8'h6f;
default:dtube_data<=8'h00;endcaseendend//位选选译模块always@(posedgeext_clk_25mornegedgeext_rst_n)beginif(!ext_rst_n) begindtube_cs_n<=4'b1111;endelseif(en_seg==1'b1)begindtube_cs_n<=4'b1111;endelseif(div_cnt<=17'd20000)begindtube_cs_n<=4'b1110;endelseif((div_cnt>17'd20000)&(div_cnt <=17'd40000))begindtube_cs_n<=4'b1101;endelseif((div_cnt>17'd40000)&(div_cnt <=17'd60000))begindtube_cs_n<=4'b1011;endelseif((div_cnt>17'd60000)&(div_cnt <=17'd80000))begindtube_cs_n<=4'b0111;endelsebegindtube_cs_n<=4'b1111;endendendmodule
目录
相关文章
|
7月前
【错题集-编程题】空调遥控(二分 / 滑动窗口)
【错题集-编程题】空调遥控(二分 / 滑动窗口)
【单片机毕业设计】篮球计分系统
【单片机毕业设计】篮球计分系统
73 0
|
传感器 算法 Linux
【乌拉喵.教程】不同负载下继电器的保护电路设计(解决继电器触点粘接的问题)
【乌拉喵.教程】不同负载下继电器的保护电路设计(解决继电器触点粘接的问题)
152 0
【乌拉喵.教程】不同负载下继电器的保护电路设计(解决继电器触点粘接的问题)
【单片机期中测试】11.交通灯
【单片机期中测试】11.交通灯
62 0
|
算法 JavaScript 前端开发
温习数据算法—罗盘时钟
温习数据算法—罗盘时钟
|
存储 编解码 芯片
基于单片机设计的遥控数字音量控制D类功率放大器设计
基于单片机设计的遥控数字音量控制D类功率放大器设计
284 1
基于单片机设计的遥控数字音量控制D类功率放大器设计
|
传感器 机器人 vr&ar
可以吃的「逻辑门」:这些科学家把甜点做成了「迷你计算机」
可以吃的「逻辑门」:这些科学家把甜点做成了「迷你计算机」
|
芯片
数电实验 数字电子钟设计 基于quartus 实现计时校时闹钟秒表稍复杂音频 分享电路图设计以及工程文件
数电实验 数字电子钟设计 基于quartus 实现计时校时闹钟秒表稍复杂音频 分享电路图设计以及工程文件
1611 2
数电实验 数字电子钟设计 基于quartus 实现计时校时闹钟秒表稍复杂音频 分享电路图设计以及工程文件
|
传感器
多功能手持读数仪VH501TC振激励方法和激励电压
采集仪对振弦传感器激励:也称为“激振”,是振弦类传感器频率数据获取的必须过程,仅当传感器收 到合适的激励信号后才能产生自振,而仅当振弦传感器产生自振后才能输出频率信号,进一步的,读数电路会检测并读取振弦传感器的自振信号,才能通过计算得到 振动频率值。振弦传感器的激励信号(能够使传感器产生自振的外部信号)一般分 为两类,一类为高压短促脉冲,一类为特定频率的多组连续低压脉冲信号。
多功能手持读数仪VH501TC振激励方法和激励电压
数字逻辑电路设计实验:计时器/奇数骑
数字逻辑电路设计实验:计时器/奇数骑
62 0