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

网友投稿 272 2022-09-21

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

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

任务一、篮球计分器 功能:按照篮球赛赛制进行设计。须具有24秒倒计时功能,十二分钟计时功能,暂停功能,进球计分功能(1分,2分,3分)等。可再自由发挥。 要求:比分与计时须在数码管实时显示,显示状态可通过按键或者拨码开关切换,计分可通过按键进行设计(不限制)。

设计:

sw1  暂停

sw2  24秒倒计时

sw3  显示计时或者得分

key0 1分

key1 2分

key2 3分

key4计分切换

顶层模块:

module top(ext_clk_25m,ext_rst_n, switch1,switch2,switch3, key_left,key_entr,key_righ,key_down, dtube_cs_n,dtube_data,led ); input ext_clk_25m ;//输入时钟 input ext_rst_n ;//复位信号 input switch1 ;//暂停开关 input switch2 ;//24s使能开关 input switch3 ;//显示切换位 input key_left ;//1分 input key_entr ;//2分 input key_righ ;//3分 input key_down ;//切换记分 output [3:0] dtube_cs_n ;//位选数据位 output [6:0] dtube_data ;//段选数据位 output [3:0] led ; wire clk ;//中间变量 wire [15:0] times_24s ; wire [15:0] times_12m ; wire [15:0] times_sore ; wire en_cnt ; wire en_seg ; wire en_24s ; wire en_sor ; //分频25MHZ变为1HZ div d1( .ext_clk_25m(ext_clk_25m), .ext_rst_n(ext_rst_n), .mclk(clk) ); //控制电路 control con1( .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) ); //计分模块 soring so1( .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_12min c1( .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_24 c2( .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]) ); //数码管显示模块 seg s1( .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) );

module control(ext_clk_25m,ext_rst_n,switch1,switch2,switch3,en_cnt,en_seg,en_24s,en_sore ); input ext_clk_25m; //输入时钟 input ext_rst_n ; //复位信号 input switch1 ; //暂停开关 input switch2 ; //24s使能开关 input switch3 ; //显示切换位 output reg en_cnt ; //暂停计数使能位 output reg en_seg ; //数码管显示使能位 output reg en_24s ; //24s使能位 output reg en_sore ; //计分使能位 reg [24:0] cnt ; //存放计数器的值 parameter TIME = 25'd2500_0000; //数码管特殊状态闪烁计数器模块 always@(posedge ext_clk_25m or negedge ext_rst_n)begin if(ext_rst_n==1'b0)begin cnt <=25'd0; end else if(cnt ==TIME-1'b1)begin cnt <=1'b0; end else begin cnt <=cnt + 1'b1; end end //数码管闪烁模块 always @(posedge ext_clk_25m or negedge ext_rst_n)begin if(ext_rst_n==1'b0)begin en_seg<=1'b0; end else if(switch1==1'b0)begin if(cnt<(TIME/2-1'b1))begin en_seg<=1'b1; end else begin en_seg<=1'b0; end end else begin en_seg<=1'b0; end end //停止计数器计时模块 always @(posedge ext_clk_25m or negedge ext_rst_n)begin if(ext_rst_n==1'b0)begin en_cnt<=1'b0; end else if(switch1==1'b0)begin en_cnt<=1'b1; end else begin en_cnt<=1'b0; end end //开启24s倒计时 always@(posedge ext_clk_25m or negedge ext_rst_n)begin if(ext_rst_n==1'b0)begin en_24s <=1'b0; end else if(switch2==1'b0)begin en_24s <=1'b1; end else begin en_24s <=1'b0; end end //计分和计时显示切换 always@(posedge ext_clk_25m or negedge ext_rst_n)begin if(ext_rst_n==1'b0)begin en_sore <=1'b0; end else if(switch3==1'b0)begin en_sore <=1'b1; end else begin en_sore <=1'b0; end endendmodule

