这次的任务相对上次来说代码书写的更为规范和简洁
任务一、篮球计分器
功能:按照篮球赛赛制进行设计。须具有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