唐衛斌
(商洛學院 物理與電子信息工程系,陜西商洛 726000)
Verilog語言是應用最廣泛的硬件描述語言(HDL)之一。它是硬件(數字邏輯電路)設計人員和EDA工具之間的界面;是一種用形式化方法來描述數字電路和設計數字邏輯系統的語言。設計者可以利用這種語言來描述自己的設計思想,然后利用EDA工具進行仿真驗證和時序分析,再自動綜合到門級電路,最后用ASIC(專用集成電路)或FPGA實現其功能[1-2]。
分頻器是FPGA設計中使用頻率非常高的基本單元之一。它是將較高頻率通過分頻得到較低頻率的一種單元電路。盡管目前在大部分設計中還廣泛使用集成鎖相環 (如altera的PLL,Xilinx的DLL)來進行時鐘的分頻、倍頻以及相移設計[3],但是,對于時鐘要求不太嚴格的設計,通過自主設計進行時鐘分頻的實現方法仍是不錯的選擇。首先這種方法可以節省鎖相環資源,再者,這種方式只消耗不多的邏輯單元就可以達到對時鐘操作的目的,具有成本低、可編程等優點[4]。而使用Verilog語言進行分頻器設計在當前設計實踐中并不多見,文獻[5]中夏宇聞教授對此稍有提及,但未給出具體代碼。本文在介紹計數器設計的基礎上,給出基于計數器的分頻器設計模版,包括偶數次分頻和奇數次分頻,這些模版在當前的設計實踐中尚且空缺,因而可以給其他數字邏輯電路設計人員直接調用,或者作為庫文件使用,從而大大縮短電路設計人員的設計時間。
計數器是實現分頻電路的基礎,計數器有普通計數器和約翰遜計數器兩種。這兩種計數器均可應用在分頻電路中[6]。
使用Verilog實現的模十加法計數器:
module cnt10(clk,rst,cnt);/*定義端口變量 */
input clk,rst;
output[3:0]cnt;
reg[3:0]cnt;
always@ (posedge clk,posedge rst)if(rst)cnt<=0; /*復位信號*/
else
begin if(cnt==9)cnt<=0; /*當計數到 9時強制歸零*/
else cnt<=cnt+1; /* 計數 */
end
endmodule
使用Modelsim仿真結果如圖1所示。

圖1 普通計數器仿真波形
從波形上可以看到輸出端口cnt反復循環輸出0~9這10個數字。普通計數器的RTL(寄存器傳輸級)結構圖如圖2所示[7]??梢娫撚嫈灯饔伤奈患臃▎卧退奈挥|發器構成。有兩個輸入端口:時鐘輸入clk和復位信號輸入rst。

圖2 普通計數器RTL結構
約翰遜計數器是一種移位計數器,采用的是把輸出的最高位取非,然后反饋送到最低位觸發器的輸入端。也稱為扭環形計數器。它在每個時鐘下只有一個輸出發生變化[8]。
約翰遜計數器沒有有效利用寄存器的所有狀態,假設最初值或復位狀態為0000,則依次為0000、0001、0011、0111、1111、1110、1100、1000、0000如此循環。
再者,如果由于干擾噪聲引入一個無效狀態,如0010,則無法恢復到有效循環中去,需要加入錯誤恢復處理。
分頻器有整數次分頻器和小數次分頻器之分。對于整數次分頻器又有奇數次和偶數次分頻器。這里只討論整數分頻。
偶數次分頻通過計數器計數是完全可以實現的。如進行N次偶數分頻,那么可以通過由待分頻的時鐘觸發計數器計數,當計數器從0計數到N/2-1時,輸出時鐘進行翻轉,并給計數器一個復位信號,使得下一個時鐘從零開始計數。以此循環下去。這種方法可以實現任意的偶數分頻[9]。基于此思路的代碼見注釋①。
從如圖3所示仿真波形上可以看到,通過計數器計數,每計數3次,輸出時鐘反相一次,從而使輸出時鐘為輸入時鐘的1/6,完成了6分頻,并且占空比是50%。

圖3 偶數次分頻仿真波形(6分頻)
奇數次分頻歸類為一般的方法為:對于實現占空比為50%的N次奇數分頻,首先進行上升沿觸發進行模N計數,計數從零開始,到(N-1)/2進行輸出時鐘翻轉,然后經過(N+1)/2再次進行翻轉得到一個占空比非50%奇數n分頻時鐘。再者同時進行下降沿觸發的模N計數,類似翻轉生成占空比非50%的奇數n分頻時鐘。兩個占空比非50%的n分頻時鐘相或運算,得到占空比為50%的奇數n分頻時鐘[10]?;诖怂悸返拇a見注釋②。
從如圖4仿真波形上可以清楚地看到count1和count2兩個計數器從1到4的計數過程,以及分別對應clk時鐘和clk_re時鐘計數所產生的clkA和clkB兩個中間時鐘,對這兩個中間時鐘相或的到最終所要的5分頻輸出時鐘clk_odd,并且占空比是50%。

