用verilog編寫的多功能數字鐘

admin @ 2014-03-26 , reply:0

概述
/*信號定義:clk:標準時鐘信號,本例中,其頻率為4Hz;clk_1k:產生鬧鈴音、報時音的時鐘信號,本例中其頻率為1024Hz;mode:功能控制信號;為0:計時功能;為1:鬧鐘功能;為2:手動校……

/* 信號定義:
clk: 標準時鐘信號,本例中,其頻率為4Hz;
clk_1k: 產生鬧鈴音、報時音的時鐘信號,本例中其頻率為1024Hz;
mode: 功能控制信號; 為0:計時功能;
為1:鬧鐘功能;
為2:手動校時功能;
turn: 接按鍵,在手動校時功能時,選擇是調整小時,還是分鐘;
若長時間按住該鍵,還可使秒信號清零,用於精確調時;
change: 接按鍵,手動調整時,每按一次,計數器加1;
如果長按,則連續快速加1,用於快速調時和定時;
hour,min,sec:此三信號分別輸出並顯示時、分、秒信號,
皆採用BCD 碼計數,分別驅動6 個數碼管顯示時間;
alert: 輸出到揚聲器的信號,用於產生鬧鈴音和報時音;
鬧鈴音為持續20 秒的急促的“嘀嘀嘀”音,若按住“change”鍵,
則可屏蔽該音;整點報時音為“嘀嘀嘀嘀—嘟”四短一長音;
LD_alert: 接發光二極體,指示是否設置了鬧鐘功能;
LD_hour: 接發光二極體,指示當前調整的是小時信號;
LD_min: 接發光二極體,指示當前調整的是分鐘信號。
*/
module clock(clk,clk_1k,mode,change,turn,alert,hour,min,sec,
LD_alert,LD_hour,LD_min);
input clk,clk_1k,mode,change,turn;
output alert,LD_alert,LD_hour,LD_min;
output[7:0] hour,min,sec;
reg[7:0] hour,min,sec,hour1,min1,sec1,ahour,amin;
reg[1:0] m,fm,num1,num2,num3,num4;
reg[1:0] loop1,loop2,loop3,loop4,sound;
reg LD_hour,LD_min;
reg clk_1Hz,clk_2Hz,minclk,hclk;
reg alert1,alert2,ear;
reg count1,count2,counta,countb;
wire ct1,ct2,cta,ctb,m_clk,h_clk;
always @(posedge clk)
begin
clk_2Hz<=~clk_2Hz;
if(sound==3) begin sound<=0; ear<=1; end
//ear 信號用於產生或屏蔽聲音
else begin sound<=sound+1; ear<=0; end
end
always @(posedge clk_2Hz) //由4Hz 的輸入時鐘產生1Hz 的時基信號
clk_1Hz<=~clk_1Hz;
always @(posedge mode) //mode 信號控制系統在三種功能間轉換
begin if(m==2) m<=0; else m<=m+1; end
always @(posedge turn)
fm<=~fm;
always //該進程產生count1,count2,counta,countb 四個信號
begin
case(m)
2: begin if(fm)
begin count1<=change; {LD_min,LD_hour}<=2; end
else
begin counta<=change; {LD_min,LD_hour}<=1; end
{count2,countb}<=0;
end
1: begin if(fm)
begin count2<=change; {LD_min,LD_hour}<=2; end
else
begin countb<=change; {LD_min,LD_hour}<=1; end
{count1,counta}<=2'b00;
end
default: {count1,count2,counta,countb,LD_min,LD_hour}<=0;
endcase
end
always @(negedge clk)
//如果長時間按下“change”鍵,則生成“num1”信號用於連續快速加1
if(count2) begin
if(loop1==3) num1<=1;
else
begin loop1<=loop1+1; num1<=0; end
end
else begin loop1<=0; num1<=0; end
always @(negedge clk) //產生num2 信號
if(countb) begin
if(loop2==3) num2<=1;
else
begin loop2<=loop2+1; num2<=0; end
end
else begin loop2<=0; num2<=0; end
always @(negedge clk)
if(count1) begin
if(loop3==3) num3<=1;
else
begin loop3<=loop3+1; num3<=0; end
end
else begin loop3<=0; num3<=0; end
always @(negedge clk)
if(counta) begin
if(loop4==3) num4<=1;
else
begin loop4<=loop4+1; num4<=0; end
end
else begin loop4<=0; num4<=0; end
assign ct1=(num3&clk)|(!num3&m_clk); //ct1 用於計時、校時中的分鐘計數
assign ct2=(num1&clk)|(!num1&count2); //ct2 用於定時狀態下調整分鐘信號
assign cta=(num4&clk)|(!num4&h_clk); //cta 用於計時、校時中的小時計數
assign ctb=(num2&clk)|(!num2&countb); //ctb 用於定時狀態下調整小時信號
always @(posedge clk_1Hz) //秒計時和秒調整進程
if(!(sec1^8'h59)|turn&(!m))
begin
sec1<=0; if(!(turn&(!m))) minclk<=1;
end
//按住“turn”按鍵一段時間,秒信號可清零,該功能用於手動精確調時
else begin
if(sec1[3:0]==4'b1001)
begin sec1[3:0]<=4'b0000; sec1[7:4]<=sec1[7:4]+1; end
else sec1[3:0]<=sec1[3:0]+1; minclk<=0;
end
assign m_clk=minclk||count1;
always @(posedge ct1) //分計時和分調整進程
begin
if(min1==8'h59) begin min1<=0; hclk<=1; end
else begin
if(min1[3:0]==9)
begin min1[3:0]<=0; min1[7:4]<=min1[7:4]+1; end
else min1[3:0]<=min1[3:0]+1; hclk<=0;
end
end
assign h_clk=hclk||counta;
always @(posedge cta) //小時計時和小時調整進程
if(hour1==8'h23) hour1<=0;
else if(hour1[3:0]==9)
begin hour1[7:4]<=hour1[7:4]+1; hour1[3:0]<=0; end
else hour1[3:0]<=hour1[3:0]+1;
always @(posedge ct2) //鬧鐘定時功能中的分鐘調節進程
if(amin==8'h59) amin<=0;
else if(amin[3:0]==9)
begin amin[3:0]<=0; amin[7:4]<=amin[7:4]+1; end
else amin[3:0]<=amin[3:0]+1;
always @(posedge ctb) //鬧鐘定時功能中的小時調節進程
if(ahour==8'h23) ahour<=0;
else if(ahour[3:0]==9)
begin ahour[3:0]<=0; ahour[7:4]<=ahour[7:4]+1; end
else ahour[3:0]<=ahour[3:0]+1;
always //鬧鈴功能
if((min1==amin)&&(hour1==ahour)&&(amin|ahour)&&(!change))
//若按住“change”鍵不放,可屏蔽鬧鈴音
if(sec1<8'h20) alert1<=1; //控制鬧鈴的時間長短
else alert1<=0;
else alert1<=0;
always //時、分、秒的顯示控制
case(m)
3'b00: begin hour<=hour1; min<=min1; sec<=sec1; end
//計時狀態下的時、分、秒顯示
3'b01: begin hour<=ahour; min<=amin; sec<=8'hzz; end
//定時狀態下的時、分、秒顯示
3'b10: begin hour<=hour1; min<=min1; sec<=8'hzz; end
//校時狀態下的時、分、秒顯示
endcase
assign LD_alert=(ahour|amin)?1:0; //指示是否進行了鬧鈴定時
assign alert=((alert1)?clk_1k&clk:0)|alert2; //產生鬧鈴音或整點報時音
always //產生整點報時信號alert2
begin
if((min1==8'h59)&&(sec1>8'h54)||(!(min1|sec1)))
if(sec1>8'h54) alert2<=ear&clk_1k; //產生短音
else alert2<=!ear&clk_1k; //產生長音
else alert2<=0;
end
endmodule




[admin via 研發互助社區 ] 用verilog編寫的多功能數字鐘已經有5363次圍觀

http://cocdig.com/docs/show-post-43520.html