📄 clock.v
字号:
module clock(glbclk,shift,select,set,ledscan,out,light,alm_light);
input glbclk, //1000Hz 时钟输入
shift,select,set;
output [7:0]out; //6位数码管公共数据线输出
output [5:0]ledscan; //六位数码管阴极扫描
output [1:0] light, //整点报时灯标志
alm_light;//闹铃标志
wire flash;
wire seh,reset,clk1000,clk4,msec,dsec,min,dmin,c_hour,c_day,c_month,c_year,c_w,alm_dmin,alm_c_hour,alm_c_day,alarmen;
wire [7:0]out1;
wire [5:0]pscan;
wire [3:0] s,ds,m,dm,yearnum,hyearnum,alm_m,alm_dm,dm1,m1,ds1,s1,dms1,ms1,week;
wire [7:0] alm_hour,hour,daynum,monthnum;
reg [7:0] out;
reg [5:0] scanf,ledscan;
reg [6:0] weekm;
reg [4:0] input1,input2,input3,input4,input5,input6;
reg [7:0] state;
reg [1:0] count2,light,alm_light;
reg [2:0] count1;
reg yearstyle,hold,keypressed,clk_day,clk_month,clk_year,clk_min,clk_hour,rst,a,b,c;
reg alm_clk_min,alm_clk_hour,c1_day;
reg [2:0] dedithercounter;
//变量定义
assign clk1000=glbclk;
au aau(glbclk,reset); //产生自动复位信号
up_count_500 flash1(clk1000,reset,flash); //产生闪烁的激励时钟
up_count_125 clockset(clk1000,reset,clk4); //产生4hz的信号
up_count_1000 mseca(clk1000,reset,msec); //产生秒激励信号
up_count_10 countsec(msec,reset,s,dsec); //产生秒位输出并给十秒进位
up_count_6 countsecd(dsec,reset,ds,min); //产生秒十位数据
up_count_10 countmin(clk_min,reset,m,dmin); //产生分钟个位数据
up_count_6 countmind(dmin,reset,dm,c_hour); //产生分钟十位数据
day_c houra(reset,clk_hour,hour,c_day); //产生小时位输出并给天进位
up_count_7 countmind7(c1_day,reset,week,c_w); //产生星期输出
month_c day(reset,clk_day,monthnum,yearstyle,daynum,c_month); //产生日期输出
year_c month(reset,clk_month,monthnum,c_year); //产生月份输出
up_count_10 year(clk_year,reset,yearnum,hyear); //产生年份个位输出
up_count_10 hyeara(hyear,reset,hyearnum,sos); //产生年份十位输出
timer timer1(glbclk,clk1000,b,((!(count1==3'b011))?1:(!select))&reset,dm1,m1,ds1,s1,dms1,ms1);//实现秒表功能
up_count_10 alm_countmin(alm_clk_min,reset,alm_m,alm_dmin);//闹钟分钟个位产生
up_count_6 alm_countmind(alm_dmin,reset,alm_dm,alm_c_hour);//闹钟分钟十位产生
day_c alm_houra(reset,alm_clk_hour,alm_hour,alm_c_day); //闹钟小时产生
scan scan1(clk1000,input1,input2,input3,input4,input5,input6,pscan,out1);
//6位 数码管扫描输出
always @(posedge glbclk or negedge reset)
if (!reset)
yearstyle<=0;
else if ({hyearnum,yearnum}%4==0)
yearstyle<=1;
else
yearstyle<=0; //产生用来区分平、闰年的变量
always @(posedge shift or negedge reset)
begin
if (!reset)
count1<=3'b000;
else
case (count1)
3'b000: count1<=3'b001;
3'b001: count1<=3'b010;
3'b010: count1<=3'b011;
3'b011: count1<=3'b100;
3'b100: count1<=3'b000;
default :count1<=3'b000;
endcase
end //区分产生的五种设置显示状态
assign seh=reset&(!shift);
always @(posedge select or negedge seh)
begin
if (!seh)
count2=2'b01;
else
case (count2)
2'b01: count2<=2'b10;
2'b10: count2<=2'b11;
2'b11: count2<=2'b01;
default: count2<=2'b01; //产生设置时闪烁位置的三种状态
endcase
end
always @(posedge clk4 or negedge set)
begin
if(!set)
begin
dedithercounter<=3'd0;
keypressed<=0;
hold<=0;
end
else
if(dedithercounter<3'd7)
begin
dedithercounter<=dedithercounter+1;
if(dedithercounter==3'd1)
hold<=1;
else if(dedithercounter==3'd4)
if(hold==1)
keypressed<=1;
else //dedithercounter=15
keypressed<=0;
end
else dedithercounter<=0;
end //分辨按键是否大于一秒
always @(posedge set or negedge reset)
if (!reset)
begin
a<=0; //闹钟开关控制信号
b<=1; //秒表启动,暂停控制信号
c<=0; //整点报时开关控制信号
end
else if({count1,count2}==5'b10001)
a<=~a;
else if(count1==3'b011)
b<=~b;
else if(count1==3'b000&&(!select))
c<=~c;
else
begin
a<=a;
b<=b;
c<=c;
end
always @(posedge glbclk)
case({count1,count2})
5'b10001: begin
alm_clk_min<=0;
alm_clk_hour<=0;
if (a==0)
state<=8'h0f;
else
state<=8'hac;
end
5'b10010: begin
alm_clk_hour=0;
if (keypressed)
alm_clk_min<=clk4;
else alm_clk_min<=set;
end
5'b10011: begin
alm_clk_min=0;
if (keypressed)
alm_clk_hour<=clk4;
else alm_clk_hour<=set;
end
default: begin
alm_clk_min<=0;
alm_clk_hour<=0;
state<=state;
end
endcase //实现闹钟的调整设定
assign alarmen=(!(alm_hour==hour&&alm_dm==dm&&alm_m==m)?0:((select|set|shift)?1:alarmen)); //实现在闹钟作用时按任意键停止
always @(posedge glbclk)
if (!alarmen&&state==8'hac&&alm_hour==hour&&alm_dm==dm&&alm_m==m&&!(ds==4'd5))
alm_light<=2'b11;
else
alm_light<=2'b00; //控制闹钟灯的亮、灭
always @(flash )
if (count1==3'b000||count1==3'b011)
scanf<=6'b111111;
else
begin
case(count2)
2'b01: begin
if(flash)
scanf<=6'b001111;
else
scanf<=6'b111111;
end
2'b10: begin
if(flash)
scanf<=6'b110011;
else
scanf<=6'b111111;
end
2'b11: begin
if(flash)
scanf<=6'b111100;
else
scanf<=6'b111111;
end
default: begin
if(flash)
scanf<=6'b001111;
else
scanf<=6'b111111;
end
endcase
end //产生设置时钟时各位闪烁的扫描信号
always @(posedge glbclk)
begin
ledscan[5]<=pscan[5]&scanf[5];
ledscan[4]<=pscan[4]&scanf[4];
ledscan[3]<=pscan[3]&scanf[3];
ledscan[2]<=pscan[2]&scanf[2];
ledscan[1]<=pscan[1]&scanf[1];
ledscan[0]<=pscan[0]&scanf[0];
out<=out1&8'b11111111;
end //实现闪烁功能
always @(posedge glbclk)
case (count1)
3'b000:
if (select)
begin
input1<={weekm[6],hyearnum};
input2<={weekm[5],yearnum};
input3<={weekm[4],monthnum[7:4]};
input4<={weekm[3],monthnum[3:0]};
input5<={weekm[2],daynum[7:4]};
input6<={weekm[1],daynum[3:0]};
end
else
begin
input1<={a,hour[7:4]}; //a为闹钟状态
input2<={1'b1,hour[3:0]};
input3<={1'b0,dm};
input4<={1'b1,m};
input5<={1'b0,ds};
input6<={c,s}; //c为整点报时状态
end
3'b001:
begin
input1<={1'b0,hyearnum};
input2<={1'b1,yearnum};
input3<={1'b0,monthnum[7:4]};
input4<={1'b1,monthnum[3:0]};
input5<={1'b0,daynum[7:4]};
input6<={1'b0,daynum[3:0]};
end
3'b010:
begin
input1<={1'b0,hour[7:4]};
input2<={1'b1,hour[3:0]};
input3<={1'b0,dm};
input4<={1'b1,m};
input5<={1'b0,ds};
input6<={1'b0,s};
end
3'b011:
begin
input1<={1'b0,dm1};
input2<={1'b1,m1};
input3<={1'b0,ds1};
input4<={1'b1,s1};
input5<={1'b0,dms1};
input6<={1'b0,ms1};
end
3'b100:
begin
input1<={1'b0,alm_hour[7:4]};
input2<={1'b1,alm_hour[3:0]};
input3<={1'b0,alm_dm};
input4<={1'b1,alm_m};
input5<={1'b0,state[7:4]};
input6<={1'b0,state[3:0]};
end
default: begin
input1<={1'b0,hour[7:4]};
input2<={1'b1,hour[3:0]};
input3<={1'b0,dm};
input4<={1'b1,m};
input5<={1'b0,ds};
input6<={1'b0,s};
end
endcase //实现各种状态的数码管显示切换
always @(posedge glbclk)
case({count1,count2})
5'b00101:begin
clk_month<=0;
clk_year<=0;
clk_min<=min;
clk_hour<=c_hour;
rst<=reset;
if (keypressed)
clk_day<=clk4;
else
clk_day<=set;
end
5'b00110:begin
begin if(((monthnum==8'b100||monthnum==8'b110||monthnum==8'b1001||monthnum==8'b10001)&&daynum==8'd49)||(monthnum==8'b10&&yearstyle&&daynum>8'd41)||(monthnum==8'b10&&(!yearstyle)&&daynum>8'd40))
clk_day<=set;
else
clk_day<=0;
end
clk_year<=0;
clk_min<=min;
clk_hour<=c_hour;
rst<=reset;
if (keypressed)
clk_month<=clk4;
else
clk_month<=set;
end
5'b00111: begin
begin
if(((monthnum==8'b100||monthnum==8'b110||monthnum==8'b1001||monthnum==8'b10001)&&daynum==8'd49)||(monthnum==8'b10&&yearstyle&&daynum>8'd41)||(monthnum==8'b10&&(!yearstyle)&&daynum>8'd40))
clk_day<=set;
else
clk_day<=0;
end
clk_month<=0;
clk_min<=min;
clk_hour<=c_hour;
rst<=reset;
if (keypressed)
clk_year<=clk4;
else
clk_year<=set;
end
5'b01001: begin
clk_hour<=0;
clk_min<=min;
rst<=reset&(!set);
end
5'b01010: begin
clk_day<=c_day;
clk_month<=c_month;
clk_year<=c_year;
clk_hour<=0;
rst<=reset;
if (keypressed)
clk_min<=clk4;
else
clk_min<=set;
end
5'b01011: begin
clk_day<=0;
clk_month<=c_month;
clk_year<=c_year;
clk_min<=min;
rst<=reset;
if (keypressed)
clk_hour<=clk4;
else
clk_hour<=set;
end
default: begin
clk_day<=c_day;
clk_month<=c_month;
clk_year<=c_year;
clk_min<=min;
clk_hour<=c_hour;
rst<=reset;
end
endcase //在各种状态下切换调整进位脉冲
always @(posedge glbclk)
if ({dm,m,ds}==0&&c&&s<4'd5)
light<=2'b11;
else
light<=2'b00; // 实现正点报时
always @(posedge glbclk)
if (select)
c1_day<=set; //在select按下时,用set调整星期
else
c1_day<=c_day;
always @(posedge c1_day or negedge reset)
if (!reset)
weekm<=7'b0000001;
else
weekm<={weekm[0],weekm[6:1]}; //实现星期显示的功能
endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -