等精度頻率計的設計與驗證

Handat發表於2024-06-15

文章摘要:藉助於QuartusII PLL_IP核產生一個任意頻率被測時鐘訊號,設計一個等精度測量模組,透過其處理後,再數碼管上顯示出六位的測量頻率數值,驗證測量的準確度。

關鍵詞:Verilog HDL;等精度頻率測量;數碼管;PLL_IP核

最終框圖:

image


頻率計,即頻率計數器,專用於測量被測訊號頻率,基本工作原理就是當被測訊號在特定時間段T內的週期個數為N時,則被測訊號的頻率freq可以透過公式freq=N/T計算得出。

在EDA設計中,常見的頻率測量方法包括頻率測量法(適合高頻被測訊號)、週期測量法(適合低頻被測訊號)和等精度測量法。頻率測量法是透過統計單位時間內上升沿(或下降沿等)來計算頻率,而週期測量法是透過測量上升沿(或下降沿等)的時間間隔來計算頻率。等精度測量法與前兩種不同,其在於門控時間的設定。

【基礎原理】

在等精度測量法中,門控時間的長度並非固定,而會根據被測時鐘訊號的週期進行調整,保證其為被測時鐘訊號週期的整數倍。在這樣的參考門限範圍內,同時記錄標準時鍾和被測時鐘訊號的週期數,隨後透過計算兩者的比例關係,得到被測訊號的時脈頻率。

image

預先設定一個軟體門限,在此門限劃定測量參考範圍,透過對測量訊號Measured_sig上升沿觸發,可得到一個相對的參考門限REF_threshold,其是被測時鐘週期的整數倍,消除了被測訊號存在的±1個時鐘週期誤差。

測量方法:

參考門限範圍內,計數被測訊號週期個數為N;給一個高頻(固定頻率Fs)標準訊號,並計數得到其在同樣門限下週期個數為Y;藉助 N * 1 / Fn = Y * 1/Fs 可知被測訊號頻率 Fn = Fs * N / Y。

f為被測訊號頻率的測量值,f'為實際頻率,參考門限T;

測量誤差β = | f'-f | / f' * 100%,若忽略標準訊號的誤差,可得到f' = N / (Y ± ΔY)* Fs;

聯立得到 β = ΔY/Y *100% ≤ 1/Y = 1/(Fs * T)

結論:被測訊號的頻率接近或高於標準訊號,測量的誤差會大,就是說,增大標準訊號頻率,或者擴大軟體門限,這樣可提高測量精度。

【時序邏輯設計】

系統時鐘sys_clk為50Mhz訊號,sys_rst為系統復位。被測訊號Measured_sig設定任意頻率,thres_cnt門限計數週期定位1.5s(可調),前0.25s為訊號保持,在中間的1.00s內是軟體門限測量範圍,後0.25s為計算時間。actual_thres是參考門限範圍,也就是被測訊號的實際測量範圍,是被測時鐘週期的整數倍。

image

meas_clk_cntact_cnt_reg是被測時鐘訊號相對於參考門限的週期個數測量,最終得到計數N。由被測時鐘訊號上升沿觸發,act_thres_regactual_thres做了一個延後保持(打拍),得到計數結束訊號act_reg_flag,透過其高電平觸發計數值轉移值act_cnt_reg保持。std_clk_cntstd_cnt_reg原理同樣如此,是標準高頻訊號相對於參考門限的週期個數測量,最終得到計數Y,透過公式計算得到被測訊號頻率。

對上述時序圖中的訊號,編寫Verilog程式:(注意不同的訊號觸發型別)

parameter   THRES_CNT_MAX = 27'd75_000_000;
parameter   THRES_CNT_250MS = 27'd12_500_000;
parameter   CNT_STAND_FREP = 27'd100_000_000;

assign Std_flag = (Std_reg)&&(!act_thres)?1'b1:1'b0;
assign act_reg_flag = (act_thres_reg)&&(!act_thres)?1'b1:1'b0;

