华科数电实验多功能数字钟,使用vivado和NexysDDR
原工程见主页
模块设计框图
工程代码
顶层文件
module CLOCK(
input CLOCK_100,KEY,SW,minutes,hours,minkey,hourkey,MUX,shift_12_24,stop,
output [7:0]LED,[7:0]POS,
output signal,
output alarm,
output info
);
//开关说明
//minutes:分钟校正(SW0)//minkey:分钟闹钟(SW2)//hours:小时校正(SW1)//hourkey:小时闹钟(SW3)
//MUX:当前时间和闹钟时间切换开关,正常为1(SW5)//shift_12_24:12和24的切换,正常为1(SW6)
//KEY:复位信号,0为复位(SW15)//SW:计时使能信号,1为计时使能(SW14)
//stop:闹钟关闭,按下即为关闭(BTNR)
//输出说明
//拨下SW5,就可以查看自己设置的闹钟时间,便于查看和设置闹钟
//拨下SW6,就可以切换小时的显示格式,即是24进制还是12进制
//当上午时,LED14点亮,下午时,LED14熄灭
//当整点时,几点LED15就会闪烁几次
//当当前时间和所设置的闹钟时间相等时,LED0就会点亮,除非按下闹钟关闭按钮
wire CLK_OUT_1hz,CLK_OUT_100hz;
wire [7:0]Q1,Q2,Q3,Qmin,Qhour,Qhour_inter,Qhour_shift;
wire [7:0]set_min,set_hour;
wire puncture;
frequency_1hz frequen_clock_1hz(
.R(KEY),
.CP(CLOCK_100),
.CLK_OUT(CLK_OUT_1hz)
); //1hz_分频器子模块
frequency_100hz frequen_clock_100hz(
.R(KEY),
.CP(CLOCK_100),
.CLK_OUT(CLK_OUT_100hz)
); //100hz_分频器子模块
CLOCK_24 time_clock(
.CLK(CLK_OUT_1hz),
.R(KEY),
.EN(SW),
.Q1(Q1),
.Q2(Q2),
.Q3(Q3),
.minutes(minutes),
.hours(hours)
); //时间计数模块,产生初始时分秒
MUX2TO1 min(
.D0(Q2),
.D1(set_min),
.S(MUX),
.Y(Qmin)
); //二选一子模块,选择输出为当前分钟或是闹钟分钟
MUX2TO1 hour_inter(
.D0(Q3),
.D1(set_hour),
.S(MUX),
.Y(Qhour_inter)
); //二选一子模块,选择输出为当前小时或是闹钟小时
shift24to12 shift(
.hour(Qhour_inter),
.Qhour(Qhour_shift)
); //24-12进制转换模块
MUX2TO1 hour_shift(
.D0(Qhour_inter),
.D1(Qhour_shift),
.S(shift_12_24),
.Y(Qhour)
); //二选一子模块,选择输出为24进制或是12进制
add_pos display(
.CLK(CLK_OUT_100hz),
.R(KEY),
.hour(Qhour),
.minite(Qmin),
.second(Q1),
.pos(POS),
.LED(LED)
);//数码管显示模块
bell bell_clock(
.CLK(CLK_OUT_1hz),
.R(KEY),
.minkey(minkey),
.hourkey(hourkey),
.set_min(set_min),
.set_hour(set_hour),
.SIGNAL(signal),
.now_hour(Q3),
.now_min(Q2),
.stop(stop)
); //闹钟模块,包括闹钟设置,时间匹配和闹钟关闭
assign puncture = (Q1==8'h59)&&(Qmin==8'h59);
PUNCTURE baoshi(
.clk(CLK_OUT_1hz),
.start(puncture),
.hour(Qhour_inter),
.LED(alarm)
); //整点报时模块
assign info = (Q3>8'h12)? 1'b0 : 1'b1;
endmodule
endmodule
分频为1hz模块
module frequency_1hz(R,CP,CLK_OUT);
input R,CP;
output reg CLK_OUT;
reg [27:0]counter;
parameter IN_FRE=100_000_000;
parameter OUT_FRE=1;
always@(posedge CP or negedge R)
begin
if(R==1'b0)
begin CLK_OUT<=0;
counter<=26'd0; end
else if(counter<(IN_FRE/OUT_FRE)-1)
begin
counter<=counter+1'b1;
CLK_OUT<=1'b0;
end
else
begin counter<=26'd0;
CLK_OUT<=1'b1; end
end
endmodule
分秒计数模块
module count10(CLK,R,EN,Q,CO);//10进制计数模块
input CLK,R,EN;
output reg[3:0]Q;
output CO;
always@( posedge CLK or negedge R)
begin
if(~R)Q<=4'b0000;//复位
else if(EN)
begin
if(Q<9)
Q<=Q+1'b1;
else
Q<=4'b0000;
end
else
Q<=Q;
end
assign CO=(Q==4'b1001);
endmodule
module count6(CLK,R,EN,Q,CO); //6进制计数模块
input CLK,R,EN;
output reg[3:0]Q;
output CO;
always@( posedge CLK or negedge R)
begin
if(~R)Q<=4'b0000;
else if(EN)
begin
if(Q<5)
Q<=Q+1'b1;//低于5时递增计数
else
Q<=4'b0000;
end
else
Q<=Q;
end
assign CO=(Q==4'b0101); //进位信号
endmodule
module count60(CLK,R,EN,Q,CO); //60进制计数模块
input CLK,R,EN;
output [7:0]Q;
output CO;
wire CO1,CO2;
count10 CLOCK10(
.CLK(CLK),
.R(R),
.EN(EN),
.Q(Q[3:0]),
.CO(CO1)
);
count6 CLOCK6(
.CLK(CLK),
.R(R),
.EN(EN&CO1),
.Q(Q[7:4]),
.CO(CO2)
);
assign CO=({Q[7:4],Q[3:0]}==8'h59);
endmodule
小时计数模块
module CLOCK_24(CLK,R,EN,Q1,Q2,Q3,minutes,hours);
input CLK,R,EN,minutes,hours;
output [7:0]Q1,Q2,Q3;//Q1为秒 Q2为分 Q3为时
reg [3:0]cnt1,cnt2;
wire CO1,CO2,CO3,CO24;
count60 second(
.CLK(CLK),
.R(R),
.EN(EN),
.Q(Q1),
.CO(CO1)
);//秒进位59
count60 minute(
.CLK(CLK),
.R(R),
.EN((~minutes&CO1)|(minutes&EN)),
.Q(Q2),
.CO(CO2)
);//分进位59
assign CO24=(~hours&EN&CO1&CO2)|(hours&EN); //小时计数使能
assign Q3[7:4]=cnt1;
assign Q3[3:0]=cnt2;
always@( posedge CLK or negedge R)
begin
if(~R) {cnt1,cnt2}<=8'h00;
else if(CO24)
begin
if({cnt1,cnt2}<8'h23) //低于23时递增计数
begin
if(cnt2<4'b1001)
cnt2<=cnt2+1'b1;
else
begin
cnt2<=4'b0000;
cnt1<=cnt1+1'b1;
end
end
else
{cnt1,cnt2}<=8'h00;
end
else {cnt1,cnt2}<={cnt1,cnt2};
end
endmodule
译码显示模块
module posdecode(
input [2:0] bcd6,
output [7:0]pos
);//位码模块
reg [7:0] posr;
assign pos=posr;
always @ (bcd6)
case (bcd6) //低位有效
3'b000:posr<=8'b11011111;
3'b001:posr<=8'b11101111;
3'b010:posr<=8'b11110111;
3'b011:posr<=8'b11111011;
3'b100:posr<=8'b11111101;
3'b101:posr<=8'b11111110;
default:posr<=8'b11111111;
endcase
endmodule
module add_pos(
input CLK,
input R,
input [7:0]hour,minite,second,
output [7:0]pos,
output reg [7:0]LED
);//扫略显示模块
reg [2:0]bcd;
wire [2:0]select;
wire [7:0]string;
wire [7:0]LED1,LED2,LED3,LED4,LED5,LED6;
wire [11:0]coding_bcd;
assign select = bcd;
posdecode all(select,pos); //选择输出数码管
register U1(hour[7:4],LED1);
register U2(hour[3:0],LED2);
register U3(minite[7:4],LED3);
register U4(minite[3:0],LED4);
register U5(second[7:4],LED5);
register U6(second[3:0],LED6);
always @ (posedge CLK or negedge R)
begin
if(R==1'b0)
begin
bcd<=0;
// LED<=8'b0000_0011;
end
else
begin
bcd<=(bcd+1'b1)%6; //有效数码管号数
end
end
always@(*)begin
case(select) //选择输出数据
3'b000:LED<=LED1;
3'b001:LED<=LED2;
3'b010:LED<=LED3;
3'b011:LED<=LED4;
3'b100:LED<=LED5;
3'b101:LED<=LED6;
endcase
end
endmodule
module register(COUNT,LED); //段码显示模块
input [3:0]COUNT;
output reg [7:0]LED;
always@(*)begin
case(COUNT)
4'b0000:LED<=8'b0000_0011; //0
4'b0001:LED<=8'b1001_1111; //1
4'b0010:LED<=8'b0010_0101; //2
4'b0011:LED<=8'b0000_1101; //3
4'b0100:LED<=8'b1001_1001; //4
4'b0101:LED<=8'b0100_1001; //5
4'b0110:LED<=8'b0100_0001; //6
4'b0111:LED<=8'b0001_1111; //7
4'b1000:LED<=8'b0000_0001; //8
4'b1001:LED<=8'b0000_1001; //9
default:LED<=8'b1111_1111;
endcase
end
endmodule
闹钟模块
Module bell(CLK,R,minkey,hourkey,set_min,set_hour,SIGNAL,now_hour,now_min,stop);
input CLK,R,minkey,hourkey;
input [7:0]now_hour,now_min;
input stop;
output [7:0]set_min;
output [7:0]set_hour;
output SIGNAL;
wire signal_1;
reg signal_2 = 1;
count60 minbell(
.CLK(CLK),
.R(1'b1),
.EN(minkey),
.Q(set_min)
); //设置闹钟分钟
count24 hourbell(
.CLK(CLK),
.R(1'b1),
.EN(hourkey),
.Q(set_hour)
); //设置闹钟小时
assign signal_1=(now_hour==set_hour)&(now_min==set_min);
assign SIGNAL = signal_1 && signal_2;
always @ (negedge stop or posedge signal_1)
begin
if(stop)
signal_2<=1'b0;
else
signal_2<=1'b1;
end
endmodule //关闭闹钟,关闭闹钟使用按键开关
module equal(now_hour,now_min,set_hour,set_min,signal);//时间比较模块
input [7:0]now_hour,now_min,set_hour,set_min;
output signal;
assign signal=(now_hour==set_hour)&(now_min==set_min);
endmodule
整点报时模块
module PUNCTURE(
input start,
input clk,
input [7:0]hour,
output reg LED
);
wire [7:0]bcd;
reg [7:0]count;
reg EN;
bito10 shift(hour,bcd);
always @ (posedge clk or posedge start) //用计数来实现LED灯的闪烁次数
begin
if(start)
begin
EN<=1;
count<= bcd<<1; //次数要*2
LED<=0;
end
else
begin
if(EN)
begin
if(count)
begin
count<=count-1 ;
LED<=~LED;
end
else
begin
count<=0;
EN<=0;
LED<=0;
end
end
end
end
endmodule
module bito10(
input [7:0]binary,
output [7:0]bcd
);
assign bcd=binary[7:4]*10+binary[3:0];
endmodule//16进制切换为10进制
12-24进制转换模块
module shift24to12(
input [7:0]hour,
output [7:0]Qhour
);
reg [7:0]A2;
assign Qhour= (hour>8'h12)? A2:hour;
always @ (*)
begin
case(hour) //分别转换
8'h13: A2=8'h01;
8'h14: A2=8'h02;
8'h15: A2=8'h03;
8'h16: A2=8'h04;
8'h17: A2=8'h05;
8'h18: A2=8'h06;
8'h19: A2=8'h07;
8'h20: A2=8'h08;
8'h21: A2=8'h09;
8'h22: A2=8'h10;
8'h23: A2=8'h11;
8'h24: A2=8'h12;
default: A2=hour;
endcase
end
endmodule
约束文件
set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets stop]
set_property PACKAGE_PIN E3 [get_ports CLOCK_100]
set_property PACKAGE_PIN V10 [get_ports KEY]
set_property PACKAGE_PIN J15 [get_ports minutes]
set_property PACKAGE_PIN L16 [get_ports hours]
set_property PACKAGE_PIN M13 [get_ports minkey]
set_property PACKAGE_PIN R15 [get_ports hourkey]
set_property PACKAGE_PIN T18 [get_ports MUX]
set_property PACKAGE_PIN U18 [get_ports shift_12_24]
set_property PACKAGE_PIN H17 [get_ports signal]
set_property PACKAGE_PIN U11 [get_ports SW]
set_property IOSTANDARD LVCMOS33 [get_ports CLOCK_100]
set_property IOSTANDARD LVCMOS33 [get_ports hourkey]
set_property IOSTANDARD LVCMOS33 [get_ports hours]
set_property IOSTANDARD LVCMOS33 [get_ports KEY]
set_property IOSTANDARD LVCMOS33 [get_ports minkey]
set_property IOSTANDARD LVCMOS33 [get_ports minutes]
set_property IOSTANDARD LVCMOS33 [get_ports MUX]
set_property IOSTANDARD LVCMOS33 [get_ports signal]
set_property IOSTANDARD LVCMOS33 [get_ports shift_12_24]
set_property IOSTANDARD LVCMOS33 [get_ports SW]
set_property PACKAGE_PIN U13 [get_ports {POS[7]}]
set_property PACKAGE_PIN K2 [get_ports {POS[6]}]
set_property PACKAGE_PIN T14 [get_ports {POS[5]}]
set_property PACKAGE_PIN P14 [get_ports {POS[4]}]
set_property PACKAGE_PIN J14 [get_ports {POS[3]}]
set_property PACKAGE_PIN T9 [get_ports {POS[2]}]
set_property PACKAGE_PIN J18 [get_ports {POS[1]}]
set_property PACKAGE_PIN J17 [get_ports {POS[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {POS[7]}]
set_property IOSTANDARD LVCMOS33 [get_ports {POS[6]}]
set_property IOSTANDARD LVCMOS33 [get_ports {POS[5]}]
set_property IOSTANDARD LVCMOS33 [get_ports {POS[4]}]
set_property IOSTANDARD LVCMOS33 [get_ports {POS[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {POS[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {POS[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {POS[0]}]
set_property PACKAGE_PIN T10 [get_ports {LED[7]}]
set_property PACKAGE_PIN R10 [get_ports {LED[6]}]
set_property PACKAGE_PIN K16 [get_ports {LED[5]}]
set_property PACKAGE_PIN K13 [get_ports {LED[4]}]
set_property PACKAGE_PIN P15 [get_ports {LED[3]}]
set_property PACKAGE_PIN T11 [get_ports {LED[2]}]
set_property PACKAGE_PIN L18 [get_ports {LED[1]}]
set_property PACKAGE_PIN H15 [get_ports {LED[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LED[7]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LED[6]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LED[5]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LED[4]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LED[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LED[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LED[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LED[0]}]
set_property PACKAGE_PIN V11 [get_ports alarm]
set_property IOSTANDARD LVCMOS33 [get_ports alarm]
set_property PACKAGE_PIN M17 [get_ports stop]
set_property IOSTANDARD LVCMOS33 [get_ports stop]
set_property PACKAGE_PIN V12 [get_ports info]
set_property IOSTANDARD LVCMOS33 [get_ports info]