reg [7:0] MinCP,HrCP;
counter60 UT1(Second,nCR,Vdd,_1HZ); counter60 UT2(Minute,nCR,Vdd,!MinCP);
counter24 UT3(Hour[7:4],Hour[3:0],nCR,Vdd,!HrCP); always@(posedge HZ)
begin if (AdjMinKey) MinCP=(Second==8'h59); else MinCP=1'b1; end
always@(posedge HZ)
begin if (AdjHrKey) HrCP=({Minute,Second}==16'h5959); else HrCP=1'b1; end Endmodule 闹钟模块
设置了分和时的计数模块,调用了模60和模24的模块。为了消抖动,脉冲技术端接一秒的信号,调时调分信号非后接使能段,这样既可以正常计数又可以在不用使能端时保持信号又可以消抖动。然后设置了比较程序,当主时钟的输出与闹钟设置的相等而且闹钟ctrlbell为1时便输出闹钟结果,否则闹钟一直输出为0,从而完成正常的功能。 module
Bell(Alarn_Clock,Hour,Minute,Second,Set_Hr,Set_Min,SetHrKey,SetMinKey,_500HZ,_1KHZIn,_1HZ,CtrlBell); output Alarn_Clock;
output [7:0] Set_Hr,Set_Min; wire [7:0] Set_Hr,Set_Min; wire Alarn_Clock;
input _500HZ,_1KHZIn,_1HZ;
input SetHrKey,SetMinKey,CtrlBell; input [7:0] Hour,Minute,Second; supply1 Vdd;
wire HrH_EQU,HrL_EQU,MinH_EQU,MinL_EQU; wire Time_EQU;
counter60 SU1(Set_Min,Vdd,!SetMinKey,_1HZ);
counter24 SU2(Set_Hr[7:4],Set_Hr[3:0],Vdd,!SetHrKey,_1HZ); Comparator SU4(HrH_EQU,Set_Hr[7:4],Hour[7:4]); Comparator SU5(HrL_EQU,Set_Hr[3:0],Hour[3:0]);
Comparator SU6(MinH_EQU,Set_Min[7:4],Minute[7:4]); Comparator SU7(MinL_EQU,Set_Min[3:0],Minute[3:0]);
assign Time_EQU=(HrH_EQU && HrL_EQU && MinH_EQU && MinL_EQU);
assign Alarn_Clock=CtrlBell ? Time_EQU:1'b0; endmodule
module Comparator(EQU,A,B) ;
input [3:0] A,B; output EQU;
assign EQU=(A==B); endmodule 秒表模块
秒表的输入脉冲为100Hz即1毫秒,调用了一个模100的计数模块和两个模60的计数模块。毫秒为99时下一个脉冲向秒进1,秒为59时同时毫秒为99时的下一个脉冲向分进1,使能端进行计数与保持。清零端应该单独设置,否则会将主时钟也清零了。用1KHZ的频率对计数进行扫描获得进位信号。 module stopwatch(Minute,Second,haomiao,nCR,en,_100HZ,HZ); input nCR,_100HZ,en,HZ;
output [7:0] Minute,Second,haomiao; wire [7:0] Minute,Second,haomiao; reg [7:0] miaoCP,SECP;
counter100 UT1(haomiao,nCR,en,_100HZ); counter60 UT2(Second,nCR,en,!miaoCP); counter60 UT3(Minute,nCR,en,!SECP); always@(posedge HZ)
begin if (haomiao==8'h99) miaoCP=(haomiao==8'h99); else miaoCP=(haomiao==8'h99); end
always@(posedge HZ)
begin if ({Second,haomiao}==16'h5999) SECP=(Second==8'h99); else SECP=({Second,haomiao}==16'h5999); end endmodule 整点报时模块
只有当分为59切秒为55时,让报警信号输出时长为5秒的信号,计数脉冲为1秒的信号。
module Radio(Alarn_Radio,Minute,Second,_1HZ); input _1KHZ;
input [7:0] Minute,Second; output Alarn_Radio; reg Alarn_Radio;
always@(Minute,Second) if (Minute==8'h59) case (Second)
8'h55:Alarn_Radio=1'b1; 8'h56:Alarn_Radio=1'b1; 8'h57:Alarn_Radio=1'b1; 8'h58:Alarn_Radio=1'b1; 8'h59:Alarn_Radio=1'b1; default: Alarn_Radio=1'b0; endcase
else Alarn_Radio=1'b0; endmodule
顶层模块
调用上述的各个模块,设置一个报警信号为闹钟与整点报时的相或输出。再设置循环扫码模块和选择显示模块,让主时钟秒表和闹钟的输出信号均可显示在数码管上并且互不影响。扫描频率均为1KHZ。 module
complete_clock(LED_Hr,LED_Min,LED_Sec,Alarn,AdjMinKey,AdjHrKey,SetHrKey,SetMinKey,stopwatchnCR,stopwatchen,_1KHZIn,_1HZ,CtrlBell,Mode1,Mode2,nCR,sel,SG); input
_1KHZIn,nCR,AdjMinKey,AdjHrKey,SetHrKey,SetMinKey,CtrlBell,Mode1,Mode2,stopwatchnCR,stopwatchen;
output [7:0] LED_Hr,LED_Min,LED_Sec,Alarn,SG,_1HZ; wire [7:0] LED_Hr,LED_Min,LED_Sec; wire _500HZ,_1HZ,_100HZ; wire [7:0]
Hour,Minute,Second,stopwatchHour,stopwatchMinute,stopwatchSecond; wire [7:0] Set_Hr,Set_Min; wire Alarn_Clock,Alarn_Radio; reg [3:0]a; reg [2:0] sel; reg [7:0] SG; output [2:0] sel;
Divided_Frequency U0(_1HZ,_500HZ,nCR,_1KHZIn,_100HZ); top_clock
U1(Hour,Minute,Second,nCR,_1HZ,AdjMinKey,AdjHrKey,_1KHZIn); Radio U2(Alarn_Radio,Minute,Second,_1HZ); Bell
U3(Alarn_Clock,Hour,Minute,Second,Set_Hr,Set_Min,SetHrKey,SetMinKey,_500HZ,_1KHZIn,_1KHZIn,CtrlBell);
stopwatch(stopwatchHour,stopwatchMinute,stopwatchSecond,stopwatchnCR,stopwatchen,_100HZ,_1KHZIn);
assign Alarn=Alarn_Clock||Alarn_Radio; _3To1MUX
Mu1(LED_Hr,Mode1,Mode2,Set_Hr,Hour,stopwatchHour,_1KHZIn); _3To1MUX
Mu2(LED_Min,Mode1,Mode2,Set_Min,Minute,stopwatchMinute,_1KHZIn); _3To1MUX
Mu3(LED_Sec,Mode1,Mode2,8'h00,Second,stopwatchSecond,_1KHZIn); always @(posedge _1KHZIn) begin
if (sel<5) sel=sel+1; else sel=0;
end always @(sel) begin
case (sel)
0: a=LED_Hr[7:4]; 1: a=LED_Hr[3:0]; 2: a=LED_Min[7:4]; 3: a=LED_Min[3:0]; 4: a=LED_Sec[7:4]; 5: a=LED_Sec[3:0]; default: a=0; endcase case (a)
0:SG<=8'b00111111; 1:SG<=8'b00000110; 2:SG<=8'b01011011; 3:SG<=8'b01001111; 4:SG<=8'b01100110; 5:SG<=8'b01101101; 6:SG<=8'b01111101; 7:SG<=8'b00000111; 8:SG<=8'b01111111; 9:SG<=8'b01101111; default: SG=8'b11111111; endcase end endmodule
module _3To1MUX(out,se1,se2,y,x,z,HZ); input [7:0] x,y,z; output [7:0] out; reg [7:0] out; input se1,se2,HZ;
always@(posedge HZ)
begin if (se1) out=x;
else if (se2) out=y; else out=z; end
endmodule (五) 时序仿真
仿真中用1KHZ信号代替1HZ信号。
可以看出在主时钟是可以进行调时和调分,秒正常计数,也可以进行进位。
可以看出在分为59秒从55开始,有时长为5秒的整点报时信号。
可以看出通过闹钟的调整位可以调整闹钟的时间,并且和主时钟相等时输出报警