天天看點

整數(奇偶)+分數分頻器的verilog實作(大合集)

分頻器實作

    • 一、50%占空比整數分頻
      • 1.1 奇數分頻器
        • 1.1.1 方法1:2N分頻上下沿波形相異或
        • 1.1.2 方法2:N分頻上下沿波形相或(輸出初始态為0)
      • 1.2 偶數分頻器
    • 二、非50%占空比分頻
    • 三、小數(分數)分頻
      • 3.1 N+0.5分頻
      • 3.2 任意小數分頻
        • 3.2.1 基于脈沖删除小數分頻的算法描述
        • 3.2.2 脈沖删除小數分頻的仿真
        • 3.2.3 脈沖删除小數分頻的RTL代碼
    • 四、5種case仿真集合

分頻在數字設計中應用廣泛,通常可以使用鎖相環PLL和計數器實作。本文介紹的分頻器是基于計數器實作的,由于使用的是DFF(D觸發器),這實際上是行波計數器(一串DFF級聯,上級的輸出作為下級的時鐘)的推廣,在同步實作中,一般不使用這種分頻後的波形(因為DFF的Tco會逐級積累,使得分頻前後的時鐘不是100%同步,若将DFF的輸出信号作為其他DFF的時鐘,第一,極限情況容易違反Tsu和Thold,進而産生亞穩态;第二,這為STA和插入掃描鍊增加了難度)。但是,作為一種分頻的思想,還是有讨論的價值的,或者說,在低頻電路中,使用起來也不會對電路造成太大問題(不要多級級聯,即不要将得到的時鐘信号在進行分頻作為其他子產品的時鐘)。

NOTE:掃描鍊(Scan chain)是可測試性設計的一種實作技術。它通過植入移位寄存器,使得測試人員可以從外部控制和觀測電路内部觸發器的信号值。

一、50%占空比整數分頻

這是計數器分頻中最簡單最基礎的分頻方式。一般可分為奇數分頻和偶數分頻。

1.1 奇數分頻器

1.1.1 方法1:2N分頻上下沿波形相異或

生成2N分頻的上升沿和下降沿觸發的波形(正交),二者異或可得到N奇數分頻波形。

具體方法:N為奇數

Step1:生成标志信号

上升沿波形翻轉标志信号:

tff1_en = (clk_cnt == 0);

下降沿波形翻轉标志信号:

tff2_en = (clk_cnt == (N + 1) / 2);

Step2:在DFF中翻轉(div1、div2位2N個clk,計數到N-1清零)

always @ (posedge clk) If (tff1_en) Div1 <= ~div1;
always @ (negedge clk) If (tff2_en) Div2 <= ~div2;

Step3:異或得到N奇分頻波形

assign div_odd = div1 ^ div2;

1.1.2 方法2:N分頻上下沿波形相或(輸出初始态為0)

在N分頻波形内進行操作。

具體操作:

Step1:産生上升/下降沿波形翻轉标志

tff1_en = (clk_cntp == (N – 1) / 2 | clk_cntp == N – 1); // clk_cntp為上升沿計數器
tff2_en = (clk_cntn == (N – 1) / 2 | clk_cntn == N – 1); // clk_cntn 為下降沿計數器

Step2:(div1、2為N個clk,計數到N-1清零)

always @ (posedge clk) if (Tff1_en) div1 <= ~div1;
always @ (negedge clk) if (Tff2_en) div2 <= ~div2;

Step3:div1與div2相或(初始态為0)、相與(初始态為1)

assign div_odd = (div1 | div2); / Div_odd = (div1 & div2);

推薦采用方法1,隻需要一個上升沿計數器即可。

1.2 偶數分頻器

N為偶數,如下操作:

Step1:計數值一半時,産生翻轉标志

tff_en=clk_cnt==N/2-1;

Step2:取反,div包含了N個clk,到N/2-1清零計數器;

always @ (posedge clk) if (tff_en) div <= ~div;

Step3:輸出

assign div_even = div;

NOTE:因為偶數分頻,分頻後的時鐘總是高低電平一半,是以按如下方式:計數器計數到N-1清零,翻轉的tff_en = (clk_cnt == N/2-1) || (clk_cnt == N-1);

二、非50%占空比分頻

假設給定:占空比DUTY(範圍0-100,精度1),分頻系數N;

算法:因為是任意占空比,是以不考慮奇偶分頻的差異;

Step1:計數器clk_cnt 計數到N-1清零後重新開始;

Step2:tff_en = clk_cnt == N*DUTY/100-1 || clk_cnt == N-1;

