找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 5418|回復(fù): 2
打印 上一主題 下一主題
收起左側(cè)

EDA多功能數(shù)字鐘(源代碼)

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:51024 發(fā)表于 2014-7-30 14:06 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
                       
這個(gè)實(shí)驗(yàn)先自己做了一次,功能可以全部實(shí)現(xiàn),由于ModelSim不熟悉仿真出現(xiàn)問題向蘇豪學(xué)長(zhǎng)求助時(shí)學(xué)長(zhǎng)說我的代碼太丑,思路不清晰,排版雜亂,要我重新寫一遍。因而今天又做了一次。這里附上兩次源代碼(兩次的代碼都在板子上跑過了,都可以實(shí)現(xiàn)所有功能)。算我自己留個(gè)紀(jì)念,也供需要的人參考。(有任何問題或建議歡迎留言。)
實(shí)驗(yàn)任務(wù)及要求

基本功能:

1,準(zhǔn)確計(jì)時(shí),以數(shù)字形式(十進(jìn)制)顯示時(shí)、分、秒的時(shí)間

2,校正時(shí)間:時(shí)、分  快校 與 慢校 (1Hz與手動(dòng))

3,復(fù)位:00:00:00

選做:

1,任意鬧鐘

2,小時(shí)為12/24進(jìn)制可切換

3,報(bào)整點(diǎn)數(shù)(幾點(diǎn)鐘LED閃爍幾下)

實(shí)驗(yàn)條件

DE0開發(fā)板,Quartus II 13.1.0 ,Altera-Modelsim。

第一次實(shí)驗(yàn)時(shí)代碼:

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進(jìn)制,快慢校正,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

//小時(shí)控制,快慢校正Ck=2‘b01加,Ck=2'b10減.

//12/24進(jìn)制選擇,Select=1——24進(jìn)制,0——12進(jìn)制

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

//整點(diǎn)報(bào)時(shí)功能,幾點(diǎn)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,數(shù)碼管顯示當(dāng)時(shí)時(shí)間,=0顯示定時(shí)設(shè)置時(shí)間

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

第二次的代碼:分了多個(gè)文件寫的,思路差不多,只是省了幾個(gè)撥碼開關(guān)


//NewDigitalClock.v

module NewDigitalClock(//頂層模塊

input EN,

input nCR,

input CP,

input Sel_Hr,

//Sel_Hr選擇小時(shí)是12還是24進(jìn)制,Sel=1,24;Sel==0,12.

input UpOrDown,

//UPOrDown:加校正減校正0——>-,1——>+

input Set_Sel,

//Set_Sel選擇設(shè)置位:0——>Min,1——>Hr;Set_EN設(shè)置校時(shí)使能

input Set_EN,//設(shè)置時(shí)間使能

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;//分鐘,秒鐘,時(shí),主使能

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),//選擇小時(shí)的進(jìn)制,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選擇設(shè)置位:0——>Min,1——>Hr;Set_EN設(shè)置校時(shí)使能

.Set_EN(Set_EN),//設(shè)置時(shí)間使能

.Sel_Hr(Sel_Hr),

//Sel_Hr選擇小時(shí)是12還是24進(jìn)制,Sel=1,24;Sel==0,12.

.Alarm(Alarm),//鬧鐘輸出

.Clock_Min(Clock_Min),//鬧鐘定時(shí)分鐘

.Clock_Hr(Clock_Hr));//鬧鐘定時(shí)小時(shí)


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(//整點(diǎn)報(bào)時(shí)

.CP(CP),

.EN(EN),

.Hr(Hr),

.Min(Min),

.Sec(Sec),

.LED(LED));


endmodule



//Counter10.v************模10可逆計(jì)數(shù)

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可逆計(jì)數(shù)

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 可逆計(jì)數(shù)

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



//Counter12or24.v*******12/24進(jìn)制切換,可逆
moduleCounter12or24(
output reg [4:0]Q,
inputnCR,
inputEN,
inputCP,
inputSel, //Sel=1,24;Sel==0,12.
input UpOrDown);


always @(posedge CP or negedgenCR)begin
if( ~nCR)
Q <= 0;
else begin
if(~EN)
Q <= Q;
else begin
if(Sel) begin
if(!UpOrDown)
Q <=((Q == 0)? 23: Q - 1);
else
Q <=((Q == 23)? 0: Q +1);
end
elsebegin
if(Q > 12)
Q <= Q - 12;
elsebegin
if(!UpOrDown)begin
if(Q == 1)
Q <=12;
else
Q <= ((Q == 0)? 11:Q -1);
end
else
Q <= ((Q == 12)? 1:Q +1);
end
end
end
end
end
endmodule


//50MHz計(jì)數(shù)分頻出1Hz*******OneHzMaker.v
module OneHzMaker(
output reg Q,
inputCP);//50MHzCP____1HzQ


reg [25:0] Cnt;


initial begin
Cnt <= 0;
Q <= 0;
end


