by:limanjihe
1. 功能要求:
能够显示年月日,星期,时分秒,并且实现闰年的自动调整。覆盖率不低于90%,且能通过DC综合。
2. 设置的输入的功能:
显示的时间范围为1900年1月1日——2200年12月31日,能实现闰年的自动调整以及月份的调整;
3. 源程序Code:
`timescale 100ms/100ms
module time_2( clk,
time_set,
rst, //time_clear--rst; time_set_en--time_set;
year_set, // 12'b1000_0011_0100=2100
mon_set, // 4'b1100=12
week_set, // 3'b111=7
day_set, // 5'b1_1111=31
hour_set, // 5'b1_1000=24
min_set, // 6'b11_1100=60
sec_set, // 6'b11_1100=60
year, // year[4'h0000],
mon,
week,
day,
hour,
min,
sec,
year_carry, // carry define
mon_carry,
day_carry,
hour_carry,
min_carry
);
input clk;
input time_set;
input rst; //time_clear--rst; time_set_en--time_set;
input[11:0] year_set; // 12'b1000_0011_0100=2100
input[3:0] mon_set; // 4'b1100=12
input[2:0] week_set; // 3'b111=7
input[4:0] day_set; // 5'b1_1111=31
input[4:0] hour_set; // 5'b1_1000=24
input[5:0] min_set; // 6'b11_1100=60
input[5:0] sec_set; // 6'b11_1100=60
output[11:0] year; // 12'b1000_0011_0100=2100
output[3:0] mon; // 4'b1100=12
output[2:0] week; // 3'b111=7
output[4:0] day; // 5'b1_1111=31
output[4:0] hour; // 5'b1_1000=24
output[5:0] min; // 6'b11_1100=60
output[5:0] sec; // 6'b11_1100=60
output min_carry,hour_carry,day_carry,mon_carry,year_carry;
reg[11:0] year; // 12'b1000_0011_0100=2100
reg[3:0] mon; // 4'b1100=12
reg[2:0] week; // 3'b111=7
reg[4:0] day; // 5'b1_1111=31
reg[4:0] hour; // 5'b1_1000=24
reg[5:0] min; // 6'b11_1100=60
reg[5:0] sec; // 6'b11_1100=60
reg min_carry,hour_carry,day_carry,mon_carry,year_carry;
reg[4:0] date; // 5'b1_1111=31
wire year_4;
wire year_100;
wire year_400;
/*
always@(rst)
begin
year<=2000;
mon<=1;
week<=6;
day<=1;
hour<=0;
min<=0;
sec<=0;
end
*/
assign year_4=(year[1:0]==2'b0);
assign year_100=!(year[3:2]==2'b11);
assign year_400=(year[3:0]==4'b0);
always@(posedge time_set or posedge clk or posedge rst ) //sec
begin
if(rst)
begin
sec<=0;
end
else if(time_set)
begin
sec<=sec_set;
end
else if(sec==59)
begin
sec<=0;
min_carry<=1;
end
else
begin
sec<=sec+1;
min_carry<=0;
end
end
always@(posedge min_carry or posedge time_set or posedge rst) //min
begin
if(rst)
begin
min<=0;
end
else if(time_set)
begin
min<=min_set;
hour_carry<=0;
end
else if(min==59)
begin
min<=0;
hour_carry<=1;
end
else
begin
min<=min+1;
hour_carry<=0;
end
end
always@(posedge hour_carry or posedge time_set or posedge rst) //hour
begin
if(rst)
begin
hour<=0;
end
else if(time_set)
begin
hour<=hour_set;
day_carry<=0;
end
else if(hour==23)
begin
hour<=0;
day_carry<=1;
end
else
begin
hour<=hour+1;
day_carry<=0;
end
end
always@(posedge day_carry or posedge time_set or posedge rst) //day
begin
if(rst)
begin
day<=1;
end
else if(time_set)
begin
day<=day_set;
mon_carry<=0;
end
else if(day==date)
begin
day<=1;
mon_carry<=1;
end
else
begin
day<=day+1;
mon_carry<=0;
end
end
always@(posedge day_carry or posedge time_set or posedge rst) //week
begin
if(rst)
begin
week<=6;
end
else if(time_set)
begin
week<=week_set;
end
else if(week==7)
begin
week<=1;
end
else
begin
week<=week+1;
end
end
always@(posedge mon_carry or posedge time_set or posedge rst) //month
begin
if(rst)
begin
mon<=1;
end
else if(time_set)
begin
mon<=mon_set;
year_carry<=0;
end
else if(mon==12)
begin
mon<=1;
year_carry<=1;
end
else
begin
mon<=mon+1;
year_carry<=0;
end
end
always@(posedge year_carry or posedge time_set or posedge rst)//year
begin
if(rst)
begin
year<=2000;
end
else if(time_set)
begin
year<=year_set;
end
else if(year==2199)
begin
year<=2000;
end
else
begin
year<=year+1;
end
end
always@(*)
begin
case(mon)
1:date=31;
2:
begin
if(((year_4&&!year_400)&&!year_100)||year_400)
date=29;
else
date=28;
end
3:date=31;
4:date=30;
5:date=31;
6:date=30;
7:date=31;
8:date=31;
9:date=30;
10:date=31;
11:date=30;
12:date=31;
// default:date=30;
endcase
end
endmodule
4.testbench code:
`timescale 10ns/10ns //100ms=10000*10ns
module time_tb_2;
//input
reg clk;
reg time_set;
reg rst; //time_clear--rst; time_set_en--time_set;
reg[11:0] year_set; // 12'b1000_0011_0100=2100
reg[3:0] mon_set; // 4'b1100=12
reg[2:0] week_set; // 3'b111=7
reg[4:0] day_set; // 5'b1_1111=31
reg[4:0] hour_set; // 5'b1_1000=24
reg[5:0] min_set; // 6'b11_1100=60
reg[5:0] sec_set; // 6'b11_1100=60
//output
wire[11:0] year; // 12'b1000_0011_0100=2100
wire[3:0] mon; // 4'b1100=12
wire[2:0] week; // 3'b111=7
wire[4:0] day; // 5'b1_1111=31
wire[4:0] hour; // 5'b1_1000=24
wire[5:0] min; // 6'b11_1100=60
wire[5:0] sec; // 6'b11_1100=60
wire min_carry,hour_carry,day_carry,mon_carry,year_carry;
//example
time_2 bt(
clk,
time_set,
rst, //time_clear--rst; time_set_en--time_set;
year_set, // 12'b1000_0011_0100=2100
mon_set, // 4'b1100=12
week_set, // 3'b111=7
day_set, // 5'b1_1111=31
hour_set, // 5'b1_1000=24
min_set, // 6'b11_1100=60
sec_set, // 6'b11_1100=60
year, // year[4'h0000],
mon,
week,
day,
hour,
min,
sec,
year_carry, // carry define
mon_carry,
day_carry,
hour_carry,
min_carry
);
//testing text;
initial begin
clk=0;
forever #5 clk=~clk; //10 = 1s
end
initial
begin
time_set=0; //1
rst=0;
#1 rst=1;
#1 rst=0;
#1000 time_set=1;//2
#1 time_set=0;
#1000 time_set=1;//3
#1 time_set=0;
#1000 time_set=1;//4
#1 time_set=0;
#1000 time_set=1;//5
#1 time_set=0;
#1000 time_set=1;//6
#1 time_set=0;
#1000 time_set=1;//7
#1 time_set=0;
#1000 time_set=1;//8
#1 time_set=0;
#1000 time_set=1;//9
#1 time_set=0;
#1000 time_set=1;//10
#1 time_set=0;
#1000 time_set=1;//11
#1 time_set=0;
#1000 time_set=1;//12
#1 time_set=0;
#1000 time_set=1;//13
#1 time_set=0;
#1000 time_set=1;//14
#1 time_set=0;
#1000 time_set=1;//15
#1 time_set=0;
#1000 time_set=1;//16
#1 time_set=0;
#1000 time_set=1;//17
#1 time_set=0;
#1000 time_set=1;//18
#1 time_set=0;
#1000 time_set=1;//19
#1 time_set=0;
end
initial
begin // January
year_set=2000; // 12'b1000_0011_0100=2100
mon_set=1; // 4'b1100=12
week_set=1; // 3'b111=7
day_set=1; // 5'b1_1111=31
hour_set=0; // 5'b1_1000=24
min_set=0; // 6'b11_1100=60
sec_set=0;
#1000; //February
year_set=1996; // 12'b1000_0011_0100=2100
mon_set=2; // 4'b1100=12
week_set=6; // 3'b111=7
day_set=28; // 5'b1_1111=31
hour_set=23; // 5'b1_1000=24
min_set=59; // 6'b11_1100=60
sec_set=0;
#1000; // February
year_set=2000; // 12'b1000_0011_0100=2100
mon_set=2; // 4'b1100=12
week_set=1; // 3'b111=7
day_set=28; // 5'b1_1111=31
hour_set=23; // 5'b1_1000=24
min_set=59; // 6'b11_1100=60
sec_set=0;
#1000; //February
year_set=2000; // 12'b1000_0011_0100=2100
mon_set=2; // 4'b1100=12
week_set=6; // 3'b111=7
day_set=29; // 5'b1_1111=31
hour_set=23; // 5'b1_1000=24
min_set=59; // 6'b11_1100=60
sec_set=0;
#1000; //February
year_set=2004; // 12'b1000_0011_0100=2100
mon_set=2; // 4'b1100=12
week_set=6; // 3'b111=7
day_set=28; // 5'b1_1111=31
hour_set=23; // 5'b1_1000=24
min_set=59; // 6'b11_1100=60
sec_set=0;
#1000; //February
year_set=2100; // 12'b1000_0011_0100=2100
mon_set=2; // 4'b1100=12
week_set=6; // 3'b111=7
day_set=28; // 5'b1_1111=31
hour_set=23; // 5'b1_1000=24
min_set=59; // 6'b11_1100=60
sec_set=0;
#1000; // February
year_set=2015; // 12'b1000_0011_0100=2100
mon_set=2; // 4'b1100=12
week_set=6; // 3'b111=7
day_set=28; // 5'b1_1111=31
hour_set=23; // 5'b1_1000=24
min_set=59; // 6'b11_1100=60
sec_set=0;
#1000; //March
year_set=2015; // 12'b1000_0011_0100=2100
mon_set=3; // 4'b1100=12
week_set=7; // 3'b111=7
day_set=29; // 5'b1_1111=31
hour_set=23; // 5'b1_1000=24
min_set=59; // 6'b11_1100=60
sec_set=0;
#1000; //March
year_set=2015; // 12'b1000_0011_0100=2100
mon_set=3; // 4'b1100=12
week_set=1; // 3'b111=7
day_set=30; // 5'b1_1111=31
hour_set=23; // 5'b1_1000=24
min_set=59; // 6'b11_1100=60
sec_set=0;
#1000; //April
year_set=2015; // 12'b1000_0011_0100=2100
mon_set=4; // 4'b1100=12
week_set=4; // 3'b111=7
day_set=30; // 5'b1_1111=31
hour_set=23; // 5'b1_1000=24
min_set=59; // 6'b11_1100=60
sec_set=0;
#1000; //May
year_set=2015; // 12'b1000_0011_0100=2100
mon_set=5; // 4'b1100=12
week_set=2; // 3'b111=7
day_set=30; // 5'b1_1111=31
hour_set=23; // 5'b1_1000=24
min_set=59; // 6'b11_1100=60
sec_set=0;
#1000; //june
year_set=2015; // 12'b1000_0011_0100=2100
mon_set=6; // 4'b1100=12
week_set=2; // 3'b111=7
day_set=30; // 5'b1_1111=31
hour_set=23; // 5'b1_1000=24
min_set=59; // 6'b11_1100=60
sec_set=0;
#1000; //july
year_set=2015; // 12'b1000_0011_0100=2100
mon_set=7; // 4'b1100=12
week_set=4; // 3'b111=7
day_set=30; // 5'b1_1111=31
hour_set=23; // 5'b1_1000=24
min_set=59; // 6'b11_1100=60
sec_set=0;
#1000; //August
year_set=2015; // 12'b1000_0011_0100=2100
mon_set=8; // 4'b1100=12
week_set=7; // 3'b111=7
day_set=30; // 5'b1_1111=31
hour_set=23; // 5'b1_1000=24
min_set=59; // 6'b11_1100=60
sec_set=0;
#1000; //september
year_set=2015; // 12'b1000_0011_0100=2100
mon_set=9; // 4'b1100=12
week_set=7; // 3'b111=7
day_set=30; // 5'b1_1111=31
hour_set=23; // 5'b1_1000=24
min_set=59; // 6'b11_1100=60
sec_set=0;
#1000; //october
year_set=2015; // 12'b1000_0011_0100=2100
mon_set=10; // 4'b1100=12
week_set=5; // 3'b111=7
day_set=30; // 5'b1_1111=31
hour_set=21; // 5'b1_1000=24
min_set=59; // 6'b11_1100=60
sec_set=0;
#1000; //november
year_set=2015; // 12'b1000_0011_0100=2100
mon_set=11; // 4'b1100=12
week_set=1; // 3'b111=7
day_set=30; // 5'b1_1111=31
hour_set=23; // 5'b1_1000=24
min_set=59; // 6'b11_1100=60
sec_set=0;
#1000; //december
year_set=2015; // 12'b1000_0011_0100=2100
mon_set=12; // 4'b1100=12
week_set=4; // 3'b111=7
day_set=31; // 5'b1_1111=31
hour_set=23; // 5'b1_1000=24
min_set=59; // 6'b11_1100=60
sec_set=0;
#1000; //december
year_set=2199; // 12'b1000_0011_0100=2100
mon_set=12; // 4'b1100=12
week_set=6; // 3'b111=7
day_set=31; // 5'b1_1111=31
hour_set=23; // 5'b1_1000=24
min_set=59; // 6'b11_1100=60
sec_set=0;
#1000;
$stop;
end
endmodule