Step3:always @ (posedge clk) if (tff_en) any_pwm <= ~any_pwm;

目标是得到一定占空比的波形,是以不需要100%的精确控制,上述算法具有缺陷,即N和DUTY不能同時太小,否則因為除法的整除原則,會舍棄掉一部分資訊,而造成結果的不正确。故,一般的簡單分頻要求的場合可以按照上述方式實作。特殊情況,需要使用PLL等來生成高精度高要求的目标時鐘。

三、小數(分數)分頻

小數(分數)分頻也算是老生常談的話題。其中,常見的類型是産生N+0.5分頻,即0.5倍分頻。

3.1 N+0.5分頻

原理:N+0.5,占空比(N+1)/(2N+1),上升沿計數器從0——N+1,高電平個數為N+1-1+1=N+1,下降沿計數器從1——N+1,低電平個數為N+1-2+1=N,則高電平個數為2N+1-N=N+1,則得到目标占空比。

Step1:上升/下降沿計數器清零

always @ (posedge clk) if (clk_cntp == 2N) clk_cntp <= 0;
always @ (negedge clk) if (clk_cntn == 2N) clk_cntn <= 0;

step2:産生翻轉标志

assign tff_en1 = (clk_cntp == N+1 | 0);
assign tff_en2 = (clk_cntn == N+1 | 1);

step3:波形翻轉

always @ (posedge clk) if (tff_en1) div1 <= ~div1; // 初始态為0
always @ (negedge clk) if (tff_en2) div2 <= ~div2; // 初始态與div1相反

step4:兩者相與

assign div = div & div2;

3.2 任意小數分頻

3.2.1 基于脈沖删除小數分頻的算法描述

本節讨論的小數分頻方案屬于前置雙模小數分頻器,顧名思義,即包含兩個整數分頻器,如下圖3-2.1,是雙模分頻器的典型結構框圖。

要實作小數x分頻,記x=nume/deno(不考慮舍去,如3.7分頻可以表示為37/10分頻,分母deno=10,分子nume=37),則:

M = nume / deno,remd = nume % deno,

remd * (M+1) + (deno-remd) * M = remd + deno * M = nume

即分子=餘數+商*分母。則在deno個輸出波形中包含了nume個參考時鐘,實作了對參考時鐘的nume/deno分頻(輸出由remd個M+1分頻時鐘和deno-remd個M分頻時鐘組成)。

整數(奇偶)+分數分頻器的verilog實作(大合集)

圖3-2.1 典型雙模小數分頻結構示意圖

得到上述M和M+1分頻時鐘後,需要将兩者平均配置設定,這就需要一個控制電路,輸出的組合有多種,需要選擇一種較好的配置設定組合方案,以得到沒有太大抖動的時鐘(時鐘頻率均勻性好,相位抖動會減小)。有關配置設定方案的選擇,參考以下文章時鐘分頻系列——偶數分頻/奇數分頻/分數分頻,文中對不同情況進行了分析最後選出最優方案。但,文中的方案需要作M+1和M的控制算法,比較複雜,始終感覺有點多餘。且,這種控制邏輯很有可能在輸出産生毛刺。如下圖3-2.2是文中小數分頻的結構視圖。

整數(奇偶)+分數分頻器的verilog實作(大合集)

圖3-2.2 基于ACCT計數器的小數分頻實作原理圖

本文采用的方案與上述不同。方案如下:

目的是實作nume個參考時鐘内,輸出deno個有M和M+1分頻的時鐘。實際上,就是在原有nume個參考時鐘中,選擇性地輸出deno個脈沖(隻不過輸出的脈沖寬度可能與參考不一樣),是以隻需要在nume個脈沖中删除nume-deno個脈沖,那麼輸出就含有了deno個脈沖,就達到nume/deno分頻的目的。

算法實作:

// ----------------------------------------算法實作描述---------------------------------------- //

算法框圖如下圖3-2.3所示,算法模型實際是一個計數器,采用計數器來實作除法操作。P為分子,Q為分母,記P/Q=M…remd(商為M,餘數remd)初始化後每次clk_cnt+Q後與P比較,實際上是計算P/Q的個數,即加多少次Q能加到P,因為初始值的不同,是以出現的情況有兩種,M和M+1次([M=P/Q]取整)。若加M次加法後都小于P,則表示還可以包含1個clk_ref,則輸出的是M+1分頻,1表示之前做了M次加法,前M次都輸出1,最後1次輸出clk_ref(之前clk_cnt加上Q還在P範圍之内);若做了M-1次加法後再做1次就超出P,說明P中隻包含M-1個Q,前M-1次均輸出1,最後1次輸出clk_ref,總共為M+0;當某一次clk_cnt+Q==P時,即餘數為0,1次完成的分頻波形輸出成功(M+1分頻remd次,M分頻Q-remd次)。按照以上描述循環判斷并輸出,就可以得到remd個M+1分頻和Q-remd個M分頻的平均組合輸出。