module div(ext_clk_25m,ext_rst_n,mclk ); input ext_clk_25m ;//输入时钟 input ext_rst_n ;//复位端口 output reg mclk ;//输出1Hz reg [23:0] cnt ;//存放计数器的值 parameter TIME= 24'd1250_0000;//时钟25MHz//分频模块,使得输入时钟为25MHz输出时钟为1Hz always@ (posedge ext_clk_25m or negedge ext_rst_n)begin if(!ext_rst_n)begin mclk <=1'b0; cnt <=24'd0; end else if(cnt ==TIME-1'b1)begin mclk <=~mclk; cnt <=1'b0; end else begin cnt <=cnt + 1'b1; end endendmodule

module counter_24(ext_clk_25m,mclk,ext_rst_n,en_24s,en_cnt,times_24s,led ); input ext_clk_25m ;//系统时钟 input mclk ;//时钟信号 input ext_rst_n ;//复位信号 input en_24s ;//24s使能位 input en_cnt ;//计数器停止使能位 output reg [15:0] times_24s ; output led ;//led指示状态 assign led =(times_24s==16'h0000); reg [24:0] cnt ;//存放计数器的值 parameter TIME= 25'd2500_0000; always@ (posedge ext_clk_25m or negedge ext_rst_n)begin if(!ext_rst_n)begin cnt <=25'd0; end else if(cnt ==TIME-1'b1)begin cnt <=1'b0; end else begin cnt <=cnt + 1'b1; end end //计数器模块高位 秒计时(99) always@(posedge ext_clk_25m or negedge ext_rst_n)begin if(!ext_rst_n)begin times_24s[7:4] <=4'h9; end else if(en_24s==1'b0)begin times_24s[7:4] <=4'h9; end else if(en_cnt==1'b1)begin times_24s[7:4] <=times_24s[7:4]; end else if(cnt%25'd25_0000==0)begin if({times_24s[7:4],times_24s[3:0]}==8'h00)begin if({times_24s[15:12],times_24s[11:8]}==8'h00)begin times_24s[7:4] <=4'h0; end else begin times_24s[7:4] <=4'h9; end end else if(times_24s[3:0]==4'h0)begin times_24s[7:4] <=times_24s[7:4]-1'b1; end else begin times_24s[7:4] <=times_24s[7:4]; end end else begin times_24s[7:4] <=times_24s[7:4]; end end //计数器模块低位 秒计时(99) always@(posedge ext_clk_25m or negedge ext_rst_n)begin if(!ext_rst_n)begin times_24s[3:0] <=4'h9; end else if(en_24s==1'b0)begin times_24s[3:0] <=4'h9; end else if(en_cnt==1'b1)begin times_24s[3:0] <=times_24s[3:0]; end else if(cnt%25'd25_0000==0)begin if({times_24s[7:4],times_24s[3:0]}==8'h00) begin if({times_24s[15:12],times_24s[11:8]}==8'h00)begin times_24s[3:0] <=4'h0; end else begin times_24s[3:0] <=4'h9; end end else if(times_24s[3:0]==4'h0)begin times_24s[3:0] <=4'h9; end else begin times_24s[3:0] <=times_24s[3:0]-1'b1; end end else begin times_24s[3:0] <=times_24s[3:0]; end end //计数器模块高位 秒计时 always@(posedge mclk or negedge ext_rst_n) begin if(!ext_rst_n)begin times_24s[15:12] <=4'h2; end else if(en_24s==1'b0)begin times_24s[15:12] <=4'h2; end else if(en_cnt==1'b1)begin times_24s[15:12] <=times_24s[15:12]; end else if({times_24s[15:12],times_24s[11:8]}==8'h00)begin times_24s[15:12] <=4'h0; end else if(times_24s[11:8]==4'h0)begin times_24s[15:12] <=times_24s[15:12]-1'b1; end else begin times_24s[15:12] <=times_24s[15:12]; end end //计数器模块低位 秒计时 always@(posedge mclk or negedge ext_rst_n)begin if(!ext_rst_n)begin times_24s[11:8] <=4'h3; end else if(en_24s==1'b0)begin times_24s[11:8] <=4'h3; end else if(en_cnt==1'b1)begin times_24s[11:8] <=times_24s[11:8]; end else if({times_24s[15:12],times_24s[11:8]}==8'h00) begin times_24s[11:8] <=4'h0; end else if(times_24s[11:8]==4'h0)begin times_24s[11:8] <=4'h9; end else begin times_24s[11:8] <=times_24s[11:8]-1'b1; end endendmodule

