程序是实现一个数字钟,有进位、清零、校时与校分功能。数字钟的分钟和小时是用数码管显示,秒信号是用LED显示8421BCD码。
下面是采用8421BCD码计数,并在一个模块中实现时钟功能的Verilog程序。由主时钟分频(50MHz)得到秒信号,计秒到60分加1,秒清零。计分到60时,分清零。同时,可以通过按键进行校分与校时。
`timescale 1ns / 1ps ////////////////////////////////////////////////////////////////////////////////// // Company: // Engineer: // // Create Date: 16:20:22 11/19/2013 // Design Name: // Module Name: DigitalClk // Project Name: // Target Devices: // Tool versions: // Description: // // Dependencies: // // Revision: // Revision 0.01 - File Created // Additional Comments: // ////////////////////////////////////////////////////////////////////////////////// module DigitalClk( input clk, input clr, input setm,//设定分钟 input seth,//设定小时 output reg[3:0]secondL,//秒数的低位 output reg[3:0]secondH,//秒数的高位 output reg[6:0]atog, output reg[3:0]an ); reg [3:0]minuteL;//分钟数的低位 reg [3:0]minuteH;//分钟数的高位 reg [3:0]hourL;//小时数的低位 reg [3:0]hourH;//小时数的高位 reg [1:0]s; //四个数码管轮流使能信号 reg [3:0]digit; //使能数码管中的数字 reg [26:0] counter; reg [7:0]minute;//记录分钟数 reg [7:0]hour;//记录小时数 reg [7:0]sec;//记录秒数 integer i; integer j; integer k; always@(posedge clk or posedge clr) begin if(clr==1) //清零键按下时将所有数据置零 begin counter<=0; secondL<=0; secondH<=0; minuteL<=0; minuteH<=0; hourH<=0; hourL<=0; minute<=0; hour<=0; sec<=0; end else if(counter==50000000)//时间达到一秒 begin counter<=0; if(setm==1)//如果设置分钟建按下(长按一秒才会起作用) begin if(minute==59) begin minute<=0; if(hour==23)//23:59进位变为00:00 begin hour<=0; end else begin hour<=hour+1; end end else begin minute<=minute+1; end end if(seth==1)//如果设置小时建按下(长按一秒才会起作用) begin if(hour==23) begin hour<=0; minute<=0; minuteH<=0; minuteL<=0; end else begin hour<=hour+1; end end //一般情况 if(sec==59)//秒针进位 begin sec<=0; if(minute==59) begin minute<=0; if(hour==23)//23:59进位后变成00:00 begin hour<=0; end else if(hour<23) begin hour<=hour+1; end end else if(minute<59)//分钟数进位 begin minute<=minute+1; end end else if(seth==0&&setm==0)//在调时,调分键没有按下的情况下,秒钟计数 begin sec<=sec+1; end for(i=0;i<6;i=i+1)//分离出秒钟数的个位和十位 begin if(sec[7:0]-i*10<10) begin secondH<=i; secondL<=sec[7:0]-i*10; i=6; end end for(j=0;j<6;j=j+1)//分离出分钟数的个位和十位 begin if(minute[7:0]-j*10<10) begin minuteH<=j; minuteL<=minute[7:0]-j*10; j=6; end end for(k=0;k<3;k=k+1)//分离出十钟数的个位和十位 begin if(hour[7:0]-k*10<10) begin hourH<=k; hourL<=hour[7:0]-k*10; k=3; end end end else begin counter<=counter+1; end end //数码管动态显示 always@(*) begin an=4'b1111; s<=counter[14:13]; an[s]=0; case(s) 0:digit<=minuteL[3:0]; 1:digit<=minuteH[3:0]; 2:digit<=hourL[3:0]; 3:digit<=hourH[3:0]; default:digit<=hourH[3:0]; endcase case(digit) 0:atog=7'b0000001; 1:atog=7'b1001111; 2:atog=7'b0010010; 3:atog=7'b0000110; 4:atog=7'b1001100; 5:atog=7'b0100100; 6:atog=7'b0100000; 7:atog=7'b0001111; 8:atog=7'b0000000; 9:atog=7'b0000100; default:atog=7'b0000001; endcase end endmodule
NET "clk" LOC="B8"; //NET "clr" LOC="P11"; NET "clr" LOC="A7"; NET "secondL[0]" LOC="M5"; NET "secondL[1]" LOC="M11"; NET "secondL[2]" LOC="P7"; NET "secondL[3]" LOC="P6"; NET "secondH[0]" LOC="N5"; NET "secondH[1]" LOC="N4"; NET "secondH[2]" LOC="P4"; NET "secondH[3]" LOC="G1"; NET"atog[0]"LOC=M12; NET"atog[1]"LOC=L13; NET"atog[2]"LOC=P12; NET"atog[3]"LOC=N11; NET"atog[4]"LOC=N14; NET"atog[5]"LOC=H12; NET"atog[6]"LOC=L14; NET"an[3]"LOC=K14; NET"an[2]"LOC=M13; NET"an[1]"LOC=J12; NET"an[0]"LOC=F12; NET"setm"LOC=G12; NET"seth"LOC=M4;