?? clock.v
字號:
module clock(clk_1Hz, clk_1kHz, func_key, key1, key2,
mode, hour, minute, second, alarm);
input clk_1Hz ; //1Hz時鐘,供數字鐘使用
input clk_1kHz ;//1 kHz時鐘, 分成500Hz供鬧鐘和整點報時使用, 分頻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 ; //連至揚聲器, 整點報時及鬧鐘
reg[3:0] mode; //功能號指示(1~5)
reg[7:0] hour,minute,second;
reg[2:0] divide; //1 kHz信號10分頻得100Hz, 先5分頻,再2分頻
reg clk_100Hz; //100Hz供跑表用
reg clk_500Hz; //500Hz供準點報時時用
reg temp1,temp2,temp3;
wire funckey,adjust_key1,adjust_key2;
always@(posedge clk_1kHz)
begin
clk_500Hz=~clk_500Hz;//由1 kHz分頻得500Hz時鐘信號,整點報時使用
temp1=func_key;
temp2=key1;
temp3=key2;
if(divide==3'b101)//由1 kHz分頻得到100Hz信號,用作跑表的時鐘
begin
divide=0;
clk_100Hz=~clk_100Hz;
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));
always@(posedge clk_1)//clk_1
begin
if(mode!=3) //數字鐘
begin //23:59:59'時變為00:00:00
if(h1[5]&h1[1]&h1[0]&m1[6]&m1[4]&m1[3]&m1[0]&s1[6]&s1[4]&s1[3]&s1[0])
{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
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])//*9:59'時,秒為0,分加7
begin
m1=m1+7; s1=0;
end
else if(s1[6]&s1[4]&s1[3]&s1[0])//59秒時,秒為0,分加1
begin
m1=m1+1;s1=0;
end
else if(s1[3]&s1[0])//*9秒時秒加7
s1=s1+7;
else //秒加1
s1=s1+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
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;//跑表的100Hz時鐘,key1此時為暫停鍵
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)
begin
if((month[2])||(month[2]&month[1])||(month[3]&month[0])||(month[4]&month[0]))//小月按30天算
if(day[5]&day[4])
day=1;
else if(day[3]&day[0])
day=day+7;
else
day=day+1;
else if(month[1])//二月按28天算
if(day[5]&day[3])
day=1;
else if(day[3]&day[0])
day=day+7;
else
day=day+1;
else //大月按31天算
if(day[5]&day[4]&day[0])
day=1;
else if(day[3]&day[0])
day=day+7;
else
day=day+1;
end
/*
always@(posedge clk_key4) //每月按30天算
begin
if(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;
else
second=s2;
if((mode==1 & !key1 &!key2) | mode==3)
begin
hour=h1;minute=m1;
end
else if(mode==2)
begin
hour=h2;minute=m2;
end
else if(mode==4 | ((mode==1) & key1))
begin
hour=h4;minute=m4;
end
else
begin
hour=month;minute=day;
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);//揚聲器在整點及鬧鐘時間發出聲響
endmodule
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -