ISE实现多功能数字钟设计

  • 格式:doc
  • 大小:260.50 KB
  • 文档页数:31

一、任务要求用FPGA器件和EDA技术实现多功能数字钟的设计。

基本功能要求:能显示小时、分钟、秒钟(时、分用7段LED显示器,秒用LED灯)。

小时计数器为同步24进制;要求手动校时、校分。

扩展功能要求:任意时刻闹钟;小时显示(12/24)切换电路自动报整点时数。

二、建立工程在ISE 14,9软件中建立名为clock 的工程文件。

芯片系列选择Spatan3E,具体芯片型号选择XC3S100E,封装类型选择CP132,速度信息选择-5。

页脚内容1三、原理设计四、顶层模块设计创建名为top_clock的文件,本设计中顶层模块用于调用各个子模块,以及将闹钟与整点报时模块综合在内,顶层源码如下:module top_clock(input Hchange, //24小时,12小时切换信号页脚内容2input Change, //用来进行时分和秒的显示切换input CLK_50, //50MHz时钟input nCR,EN,Clock_EN,input Adj_Min,Adj_Hour,Adj_Clock, //使能信号,小时分钟调时允许信号,闹钟使能信号(拨钮开关)output [6:0] HEX0,output reg Led_Alarm,output reg [3:0] HEX //共阳极数码管对应端);reg Alarm;wire ENM_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;reg LD_6_RADIO;reg [7:0] sum,counter;页脚内容3supply1 Vdd;wire CP_1Hz;//===========分频=============Divider50MHz U0(.CLK_50M(CLK_50),.nCLR(nCR),.CLK_1HzOut(CP_1Hz));//用以时钟计数的CP defparam U0.N = 25,U0.CLK_Freq = 50000000,U0.OUT_Freq = 1;Divider50MHz U1(.CLK_50M(CLK_50),.nCLR(nCR),.CLK_1HzOut(CP_200Hz));//用以动态扫描的CP,供给数码管defparam U1.N = 18,U1.CLK_Freq = 50000000,U1.OUT_Freq = 200;页脚内容4//===========60进制秒计数器=========Scounter10 S0(TSecond[3:0],nCR,EN,CP_1Hz);//秒:个位Scounter6 S1(TSecond[7:4],nCR,(TSecond[3:0]==4'h9),CP_1Hz);//秒:十位//===========60进制分计数器=========Mcounter10 M0(TMinute[3:0],nCR,ENM_L,EN,CP_1Hz);//分:个位Mcounter6 M1(TMinute[7:4],nCR,ENM_H,EN,CP_1Hz);//分:十位assign ENM_L=Adj_Min?Vdd:(TSecond==8'h59);//分钟按书上CP调时assign ENM_H=(Adj_Min&&(TMinute[3:0]==4'h9))||(TMinute[3:0]==4'h9)&&(TSecond==8'h59); //24小时制counter24 H0(Hour_24[7:4],Hour_24[3:0],nCR,ENH,EN,CP_1Hz);assign ENH = Adj_Hour?Vdd:((TMinute==8'h59)&&(TSecond==8'h59));//===========12小时与24小时进制切换控制==========assign Display_HourAdjust=((Hour_24==8'h20)||(Hour_24==8'h21))?(Hour_24-24):(Hour_24-18);assign Hour_12 = (Hour_24<8'h13)?Hour_24:Display_HourAdjust;assign Display_HourT = Hchange?Hour_12:Hour_24;//===========闹钟============//----------时钟秒---------页脚内容5//counter60 CCS(nCR,CP_1Hz,EN,CSecond[7:4],CSecond[3:0]);//----------时钟分---------counter60 CCM(nCR,CP_1Hz,CMin_EN,CMinute[7:4],CMinute[3:0]);//--产生分使能信号--assign CMin_EN = (!EN && Adj_Clock && Adj_Min);//----------时钟时---------Counter24C CCH(nCR,CP_1Hz,CHour_EN,CHour[7:4],CHour[3:0]);//--产生时使能信号--assign CHour_EN = (!EN && Adj_Clock && Adj_Hour);//--闹钟响--always@(EN or Clock_EN) //闹钟开关beginif(EN && Clock_EN && (CHour == Display_HourT) && (CMinute == TMinute))Alarm <= 1;else Alarm <= 0;endalways@(posedge CLK_50 or negedge EN or negedge Alarm) //表示闹钟的LEDbegin页脚内容6if(~EN) Led_Alarm <= 0;elsebeginif(~Alarm) Led_Alarm <= 0;else Led_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) begin Display_Hour <= CHour;Minute <= CMinute;endelse begin Display_Hour <= Display_HourT;Minute <= TMinute;endendalways@(posedge CP_200Hz)begin页脚内容7if(Change==1) //数码管进行时分显示begincase(HEX)4'b1110: begin HEX<=4'b0111; bcd<= Display_Hour [7:4]; end //第一根数码管显示小时十位4'b0111: begin HEX<=4'b1011; bcd<= Display_Hour [3:0]; end //第二根显示小时个位4'b1011: begin HEX<=4'b1101; bcd<= Minute [7:4]; end //第三根显示分钟十位4'b1101: begin HEX<=4'b1110; bcd<= Minute [3:0]; end //第四根显示分钟个位default: begin HEX<=0111; bcd<=Display_Hour [7:4]; endendcaseendelse //数码管进行秒显示,change为低电平时显示秒begincase(HEX)4'b1110: begin HEX<=4'b1101; bcd<= TSecond [7:4]; end //第三根显示秒十位页脚内容84'b1101: begin HEX<=4'b1110; bcd<= TSecond [3:0]; end //第四根显示秒个位default: begin HEX<=1101; bcd<= TSecond [7:4]; endendcaseendendSEG7_LUT L0(HEX0,bcd); //调用数码管子函数//======整点报时==========assign LD_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;页脚内容9endendalways@(posedge CP_1Hz)if(Minute[7:0]==8'h00)begincounter[7:0]<=counter[7:0]+1'b1;endelsebegincounter[7:0]<=8'h00;endendmodule页脚内容10五、顶层模块设计图六、子模块设计1、50MHz分频器module Divider50MHz(CLK_50M,nCLR,CLK_1HzOut);parameter N = 25; //位宽parameter CLK_Freq = 50000000; //50MHz时钟输入parameter OUT_Freq = 1; //1Hz时钟输出页脚内容11input nCLR,CLK_50M; //输入端口说明output reg CLK_1HzOut; //输出端口说明reg [N-1:0] Count_DIV; //内部节点,存放计数器的输出值always@(posedge CLK_50M or negedge nCLR)beginif(!nCLR) begin CLK_1HzOut <= 0; Count_DIV <= 0; endelse beginif(Count_DIV <(CLK_Freq/(2*OUT_Freq)-1))//计数器模Count_DIV <= Count_DIV + 1'b1; //分频器计数加1else beginCount_DIV <= 0; //分频器输出清零CLK_1HzOut <= ~CLK_1HzOut; //输出信号取反endendendendmodule页脚内容122、秒模10计数器module Scounter10(Q,nCR,EN,CP);input CP,nCR,EN;output Q;reg [3:0] Q;always @(posedge CP or negedge nCR)beginif(~nCR) Q <= 4'b0000;//异步清零else if(~EN) Q <= Q; //暂停计数else if(Q==4'b1001) Q <= 4'b0000;else Q <= Q + 1'b1;end3、秒模6计数器module Scounter6(Q,nCR,EN,CP);input CP,nCR,EN;output Q;reg [3:0] Q;页脚内容13always @(posedge CP or negedge nCR)beginif(~nCR) Q <= 4'b0000;//异步清零else if(~EN) Q <= Q; //暂停计数else if(Q==4'b0101) Q <= 4'b0000;else Q <= Q + 1'b1;end4、分模10计数器module Mcounter10(Q,nCR,EN1,EN2,CP);input CP,nCR,EN1,EN2;output Q;reg [3:0] Q;always @(posedge CP or negedge nCR)beginif(~nCR) Q <= 4'b0000;//异步清零else if(~EN1||!EN2) Q <= Q; //暂停计数else if(Q==4'b1001) Q <= 4'b0000;页脚内容14else Q <= Q + 1'b1;end5、分模6计数器module Mcounter6(Q,nCR,EN1,EN2,CP);input CP,nCR,EN1,EN2;output Q;reg [3:0] Q;always @(posedge CP or negedge nCR)beginif(~nCR) Q <= 4'b0000;//异步清零else if(~EN1||~EN2) Q <= Q; //暂停计数else if(Q==4'b0101) Q <= 4'b0000;else Q <= Q + 1'b1;end6、模24计数器module counter24(CntH,CntL,nCR,EN1,EN2,CP);input CP,nCR,EN1,EN2;页脚内容15output reg [3:0] CntH,CntL;//小时的十位和个位输出always@(posedge CP or negedge nCR)beginif(~nCR) {CntH,CntL} <= 8'h00; //异步清零else if(~EN1||~EN2) {CntH,CntL} <= {CntH,CntL};//暂停计数else if((CntH)>2||(CntL>9)||(CntH)==2&&(CntL)>=3){CntH,CntL} <= 8'h00; //对小时计数器出错时的处理else if((CntH)==2&&(CntL)<3) //进行20~23计数begin CntH <=CntH; CntL <= CntL + 1'b1; endelse if(CntL==9) //小时十位的计数begin CntH <=CntH + 1'b1; CntL <= 4'b0000; endelsebegin CntH <= CntH; CntL <= CntL + 1'b1; endendendmodule7、模60计数器module counter60(nCLR,Clk,EN,CntH,CntL);页脚内容16input nCLR,Clk,EN;output reg [3:0] CntH,CntL;always@(posedge Clk or negedge nCLR)beginif(~nCLR){CntH,CntL} <= 0; //异步清零else if(~EN){CntH,CntL} <= {CntH,CntL}; //暂停信号else if(((CntH > 5)||(CntL > 9))||((CntH == 5)&&(CntL == 9))) {CntH,CntL} <= 8'h00; //异常处理else if(CntL == 9)begin CntH <= CntH + 1'b1;CntL <= 0;end //十位计数elsebegin CntH <= CntH;CntL <= CntL + 1'b1;end //个位计数endendmodule页脚内容178、数码管显示module SEG7_LUT(oSEG,iDIG);input [3:0] iDIG; //二进制输入output reg [6:0] oSEG; //7段码输出always@(iDIG)begincase(iDIG)4'h0: oSEG = 7'b000_0001;4'h1: oSEG = 7'b100_1111;4'h2: oSEG = 7'b001_0010;4'h3: oSEG = 7'b000_0110;4'h4: oSEG = 7'b100_1100;4'h5: oSEG = 7'b010_0100;4'h6: oSEG = 7'b010_0000;4'h7: oSEG = 7'b000_1111;4'h8: oSEG = 7'b000_0000;4'h9: oSEG = 7'b000_0100;页脚内容18default: oSEG=7'b1111111;endcaseendendmodule七、各模块仿真1、模10计数器测试代码:// Inputsreg nCR;reg EN;reg CP;// Outputs页脚内容19wire [3:0] Q;// Instantiate the Unit Under Test (UUT)counter10 uut (.Q(Q),.nCR(nCR),.EN(EN),.CP(CP));parameter PERIOD =40;//时钟信号周期设置为40ns always beginCP=1'b0;#(PERIOD/2) CP=1'b1;#(PERIOD/2);endinitial begin// Initialize InputsnCR = 0;页脚内容20EN = 1;CP = 1;// Wait 100 ns for global reset to finish#100;nCR=1;// Add stimulus hereendendmodule2、模6计数器测试代码:// Inputsreg nCR;reg EN;页脚内容21reg CP;// Outputswire [3:0] Q;// Instantiate the Unit Under Test (UUT)counter6 uut (.Q(Q),.nCR(nCR),.EN(EN),.CP(CP));parameter PERIOD =40;//时钟信号周期设置为40ns always beginCP=1'b0;#(PERIOD/2) CP=1'b1;#(PERIOD/2);endinitial begin页脚内容22// Initialize InputsnCR = 0;EN = 1;CP = 1;// Wait 100 ns for global reset to finish#100;nCR =1;// Add stimulus hereendendmodule3、模24计数器测试代码:// Inputs页脚内容23reg nCR;reg EN;reg CP;// Outputswire [3:0] CntH;wire [3:0] CntL;// Instantiate the Unit Under Test (UUT)counter24 uut (.CntH(CntH),.CntL(CntL),.nCR(nCR),.EN(EN),.CP(CP));parameter PERIOD =40;//时钟信号周期设置为40ns always beginCP=1'b0;页脚内容24#(PERIOD/2) CP=1'b1;#(PERIOD/2);endinitial begin// Initialize InputsnCR = 0;EN = 1;CP = 1;// Wait 100 ns for global reset to finish#100;nCR=1;// Add stimulus hereendendmodule页脚内容254、模60计数器测试代码:// Inputsreg nCLR;reg Clk;reg EN;// Outputswire [3:0] CntH;wire [3:0] CntL;// Instantiate the Unit Under Test (UUT)counter60 uut (.nCLR(nCLR),.Clk(Clk),页脚内容26.EN(EN),.CntH(CntH),.CntL(CntL));parameter PERIOD =40;//时钟信号周期设置为40ns always beginClk=1'b0;#(PERIOD/2) Clk=1'b1;#(PERIOD/2);endinitial begin// Initialize InputsnCLR = 0;Clk = 1;EN = 1;// Wait 100 ns for global reset to finish#100;页脚内容27nCLR=1;// Add stimulus hereendendmodule八、引脚分配NET "CLK_50" TNM_NET = CLK_50;TIMESPEC TS_CLK_50 = PERIOD "CLK_50" 20 ns HIGH 50%; NET "CLK_50" LOC = B8;NET "nCR" LOC = P11;NET "EN" LOC = L3;NET "Adj_Min" LOC = K3;NET "Adj_Hour" LOC = B4;NET "Change" LOC = G3;NET "Led_Alarm" LOC = N4;NET "Adj_Clock" LOC = E2;NET "Clock_EN" LOC = N3;NET "HEX0[6]" LOC = L14;页脚内容28NET "HEX0[5]" LOC = H12;NET "HEX0[4]" LOC = N14;NET "HEX0[3]" LOC = N11;NET "HEX0[2]" LOC = P12;NET "HEX0[1]" LOC = L13;NET "HEX0[0]" LOC = M12;NET "HEX[0]" LOC = F12;NET "HEX[1]" LOC = J12;NET "HEX[2]" LOC = M13;NET "HEX[3]" LOC = K14;NET "Hchange" LOC = F3;NET "CLK_50" SLEW = FAST;NET "LD_6" LOC = G1;九、设计实现1.运行Implement Design选项,进行转换、映射、布局布线操作。