// ------------------------------------------------------------------------------------------------- //

but,為什麼就是M+1和M的平均組合輸出呢?

這個問題,需要思考一下。因為餘數為remd,實際上就是控制了M+1分頻的個數,Q-remd就是控制循環的結束(一個完整循環)。每作M或M-1次加Q操作後都會産生1個計算餘數(不同于上述remd),該計算餘數作為下一次分頻的起始計數值,每次增加Q,則計算餘數會按照算數規律周期地平均配置設定M和M+1分頻時鐘,最終,計算餘數完成循環歸0。這裡,不得不感慨算術的美學,這樣一個簡單的加法,卻能夠實作如此複雜的算法控制。

整數(奇偶)+分數分頻器的verilog實作(大合集)

圖3-2.3 脈沖删除小數分頻實作的算法流程圖

直覺了解:事實上,P/Q=M…remd,clk_cnt每次加上Q,最終超過P,則clk_cnt+Q-P表示的計算餘數cal_remd永遠隻有種Q種可能,當cal_remd<remd,則下一輪加Q次數是M+1(最後一次加Q超過P時delete變成0)次;若cal_remd>=remd,則下一輪加M次Q就超過P。是以cal_remd=0,1,2,3,4,5,6共7種情況小于remd,是以有remd次M+1分頻,剩餘的就是Q-remd次M分頻。

3.2.2 脈沖删除小數分頻的仿真

為了直覺地展示上述算法,舉例說明,和上文圖3-2.2中一樣,實作8.7分頻。仿真波形圖如下圖3-2.4,看出,clk_out按照 9998-998-998 的這方式,且輸出沒有毛刺,與基于ACCT方式實作的方案一緻。

整數(奇偶)+分數分頻器的verilog實作(大合集)

圖3-2.4 脈沖删除小數分頻實作8.7分頻仿真波形

實際上,ACCT實作8.7分頻,文中給出了3中輸出組合,文中作者最終選擇的方案與本文仿真結果的方案一緻。如下圖3-2.5,是8.7分頻的輸出組合方案。文章中作者需要判定哪種組合的輸出抖動小,然後在verilog代碼中修改case項,實作不同的混頻輸出,而,本文基于加法計數器的算數邏輯,巧妙避免人為的方案選擇,算法會自動選擇最優解輸出分頻波形。

整數(奇偶)+分數分頻器的verilog實作(大合集)

圖3-2.5 小數8.7分頻輸出組合方案

3.2.3 脈沖删除小數分頻的RTL代碼

RTL代碼如下:

module clk_divider # (
	parameter P_NUM = 8'd13 ,
	parameter Q_NUM = 8'd11 ,
	parameter CNT_WID = 8

) (
	input 	clk ,
	input 	rst_n ,
	
	output  clk_out
);

reg delete;
wire [CNT_WID - 1 : 0] num;
reg  [CNT_WID - 1 : 0] clk_cnt;
assign num = clk_cnt + Q_NUM; // 測試用,觀察clk_cnt+ Q_NUM的值

always @ (posedge clk) begin
	if (!rst_n)
		delete <= 1'b0;
	else if (clk_cnt + Q_NUM >= P_NUM)
		delete <= 1'b0;
	else if (clk_cnt + Q_NUM < P_NUM ) 
		delete <= 1'b1;
end

always @ (posedge clk) begin
	if (!rst_n)
		clk_cnt <= {CNT_WID{1'b0}};
	else begin
		if (clk_cnt + Q_NUM >= P_NUM)
			clk_cnt <= clk_cnt + Q_NUM - P_NUM;
		else 
			clk_cnt <= clk_cnt + Q_NUM;
	end	
end

assign clk_out = (delete) ? 1'b1 : clk;

endmodule

           

四、5種case仿真集合

下圖給出了上述所有情況的仿真波形:

整數(奇偶)+分數分頻器的verilog實作(大合集)

圖4-1.1 5種case的仿真波形圖

整數(奇偶)+分數分頻器的verilog實作(大合集)

圖4-1.2 奇數分頻(N=5)仿真波形圖

所有分頻方式的工程下載下傳連結:5種分頻方式modelsim工程

繼續閱讀