always @(posedge sys_clk or negedge sys_rst)begin
    if(!sys_rst)	thres_cnt <= 27'd0;
    else if(thres_cnt == THRES_CNT_MAX -1'b1)	thres_cnt <= 27'd0;
    else thres_cnt <= thres_cnt + 1'b1;
end

always @(posedge sys_clk or negedge sys_rst)begin
    if(!sys_rst)	thres_range <= 1'b0;
    else if((thres_cnt > (THRES_CNT_250MS-1'b1))&&(thres_cnt < (THRES_CNT_MAX-THRES_CNT_250MS-1'b1)))	 thres_range <= 1'b1;
    else thres_range <= 1'b0;
end

always @(posedge measured_sig or negedge sys_rst)begin
    if(!sys_rst)	act_thres <= 1'b0;
    else 	act_thres <= thres_range;
end

always @(posedge measured_sig or negedge sys_rst)begin
    if(!sys_rst)	meas_clk_cnt <= 48'd0;
    else if(!act_thres)	meas_clk_cnt <= 48'd0;
    else meas_clk_cnt <= meas_clk_cnt + 1'b1;
end

always @(posedge measured_sig or negedge sys_rst)begin
    if(!sys_rst)	act_thres_reg <= 1'b0;
    else 	act_thres_reg <= act_thres;
end

always @(posedge measured_sig or negedge sys_rst)begin
    if(!sys_rst)act_cnt_reg <= 48'd0;
    else if(act_reg_flag) act_cnt_reg <= meas_clk_cnt;
end

always @(posedge clk_stand or negedge sys_rst)begin
    if(!sys_rst) std_clk_cnt <= 48'd0;
    else if(!act_thres)std_clk_cnt <= 48'd0;
    else std_clk_cnt <= std_clk_cnt + 1'b1;
end

always @(posedge clk_stand or negedge sys_rst)begin
    if(!sys_rst) Std_reg <= 1'd0;
    else Std_reg <= act_thres;
end

always @(posedge clk_stand or negedge sys_rst)begin
    if(!sys_rst)    std_cnt_reg <= 48'd0;
    else if(Std_flag)	std_cnt_reg <= std_clk_cnt;
end

always @(posedge sys_clk or negedge sys_rst)begin
    if(!sys_rst)	calc_flag <= 1'd0;
    else if(thres_cnt == THRES_CNT_MAX-1)calc_flag <= 1'd1;
    else calc_flag <= 1'd0;
end

always @(posedge sys_clk or negedge sys_rst)begin
    if(!sys_rst)frep_result <= 32'd0;
    else if(calc_flag)frep_result <= (CNT_STAND_FREP/ std_cnt_reg* act_cnt_reg);
end

其中的標準高頻訊號clk_stand需要藉助於QuartusII的PLL_IP核產生,模組例項化其中。

//Stand_clk from PLL_IP_core
clk_stand	clk_stand_inst (
	.areset ( !sys_rst  ),//Hign Level take effect
	.inclk0 ( sys_clk   ),
	.c0 ( clk_stand )	);

【頻測模組模擬驗證】

在模擬程式及模擬現象中,設定系統時鐘20ns,即50Mhz,而被測時鐘週期216ns,即1 / 216 * 10e9 ≈ 4.6296Mhz。並且,為方便觀察波形變化,將軟體門限縮小了10e5倍(精度減小),最終得到被測訊號頻率 32'h46a806 ≈ 4.6305Mhz,誤差0.9khz,模擬上的時序變化均達到時序邏輯要求。

always #10 sys_clk =~sys_clk;
always #108 clk_test =~clk_test;
defparam frep_calc_inst.THRES_CNT_MAX = 750;
defparam frep_calc_inst.THRES_CNT_250MS = 125;

image
image

【部署其他模組】

考慮到最後的板級驗證,沒有訊號源和示波器透過,在此再建立一個PLL_IP核產生一個“任意時鐘訊號”,作為被測訊號,並且將最終的結果輸入到六位數碼管上顯示出來觀察,該被測訊號的實際頻率為3.580097Mhz。

image

其次,例項化數碼管顯示模組,這裡還是存在問題的,測訊號的實際頻率十六進位制顯示採用六位即可,這裡圖個方便,用assign直接賦值了。

digital digital_inst(
    .sys_clk    (sys_clk    ),
    .sys_rst    (sys_rst    ),

    .clk_2khz   (clk_2khz   ), 
    .num6       (num6       ),	//assign  num6  = frep_result[23:20];
    .num5       (num5       ),	//assign  num5  = frep_result[19:16];
    .num4       (num4       ),	//......
    .num3       (num3       ),
    .num2       (num2       ),
    .num1       (num1       ),
    .sel_cnt    (sel_cnt    ),	//所使用到的位數
    .dp_cnt     (dp_cnt     ),	//小數點所在位號
    
    .seg_sel    (seg_sel    ),	//數碼管位選
    .seg_led    (seg_led    )	//數碼管段選
);

【板級驗證方案】

從下圖可以看到,程式碼裡採用了除法運算。在FPGA或ASIC設計中,除法運算本身是一種複雜的算術操作,相比於加法、減法和乘法,它需要更多的計算步驟和邏輯單元來完成,除法操作往往需要專門的硬體除法器。

image

上機測試後,燒錄至EP4CE10F17C8開發板,數碼管顯示十六進位制36A0C1,剛好是3,580,097hz。軟體門限範圍為1.00s,標準訊號設定100Mhz,測量準確度還是比較高的。

image

文獻參考:

[1]基於Altera EP4CE10 征途Mini開發板文件(https://doc.embedfire.com/fpga/altera/ep4ce10_mini/zh/latest/fpga/Frequency_Meter.html)

[2]王立華,周松江,高世皓,等. 基於內嵌Cortex-M3核心FPGA的等精度頻率計設計[J]. 實驗室研究與探索,2017,36(7):139-143,181. DOI:10.3969/j.issn.1006-7167.2017.07.033.


本篇文章中使用的Verilog程式模組,若有需見網頁左欄Gitee倉庫連結:https://gitee.com/silly-big-head/little-mouse-funnyhouse/tree/FPGA-Verilog/

相關文章