圖4 奇數次分頻仿真波形(5分頻)
對該 5次分頻電路進行軟件綜合 (synopsys_DC),獲得RTL結構圖如圖5所示。

圖5 分頻器綜合結果—RTL結構圖
可以看到該邏輯電路是由若干與非門、或非門、反相器、或門以及D觸發器構成,是典型的數字電路。該電路再經過后續軟件進行布局布線、后仿真、時序分析、生成版圖,就可以獲得ASIC單元電路,應用到ASIC設計制造之中。
本文詳細給出了偶數次分頻和奇數次分頻的通用Verilog代碼,并給出了相應的解釋,通過了ModelSim的仿真。從仿真波形上看,兩段代碼均正確無誤的完成了預期的功能。可見兩段代碼可以作為設計模版提供給其他數字邏輯設計人員直接調用,或者作為庫文件使用。
注釋:
①偶數次分頻器代碼
module even_division(clk,rst,count,clk_odd);/*定義模塊 */
input clk,rst; /*輸入端口*/
output clk_even;//輸出端口
output[3:0]count;//輸出端口
reg clk_even;//寄存器變量
reg[3:0]count;//寄存器變量
parameter N=6;//定義參數 6分頻
always@(posedge clk)
if(!rst) //復位所有輸出寄存器
begin count<=1'b0;
clk_even<=1'b0;
end
else if(count< N/2-1)begin //0~N/2-1計數,對本例為0~2計數
count<=count+1'b1;//計數器加1
end
else begin
count <=1'b0;//計數器賦零
clk_even<=~clk_even;//輸出時鐘反相end
endmodule
②奇數次分頻器代碼
module odd_division(clk,rst,clk_odd);
input clk,rst;//定義輸入時鐘和復位信號
output clk_odd;//定義輸出時鐘
reg[3:0]count1,count2;//定義兩個計數器
reg clkA,clkB;//定義兩個中間時鐘
wire clk_odd,clk_re;//定義輸出時鐘和反相輸入時鐘為連線型變量
parameter N=5;//定義參數為5,即5分頻電路
assign clk_re=~clk;//將輸入時鐘反相,賦值給clk_re
assign clk_odd=clkA|clkB;//給出輸出時鐘的表達式clkA和clkB相或
always@(posedge clk)
if(!rst)
begin count1<=1'b0;clkA <=1'b0;//復位時鐘clkA和計數器count1
end
else if(count1<(N-1))//開始 0~N-1 計數
begin count1<=count1+1'b1;
if(count1==(N-1)/2)//如果計數器count1=(N-1)/2,時鐘clkA反相
begin clkA<=~clkA; end
end
else begin clkA<=~clkA;count1<=1'b0; /*否則時鐘clkA反相,計數器count1歸零*/
end
always@(posedge clk_re)//反相時鐘工作
if(!rst)
begin count2<=1'b0;clkB<=1'b0;//復位時鐘clkB和計數器count2
end
else if(count2<(N-1))//開始 0~N-1 計數
begin count2<=count2+1'b1;
if(count2==(N-1)/2)//如果計數器count2=(N-1)/2,時鐘clkB反相
begin clkB <= ~clkB; end
end
else begin clkB<=~clkB;count2<=1'b0;
//否則時鐘clkB反相,計數器count2歸零
end
endmodule
[1]喬廬峰.Verilog HDL數字系統設計與驗證[M].電子工業出版社,2009:106-125.
[2]王金明,楊吉斌.數字系統設計與Verilog HDL[M].電子工業出版社,2002:182-235.
[3]潘 松,黃繼業,潘 明.EDA技術實用教程:Verilog HDL版[M].4版.科學出版社,2010:300-340.
[4]李俊一,牛萍娟.基于Verilog HDL設計的多功能數字鐘[J].微計算機信息.2006,22(11):44-50.
[5]Sanir Palnitkar,夏宇聞,胡燕祥.Verilog HDL數字設計與綜合[M].2版.電子工業出版社,2009:240-260.
[6]約瑟夫·卡瓦納,陳亦歐.Verilog HDL數字設計與建模[M].電子工業出版社,2011:305-326.
[7]沈 理.Verilog RTL模型[J].同濟大學學報:自然科學版,2002,30(10):28-33.
[8]李勇堅,何積豐,孫永強.Verilog操作語義研究[J].軟件學報,2002,13(10):53-62.
[9]劉小平,何云斌,董懷國.基于Verilog HDL的有限狀態機設計與描述[J].計算機工程與設計,2008,29(4):56-60.
[10]俞莉瓊,付宇卓.有限狀態機的Verilog設計與研究[J].微電子學與計算機,2004,21(11):20-25.