module counter_12min(ext_clk_25m,mclk,ext_rst_n,en_24s,en_cnt,times_12m,led ); input ext_clk_25m ;//系统时钟 input mclk ;//时钟信号 input ext_rst_n ;//复位信号 input en_24s ;//24s使能位 input en_cnt ;//计数器停止使能位 output reg[15:0]times_12m ;//15-12分高位 11-8 分低位 7-4秒高位 3-0秒低位 output led ;//led指示状态 assign led =(times_12m==16'h0000); //计数器模块高位 分钟计时 always@(posedge mclk or negedge ext_rst_n)begin if(!ext_rst_n)begin times_12m[15:12] <=4'h1; end else if(en_24s==1'b1)begin times_12m[15:12] <=4'h1; end else if(en_cnt==1'b1)begin times_12m[15:12] <=times_12m[15:12]; end else if({times_12m[15:12],times_12m[11:8]}==8'h00)begin times_12m[15:12] <=4'h0; end else if({times_12m[7:4],times_12m[3:0]}==8'h00) begin if(times_12m[11:8]==4'h0)begin times_12m[15:12] <=times_12m[15:12]-1'b1; end else begin times_12m[15:12] <=times_12m[15:12]; end end else begin times_12m[15:12] <=times_12m[15:12]; end end //计数器模块低位 分钟计时 always@(posedge mclk or negedge ext_rst_n)begin if(!ext_rst_n)begin times_12m[11:8] <=4'h1; end else if(en_24s==1'b1)begin times_12m[11:8] <=4'h1; end else if(en_cnt==1'b1)begin times_12m[11:8] <=times_12m[11:8]; end else if({times_12m[15:12],times_12m[11:8]}==8'h00)begin times_12m[11:8] <=4'h0; end else if({times_12m[7:4],times_12m[3:0]}==8'h00) begin if(times_12m[11:8]==4'h0)begin times_12m[11:8] <=4'h9; end else begin times_12m[11:8] <=times_12m[11:8]-1'b1; end end else begin times_12m[11:8] <=times_12m[11:8]; end end //计数器模块高位 秒计时 always@(posedge mclk or negedge ext_rst_n) begin if(!ext_rst_n)begin times_12m[7:4] <=4'h5; end else if(en_24s==1'b1)begin times_12m[7:4] <=4'h5; end else if(en_cnt==1'b1)begin times_12m[7:4] <=times_12m[7:4]; end else if({times_12m[7:4],times_12m[3:0]}==8'h00)begin if({times_12m[15:12],times_12m[11:8]}==8'h00)begin times_12m[7:4] <=4'h0; end else begin times_12m[7:4] <=4'h5; end end else if(times_12m[3:0]==4'h0)begin times_12m[7:4] <=times_12m[7:4]-1'b1; end else begin times_12m[7:4] <=times_12m[7:4]; end end //计数器模块低位 秒计时 always@(posedge mclk or negedge ext_rst_n)begin if(!ext_rst_n)begin times_12m[3:0] <=4'h9; end else if(en_24s==1'b1)begin times_12m[3:0] <=4'h9; end else if(en_cnt==1'b1)begin times_12m[3:0] <=times_12m[3:0]; end else if({times_12m[7:4],times_12m[3:0]}==8'h00) begin if({times_12m[15:12],times_12m[11:8]}==8'h00)begin times_12m[3:0] <=4'h0; end else begin times_12m[3:0] <=4'h9; end end else if(times_12m[3:0]==4'h0)begin times_12m[3:0] <=4'h9; end else begin times_12m[3:0] <=times_12m[3:0]-1'b1; end end endmodule

