二.设计一数字钟系统,要求如下:
1. 有基础的实时数字钟功能,即时,分,秒的正常显示模式。(24小时制)
2. 可对系统用手动方式校准,设计两个按键,按动校时键,时计数器加一,按动校分键,则电路处于校分状态。
3. 整点报时,要求在59分50秒,52秒,54秒,56秒和58秒发出一个低音信号,00分00秒发出一个高音信号。
源程序如下:
module clock (clk,reset,hour_g,hour_d,minute_g,minute_d,second_g,second_d,add_s,add_f,lowalarm,highalarm);
input clk,reset,add_s,add_f;
output[3:0] hour_g,hour_d,minute_g,minute_d,second_g,second_d;
reg[3:0] hour_g,hour_d,minute_g,minute_d,second_g,second_d;
wire cout_s,cout_m;
reg[3:0] jishi;
output lowalarm,highalarm;//低音和高音信号
reg lowalarm;
wire highalarm;
always @(posedge clk)
begin
if(!reset) second_d<=0;
else if(second_d==9)
second_d<=0;
else
second_d<=second_d+1;
end
always @(posedge clk)
begin
if(!reset) second_g<=0;
else if(second_d==9)
begin
if(second_g==5)
second_g<=0;
else
second_g<=second_g+1;
end
end
assign cout_s=((second_d==9)&&(second_g==5))?1:0;
always @(posedge clk)
begin
if(!reset)
minute_d <= 0;
else if(cout_s)
begin
if(minute_d==9)
minute_d <= 0;
else
minute_d <=minute_d+1;
end
end
always @(posedge clk)
begin
if(!reset)
minute_g <= 0;
else if(cout_s)
begin
if(minute_d==9)
begin
if(minute_g==5)
minute_g <= 0;
else
minute_g<= minute_g+1;
end
end
end
assign cout_m = ((minute_d==9)&&(minute_g==5))?1:0;
always @(posedge clk)
begin
if(!reset)
hour_d <= 0;
else if(cout_m&&cout_s)
begin
if((hour_d==3)&&(hour_g==2))
hour_d<=0;
else
if(hour_d==9)
hour_d <=0;
else
hour_d <= hour_d + 1;
end
end
always @(posedge clk)
begin
if(!reset)
hour_g <= 0;
else if(cout_m&&cout_s)
begin
if((hour_d==3)&&(hour_g==2))
hour_g <= 0;
else if(hour_d==9)
hour_g<=hour_g+1;
end
end
always @(posedge clk)
begin
if(add_s)
begin
if((hour_d==3)&&(hour_g==2))
begin
hour_g<=0;
hour_d<=0;
end
else
if(hour_d==9)
begin
hour_d<=0;
hour_g<=hour_g+1;
end
else
hour_d<=hour_d+1;
end
end
always @(posedge clk)
begin
if(add_f)
begin
if((minute_d==9)&&(minute_g==5))
begin
minute_d<=0;
minute_g<=0;
end
else
if(minute_d==9)
begin
minute_d<=0;
minute_g<=minute_g+1;
end
else
minute_d<=minute_d+1;
end
end
always @(posedge clk)
begin
if(!reset)
begin
lowalarm<=0;
jishi<=1;
end
else
if((minute_g==5)&&(minute_d==9))
begin
if(second_g==5)
begin
if((second_d==1)||(second_d==3)||(second_d==5)||(second_d==7))
lowalarm<=1;
else
begin
lowalarm<=0;
jishi<=jishi+1;
end
end
if(second_g==4&&second_d==9)
lowalarm<=1;
end
end
assign highalarm=((minute_g==0)&&(minute_d==0)&&(second_g==0)&&(second_d==0))?1:0;
endmodule
`timescale 1ns/1ns
module clock_tb();
reg clk,reset;
wire[3:0] hour_g,hour_d,minute_g,minute_d,second_g,second_d;
wire lowalarm,highalarm;
reg add_s,add_f;
clock u1(.clk(clk),.reset(reset),.hour_g(hour_g),.hour_d(hour_d),.minute_g(minute_g),
.minute_d(minute_d),.second_g(second_g),.second_d(second_d),.add_s(add_s),.add_f(add_f),.lowalarm(lowalarm),.highalarm(highalarm));
parameter DELY=100;
always #(DELY/2) clk=~clk;
initial
begin
clk=0;add_s=0;add_f=0;reset=0;
#150 reset=1;
#(DELY*100000) add_s=1;
#DELY add_s=0;
#(DELY*5) add_f=1;
#DELY add_f=0;
#DELY $finish;
end
endmodule