一、任务要求用FPGA器件和EDA技术实现多功能数字钟的设计。基本功能要求:能显示小时、分钟、秒钟(时、分用7段LED显示器,秒用LED灯)。小时计数器为同步24进制;要求手动校时、校分。扩展功能要求:任意时刻闹钟;小时显示(12/24)切换电路自动报整点时数。二、建立工程在ISE14,9软件中建立名为clock的工程文件。芯片系列选择Spatan3E,具体芯片型号选择XC3S100E,封装类型选择CP132,速度信息选择-5。三、原理设计四、顶层模块设计创建名为top_clock的文件,本设计中顶层模块用于调用各个子模块,以及将闹钟与整点报时模块综合在内,顶层源码如下:moduletop_clock(inputHchange,//24小时,12小时切换信号inputChange,//用来进行时分和秒的显示切换inputCLK_50,//50MHz时钟inputnCR,EN,Clock_EN,inputAdj_Min,Adj_Hour,Adj_Clock,//使能信号,小时分钟调时允许信号,闹钟使能信号(拨钮开关)output[6:0]HEX0,outputregLed_Alarm,outputreg[3:0]HEX//共阳极数码管对应端);regAlarm;wireENM_L,ENM_H,ENH;wire[7:0]Hour_24,TMinute,TSecond,CHour,CMinute;//中间变量声明,正常时钟变量和闹钟时钟变量wire[7:0]Hour_12,Display_HourT,Display_HourAdjust;reg[3:0]bcd=4'b0000;//记载数码管所要显示的数据reg[7:0]Display_Hour,Minute;regLD_6_RADIO;reg[7:0]sum,counter;supply1Vdd;wireCP_1Hz;//===========分频=============Divider50MHzU0(.CLK_50M(CLK_50),.nCLR(nCR),.CLK_1HzOut(CP_1Hz));//用以时钟计数的CPdefparamU0.N=25,U0.CLK_Freq=50000000,U0.OUT_Freq=1;Divider50MHzU1(.CLK_50M(CLK_50),.nCLR(nCR),.CLK_1HzOut(CP_200Hz));//用以动态扫描的CP,供给数码管defparamU1.N=18,U1.CLK_Freq=50000000,U1.OUT_Freq=200;//===========60进制秒计数器=========Scounter10S0(TSecond[3:0],nCR,EN,CP_1Hz);//秒:个位Scounter6S1(TSecond[7:4],nCR,(TSecond[3:0]==4'h9),CP_1Hz);//秒:十位//===========60进制分计数器=========Mcounter10M0(TMinute[3:0],nCR,ENM_L,EN,CP_1Hz);//分:个位Mcounter6M1(TMinute[7:4],nCR,ENM_H,EN,CP_1Hz);//分:十位assignENM_L=Adj_Min?Vdd:(TSecond==8'h59);//分钟按书上CP调时assignENM_H=(Adj_Min&&(TMinute[3:0]==4'h9))||(TMinute[3:0]==4'h9)&&(TSecond==8'h59);//24小时制counter24H0(Hour_24[7:4],Hour_24[3:0],nCR,ENH,EN,CP_1Hz);assignENH=Adj_Hour?Vdd:((TMinute==8'h59)&&(TSecond==8'h59));//===========12小时与24小时进制切换控制==========assignDisplay_HourAdjust=((Hour_24==8'h20)||(Hour_24==8'h21))?(Hour_24-24):(Hour_24-18);assignHour_12=(Hour_248'h13)?Hour_24:Display_HourAdjust;assignDisplay_HourT=Hchange?Hour_12:Hour_24;//===========闹钟============//----------时钟秒---------//counter60CCS(nCR,CP_1Hz,EN,CSecond[7:4],CSecond[3:0]);//----------时钟分---------counter60CCM(nCR,CP_1Hz,CMin_EN,CMinute[7:4],CMinute[3:0]);//--产生分使能信号--assignCMin_EN=(!EN&&Adj_Clock&&Adj_Min);//----------时钟时---------Counter24CCCH(nCR,CP_1Hz,CHour_EN,CHour[7:4],CHour[3:0]);//--产生时使能信号--assignCHour_EN=(!EN&&Adj_Clock&&Adj_Hour);//--闹钟响--always@(ENorClock_EN)//闹钟开关beginif(EN&&Clock_EN&&(CHour==Display_HourT)&&(CMinute==TMinute))Alarm=1;elseAlarm=0;endalways@(posedgeCLK_50ornegedgeENornegedgeAlarm)//表示闹钟的LEDbeginif(~EN)Led_Alarm=0;elsebeginif(~Alarm)Led_Alarm=0;elseLed_Alarm=~Led_Alarm;endend//alarm_clockAL0(Hour24,Minute,CP_1Hz,Set_Alarm,Close_clock,nCR,KeySet_Hour_ev,KeySet_Minute_ev,LD_7,Alarm_Hour,Alarm_Minute);//===========数码显示=========always@(Adj_Clock)//确定数码管显示闹钟还是正常时钟beginif(Adj_Clock)beginDisplay_Hour=CHour;Minute=CMinute;endelsebeginDisplay_Hour=Display_HourT;Minute=TMinute;endendalways@(posedgeCP_200Hz)beginif(Change==1)//数码管进行时分显示begincase(HEX)4'b1110:beginHEX=4'b0111;bcd=Display_Hour[7:4];end//第一根数码管显示小时十位4'b0111:beginHEX=4'b1011;bcd=Display_Hour[3:0];end//第二根显示小时个位4'b1011:beginHEX=4'b1101;bcd=Minute[7:4];end//第三根显示分钟十位4'b1101:beginHEX=4'b1110;bcd=Minute[3:0];end//第四根显示分钟个位default:beginHEX=0111;bcd=Display_Hour[7:4];endendcaseendelse//数码管进行秒显示,change为低电平时显示秒begincase(HEX)4'b1110:beginHEX=4'b1101;bcd=TSecond[7:4];end//第三根显示秒十位4'b1101:beginHEX=4'b1110;bcd=TSecond[3:0];end//第四根显示秒个位default:beginHEX=1101;bcd=TSecond[7:4];endendcaseendendSEG7_LUTL0(HEX0,bcd);//调用数码管子函数//======整点报时==========assignLD_6=LD_6_RADIO;always@(CP_1Hz)beginif((Minute[7:0]==8'h00)&&(counter[7:0](Hour_24[7:4]*10+Hour_24[3:0])))beginLD_6_RADIO=CP_1Hz;endelsebeginLD_6_RADIO=0;endendalways@(posedgeCP_1Hz)if(Minute[7:0]==8'h00)begincounter[7:0]=counter[7:0]+1'b1;endelsebegincounter[7:0]=8'h00;endendmodule五、顶层模块设计图六、子模块设计1、50MHz分频器moduleDivider50MHz(CLK_50M,nCLR,CLK_1HzOut);parameterN=25;//位宽parameterCLK_Freq=50000000;//50MHz时钟输入parameterOUT_Freq=1;//1Hz时钟输出inputnCLR,CLK_50M;//输入端口说明outputregCLK_1HzOut;//输出端口说明reg[N-1:0]Count_DIV;//内部节点,存放计数器的输出值always@(posedgeCLK_50MornegedgenCLR)beginif(!nCLR)beginCLK_1HzOut=0;Count_DIV=0;endelsebeginif(Count_DIV(CLK_Freq/(2*OUT_Freq)-1))//计数器模Count_DIV=Count_DIV+1'b1;//分频器计数加1elsebeginCount_DIV=0;//分频器输出清零CLK_1HzOut=~CLK_1HzOut;//输出信号取反endendendendmodule2、秒模10计数器moduleScounter10(Q,nCR,EN,CP);inputCP,nCR,EN;outputQ;reg[3:0]Q;always@(posedgeCPornegedgenCR)beginif(~nCR)Q=4'b0000;//异步清零elseif(~EN)Q=Q;//暂停计数elseif(Q==4'b1001)Q=4'b0000;elseQ=Q+1'b1;end3、秒模6计数器moduleScounter6(Q,nCR,EN,CP);inputCP,nCR,EN;outputQ;reg[3:0]Q;always@(posedgeCPornegedgenCR)beginif(~nCR)Q=4'b0000;//异步清零elseif(~EN)Q=Q;//暂停计数elseif(Q==4'b0101)Q=4'b0000;elseQ=Q+1'b1;end4、分模10计数器moduleMcounter10(Q,nCR,EN1,EN2,CP);inputCP,nCR,EN1,EN2;outputQ;reg[3:0]Q;always@(posedgeCPornegedgenCR)beginif(~nCR)Q=4'b0000;//异步清零elseif(~EN1||!EN2)Q=Q;//暂停计数elseif(Q==4'b1001)Q=4'b0000;elseQ=Q+1'b1;end5、分模6计数器moduleMcounter6(Q,nCR,EN1,EN2,CP);inputCP,nCR,EN1,EN2;outputQ;reg[3:0]Q;always@(posedgeCPornegedgenCR)beginif(~nCR)Q=4'b0000;//异步清零elseif(~