module soring(ext_clk_25m,ext_rst_n,key_down,key_left,key_entr,key_righ,en_sore,sore,led ); input ext_clk_25m ;//时钟信号 input ext_rst_n ;//复位信号 input key_down ;//切换记分 input key_left ;//1分 input key_entr ;//2分 input key_righ ;//3分 input en_sore ;//积分使能位 output [15:0] sore ;//15-8 7-0分别为两个队的分数 output reg [1:0] led ;// //按键抖动判断逻辑 wire key; //所有的按键相与的结果,用于按键触发判断 reg[3:0]keyr ; //按键值key的缓冲寄存器 assign key =key_down & key_entr&key_left&key_righ; always@(posedge ext_clk_25m or negedge ext_rst_n)begin if(!ext_rst_n)begin keyr <=4'b1111; end else begin keyr <={keyr[2:0],key}; end end wire key_neg; wire key_pos; assign key_neg=~keyr[2] &keyr [3];//有按键被按下 assign key_pos=keyr[2] &~keyr [3];//有按键被释放 //定时器计数逻辑,用于对按键的消抖的判断 reg [19:0] cnt; always@(posedge ext_clk_25m or negedge ext_rst_n)begin if(!ext_rst_n)begin cnt <=20'd0; end else if(key_pos||key_neg)begin cnt <=20'd0; end else if(cnt <20'd999_999)begin cnt <= cnt +1'b1; end else begin cnt <=20'd0; end end reg[3:0]key_value_c; reg[3:0]key_value_n; //定时采取按键值 always@(posedge ext_clk_25m or negedge ext_rst_n)begin if(!ext_rst_n)begin key_value_c <=4'b1111; key_value_n <=4'b1111; end else begin if(cnt ==20'd999_999)begin key_value_c <={key_down,key_righ,key_entr,key_left}; end else begin key_value_n <=key_value_c; end end end wire [3:0]key_press =key_value_n & ~key_value_c; //计分标志模块 reg sore_f; always@(posedge ext_clk_25m or negedge ext_rst_n)begin if(ext_rst_n==1'b0)begin sore_f<=1'b0; end else if(en_sore==1'b0)begin sore_f<=1'b0; end else if(key_press[3]==1'b1)begin sore_f<=~sore_f; end else begin sore_f<=sore_f; end end //led指示模块 always@(posedge ext_clk_25m or negedge ext_rst_n)begin if(ext_rst_n==1'b0)begin led<=2'b11; end else if(en_sore==1'b0)begin led<=led; end else if(sore_f==1'b0)begin led<=2'b10; end else begin led<=2'b01; end end //第一队比分 reg [7:0] sore_1; assign sore[15:12]=sore_1/10; assign sore[11:8]=sore_1%10; always@(posedge ext_clk_25m or negedge ext_rst_n)begin if(ext_rst_n==1'b0)begin sore_1<=8'h00; end else if(en_sore==1'b0)begin sore_1<=sore_1; end else if(sore_1==8'd99)begin sore_1<=8'h00; end else if(key_press[0]==1'b1&&sore_f==1'b0)begin sore_1<=sore_1+1'b1; end else if(key_press[1]==1'b1&&sore_f==1'b0)begin sore_1<=sore_1+2'b10; end else if(key_press[2]==1'b1&&sore_f==1'b0)begin sore_1<=sore_1+2'b11; end else begin sore_1<=sore_1; end end //第二队比分 reg [7:0] sore_2; assign sore[7:4]=sore_2/10; assign sore[3:0]=sore_2%10; always@(posedge ext_clk_25m or negedge ext_rst_n)begin if(ext_rst_n==1'b0)begin sore_2<=8'h00; end else if(en_sore==1'b0)begin sore_2<=sore_2; end else if(sore_2==8'd99)begin sore_2<=8'h00; end else if(key_press[0]==1'b1&&sore_f==1'b1)begin sore_2<=sore_2+1'b1; end else if(key_press[1]==1'b1&&sore_f==1'b1)begin sore_2<=sore_2+2'b10; end else if(key_press[2]==1'b1&&sore_f==1'b1)begin sore_2<=sore_2+2'b11; end else begin sore_2<=sore_2; end endendmodule

