赞
踩
数字钟是数电实验最后一个用verilog写的实验,稍微有些难度,现在再回来看之前写的代码还是有很多不足和问题,但在当时并没有注意到。
1.60进制计数
在计数模块中就考虑到修改时间时的计数修改,便于修改时间
60进制需要考虑到进位,为了能保证同时进位,需要在计数58时就将下一个计数器的计数使能开启,计数59时计数使能关闭
module count60(input clk,input jinwei,input changen,input reset,input [1:0]button,output reg [7:0]q,output reg s); reg [5:0]count; always@(posedge clk) begin if(reset==0||(count>(6'd59))) begin count<=0;s<=0; end else if(changen!=0) case(button) 2'b10:begin count<=(count==6'd59)?0:(count+1);s<=s; end 2'b01:begin count<=(count==0)?(6'd58):(count-1);s<=s; end endcase else if(jinwei==0) begin count<=count;s<=s; end else if(count==6'd58) begin count<=count+1;s<=1; end else if(count==6'd59) begin count<=0;s<=0; end else begin count<=count+1;s<=0; end q[3:0]<=count%(4'd10); q[7:4]<=count/(4'd10); end endmodule
2.24进制计数模块
changen为修改计数使能,当其值不为0时,根据按键情况进行计数加减,每个时钟有效沿来时加减一次
输出为q[7:0],高4位为计数十位,低4位为计数个位
module count24(input clk,input jinwei,input changen,input reset,input [1:0]button,output reg [7:0]q); reg [4:0]count; always@(posedge clk) begin if(reset==0||(count>(5'd23))) count<=0; else if(changen!=0) case(button) 2'b10:count<=(count==5'd23)?0:(count+1); 2'b01:count<=(count==0)?(5'd23):(count-1); endcase else if(jinwei==0) count<=count; else if(count==5'd23) count<=0; else count<=count+1; q[3:0]<=count%(4'd10); q[7:4]<=count/(4'd10); end endmodule
采用两个标志位chg1,chg2。五向按键中键进行修改使能与修改结束,chg1为其标志位。
再由左右按键选择需要修改的时钟
module timechange(input clk,input [2:0]button ,output reg[2:0]changen); reg chg1=0; reg chg2=0; always@(posedge button[2]) begin if (chg1==0) chg1<=1; else chg1<=0; end always@(posedge clk) begin if(chg1==1&&chg2==0) begin changen<=3'b100; chg2<=1; end else if(chg1==1&&chg2==1) case(button[1:0]) 2'b10:changen<={changen[1:0],changen[2]}; 2'b01:changen<={changen[0],changen[2:1]}; endcase else if(chg1==0) begin changen<=3'b000; chg2<=0; end end endmodule
这个模块挺折磨人的,分频没做好的话显示的就是一塌糊涂的东西,我当时搞了好久
当修改使能时,对应的计数器会闪烁。再由count_t轮流计数,分别亮灯显示各计数器的各位
module print(input clk,input [7:0]s,input [7:0]m,input [7:0]h,input [2:0]changen,output reg [5:0]led1,output reg [6:0]led2); reg [3:0] num; reg [26:0] temp;//分频率器的中间变量 reg [25:0] tempc=0; reg clk_t; reg [2:0]count_t=0; wire clk_tc; wire count; assign count=count_t; assign clk_tc=tempc[25]; parameter S0=7'b0000001,S1=7'b1111001,S2=7'b0010010,S3=7'b0000110,S4=7'b1001100, S5=7'b0100100,S6=7'b0100000,S7=7'b0001111,S8=7'b0000000,S9=7'b0000100; always@(posedge clk)//时钟的分频模块 begin if(temp<27'd1000)//clk_t频率100KHZ temp<=temp+1; else begin temp<=0; clk_t<=~clk_t; end end always@(posedge clk)//修改时间的闪烁模块 begin if(tempc<26'd50000000) tempc<=tempc+1; else tempc<=0; end always@(posedge clk_t) begin if(count_t==3'b101) count_t<=0; else count_t<=count_t+1; end always@(count_t) begin case(count_t) 3'b000:num<=s[3:0]; 3'b001:num<=s[7:4]; 3'b010:num<=m[3:0]; 3'b011:num<=m[7:4]; 3'b100:num<=h[3:0]; 3'b101:num<=h[7:4]; endcase end always@(posedge clk_t) begin case(count_t) 3'b000:begin if(changen==(3'b001)&&clk_tc==1) led1<=6'b111111;else led1<=6'b111110; end 3'b001:begin if(changen==(3'b001)&&clk_tc==1) led1<=6'b111111;else led1<=6'b111101; end 3'b010:begin if(changen==(3'b010)&&clk_tc==1) led1<=6'b111111;else led1<=6'b111011; end 3'b011:begin if(changen==(3'b010)&&clk_tc==1) led1<=6'b111111;else led1<=6'b110111; end 3'b100:begin if(changen==(3'b100)&&clk_tc==1) led1<=6'b111111;else led1<=6'b101111; end 3'b101:begin if(changen==(3'b100)&&clk_tc==1) led1<=6'b111111;else led1<=6'b011111; end endcase case(num) 5'd0:led2<=S0; 5'd1:led2<=S1; 5'd2:led2<=S2; 5'd3:led2<=S3; 5'd4:led2<=S4; 5'd5:led2<=S5; 5'd6:led2<=S6; 5'd7:led2<=S7; 5'd8:led2<=S8; 5'd9:led2<=S9; endcase end endmodule
module topclock(input clk,input reset,input [4:0]button,output [7:0]led1,output [6:0]led2); reg [25:0]inclk;//1s分频 reg inclklk; always @(posedge clk) begin if(inclk<26'd50000000) inclk <= inclk + 1; else begin inclk <=0; inclklk<=~inclklk; end end assign led1[1:0]=2'b11; wire [7:0]sec;//时钟计数和进位中间变量 wire [7:0]min; wire [7:0]hour; wire sjin,mjin,hjin; wire [2:0]changen;//调时间使能和中间变量 wire [2:0]changen1; wire [2:0]changen2; assign changen2=changen; assign changen1=changen; assign sjin=inclklk; //button[1:0]上下键调时间数字,button[3:2]左右键改数字位,button[4]确定和开始改时间 timechange tc(clk,button[4:2],changen); count60 s(sjin,1,changen1[0],reset,button[1:0],sec,mjin);//时钟计数和进位 count60 m(sjin,mjin,changen1[1],reset,button[1:0],min,hjin); count24 h(sjin,(hjin&&mjin),changen1[2],reset,button[1:0],hour); print tp(clk,sec,min,hour,changen2,led1[7:2],led2); endmodule
由于五向按键中键同时是板子的一个时钟,所以需要在文件中额外加一句NET “button<4>” CLOCK_DEDICATED_ROUTE = FALSE;用来取消时钟的使用。
# PlanAhead Generated IO constraints NET "button[4]" IOSTANDARD = LVCMOS33; NET "button[3]" IOSTANDARD = LVCMOS33; NET "button[2]" IOSTANDARD = LVCMOS33; NET "button[1]" IOSTANDARD = LVCMOS33; NET "button[0]" IOSTANDARD = LVCMOS33; NET "led1[7]" IOSTANDARD = LVCMOS33; NET "led1[6]" IOSTANDARD = LVCMOS33; NET "led1[5]" IOSTANDARD = LVCMOS33; NET "led1[4]" IOSTANDARD = LVCMOS33; NET "led1[3]" IOSTANDARD = LVCMOS33; NET "led1[2]" IOSTANDARD = LVCMOS33; NET "led1[1]" IOSTANDARD = LVCMOS33; NET "led1[0]" IOSTANDARD = LVCMOS33; NET "led2[6]" IOSTANDARD = LVCMOS33; NET "led2[5]" IOSTANDARD = LVCMOS33; NET "led2[4]" IOSTANDARD = LVCMOS33; NET "led2[3]" IOSTANDARD = LVCMOS33; NET "led2[2]" IOSTANDARD = LVCMOS33; NET "led2[1]" IOSTANDARD = LVCMOS33; NET "led2[0]" IOSTANDARD = LVCMOS33; # PlanAhead Generated physical constraints NET "button[4]" LOC = E16; NET "button[3]" LOC = T16; NET "button[2]" LOC = R10; NET "button[1]" LOC = F15; NET "button[0]" LOC = V10; NET "led1[7]" LOC = M1; NET "led1[6]" LOC = L1; NET "led1[5]" LOC = N4; NET "led1[4]" LOC = N2; NET "led1[3]" LOC = N5; NET "led1[2]" LOC = M3; NET "led1[1]" LOC = M6; NET "led1[0]" LOC = N6; NET "led2[6]" LOC = L3; NET "led2[5]" LOC = N1; NET "led2[4]" LOC = L5; NET "led2[3]" LOC = L4; NET "led2[2]" LOC = K3; NET "led2[1]" LOC = M2; NET "led2[0]" LOC = L6; # PlanAhead Generated IO constraints NET "clk" IOSTANDARD = LVCMOS33; NET "reset" IOSTANDARD = LVCMOS33; # PlanAhead Generated physical constraints NET "clk" LOC = E3; NET "reset" LOC = P3; NET "button<4>" CLOCK_DEDICATED_ROUTE = FALSE;
最明显的不足之处就是没有按键消抖,当时还不会。。。。
修改时间的时候还得一直按着五向按键一秒钟变一次挺累的。。。
分频做的也不好搞得我自己当时都晕了,好不容易做出来赶紧给老师验收qwq
这个数字钟修改了三个大版本才最终成功到板子上,之前有点想放弃了找来一个人帮我看哪里出错了结果他找不出来qwq只能靠自己了
不保证这些模块写上去能直接用,因为有可能我在仿真的时候改了某些模块always@里面的东西,太久远了我自己也不记得了。。。
不过大部分是对的
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。