唐衛(wèi)斌
(商洛學(xué)院 物理與電子信息工程系,陜西商洛 726000)
Verilog語言是應(yīng)用最廣泛的硬件描述語言(HDL)之一。它是硬件(數(shù)字邏輯電路)設(shè)計(jì)人員和EDA工具之間的界面;是一種用形式化方法來描述數(shù)字電路和設(shè)計(jì)數(shù)字邏輯系統(tǒng)的語言。設(shè)計(jì)者可以利用這種語言來描述自己的設(shè)計(jì)思想,然后利用EDA工具進(jìn)行仿真驗(yàn)證和時序分析,再自動綜合到門級電路,最后用ASIC(專用集成電路)或FPGA實(shí)現(xiàn)其功能[1-2]。
分頻器是FPGA設(shè)計(jì)中使用頻率非常高的基本單元之一。它是將較高頻率通過分頻得到較低頻率的一種單元電路。盡管目前在大部分設(shè)計(jì)中還廣泛使用集成鎖相環(huán) (如altera的PLL,Xilinx的DLL)來進(jìn)行時鐘的分頻、倍頻以及相移設(shè)計(jì)[3],但是,對于時鐘要求不太嚴(yán)格的設(shè)計(jì),通過自主設(shè)計(jì)進(jìn)行時鐘分頻的實(shí)現(xiàn)方法仍是不錯的選擇。首先這種方法可以節(jié)省鎖相環(huán)資源,再者,這種方式只消耗不多的邏輯單元就可以達(dá)到對時鐘操作的目的,具有成本低、可編程等優(yōu)點(diǎn)[4]。而使用Verilog語言進(jìn)行分頻器設(shè)計(jì)在當(dāng)前設(shè)計(jì)實(shí)踐中并不多見,文獻(xiàn)[5]中夏宇聞教授對此稍有提及,但未給出具體代碼。本文在介紹計(jì)數(shù)器設(shè)計(jì)的基礎(chǔ)上,給出基于計(jì)數(shù)器的分頻器設(shè)計(jì)模版,包括偶數(shù)次分頻和奇數(shù)次分頻,這些模版在當(dāng)前的設(shè)計(jì)實(shí)踐中尚且空缺,因而可以給其他數(shù)字邏輯電路設(shè)計(jì)人員直接調(diào)用,或者作為庫文件使用,從而大大縮短電路設(shè)計(jì)人員的設(shè)計(jì)時間。
計(jì)數(shù)器是實(shí)現(xiàn)分頻電路的基礎(chǔ),計(jì)數(shù)器有普通計(jì)數(shù)器和約翰遜計(jì)數(shù)器兩種。這兩種計(jì)數(shù)器均可應(yīng)用在分頻電路中[6]。
使用Verilog實(shí)現(xiàn)的模十加法計(jì)數(shù)器:
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; /*復(fù)位信號*/
else
begin if(cnt==9)cnt<=0; /*當(dāng)計(jì)數(shù)到 9時強(qiáng)制歸零*/
else cnt<=cnt+1; /* 計(jì)數(shù) */
end
endmodule
使用Modelsim仿真結(jié)果如圖1所示。
圖1 普通計(jì)數(shù)器仿真波形
從波形上可以看到輸出端口cnt反復(fù)循環(huán)輸出0~9這10個數(shù)字。普通計(jì)數(shù)器的RTL(寄存器傳輸級)結(jié)構(gòu)圖如圖2所示[7]??梢娫撚?jì)數(shù)器由四位加法單元和四位觸發(fā)器構(gòu)成。有兩個輸入端口:時鐘輸入clk和復(fù)位信號輸入rst。
圖2 普通計(jì)數(shù)器RTL結(jié)構(gòu)
約翰遜計(jì)數(shù)器是一種移位計(jì)數(shù)器,采用的是把輸出的最高位取非,然后反饋送到最低位觸發(fā)器的輸入端。也稱為扭環(huán)形計(jì)數(shù)器。它在每個時鐘下只有一個輸出發(fā)生變化[8]。
約翰遜計(jì)數(shù)器沒有有效利用寄存器的所有狀態(tài),假設(shè)最初值或復(fù)位狀態(tài)為0000,則依次為0000、0001、0011、0111、1111、1110、1100、1000、0000如此循環(huán)。
再者,如果由于干擾噪聲引入一個無效狀態(tài),如0010,則無法恢復(fù)到有效循環(huán)中去,需要加入錯誤恢復(fù)處理。
分頻器有整數(shù)次分頻器和小數(shù)次分頻器之分。對于整數(shù)次分頻器又有奇數(shù)次和偶數(shù)次分頻器。這里只討論整數(shù)分頻。
偶數(shù)次分頻通過計(jì)數(shù)器計(jì)數(shù)是完全可以實(shí)現(xiàn)的。如進(jìn)行N次偶數(shù)分頻,那么可以通過由待分頻的時鐘觸發(fā)計(jì)數(shù)器計(jì)數(shù),當(dāng)計(jì)數(shù)器從0計(jì)數(shù)到N/2-1時,輸出時鐘進(jìn)行翻轉(zhuǎn),并給計(jì)數(shù)器一個復(fù)位信號,使得下一個時鐘從零開始計(jì)數(shù)。以此循環(huán)下去。這種方法可以實(shí)現(xiàn)任意的偶數(shù)分頻[9]。基于此思路的代碼見注釋①。
從如圖3所示仿真波形上可以看到,通過計(jì)數(shù)器計(jì)數(shù),每計(jì)數(shù)3次,輸出時鐘反相一次,從而使輸出時鐘為輸入時鐘的1/6,完成了6分頻,并且占空比是50%。
圖3 偶數(shù)次分頻仿真波形(6分頻)
奇數(shù)次分頻歸類為一般的方法為:對于實(shí)現(xiàn)占空比為50%的N次奇數(shù)分頻,首先進(jìn)行上升沿觸發(fā)進(jìn)行模N計(jì)數(shù),計(jì)數(shù)從零開始,到(N-1)/2進(jìn)行輸出時鐘翻轉(zhuǎn),然后經(jīng)過(N+1)/2再次進(jìn)行翻轉(zhuǎn)得到一個占空比非50%奇數(shù)n分頻時鐘。再者同時進(jìn)行下降沿觸發(fā)的模N計(jì)數(shù),類似翻轉(zhuǎn)生成占空比非50%的奇數(shù)n分頻時鐘。兩個占空比非50%的n分頻時鐘相或運(yùn)算,得到占空比為50%的奇數(shù)n分頻時鐘[10]。基于此思路的代碼見注釋②。
從如圖4仿真波形上可以清楚地看到count1和count2兩個計(jì)數(shù)器從1到4的計(jì)數(shù)過程,以及分別對應(yīng)clk時鐘和clk_re時鐘計(jì)數(shù)所產(chǎn)生的clkA和clkB兩個中間時鐘,對這兩個中間時鐘相或的到最終所要的5分頻輸出時鐘clk_odd,并且占空比是50%。
圖4 奇數(shù)次分頻仿真波形(5分頻)
對該 5次分頻電路進(jìn)行軟件綜合 (synopsys_DC),獲得RTL結(jié)構(gòu)圖如圖5所示。
圖5 分頻器綜合結(jié)果—RTL結(jié)構(gòu)圖
可以看到該邏輯電路是由若干與非門、或非門、反相器、或門以及D觸發(fā)器構(gòu)成,是典型的數(shù)字電路。該電路再經(jīng)過后續(xù)軟件進(jìn)行布局布線、后仿真、時序分析、生成版圖,就可以獲得ASIC單元電路,應(yīng)用到ASIC設(shè)計(jì)制造之中。
本文詳細(xì)給出了偶數(shù)次分頻和奇數(shù)次分頻的通用Verilog代碼,并給出了相應(yīng)的解釋,通過了ModelSim的仿真。從仿真波形上看,兩段代碼均正確無誤的完成了預(yù)期的功能??梢妰啥未a可以作為設(shè)計(jì)模版提供給其他數(shù)字邏輯設(shè)計(jì)人員直接調(diào)用,或者作為庫文件使用。
注釋:
①偶數(shù)次分頻器代碼
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;//定義參數(shù) 6分頻
always@(posedge clk)
if(!rst) //復(fù)位所有輸出寄存器
begin count<=1'b0;
clk_even<=1'b0;
end
else if(count< N/2-1)begin //0~N/2-1計(jì)數(shù),對本例為0~2計(jì)數(shù)
count<=count+1'b1;//計(jì)數(shù)器加1
end
else begin
count <=1'b0;//計(jì)數(shù)器賦零
clk_even<=~clk_even;//輸出時鐘反相end
endmodule
②奇數(shù)次分頻器代碼
module odd_division(clk,rst,clk_odd);
input clk,rst;//定義輸入時鐘和復(fù)位信號
output clk_odd;//定義輸出時鐘
reg[3:0]count1,count2;//定義兩個計(jì)數(shù)器
reg clkA,clkB;//定義兩個中間時鐘
wire clk_odd,clk_re;//定義輸出時鐘和反相輸入時鐘為連線型變量
parameter N=5;//定義參數(shù)為5,即5分頻電路
assign clk_re=~clk;//將輸入時鐘反相,賦值給clk_re
assign clk_odd=clkA|clkB;//給出輸出時鐘的表達(dá)式clkA和clkB相或
always@(posedge clk)
if(!rst)
begin count1<=1'b0;clkA <=1'b0;//復(fù)位時鐘clkA和計(jì)數(shù)器count1
end
else if(count1<(N-1))//開始 0~N-1 計(jì)數(shù)
begin count1<=count1+1'b1;
if(count1==(N-1)/2)//如果計(jì)數(shù)器count1=(N-1)/2,時鐘clkA反相
begin clkA<=~clkA; end
end
else begin clkA<=~clkA;count1<=1'b0; /*否則時鐘clkA反相,計(jì)數(shù)器count1歸零*/
end
always@(posedge clk_re)//反相時鐘工作
if(!rst)
begin count2<=1'b0;clkB<=1'b0;//復(fù)位時鐘clkB和計(jì)數(shù)器count2
end
else if(count2<(N-1))//開始 0~N-1 計(jì)數(shù)
begin count2<=count2+1'b1;
if(count2==(N-1)/2)//如果計(jì)數(shù)器count2=(N-1)/2,時鐘clkB反相
begin clkB <= ~clkB; end
end
else begin clkB<=~clkB;count2<=1'b0;
//否則時鐘clkB反相,計(jì)數(shù)器count2歸零
end
endmodule
[1]喬廬峰.Verilog HDL數(shù)字系統(tǒng)設(shè)計(jì)與驗(yàn)證[M].電子工業(yè)出版社,2009:106-125.
[2]王金明,楊吉斌.數(shù)字系統(tǒng)設(shè)計(jì)與Verilog HDL[M].電子工業(yè)出版社,2002:182-235.
[3]潘 松,黃繼業(yè),潘 明.EDA技術(shù)實(shí)用教程:Verilog HDL版[M].4版.科學(xué)出版社,2010:300-340.
[4]李俊一,牛萍娟.基于Verilog HDL設(shè)計(jì)的多功能數(shù)字鐘[J].微計(jì)算機(jī)信息.2006,22(11):44-50.
[5]Sanir Palnitkar,夏宇聞,胡燕祥.Verilog HDL數(shù)字設(shè)計(jì)與綜合[M].2版.電子工業(yè)出版社,2009:240-260.
[6]約瑟夫·卡瓦納,陳亦歐.Verilog HDL數(shù)字設(shè)計(jì)與建模[M].電子工業(yè)出版社,2011:305-326.
[7]沈 理.Verilog RTL模型[J].同濟(jì)大學(xué)學(xué)報(bào):自然科學(xué)版,2002,30(10):28-33.
[8]李勇堅(jiān),何積豐,孫永強(qiáng).Verilog操作語義研究[J].軟件學(xué)報(bào),2002,13(10):53-62.
[9]劉小平,何云斌,董懷國.基于Verilog HDL的有限狀態(tài)機(jī)設(shè)計(jì)與描述[J].計(jì)算機(jī)工程與設(shè)計(jì),2008,29(4):56-60.
[10]俞莉瓊,付宇卓.有限狀態(tài)機(jī)的Verilog設(shè)計(jì)與研究[J].微電子學(xué)與計(jì)算機(jī),2004,21(11):20-25.