📄 route.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 + -