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

📄 clock_verilog.txt

📁 verilog语言实现的数字钟
💻 TXT
字号:
module clock(clk_1Hz, clk_1kHz, func_key, key1, key2,mode, hour, minute, second, alarm,clk_key12,clk_1);
input clk_1Hz ;     //1Hz时钟,供数字钟使用
input clk_1kHz ;    //1 kHz时钟, 分成500 Hz供闹钟和整点报时使用, 分频100Hz供跑表使用
input func_key ;     //功能键, 1表示数字钟, 2表示跑表, 3表示调时, 4表示设置闹钟,5表示日期设置
input key1 ;         //功能1时显示闹钟时间, 功能2时暂停, 功能3、4时调小时, 功能5时调月份
input key2 ;         //功能1时显示日期, 功能2时清零, 功能3、4时调分, 功能5时调日
output [3:0] mode;   //功能号指示
output [7:0] hour ;  //功能1、3和4时显示小时, 功能2时显示分钟, 功能5时显示月份
output [7:0] minute; //功能1、3和4时显示分钟, 功能2时显示秒, 功能5时显示日期
output [7:0] second; //功能1时显示秒, 功能2时显示1/100秒, 其余时固定显示0
output alarm ;       //连至扬声器, 整点报时及闹钟
output clk_key12;
output clk_1;
reg[3:0] mode;       //功能号指示(1~5)
reg[7:0] hour,minute,second;
reg[2:0] divide;     //1 kHz信号10分频得100 Hz, 先5分频,再2分频
reg clk_100Hz;      //100 Hz供跑表用
reg clk_500Hz;      //500 Hz供准点报时时用
reg clk_day;            //周期为一天,每24小时取反一次
reg temp1,temp2,temp3;
wire funckey,adjust_key1,adjust_key2;
//------------------------------------------------------
always@(posedge clk_1kHz)
begin
clk_500Hz=~clk_500Hz;   //由1 kHz分频得500 Hz时钟信号,整点报时使用
temp1=func_key;
temp2=key1;
temp3=key2;
if(divide==3'b101)        
  begin
    divide=0;clk_100Hz=~clk_100Hz;      //由1 kHz分频得到100 Hz信号,用作跑表的时钟
  end
else divide=divide+1;
end
//------------------------------------------------------
assign funckey=func_key^temp1; //将func_key(乒乓开关)转换为琴键开关,按键一次则产生一个正脉冲,琴键开关
assign adjust_key1=key1^temp2; //将key1(乒乓开关)转换为琴键开关
assign adjust_key2=key2^temp3; //将key2(乒乓开关)转换为琴键开关
//-----------------------------------------------------------
always@(posedge funckey)
begin
if(mode[2]&mode[0]) mode[2]=0; //功能号在1~5之间变化,实现功能的循环
else mode=mode+1;
end
//------------------------------------------------------------
//------------------------------------------------------------
//功能1与功能3:数字钟及时间设置, 功能3以外其他功能将不影响数字钟的运行
reg[5:0] h1;      //功能1(数字钟)的时、分、秒
reg[6:0] m1,s1;
wire clk_1;       //数字钟时为1 Hz时钟, 时间设置时为按调整键产生的脉冲
assign clk_1=(clk_1Hz&&mode!=3)||(mode==3&&(adjust_key1||adjust_key2));  //非模式3时,数字钟的运行不受影响
//-------------------------------------------------------------
always@(posedge clk_1)
begin
  if(mode!=3)                          			//数字钟
    begin      
      if((h1[4]&h1[0]&m1[6]&m1[4]&m1[3]&m1[0]&s1[6]&s1[4]&s1[3]&s1[0])||(h1[5]&h1[1]&h1[0]&m1[6]&m1[4]&m1[3]&m1[0]&s1[6]&s1[4]&s1[3]&s1[0]) )  //11:59:59 23:59:59
        clk_day=~clk_day;                	  		
      else if(h1[5]&h1[1]&h1[0]&m1[6]&m1[4]&m1[3]&m1[0]&s1[6]&s1[4]&s1[3]&s1[0])    //23:59:59'时变为00:00:00
        {h1,m1,s1}=0;
      else if(h1[3]&h1[0]&m1[6]&m1[4]&m1[3]&m1[0]&s1[6]&s1[4]&s1[3]&s1[0])
        begin                          			//*9:59:59'时小时加7,分、秒变为0,实现9到10,19到20的跳转过程
         h1=h1+7;m1=0;s1=0;                 
        end
      else if(m1[6]&m1[4]&m1[3]&m1[0]&s1[6]&s1[4]&s1[3]&s1[0])
        begin					 //59:59' 时分、秒为0,小时加1
         h1=h1+1;m1=0;s1=0;
        end
      else if(m1[3]&m1[0]&s1[6]&s1[4]&s1[3]&s1[0])
        begin                      			   //*9:59'时秒为0,分加7,实现[n9]到[(n+1)0]的跳转
         m1=m1+7; s1=0;
        end
      else if(s1[6]&s1[4]&s1[3]&s1[0])
        begin                       			  //59秒时秒为0,分加1
         m1=m1+1;s1=0;
        end
      else if(s1[3]&s1[0]) 
        s1=s1+7;                    			  //*9秒时秒加7
      else s1=s1+1;                			   //秒加1
    end
  else if(adjust_key1)            			    //调时
   begin
     if(h1[5]&h1[1]&h1[0]) 
      h1=0;
     else if(h1[3]&h1[0]) 
      h1=h1+7;
     else 
      h1=h1+1;
   end
//----------------------------
  else if(m1[6]&m1[4]&m1[3]&m1[0])
   m1=0;                              //调分,在调节过程中,如果发生进位,不予考虑
  else if(m1[3]&m1[0])
   m1=m1+7;
  else m1=m1+1;
//----------------------------------修改程序段
 // else if (adjust_key2)
   //begin
   // if(m1[6]&m1[4]&m1[3]&m1[0])
  //   m1=0;                              //调分,在调节过程中,如果发生进位,不予考虑
  //  else if(m1[3]&m1[0])
  //   m1=m1+7;
  //  else m1=m1+1;
  // end    
//-------------------------------------------
end
//----------------------------------------------------------
//----------------------------------------------------------
//功能2:跑表,key1作为暂停键,key2作为清零键
reg[6:0] h2,m2; //功能2(数字跑表)时的时、分、秒
reg[7:0] s2;
wire clk_2;
assign clk_2=clk_100Hz&&mode==2&&(!key1); //跑表的100 Hz时钟,key1此时为暂停键,key是乒乓开关用法
always@(posedge clk_2)
begin
  if(key2||(h2[6]&h2[4]&h2[3]&h2[0]&m2[6]&m2[4]&m2[3]&m2[0]&s2[7]&s2[4]&s2[3]&s2[0]))
    {h2,m2,s2}=0;                                                           //跑表时key2清零,59:59'99"时清零
  else if(h2[3]&h2[0]&m2[6]&m2[4]&m2[3]&m2[0]&s2[7]&s2[4]&s2[3]&s2[0])
   begin
    h2=h2+7;m2=0;s2=0;
   end
  else if(m2[6]&m2[4]&m2[3]&m2[0]&s2[7]&s2[4]&s2[3]&s2[0])
   begin
    h2=h2+1;m2=0;s2=0;
   end
  else if(m2[3]&m2[0]&s2[7]&s2[4]&s2[3]&s2[0])
   begin
    m2=m2+7; s2=0;
   end
  else if(s2[7]&s2[4]&s2[3]&s2[0])
   begin
    m2=m2+1;s2=0;
   end
  else if(s2[3]&s2[0]) 
   s2=s2+7;
  else 
   s2=s2+1;
end
//--------------------------------------------------------------
//--------------------------------------------------------------
//功能4:闹钟设置,key1和key2分别用来调时和调分
reg[5:0] h4; //功能4(闹钟设置)时的时和分
reg[6:0] m4;
wire clk_key1,clk_key2;
assign clk_key1=adjust_key1 && mode==4; //功能4时key1作为调时键
assign clk_key2=adjust_key2 && mode==4; //功能4时key2作为调分键
always@(posedge clk_key1) //最大24小时
begin
  if(h4[5]&h4[1]&h4[0]) 
   h4=0;
  else if(h4[3]&h4[0])
   h4=h4+7;
  else 
   h4=h4+1;
end
always@(posedge clk_key2) //最大60分
begin
  if(m4[6]&m4[4]&m4[3]&m4[0])
   m4=0;
  else if(m4[3]&m4[0])
   m4=m4+7;
  else
   m4=m4+1;
end
//-------------------------------------------------------------
//-------------------------------------------------------------
//功能5:调日期,key1和key2分别调月和调日
//reg[4:0] month;
//reg[5:0] day;
//wire clk_key3,clk_key4;
//assign clk_key3=adjust_key1 && mode==5; //功能5时key1作为调月键
//assign clk_key4=adjust_key2 && mode==5; //功能5时key2作为调日键
//always@(posedge clk_key3) //最大12个月
//begin
//if(month[4]&month[1]) 
// month=1;
//else if(month[3]&month[0]) 
// month=month+7;
// else 
//month=month+1;
//end
//always@(posedge clk_key4) //每月按30天算
//begin
//if(day[5]&day[4]) 
//  day=1;
//else if(day[3]&day[0])
//  day=day+7;
//  else
//   day=day+1;
//end
//----------------------------------------------------------------
//正常情况下的日期计算
reg[4:0] month;
reg[5:0] day;
wire clk_key12;
//,clk_key3,clk_key4;
//assign clk_key3=adjust_key1&&mode==5; //功能5时key1作为调月键
//assign clk_key4=adjust_key2&&mode==5; //功能5时key2作为调日键 
assign clk_key12=(clk_day&&mode!=5)||((adjust_key1||adjust_key2)&&mode==5);
always@(posedge clk_key12)
begin 
  if(mode!=5)
 begin
      if(month==1&&day[5]&&day[4]&&day[0])  //1
        begin
         month=2;day=1;
        end
      else if(month==2&&day[5]&&day[3])  //2
        begin
          month=3;day=1;
        end
      else if(month==3&&day[5]&&day[4]&&day[0]) //3
        begin
         month=4;day=1;
        end
      else if(month==4&&day[5]&&day[4])  //4
        begin
         month=5;day=1;
        end
      else if(month==5&&day[5]&&day[4]&&day[0])   //5
        begin
          month=6;day=1;
        end
      else if(month==6&&day[5]&&day[4])   //6
        begin
          month=7;day=1;
        end
      else if(month==7&&day[5]&&day[4]&&day[0])  //7
        begin
          month=8;day=1;
        end
      else if(month==8&&day[5]&&day[4]&&day[0])  //8
        begin
          month=9;day=1;
        end
      else if(month==9&&day[5]&&day[4])  //9
        begin
          month=16;day=1;
        end
      else if(month==16&day[5]&&day[4]&&day[0])  //10
        begin
         month=17;day=1;
        end
      else if(month==17&&day[5]&&day[4])  //11
        begin
         month=18;day=1;
        end
      else if(month==18&&day[5]&&day[4]&&day[0])  //12
        begin
         month=1;day=1;
        end
      else if(day[3]&&day[0])
         day=day+7;
      else 
         day=day+1;
 end 
 
 else if(adjust_key2)  //日期调整,天数
 begin
  if((month==1||month==3||month==5||month==7||month==8||month==16||month==18)&&day[5]&&day[4]&&day[0]||(month==4||month==6||month==9||month==17)&&day[5]&&day[4]||month==2&&day[5]&&day[3])
   day=1;
  else if(day[3]&day[0])
   day=day+7;
  else
   day=day+1;
 end 

  else if(month[4]&month[1]) 
   month=1;
  else if(month[3]&month[0]) 
   month=month+7;
  else 
   month=month+1;
end 



  //else if((month==1||month==3||month==5||month==7||month==8||month==16||month==18)&&day[5]&&day[4]&&day[0]||(month==4||month==6||month==9||month==17)&&day[5]&&day[4]||month==2&&day[5]&&day[3])
   //day=1;
  //else if(day[3]&day[0])
   //day=day+7;
  //else
   //day=day+1;
//end


//----------------------------------------------------------------
//----------------------------------------------------------------
//显示模块:在各功能号下分别显示相应的值
always@(h1 or m1 or s1 or h2 or m2 or s2 or h4 or m4 or month or day or mode or key1 or key2)
begin
  if(mode[2]|(mode[1]&mode[0])|(mode==1&(key1|key2)))
   second=0;
  else if(mode==1)
   second=s1;     //模式1,时钟正常的秒计数
  else
   second=s2;     //模式2,跑表的1/100秒计数
//-------------------------------
  if((mode==1 & !key1 &!key2) | mode==3)   //模式1中定时时间和日期的显示,模式3中定时时间的显示
   begin
    hour=h1;minute=m1;     //模式1,时分计数
   end
  else if(mode==2)   
   begin
    hour=h2;minute=m2;     //模式2,跑表的分秒计数
   end
  else if(mode==4|((mode==1)&key1))    //模式4,定时时分计数,模式1,定时时分显示
   begin
    hour=h4;minute=m4;
   end
  else
   begin
    hour=month;minute=day;                //模式1,日期显示
   end
end
//-----------------------------------------------------------------
//-----------------------------------------------------------------
//发声单元:整点报时和定点闹时
wire spk,temp4,temp5;
assign temp4=m1[6]&m1[4]&m1[3]&m1[0]&s1[6]&s1[4]&!s1[0];  	//59:50', 52', 54', 56', 58'时
assign temp5=({m1,s1}==0)||((h1==h4)&&(m1==m4)&&!s1[0]);  	//定时到时每隔1秒及整点时
assign spk=(temp4&&clk_500Hz)||(temp5&&clk_1kHz);       	//整点及闹时送到扬声器的不同频率
assign alarm=(temp4||temp5)?spk:0;                                            	//扬声器在整点及闹钟时间发出声响
endmodule
//-----------------------------------------------------------------



















⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -