基本功能:
1,准确计时,以数字形式(十进制)显示时、分、秒的时间
2,校正时间:时、分 快校 与 慢校 (1Hz与手动)
3,复位:00:00:00
选做:
1,任意闹钟
2,小时为12/24进制可切换
3,报整点数(几点钟LED闪烁几下)
DE0开发板,Quartus II 13.1.0 ,Altera-Modelsim。
第一次实验时代码:
moduledemultiply(CP,MainCLK);//50MHz分频出1Hz
input MainCLK;
output CP;
regCP;
reg[24:0]counter;
initial
begin counter=0;CP=0;end
always @(posedge MainCLK)
begin
if(counter==24999999)
begin CP=~CP;counter=0;end
elsecounter=counter+1;
end
endmodule
moduleshow(OUT,IN,CP);//译码显示模块
output [7:0]OUT;
input [3:0]IN;
input CP;
reg [7:0]OUT;
always @(posedgeCP)
case (IN)
0:OUT=8'b11000000;
1:OUT=8'b11111001;
2:OUT=8'b10100100;
3:OUT=8'b10110000;
4:OUT=8'b10011001;
5:OUT=8'b10010010;
6:OUT=8'b10000010;
7:OUT=8'b11111000;
8:OUT=8'b10000000;
9:OUT=8'b10010000;
default:OUT=8'b10001001;
endcase
endmodule
//秒/分控制(60进制,快慢校正,Ck=2'b10为减,Ck=2'b01为加)
module SecOrMinControl(Q,nCR,EN,ENQ,CP,Ck);
output [7:0]Q;
input nCR,EN,CP,ENQ;
input [1:0]Ck;
reg[7:0]Q;
always @(posedge CP)
begin
if(~nCR) Q<=8'b00000000;
else if(~EN) Q<=Q;
else
case (Ck[1:0])
2'b01:
if((Q[3:0]==4'b1001)&&(Q[7:4]!=4'b0101))beginQ[7:4]<=Q[7:4]+1'b1;Q[3:0]<=4'b0000;end
elseif(Q[7:0]==8'b01011001)Q[7:0]<=8'b00000000;
else beginQ[7:4]<=Q[7:4];Q[3:0]<=Q[3:0]+1'b1;end
2'b10:
if((Q[3:0]==4'b0000)&&(Q[7:4]!=4'b0000))beginQ[7:4]<=Q[7:4]-1'b1;Q[3:0]<=4'b1001;end
elseif(Q[7:0]==8'b00000000)Q[7:0]<=8'b01011001;
else beginQ[7:4]<=Q[7:4];Q[3:0]<=Q[3:0]-1'b1;end
default: if(~ENQ)Q<=Q;
else
begin
if((Q[3:0]==4'b1001)&&(Q[7:4]!=4'b0101))beginQ[7:4]<=Q[7:4]+1'b1;Q[3:0]<=4'b0000;end
elseif(Q[7:0]==8'b01011001)Q[7:0]<=8'b00000000;
else beginQ[7:4]<=Q[7:4];Q[3:0]<=Q[3:0]+1'b1;end
end
endcase
end
endmodule
//小时控制,快慢校正Ck=2‘b01加,Ck=2'b10减.
//12/24进制选择,Select=1——24进制,0——12进制
moduleHrControl(Q,nCR,EN,ENQ,CP,Ck,Select);
output [4:0]Q;
input nCR,EN,CP,ENQ,Select;
input [1:0]Ck;
reg[4:0]Q;
always @(posedge CP)
begin
if(~nCR) Q<=5'b00000;
else if(~EN) Q<=Q;
else
case (Ck[1:0])
2'b01:if(Select==1)
if(Q==5'b10111)Q<=5'b00000;
else Q<=Q+1'b1;
elseif(Q>5'b01100)Q<=Q-5'b01100;
elseif(Q==5'b01100)Q<=5'b0001;
else Q<=Q+1'b1;
2'b10:if(Select==1)
if(Q==5'b00000)Q<=5'b10111;
else Q<=Q-1'b1;
elseif(Q>5'b01100)Q<=Q-5'b01100;
else if((Q==5'b00001)||(Q==5'b00000))Q<=5'b01100;
elseQ<=Q-1'b1;
default:
if(~ENQ)Q<=Q;
else
if(Select==1)
if(Q==5'b10111)Q<=5'b0000000;
else Q<=Q+1'b1;
elseif(Q==5'b01100)Q<=5'b00001;
else Q<=Q+1'b1;
endcase
end
endmodule
//整点报时功能,几点LED亮几次
moduleTellTime(LED,Hr,ENL,EN,MainCLK);
input MainCLK ,ENL, EN;
input [4:0]Hr;
output LED;
regflag;
regLED;
reg[5:0]CntTimes;
reg[25:0]counter_number;
initial beginflag=0;counter_number=0;CntTimes=0;end
always @(posedge MainCLK)
begin
if(~EN) LED<=0;
else
if(ENL)
beginflag<=1;end
if(flag==1)
begin
if(CntTimes>=2'b10*Hr)
beginLED<=0;flag<=0;CntTimes=0;end
elseif(counter_number==24999999)
begincounter_number<=0;LED<=~LED;CntTimes<=CntTimes+1'b1;end
elsecounter_number<=counter_number+1'b1;
end
end
endmodule
module ALARM_Clock(SetHr,SetMin,SetSec,Alarm,CP,MainCLK,nCR,EN,ENAC,CkSec,CkMin,CkHr,Select,Sec,Min,Hr);
output [4:0]SetHr;
output [7:0]SetSec,SetMin;
output Alarm;
inputCP,EN,Select,nCR,MainCLK,ENAC;
input [1:0]CkMin,CkHr,CkSec;
input [7:0]Sec,Min;
input [4:0]Hr;
regAlarm;
regflag;
reg[3:0]CntTimes;
reg[25:0]counter_number;
wire ENSec;
wire ENSM,ENMH,ENL;
wire [7:0]Sec,Min;
wire [4:0]Hr;
assign ENSM=0;
assign ENMH=0;
assign ENSec=0;
initial beginflag=0;counter_number=0;CntTimes=0;end
SecOrMinControlAlarmSecControl(SetSec,nCR,EN,ENSec,CP,CkSec);
SecOrMinControlAlarmMinControl(SetMin,nCR,EN,ENSM,CP,CkMin);
HrControlAlarmHourControl(SetHr,nCR,EN,ENMH,CP,CkHr,Select);
always @(posedge MainCLK)
if(~EN||~nCR||~ENAC)Alarm<=0;
else
begin
if(Hr==SetHr&&Min==SetMin&&Sec==SetSec)flag<=1;
if(flag==1)
begin
if(CntTimes>=4'b1100)
beginAlarm<=0;flag<=0;CntTimes=0;end
elseif(counter_number==49999)
begincounter_number<=0;Alarm<=~Alarm;CntTimes<=CntTimes+1'b1;end
elsecounter_number<=counter_number+1'b1;
end
end
endmodule
//顶层模块,其中SHOWAC=1,数码管显示当时时间,=0显示定时设置时间
moduleDigtalClock(Hr0,Hr1,Min0,Min1,Sec0,Sec1,Light,Alarm,nCR,EN,MainCLK,CkSec,CkMin,CkHr,Select,ENAC,SHOWAC);
output [7:0]Min0,Min1,Hr0,Hr1;
output [3:0]Sec0,Sec1;
output Light,Alarm;
inputnCR,EN,MainCLK,Select,ENAC,SHOWAC;
input [1:0]CkSec,CkMin,CkHr;
wire ENSec;
wire ENSM,ENMH,ENL;
wire [7:0]Sec,Min;
wire [4:0]Hr;
wire [7:0]SetSec,SetMin;
wire [4:0]SetHr;
assign ENSec =EN;
assign ENSM=(Sec==8'b01011000);
assign ENMH=(Min==8'b01011001&&Sec==8'b01011000);
assignENL=(Min==8'b00000000&&Sec==8'b00000000);
assign Sec0 =(SHOWAC==0?SetSec:Sec);
assign Sec1 =(SHOWAC==0?SetSec>>4:Sec>>4);
demultiplyOneHzMaker(CP,MainCLK);
SecOrMinControlSecControl(Sec,nCR,EN,ENSec,CP,(ENAC==1?2'b00:CkSec));
SecOrMinControlMinControl(Min,nCR,EN,ENSM,CP,(ENAC==1?2'b00:CkMin));
HrControlHourControl(Hr,nCR,EN,ENMH,CP,(ENAC==1?2'b00:CkHr),(ENAC==1?1'b1:Select));
ALARM_ClockYalling(SetHr,SetMin,SetSec,Alarm,CP,MainCLK,nCR,EN,ENAC,(ENAC==1?CkSec:2'b00),(ENAC==1?CkMin:2'b00),(ENAC==1?CkHr:2'b00),Select,Sec,Min,Hr);
TellTimeShining(Light,Hr,ENL,EN,MainCLK);
showMinSh0(Min0,(SHOWAC==0?SetMin[3:0]:Min[3:0]),CP);
showMinSh1(Min1,(SHOWAC==0?SetMin[7:4]:Min[7:4]),CP);
showHrSh0(Hr0,(SHOWAC==0?SetHr:Hr),CP);
showHrSh1(Hr1,(SHOWAC==0?SetHr/10:Hr/10),CP);
endmodule
第二次的代码:分了多个文件写的,思路差不多,只是省了几个拨码开关
//NewDigitalClock.v
module NewDigitalClock(//顶层模块
input EN,
input nCR,
input CP,
input Sel_Hr,
//Sel_Hr选择小时是12还是24进制,Sel=1,24;Sel==0,12.
input UpOrDown,
//UPOrDown:加校正减校正0——>-,1——>+
input Set_Sel,
//Set_Sel选择设置位:0——>Min,1——>Hr;Set_EN设置校时使能
input Set_EN,//设置时间使能
input Alarm_Clock_EN,//闹钟使能
inputShowAlarm,//1---Alarm,0---Clock.
output [3:0] Sec_L,
output [3:0]Sec_H,
output [6:0] Min_L,
output [6:0] Min_H,
output [6:0]Hr_L,
output [6:0] Hr_H,
output Alarm,
output LED );
wire [7:0] Sec,Min;
wire [4:0] Hr;
wire [7:0] Clock_Min;
wire [4:0] Clock_Hr;
wire EN_Min,EN_Sec, EN_Hr, EN_Main;//分钟,秒钟,时,主使能
wire Hr_UpOrDown,Min_UpOrDown, Sec_UpOrDown;
assign EN_Sec = (EN &&EN_Main);
assign EN_Min = (EN_Sec &&((!Alarm_Clock_EN && Set_EN == 1 && Set_Sel == 0)|| (!(!Alarm_Clock_EN && Set_EN == 1 && Set_Sel ==0) && ( Sec == 8'h59))));
assign EN_Hr = (EN_Sec &&((!Alarm_Clock_EN && Set_EN == 1 && Set_Sel == 1)|| (!(!Alarm_Clock_EN && Set_EN == 1 && Set_Sel ==1) && (Min == 8'h59 && Sec ==8'h59))));
assign Min_UpOrDown = !(Set_EN == 1 &&Set_Sel == 0 && UpOrDown == 0);
assign Hr_UpOrDown = !(Set_EN == 1 &&Set_Sel == 1 && UpOrDown == 0);
assign Sec_UpOrDown = 1;
assign Sec_H = Sec[7:4];
assign Sec_L = Sec[3:0];
OneHzMaker OneHz(
.Q(EN_Main),
.CP(CP));
Counter60 SecTiming(
.Q(Sec),
.nCR(nCR),
.EN(EN_Sec),
.CP(CP),
.UpOrDown(Sec_UpOrDown));
Counter60 MinTiming(
.Q(Min),
.nCR(nCR),
.EN(EN_Min),
.CP(CP),
.UpOrDown(Min_UpOrDown));
Counter12or24 HrTiming(
.Q(Hr),
.nCR(nCR),
.EN(EN_Hr),
.CP(CP),
.Sel(Sel_Hr),//选择小时的进制,1——24,0——12
.UpOrDown(Hr_UpOrDown));
Alarm_Clock AlarmOn(//闹钟
.CP(CP),
.nCR(nCR),
.EN(Alarm_Clock_EN),
.Min(Min),
.Hr(Hr),
.UpOrDown(UpOrDown),
//UpOrDown:加校正减校正0——>-,1——>+
.Set_Sel(Set_Sel),
//Set_Sel选择设置位:0——>Min,1——>Hr;Set_EN设置校时使能
.Set_EN(Set_EN),//设置时间使能
.Sel_Hr(Sel_Hr),
//Sel_Hr选择小时是12还是24进制,Sel=1,24;Sel==0,12.
.Alarm(Alarm),//闹钟输出
.Clock_Min(Clock_Min),//闹钟定时分钟
.Clock_Hr(Clock_Hr));//闹钟定时小时
show Hr_L_show(
.OUT(Hr_L),
.IN(ShowAlarm?Clock_Hr:Hr),
.CP(CP));
show Hr_H_show(
.OUT(Hr_H),
.IN(ShowAlarm?Clock_Hr/10:Hr/10),
.CP(CP));
show Min_L_show(
.OUT(Min_L),
.IN(ShowAlarm?Clock_Min[3:0]:Min[3:0]),
.CP(CP));
show Min_H_show(
.OUT(Min_H),
.IN(ShowAlarm?Clock_Min[7:4]:Min[7:4]),
.CP(CP));
LEDTellTime(//整点报时
.CP(CP),
.EN(EN),
.Hr(Hr),
.Min(Min),
.Sec(Sec),
.LED(LED));
endmodule
//Counter10.v************模10可逆计数
module Counter10(
output reg [3:0] Q,
input nCR,
input EN,
input CP,
input UpOrDown);
initial
Q<= 0;
always @ (posedge CP or negedge nCR )begin
if(~nCR)
Q<= 0;
else
if(~EN)
Q<= Q;
else
if(!UpOrDown)
Q<= ((Q == 0)?9 : Q - 1);
else
Q<= ((Q == 9)?0 : Q + 1);
end
endmodule
//Counter6.v******模6可逆计数
module Counter6(
output reg [3:0]Q,
input nCR,
input EN,
input CP,
input UpOrDown);
initial
Q<= 0;
always @(posedge CP or negedge nCR)begin
if(~nCR)
Q<= 0;
else
if(~EN)
Q<= Q;
else
if(!UpOrDown)
Q<= ((Q == 0)? 5 : Q - 1);
else
Q<=((Q == 5)? 0: Q + 1);
end
endmodule
//Counter60.v*******模60 可逆计数
module Counter60(
output [7:0]Q,
input nCR,
input EN,
input CP,
input UpOrDown);
wire EN_LH;
assign EN_LH = (EN && (UpOrDown? (Q[3:0]== 9) : (Q[3:0] == 0)));
Counter10 Q_L(
.Q(Q[3:0]),
.nCR(nCR),
.EN(EN),
.CP(CP),
.UpOrDown(UpOrDown));
Counter6 Q_H(
.Q(Q[7:4]),
.nCR(nCR),
.EN(EN_LH),
.CP(CP),
.UpOrDown(UpOrDown));
endmodule
欢迎光临 (http://www.51hei.com/bbs/) | Powered by Discuz! X3.1 |