always @(posedge CP)begin
if(Cnt == 49999998)begin
Q <= 1;
Cnt <= Cnt + 1;
end
else
if(Cnt == 49999999)begin
Q <= 0;
Cnt <= 0;
end
else begin
Cnt <= Cnt + 1;
Q <= 0;
end
end


endmodule



//show.v****數(shù)碼管顯示
module show(
output reg [7:0] OUT,
input [3:0] IN,
input CP);


always @(posedgeCP)
case (IN)
0: OUT =7'b1000000;
1: OUT =7'b1111001;
2: OUT =7'b0100100;
3: OUT =7'b0110000;
4: OUT =7'b0011001;
5: OUT =7'b0010010;
6: OUT =7'b0000010;
7: OUT =7'b1111000;
8: OUT =7'b0000000;
9: OUT =7'b0010000;
default:
OUT = 7'b0001001;
endcase
endmodule




//Alarm_Clock.v*******鬧鐘模塊
moduleAlarm_Clock(
input CP,
input nCR,
inputEN,//0——無鬧鐘,1——有鬧鐘
input [7:0] Min,
input [4:0] Hr,
inputUpOrDown,//UpOrDown:加校正減校正0——>-,1——>+
input Set_Sel,
//Set_Sel選擇設(shè)置位:0——>Min,1——>Hr;Set_EN設(shè)置校時(shí)使能
inputSet_EN,//設(shè)置時(shí)間使能
inputSel_Hr,//Sel_Hr選擇小時(shí)是12還是24進(jìn)制,Sel=1,24;Sel==0,12.
output  regAlarm,//鬧鐘輸出
output [7:0]Clock_Min,//鬧鐘定時(shí)分鐘
output [4:0]Clock_Hr//鬧鐘定時(shí)小時(shí)
);


reg [31:0] Times;
reg flag;
wireCPOfAlarmClock;//500Hz
wireEN_Alarm_Clock_Min;
wireEN_Alarm_Clock_Hr;
wire OneHz;


assign EN_Alarm_Clock_Min =(OneHz && EN && Set_EN &&!Set_Sel);
assign EN_Alarm_Clock_Hr =(OneHz && EN && Set_EN &&Set_Sel);


FiveHHzMakerCPForAlarmClockMaker(
.OUT(CPOfAlarmClock),
.CP(CP));
Counter60MinOfAlarm(
.Q(Clock_Min[7:0]),
.nCR(nCR),
.EN(EN_Alarm_Clock_Min),
.CP(CP),
.UpOrDown(UpOrDown));
Counter12or24HrOfAlarm(
.Q(Clock_Hr[4:0]),
.nCR(nCR),
.EN(EN_Alarm_Clock_Hr),
.CP(CP),
.Sel(Sel_Hr),
.UpOrDown(UpOrDown));


OneHzMakerOneHzForAlarmClock(
.Q(OneHz),
.CP(CP));


initial begin
Times = 0;
flag = 0;
end


always @ (posedge CP)begin
if(~EN )
Alarm <= 0;
else begin
if((Min == Clock_Min)&& (Hr == Clock_Hr ) && OneHz )
flag <=1;
if(CPOfAlarmClock &&(flag == 1)) begin
if(Times > 100000000) begin
Times <= 0;
flag <= 0;
Alarm <= 0;
end
else begin
Times <= Times+1;
Alarm <=~Alarm;
end
end
end
end
endmodule


//500Hz****FiveHHzMaker.v
moduleFiveHHzMaker(
output reg OUT,
input CP );
reg [24:0]counter;
initialbegin
counter = 0;
OUT = 0;
end


always @(posedgeCP)begin
if( counter == 49999)begin
OUT <= ~OUT;
counter <= 0;
end
else
counter <= counter +1;
end
endmodule



//LED.v****整點(diǎn)報(bào)時(shí)
module LED(
input CP,
input EN,
input [4:0] Hr,
input [7:0] Min,
input [7:0] Sec,
output  regLED);
wire OneHz;
reg [5:0] Times ;
reg flag ;


OneHzMakerOneHzForLED(
.Q(OneHz),
.CP(CP));
initialbegin
Times =0;
flag =0;
LED <=0;
end


always @(posedgeCP)begin
if(~EN)
LED <=0;
else begin
if(!Min &&!Sec)
flag <= 1;
if(flag == 1)begin
if(OneHz == 1 && Times>=2*Hr ) begin
Times <= 0;
flag <= 0;
LED <= 0;
end
elsebegin
if(OneHz ==1)begin
LED <= ~LED;
Times <= Times+1;
end
end
end
end
end
endmodule



不知道為什么新浪博文會(huì)把格式打亂,發(fā)表出來的排版空格效果跟寫的有點(diǎn)不一樣。。。白白按照蘇豪的要求改了半天。。。




分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:86421 發(fā)表于 2015-10-12 20:43 | 只看該作者
這是高手呀
回復(fù)

使用道具 舉報(bào)

板凳
ID:1051745 發(fā)表于 2023-5-11 23:24 來自手機(jī) | 只看該作者
您好 請(qǐng)問您的激勵(lì)文件是怎么寫的
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表