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

📄 route.v

📁 用verlog HDL写的电子日历,可以显示年,月,日和时间,具有闹铃的功能
💻 V
字号:
//=======选择设置计数初值的对象子模块=======//   
module route(clk_4Hz,mode,select,set,set_hr,set_min,set_sec,set_year,set_mon,set_day,set_week,set_ahr,set_amin,disp_mode,sel);
  input clk_4Hz;            // clk_4Hz作为连续快速加1的时钟信号
  input mode;               // 选择显示时间或日历或闹钟定时的功能控制信号
  input select,set;         // select为选择设置计数初值对象的按钮信号,set为设置计数初值的按钮信号,均为正脉冲
  output set_hr,set_min,set_sec,set_year,set_mon,set_day,set_week;// 作为fdiv_cnt子模块的输入
  output set_ahr,set_amin;  // 作为alarm子模块的输入
  output disp_mode; 
  output [1:0] sel;         //声明为输出是便于观察波形
  reg[1:0] disp_mode;   
  wire set_hr,set_min,set_sec,set_year,set_mon,set_day,set_week;
  reg[1:0] sel;
  reg[1:0] loop1,num1; // 中间变量,用于设置初值时连续快速加1
  // ----(1)mode信号用于控制显示不同的输出信号  
  always @(posedge mode)            
    begin
      if(disp_mode==3) disp_mode<=0;
      else disp_mode<=disp_mode+1;
    end
   
  //----(2)此模块使计数器sel[2..0]加1 
    always @(posedge select or posedge mode)       
      begin
        if (mode) 					//只要按一次mode键,则sel恢复到为0(正常显示状态)
          sel<=0;					
        else 
          begin
            if((disp_mode==0)|(disp_mode==1))//选择时分秒或年月日
              begin
              if(sel==3)
                sel<=1;		
              else 
                sel<=sel+1;     	// 每按一次select键,计数器sel[1..0]加1,对应于不同的设置对象
              end
            else if(disp_mode==3)	//在disp_mode==3时,选择闹钟定时,sel[1..0]随select信号触发而加1
              if(sel==2)
                 sel<=1;
              else 
                sel<=sel+1;   
          end
      end
 
//----(3)若长时间按下set键,则生成num1信号,用于设置初值时连续快速加1
    always @(posedge clk_4Hz)          
      begin
        if (set)                    
          begin
            if(loop1==3) num1<=1; // 当set为1时,若loop1为3,则使num1为1
            else
              begin
                loop1<=loop1+1;
                num1<=0;
              end
          end
        else                      // 正常计数时,loop1=0,num1=0
          begin
            loop1<=0;
            num1<=0;
          end
      end

//----(4)以下连续赋值语句根据计数器sel[1..0]的值和set确定设置计数初值的时钟信号的值
	assign set_hr= (disp_mode==0)&&(sel==1) && ((num1&&clk_4Hz)||(!num1&&set));   // set_hr
	assign set_min= (disp_mode==0)&&(sel==2) && ((num1&&clk_4Hz)||(!num1&&set));  // set_min  
	assign set_sec= (disp_mode==0)&&(sel==3) && ((num1&&clk_4Hz)||(!num1&&set));  // set_sec 
	assign set_year= (disp_mode==1)&&(sel==1) && ((num1&&clk_4Hz)||(!num1&&set)); // set_year 
	assign set_mon= (disp_mode==1)&&(sel==2) && ((num1&&clk_4Hz)||(!num1&&set));  // set_mon  
	assign set_day= (disp_mode==1)&&(sel==3) && ((num1&&clk_4Hz)||(!num1&&set));  // set_day  
	assign set_week= (disp_mode==2) && ((num1&&clk_4Hz)||(!num1&&set));           // set_week与sel无关 
	assign set_ahr=(disp_mode==3)&& (sel==1) && ((num1&&clk_4Hz)||(!num1&&set));  // set_ahr,当num1为1时,set_ahr=clk_4Hz,当num1为0时,set_ahr=set 
	assign set_amin=(disp_mode==3)&& (sel==2) && ((num1&&clk_4Hz)||(!num1&&set));  // set_amin

endmodule
/*注1:这里必须采用assign语句,与always模块并行执行;若采用case语句,则必须放在always块内,
       但当长时间按下set键,num1=1时,(num1&&clk_4Hz)并不=clk_4Hz,而是为0,仿真结果与预想的不一样!
 注2:这里的clk_4Hz是作为连续快速加1的时钟信号,当长时间按下set键时,num1为1,则设置初值的时钟信号即等于clk_4Hz;
      当短时间按动set键时,num1为0,则!num1为1,来一次set信号,则设置初值的时钟信号即等于set,将立刻捕捉到set。
 注3:这里(disp_mode==0)表示只在选择显示时分秒时,set_hr或set_min或set_sec有

⌨️ 快捷键说明

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