module seg( ext_clk_25m,ext_rst_n, times_24s,times_12m,times_sore, en_24s,en_seg,en_sore, dtube_cs_n,dtube_data ); input ext_clk_25m ;//时钟信号25MHz input ext_rst_n ;//复位信号 input [15:0] times_24s ;//24秒倒计时显示位 input [15:0] times_12m ;//12分倒计时显示位 input [15:0] times_sore ;//分数显示数据 input en_24s ;//24秒倒计时使能端 input en_seg ;//显示使能端 input en_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@ (posedge ext_clk_25m or negedge ext_rst_n)begin if(!ext_rst_n) begin div_cnt <= 8'd0; end else if(div_cnt==17'd80000)begin div_cnt <= 8'd0; end else begin div_cnt <= div_cnt+1'b1; end end //显示当前的数据模块 always @(posedge ext_clk_25m or negedge ext_rst_n)begin if(!ext_rst_n)begin display_num <= 4'h0; end else if(div_cnt < 17'd20000)begin if(en_24s==1'b1)begin display_num <= times_24s[3:0]; end else if(en_sore==1'b1)begin display_num <= times_sore[3:0]; end else begin display_num <= times_12m[3:0]; end end else if((div_cnt>17'd20000)&(div_cnt <17'd40000))begin if(en_24s==1'b1)begin display_num <= times_24s[7:4]; end else if(en_sore==1'b1)begin display_num <= times_sore[7:4]; end else begin display_num <= times_12m[7:4]; end end else if((div_cnt>17'd40000)&(div_cnt < 17'd60000))begin if(en_24s==1'b1)begin display_num <= times_24s[11:8]; end else if(en_sore==1'b1)begin display_num <= times_sore[11:8]; end else begin display_num <= times_12m[11:8]; end end else begin if(en_24s==1'b1)begin display_num <= times_24s[15:12]; end else if(en_sore==1'b1)begin display_num <= times_sore[15:12]; end else begin display_num <= times_12m[15:12]; end end end //段选数据译码模块(共阴数码管) always @(*)begin if(!ext_rst_n)begin dtube_data <= 8'h00; end else begin case(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; endcase end end //位选选译模块 always @(posedge ext_clk_25m or negedge ext_rst_n)begin if(!ext_rst_n) begin dtube_cs_n <= 4'b1111; end else if(en_seg==1'b1)begin dtube_cs_n <= 4'b1111; end else if(div_cnt <= 17'd20000)begin dtube_cs_n <= 4'b1110; end else if((div_cnt>17'd20000)&(div_cnt <=17'd40000))begin dtube_cs_n <= 4'b1101; end else if((div_cnt>17'd40000)&(div_cnt <=17'd60000))begin dtube_cs_n <= 4'b1011; end else if((div_cnt>17'd60000)&(div_cnt <=17'd80000))begin dtube_cs_n <=4'b0111; end else begin dtube_cs_n <= 4'b1111; end end endmodule

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:HLS开发学习-08- Vivado HLS下C_C++测试平台的基本架构
下一篇:私域流量玩家注意了!微信又出新功能,群内直播终于落地!
相关文章

 发表评论

暂时没有评论,来抢沙发吧~