⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 clock.v

📁 用vierilog语言描写的电子时钟源码
💻 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 + -