0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

FPGA頻率測量的三種方法

FPGA設(shè)計論壇 ? 來源:FPGA設(shè)計論壇 ? 2025-01-09 09:37 ? 次閱讀

1、FPGA頻率測量?

頻率測量在電子設(shè)計和測量領(lǐng)域中經(jīng)常用到,因此對頻率測量方法的研究在實際工程應(yīng)用中具有重要意義。

通常的頻率測量方法有三種:直接測量法,間接測量法,等精度測量法。

2、直接測量法

2.1、方法

直接測量法也叫頻率測量法,即在固定在時間t內(nèi)對被測信號的脈沖數(shù)進(jìn)行計數(shù),然后求出單位時間內(nèi)的脈沖數(shù),即為被測信號的頻率。

下圖中的信號分別為:

sys_clk:系統(tǒng)的基準(zhǔn)時鐘

gate:根據(jù)基準(zhǔn)時鐘生成的閘門信號,用于生成一個固定的時間(例如1s,方便計算)

clk_fx:被測信號

c1f0d86e-cd83-11ef-9310-92fbcf53809c.png

gate是在基準(zhǔn)時鐘下生成的固定時間信號,它持續(xù)的時間 Tg = sys_clk 計數(shù)個數(shù)N(可設(shè)置);在gate持續(xù)為高的時間內(nèi),可使用被測信號clk_fx對其進(jìn)行計數(shù),計數(shù)個數(shù)為cnt(圖中為5),則cnt個被測信號的周期即為gate時長。

此種方法的本質(zhì)是:同樣的時間內(nèi)分別使用兩種時鐘計時,則有 Tg = Tfx---- Tsys_clk 計數(shù)個數(shù)N = Tclk_fx cnt,公式變換后:clk_fx = cnt sys_clk / 計數(shù)個數(shù)N (其中clk_fx為待測信號頻率,sys_clk為基準(zhǔn)時鐘頻率)

2.2、誤差分析

從圖可以看出,在gate為高電平期間,被測信號實際上差不多有六個周期被囊括在內(nèi),但是因為被測信號是相對與系統(tǒng)的異步信號,相位不同,第一個周期無法被采樣,所以實際采樣為5,這樣造成的誤差為一個被測信號周期。可以預(yù)見,這種測量方法帶來的測量誤差即為一個被測信號周期。

那么理論上測得的準(zhǔn)確頻率:clk_fxe = cnt sys_clk / 計數(shù)個數(shù)N----理論上cnt無誤差

實際上測量的頻率值:clk_fx= cnt±1 sys_clk / 計數(shù)個數(shù)N----cnt會存在一個周期的測量誤差

測量誤差 = |(clk_fxe -clk_fx)/clk_fxe | 100% = 1 / cnt 100%

所以測得的cnt越大,那么測出來的誤差值就小,而cnt越大則代表被測信號的頻率越高,所以可以推斷該種測量方法適合測量高頻信號;此外,選擇的閘門時間越長則被測信號的個數(shù)越多,同樣測量就越精確,但是增大閘門時間又會帶來測量時間過長的問題,需要依據(jù)具體需求進(jìn)行取舍。

2.3、Verilog代碼

Verilog源碼如下:

閘門時間設(shè)定為0.5s,非閘門時間也0.5s,則每1秒更新一次測量數(shù)據(jù)

使用計數(shù)器生成閘門時間,閘門時間取反得到非閘門時間

在閘門時間對被測信號計數(shù)

在非閘門時間更新測量數(shù)據(jù)

使用parameter定義參數(shù),方便調(diào)用修改

//直接測量法(高頻)
modulecymometer_direct(
input sys_clk,//基準(zhǔn)時鐘,設(shè)計為50M(可更改)
input sys_rst_n,//復(fù)位信號,低電平有效
input clk_fx,//待測信號
output reg [31:0]fre//測量結(jié)果
);

parameterTIME_SYS  = 20;//系統(tǒng)時鐘周期:20ns--頻率=50MHz
parameterTIME_GATE = 500_000_000;//500ms閘門設(shè)置的時間,單位:ns
localparamN = TIME_GATE /TIME_SYS;//生成閘門需要計數(shù)的個數(shù)

reg gate;//閘門
reg [31:0] cnt_gate;//用于生成閘門的計數(shù)器
reg [31:0] cnt_fx;//閘門時間內(nèi)對被測信號計數(shù)

wiregate_n;//閘門取反,用于在非閘門時輸出測得的頻率值

assigngate_n = ~gate;//閘門取反,用于在非閘門時輸出測得的頻率值

//分頻計數(shù)器,閘門時間設(shè)定為1ms,則每2ms測量一次
always @(posedge sys_clk or negedge sys_rst_n)begin
if(!sys_rst_n)begin
cnt_gate <=0;
gate <=0;
end
else begin
if(cnt_gate == N-1)begin
cnt_gate <= 0;
gate <= ~gate;
end
else
cnt_gate<=cnt_gate+1;
end
end 
 
//閘門時間內(nèi)對被測信號計數(shù)
always @(posedge clk_fx or negedge sys_rst_n)begin
if(!sys_rst_n)
cnt_fx <= 0;
else if(gate)
cnt_fx <= cnt_fx + 1;
else
cnt_fx <= 0;
end

//在非閘門時輸出測得的頻率值
always @(posedge gate_n or negedge sys_rst_n)begin
if(!sys_rst_n)
fre <= 0;
else 
//TIME_GATE/cnt_fx=規(guī)定時間/被測信號個數(shù)=被測信號周期,取倒數(shù)即為頻率
fre <= 1000_000_000/TIME_GATE * cnt_fx;
end

endmodule

2.4、仿真分析

Testbench:

設(shè)計被測信號周期為489*2=978ns,則其理論頻率為1/978ns=1022494.88Hz;

`timescale 1ns/1ns//時間單位/精度

//------------<模塊及端口聲明>----------------------------------------
module tb_cymometer_direct();

reg sys_clk;
reg         sys_rst_n;
reg         clk_fx;

wire [31:0] fre;

// defparam cymometer_direct_inst.TIME_GATE = 500_000;          //地址位寬

//------------<例化被測試模塊>----------------------------------------
cymometer_directcymometer_direct_inst(
.sys_clk(sys_clk),
.sys_rst_n(sys_rst_n),
.clk_fx(clk_fx),

.fre       (fre)
);

//------------<設(shè)置初始測試條件>----------------------------------------
initial begin
sys_clk = 1'b0;//初始時鐘為0
sys_rst_n <= 1'b0;//初始復(fù)位
clk_fx<= 1'b0;
#5//5個時鐘周期后
sys_rst_n <= 1'b1;//拉高復(fù)位,系統(tǒng)進(jìn)入工作狀態(tài)
// #2500_000
// forever#2560 clk_fx = ~clk_fx;
end
//------------<設(shè)置時鐘>----------------------------------------------
always #10 sys_clk = ~sys_clk;//系統(tǒng)時鐘周期20ns
always #489 clk_fx = ~clk_fx;//被測信號周期489*2ns = 978ns

endmodule

仿真如下圖:

c202c16e-cd83-11ef-9310-92fbcf53809c.png

上圖在閘門時間內(nèi)測得的被測信號個數(shù)cnt_fx為511248,測得被測信號頻率為1022496Hz;理論頻率=1/978ns=1022494.88Hz(MHz級別)。

可以看出這個測量結(jié)果還是比較準(zhǔn)確的。因為閘門時間夠長,且被測信號自身頻率就比較高(約1Mhz)。

接下來更改一下Testbench,比較一下閘門時間對被測信號的影響以及被測信號自身頻率高低對測量的影響:

第1個模塊:被測信號頻率為1022494.88Hz(MHz級別),閘門時間0.5s

第2個模塊:被測信號頻率為1022494.88Hz(MHz級別),閘門時間0.5ms

第3個模塊:被測信號頻率為76103.5Hz(KHz級別),閘門時間0.5s

第4個模塊:被測信號頻率為21.217Hz(Hz級別),閘門時間0.5s

//多變量對比測試
`timescale 1ns/1ns//時間單位/精度

//------------<模塊及端口聲明>----------------------------------------
module tb_cymometer_direct();

reg sys_clk;
reg sys_rst_n;
reg         clk_fx1;
reg     clk_fx2;
reg        clk_fx3;
reg     clk_fx4;

wire [31:0]fre1;
wire [31:0]fre2;
wire [31:0]fre3;
wire [31:0]fre4;

 defparam cymometer_direct_inst2.TIME_GATE = 500_000;          //重設(shè)閘門時間1ms

//------------<例化被測試模塊>----------------------------------------
cymometer_directcymometer_direct_inst1(
.sys_clk(sys_clk),
.sys_rst_n(sys_rst_n),
.clk_fx(clk_fx1),

.fre       (fre1)
);

cymometer_directcymometer_direct_inst2(
.sys_clk(sys_clk),
.sys_rst_n(sys_rst_n),
.clk_fx(clk_fx2),

.fre       (fre2)
);

cymometer_directcymometer_direct_inst3(
.sys_clk(sys_clk),
.sys_rst_n(sys_rst_n),
.clk_fx(clk_fx3),

.fre       (fre3)
);

cymometer_directcymometer_direct_inst4(
.sys_clk(sys_clk),
.sys_rst_n(sys_rst_n),
.clk_fx(clk_fx4),

.fre       (fre4)
);
//------------<例化被測試模塊>----------------------------------------

//------------<設(shè)置初始測試條件>----------------------------------------
initial begin
sys_clk = 1'b0;//初始時鐘為0
sys_rst_n <= 1'b0;//初始復(fù)位
clk_fx1<= 1'b0;
clk_fx2<= 1'b0;
clk_fx3<= 1'b0;
clk_fx4<= 1'b0;
#5//5個時鐘周期后
sys_rst_n <= 1'b1;//拉高復(fù)位,系統(tǒng)進(jìn)入工作狀態(tài)

end
//------------<設(shè)置時鐘>----------------------------------------------
always #10 sys_clk = ~sys_clk;//系統(tǒng)時鐘周期20ns

always #489 clk_fx1 = ~clk_fx1;//被測信號周期489*2ns,理論頻率1022494.88Hz(MHz級別)
always #489 clk_fx2 = ~clk_fx2;//被測信號周期489*2ns,理論頻率1022494.88Hz(MHz級別)

always #6570 clk_fx3 = ~clk_fx3;//被測信號周期6570*2ns,理論頻率76103.5Hz(KHz級別)
always #23565678 clk_fx4 = ~clk_fx4;//被測信號周期23565678*2ns,理論頻率21.217Hz(Hz級別)

endmodule

測量結(jié)果如下:

c217609c-cd83-11ef-9310-92fbcf53809c.png

將測量結(jié)果整理成下表:

閘門時間 理論頻率(Hz) 實際測量頻率(Hz) 測量誤差
模塊1 0.5s 1022494.88 1022496 1.095e-4%
模塊2 0.5ms 1022494.88 1022000 4.840e-4%
模塊3 0.5s 76103.5 76104 6.570e-4%
模塊4 0.5s 21.217 20 5.736%

從上表的測試結(jié)果可以對直接測量法做出如下總結(jié):

閘門時間越長,測量結(jié)果越精準(zhǔn),但是也會導(dǎo)致單次測量時間過長

直接測量法適合測量高頻信號,測量誤差與閘門時間及被測信號頻率相關(guān)

3、間接測量法

3.1、方法

間接測量法也叫周期測量法,即在一個被測信號的周期內(nèi),測量基準(zhǔn)時鐘的個數(shù),得到被測信號的周期,再將其轉(zhuǎn)化為頻率。

下圖中的信號分別為:

sys_clk:系統(tǒng)的基準(zhǔn)時鐘

clk_fx:被測信號

c22acefc-cd83-11ef-9310-92fbcf53809c.png

在被測信號clk_fx為高電平的時間內(nèi),使用基準(zhǔn)時鐘進(jìn)行計數(shù),計數(shù)個數(shù)為cnt(圖中為8),則cnt基準(zhǔn)時鐘周期=半個被測信號的周期。

所以cnt/ FERQ_SYS(基準(zhǔn)時鐘頻率)=(1/2) * (1/clk_fx),化簡后clk_fx =FERQ_SYS/(cnt*2)

此種方法適用于測量低頻信號,但同時也會帶來測量速度過慢的問題,誤差來自一個系統(tǒng)基準(zhǔn)時鐘。

3.2、誤差分析

從圖可以看出,在被測信號高電平期間,被測信號實際上差不多有8.5個周期被囊括在內(nèi),但是因為被測信號是相對與系統(tǒng)的異步信號,相位不同,所以實際采樣為8,這樣造成的誤差為1個基準(zhǔn)信號周期??梢灶A(yù)見,這種測量方法帶來的測量誤差即為一個基準(zhǔn)信號周期。

那么理論上測得的準(zhǔn)確頻率:clk_fx =FERQ_SYS/(cnt*2)----理論上cnt無誤差

實際上測量的頻率值:clk_fx =FERQ_SYS/((cnt±1)*2)----cnt會存在一個周期的測量誤差

測量誤差 = |(clk_fxe -clk_fx)/clk_fxe | 100% = 1 / cnt 100%

所以測得的cnt越大,那么測出來的誤差值就小,而cnt越大則代表被測信號的頻率越低(周期越高),所以可以推斷該種測量方法適合測量低頻信號。

2.3、Verilog代碼

Verilog源碼如下:

在被測信號計數(shù)高電平期間使用基準(zhǔn)時鐘計數(shù)

在被測信號計數(shù)低電平期間更新測量數(shù)據(jù)

使用parameter定義參數(shù),方便調(diào)用修改

//間接測量法(低頻)
module cymometer_indirect(
input sys_clk,//基準(zhǔn)時鐘,設(shè)計為50M(可更改)
input sys_rst_n,   //復(fù)位信號,低電平有效
                                    //待測信號
input clk_fx,//測量結(jié)果
output reg [31:0]fre
);

parameterTIME_SYS  = 20;//系統(tǒng)時鐘周期:20ns--頻率=50MHz

reg [31:0]cnt_fx;//對被測信號高電平進(jìn)行計數(shù)的計數(shù)器

//在測信號高電平期間進(jìn)行計數(shù)
always @(posedge sys_clk or negedge sys_rst_n)begin
if(!sys_rst_n)
cnt_fx <= 0;
else if(clk_fx)
cnt_fx <= cnt_fx+1;
else
cnt_fx <= 0;
end
//在測信號低電平期輸出測量數(shù)據(jù)
always @(negedge clk_fx or negedge sys_rst_n )begin
if(!sys_rst_n)
fre<=0;
else
fre<=1000_000_000/(TIME_SYS*cnt_fx*2);
end
 
endmodule

3.4、仿真分析

Testbench依然采用在直接測量法測試用的3個頻率設(shè)置

模塊1被被測信號周期23565678*2ns,理論頻率21.217Hz(Hz級別)

模塊2被測信號周期6570*2ns,理論頻率76103.5Hz(KHz級別)

模塊3被測信號周期489*2ns,理論頻率1022494.88Hz(MHz級別)

`timescale 1ns/1ns//時間單位/精度

//------------<模塊及端口聲明>----------------------------------------
module tb_cymometer_indirect();

reg sys_clk;
regsys_rst_n;
regclk_fx1;
regclk_fx2;
regclk_fx3;

wire [31:0]fre1;
wire [31:0]fre2;
wire [31:0]fre3;

//------------<例化被測試模塊>----------------------------------------
cymometer_indirectcymometer_indirect_inst1(
.sys_clk(sys_clk),
.sys_rst_n(sys_rst_n),
.clk_fx(clk_fx1),

.fre       (fre1)
);

cymometer_indirectcymometer_indirect_inst2(
.sys_clk(sys_clk),
.sys_rst_n(sys_rst_n),
.clk_fx(clk_fx2),

.fre       (fre2)
);

cymometer_indirectcymometer_indirect_inst3(
.sys_clk(sys_clk),
.sys_rst_n(sys_rst_n),
.clk_fx(clk_fx3),

.fre       (fre3)
);

//------------<設(shè)置初始測試條件>----------------------------------------
initial begin
sys_clk = 1'b0;//初始時鐘為0
sys_rst_n <= 1'b0;//初始復(fù)位
clk_fx1<= 1'b0;
clk_fx2<= 1'b0;
clk_fx3<= 1'b0;
#5//5個時鐘周期后
sys_rst_n <= 1'b1;//拉高復(fù)位,系統(tǒng)進(jìn)入工作狀態(tài)

end
//------------<設(shè)置時鐘>----------------------------------------------
always #10 sys_clk = ~sys_clk;//系統(tǒng)時鐘周期20ns

always #23565678 clk_fx1 = ~clk_fx1;//被測信號周期23565678*2ns,理論頻率21.217Hz(Hz級別)
always #6570 clk_fx2 = ~clk_fx2;//被測信號周期6570*2ns,理論頻率76103.5Hz(KHz級別)
always #489 clk_fx3 = ~clk_fx3;//被測信號周期489*2ns,理論頻率1022494.88Hz(MHz級別)

endmodule

仿真如下圖1:

c240a704-cd83-11ef-9310-92fbcf53809c.png

將測量結(jié)果整理成下表:

理論頻率(Hz) 實際測量頻率(Hz) 測量誤差
模塊1 21.217297 21 1.02%
模塊2 76103.5 75987 0.15%
模塊3 1022494.88 1041666 1.87%

從上表的測試結(jié)果可以對間接測量法做出如下總結(jié):間接測量法適合測量低頻信號,測量誤差與測信號頻率相關(guān)。

需要注意的是,輸出信號不能處理浮點數(shù),推薦的解決辦法是將其放大整數(shù)倍(100倍),以便實現(xiàn)小數(shù)點的頻率測量(不然小數(shù)點被截斷會帶來額外的誤差)。

將測量結(jié)果乘以1000,一定程度上消除小數(shù)截斷帶來的誤差,模塊1的測試結(jié)果為21.217Hz,測量誤差為1.9998e-3%,大大低于另外兩個高頻信號。(這里不給出具體的測試過程了,可以自己嘗試下)。

4、等精度測量法

4.1、概念

上述兩種方法都會產(chǎn)生±1 個被測時鐘周期的誤差,在實際應(yīng)用中有一定的局限 性;而且根據(jù)兩種方式的測量原理,很容易發(fā)現(xiàn)頻率測量法適合于測量高頻時鐘信號,而周期測量法適合于低頻時鐘信號的測量,但二者都不能兼顧高低頻率同樣精度的測量要求。

等精度測量法與前兩種方式不同,其最大的特點是,測量的實際門控時間不是一個固 定值,它與被測時鐘信號相關(guān),是被測時鐘信號周期的整數(shù)倍。在實際門控信號下,同時對標(biāo)準(zhǔn)時鐘和被測時鐘信號的時鐘周期進(jìn)行計數(shù),再通過公式計算得到被測信號的時鐘頻率。 由于實際門控信號是被測時鐘周期的整數(shù)倍,就消除了被測信號產(chǎn)生的±1 時鐘周期的誤差,但是會產(chǎn)生對標(biāo)準(zhǔn)時鐘信號±1時鐘周期的誤差,而標(biāo)準(zhǔn)時鐘通常又是頻率極高,所以誤差較之前兩種方法就大大降低。

此種測量方法相對誤差與被測信號頻率的大小無關(guān),僅與閘門時間和基準(zhǔn)時鐘頻率有關(guān),即實現(xiàn)了整個測試頻段的等精度測量。閘門時間越長,基準(zhǔn)時鐘頻率越高,測頻的相對誤差越小。需要注意的是,原則上門控時間越長,則精度越高,但測量低頻信號(Hz級別)時,建議將門控時間設(shè)置為被測信號的十幾倍即可,否則測量時間將會過長。

c25368bc-cd83-11ef-9310-92fbcf53809c.png

了解了等精度測量原理之后,我們來說明一下被測時鐘信號的計算方法:

首先通過被測信號生成實際閘門

分別對實際閘門下被測時鐘信號和標(biāo)準(zhǔn)時鐘信號的時鐘周期進(jìn)行計數(shù)。

實際閘門下被測時鐘信號周期數(shù)為 X,設(shè)被測信號時鐘周期為 Tfx,它的時鐘頻率 fx = 1/Tfx,由此可得等式:X * Tfx = X / fx = Tx(實際閘門)----這里無誤差。

實際閘門下標(biāo)準(zhǔn)時鐘信號周期數(shù)為 Y(誤差為1),設(shè)被測信號時鐘周期為 Tfs,它的時鐘頻率 fs = 1/Tfs,由此可得等式:Y * Tfs = Y / fs = Tx(實際閘門)----這里最大誤差為1個基準(zhǔn)時鐘周期。

將兩等式結(jié)合得到只包含各自時鐘周期計數(shù)和時鐘頻率的等式:X / fx = Y / fs = Tx(實際閘門),等式變換,得到被測時鐘信號時鐘頻率計算公式:fx = X * fs / Y。

將已知量標(biāo)準(zhǔn)時鐘信號時鐘頻率 fs 和測量量 X、Y 帶入計算公式,得到被測時鐘信號時鐘頻率 fx。

4.2、誤差分析

根據(jù)前文及上圖,不難發(fā)現(xiàn),誤差來源于使用基準(zhǔn)時鐘在閘門時間測量時會存在一個基準(zhǔn)時鐘周期的誤差。

那么理論上測得的準(zhǔn)確頻率:clk_fxe = X * fs / Y----理論上Y無誤差

實際上測量的頻率值:clk_fx = X * fs / Y----Y會存在1個周期的測量誤差

測量誤差 = |(clk_fxe - clk_fx)/ clk_fxe | 100% = 1 / Y 100%

所以測得的Y越大,那么測出來的誤差值就小。當(dāng)閘門時間越大,Y越大;基準(zhǔn)時鐘頻率越高,Y越大。所以通過提高基準(zhǔn)時鐘頻率或者增加閘門時間(但是會使測量過長,需要取舍),可以有效提高測量精度。

4.3、Verilog代碼

Verilog源碼如下:

//等精度測量法(低頻)
module cymometer_equal (   
        input                 clk_fs ,    
        input                 rst_n  ,            
        input                 clk_fx , 

        output   reg [63:0]   fre      
);

parameterCLK_FS    = 26'd50_000_000;           
parameter   GATE_TIME = 16'd100;    //門控時間,越大誤差越小,但測量時間也會變長    

//reg define
reg                gate_fx;   //門控信號,被測信號域下         
reg                gate_fs     ;           //同步到基準(zhǔn)時鐘的門控信號
reg                gate_fs_r   ;          //用于同步gate信號的寄存器
reg                gate_fs_d0  ;           //用于采集基準(zhǔn)時鐘下gate下降沿
reg                gate_fs_d1  ;           //用于采集基準(zhǔn)時鐘下gate下降沿
reg                gate_fx_d0  ;          //用于采集被測時鐘下gate下降沿
reg                gate_fx_d1  ;           //用于采集被測時鐘下gate下降沿
reg    [15:0]   gate_cnt    ;          //門控計數(shù)
reg    [31:0]   fs_cnt      ;           //門控時間內(nèi)基準(zhǔn)時鐘的計數(shù)值
reg    [31:0]   fs_cnt_temp ;           //fs_cnt 臨時值
reg    [31:0]   fx_cnt      ;           //門控時間內(nèi)被測時鐘的計數(shù)值
reg    [31:0]   fx_cnt_temp ;           //fx_cnt 臨時值

//wire define
wire               neg_gate_fs;            //基準(zhǔn)時鐘下門控信號下降沿=
wire               neg_gate_fx;            //被測時鐘下門控信號下降沿

//捕捉信號下降沿
assign neg_gate_fs = gate_fs_d1 & (~gate_fs_d0);
assign neg_gate_fx = gate_fx_d1 & (~gate_fx_d0);

//檢測gate_fx下降沿
always @(posedge clk_fx or negedge rst_n) begin
    if(!rst_n) begin
        gate_fx_d0 <= 1'b0;
        gate_fx_d1 <= 1'b0;
    end
    else begin
        gate_fx_d0 <= gate_fx;
        gate_fx_d1 <= gate_fx_d0;
    end
end
//檢測gate_fs下降沿
always @(posedge clk_fs or negedge rst_n) begin
    if(!rst_n) begin
        gate_fs_d0 <= 1'b0;
        gate_fs_d1 <= 1'b0;
    end
    else begin
        gate_fs_d0 <= gate_fs;
        gate_fs_d1 <= gate_fs_d0;
    end
end
//被測時鐘閘門計數(shù)器
always @(posedge clk_fx or negedge rst_n) begin
    if(!rst_n)
        gate_cnt <= 16'd0; 
    else if(gate_cnt == GATE_TIME*2)
        gate_cnt <= 16'd0;
    else 
        gate_cnt <= gate_cnt + 1'b1;
end
//被測時鐘閘門生成
always @(posedge clk_fx or negedge rst_n) begin
    if(!rst_n)
        gate_fx <= 1'b0;     
    else if(gate_cnt == GATE_TIME)
        gate_fx <= 1'b1;
    else if(gate_cnt == GATE_TIME*2)
        gate_fx <= 1'b0;
    else 
        gate_fx <= gate_fx;
end
//把閘門從被測時鐘域同步到基準(zhǔn)時鐘域
always @(posedge clk_fs or negedge rst_n) begin
    if(!rst_n) begin
        gate_fs_r <= 1'b0;
        gate_fs   <= 1'b0;
    end
    else begin
        gate_fs_r <= gate_fx;
        gate_fs   <= gate_fs_r;
    end
end
//在被測時鐘域?qū)Ρ粶y信號計數(shù)
always @(posedge clk_fx or negedge rst_n) begin
    if(!rst_n) begin
        fx_cnt_temp <= 0;
        fx_cnt <= 0;
    end
    else if(gate_fx)
        fx_cnt_temp <= fx_cnt_temp + 1'b1;
    else if(neg_gate_fx) begin
        fx_cnt_temp <= 0;
        fx_cnt <= fx_cnt_temp;
    end
end
//在基準(zhǔn)時鐘域?qū)鶞?zhǔn)時鐘計數(shù)
always @(posedge clk_fs or negedge rst_n) begin
    if(!rst_n) begin
        fs_cnt_temp <= 0;
        fs_cnt <= 0;
    end
    else if(gate_fs)
        fs_cnt_temp <= fs_cnt_temp + 1'b1;
    else if(neg_gate_fs) begin
        fs_cnt_temp <= 0;
        fs_cnt <= fs_cnt_temp;
    end
end
//在基準(zhǔn)時鐘域輸出結(jié)果
always @(posedge clk_fs or negedge rst_n) begin
    if(!rst_n) begin
        fre <= 0;
    end
    else if(gate_fs == 1'b0)
        fre <= (CLK_FS * fx_cnt ) / fs_cnt;
end

endmodule

4.4、仿真分析

Testbench:

設(shè)計被測信號周期為489*2=978ns,則其理論頻率為1/978ns=1022494.88Hz

`timescale 1 ns/ 1 ns
//------------<模塊及端口聲明>----------------------------------------
module tb_cymometer_equal();

reg clk_fs;
reg clk_fx;
reg rst_n;
                                              
wire [63:0]  fre;

//------------<例化被測試模塊>----------------------------------------                          
cymometer_equal cymometer_equal_inst ( 
.clk_fs(clk_fs),
.clk_fx(clk_fx),
.fre(fre),
.rst_n(rst_n)
);
//------------<設(shè)置初始測試條件>----------------------------------------
initialbegin                                                  
clk_fs = 1'b0;
clk_fx <= 1'b0;
rst_n <= 1'b0;
#116 
rst_n <= 1'b1;

end 
//------------<設(shè)置時鐘>----------------------------------------------                                                   
always#10 clk_fs <= ~clk_fs;                                     
always  #489 clk_fx <= ~clk_fx;  
                                                 
endmodule

仿真結(jié)果如下所示

c25d6a38-cd83-11ef-9310-92fbcf53809c.png

上圖的測量結(jié)果為1022494Hz,理論頻率為1/978ns=1022494.88Hz,可以看到這個結(jié)果相當(dāng)精確。

接下來更改一下Testbench,比較一下閘門時間對被測信號的影響以及被測信號自身頻率高低對測量的影響(為避免仿真時間過長,閘門時間均設(shè)為10個被測信號周期,因為基準(zhǔn)時鐘頻率較高,所以閘門時間少點不會有什么影響)

第1個模塊:被測信號頻率為1022494.88Hz(MHz級別)

第2個模塊:被測信號頻率為76103.5Hz(KHz級別)

第3個模塊:被測信號頻率為21.217Hz(Hz級別)

仿真結(jié)果如下:

c267f0d4-cd83-11ef-9310-92fbcf53809c.png

將測量結(jié)果整理成下表:

理論頻率(Hz) 實際測量頻率(Hz) 測量誤差
模塊1 1022494.88 1022494 8.60e-5%
模塊2 76103.5 76103 6.57e-4%
模塊3 21.217297 21 1.02%

從上表的測試結(jié)果發(fā)現(xiàn)等精度測量法同時適用于高低頻域,測量結(jié)果誤差只和基準(zhǔn)時鐘頻率有關(guān)。

這里需要注意的是,因為測量結(jié)果都是整數(shù)(FPGA自動截斷小數(shù)),如果被測頻率較低,那么因為小數(shù)被截斷,會使得誤差增大。一個比較方便的解決辦法是把計算公式都放大一定的倍數(shù),從而使得“小數(shù)點前移”。 將測量結(jié)果乘以1000,一定程度上消除小數(shù)截斷帶來的誤差,模塊3的測試結(jié)果為21.217Hz,測量誤差為1.9998e-3%,基本和另外兩個信號處于同一數(shù)量級。(這里不給出具體的測試過程了,可以自己嘗試下)。

5、總結(jié)

直接測量法適合測量高頻信號;頻率越高、測量時間越長,測量結(jié)果越精準(zhǔn);

間接測量法適合測量低頻信號,但測量精度取決于自身頻率;

等精度測量法相對誤差與被測信號頻率的大小無關(guān),僅與閘門時間和基準(zhǔn)時鐘頻率有關(guān),即實現(xiàn)了整個測試頻段的等精度測量。閘門時間越長,基準(zhǔn)時鐘頻率越高,測頻的相對誤差就越小。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • FPGA
    +關(guān)注

    關(guān)注

    1630

    文章

    21759

    瀏覽量

    604296
  • 頻率
    +關(guān)注

    關(guān)注

    4

    文章

    1513

    瀏覽量

    59268
  • 測量
    +關(guān)注

    關(guān)注

    10

    文章

    4894

    瀏覽量

    111490

原文標(biāo)題:FPGA頻率測量的三種方法

文章出處:【微信號:gh_9d70b445f494,微信公眾號:FPGA設(shè)計論壇】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    labview查看本機(jī)ip的三種方法

    做TCP通訊的時候,有時候需要知道自己的IP雖然知道自己電腦ip可以不用這么麻煩,但是有時候就想用自己所學(xué)來獲得自己所需,職業(yè)病 咳咳這里給出得到本地IP的三種方法。源程序,在附件里。
    發(fā)表于 11-27 17:17

    啟動Redis的三種方法

    Redis筆記(1)——安裝、卸載、三種方法啟動Redis,Redis命令使用(干貨十足),Redis兩種方法設(shè)置密碼,時間復(fù)雜度(更完善哦~)
    發(fā)表于 06-08 16:09

    LwIP協(xié)議棧開發(fā)嵌入式網(wǎng)絡(luò)的三種方法有何關(guān)系

    LwIP協(xié)議棧開發(fā)嵌入式網(wǎng)絡(luò)的三種方法分析 輕量級的TCP/IP協(xié)議棧LwIP,提供了三種應(yīng)用程序設(shè)計方法,且很容易被移植到多任務(wù)的操作系統(tǒng)中。本文結(jié)合μC/OS-II這一實時操作系統(tǒng),以建立TCP
    發(fā)表于 08-05 07:55

    基于STM32F1 MCU測速的三種方法

    的文章提到,測速的三種方法:(1)在規(guī)定時間內(nèi)測量所產(chǎn)生的脈沖個數(shù)來獲得被測速度,稱為M法測速;(2)測量相鄰兩個脈沖的時間來測量速度,稱為T法測速;(3)同時
    發(fā)表于 09-13 07:08

    噪聲系數(shù)測量三種方法

    噪聲系數(shù)測量三種方法 本文介紹了測量噪聲系數(shù)的三種方法:增益法、Y
    發(fā)表于 05-07 13:38 ?2162次閱讀

    解決電池問題有三種方法

    解決電池問題有三種方法      對于手機(jī)電池問題如何解決,業(yè)內(nèi)人士指出有以下三種方法:   一、發(fā)明新型電池。目前有日本生產(chǎn)商已經(jīng)展示了概念性的燃
    發(fā)表于 11-10 14:26 ?959次閱讀

    臺式機(jī)CMOS放電三種方法

    現(xiàn)有的主板大多設(shè)計了CMOS放電跳線方便用戶進(jìn)行放電操作,不過CMOS放電的方法也不止這一,閱讀下文了解臺式機(jī)CMOS放電三種方法
    發(fā)表于 01-09 11:01 ?5.3w次閱讀
    臺式機(jī)CMOS放電<b class='flag-5'>三種方法</b>

    python統(tǒng)計詞頻的三種方法

    python統(tǒng)計詞頻的三種方法方法。
    發(fā)表于 05-25 14:33 ?2次下載

    單片機(jī)測量PWM占空比的三種方法

    單片機(jī)測量PWM占空比的三種方法PWM(Pulse Width Modulation),一般指脈沖寬度調(diào)節(jié),是利用微處理器的數(shù)字輸出來對模擬電路進(jìn)行控制的一非常有效的技術(shù),廣泛應(yīng)用在從測量
    發(fā)表于 11-19 11:21 ?69次下載
    單片機(jī)<b class='flag-5'>測量</b>PWM占空比的<b class='flag-5'>三種方法</b>

    噪聲系數(shù)測量三種方法

    本文介紹了測量噪聲系數(shù)的三種方法:增益法、Y系數(shù)法和噪聲系數(shù)測試儀法。這三種方法的比較以表格的形式給出。
    的頭像 發(fā)表于 05-18 11:02 ?1329次閱讀
    噪聲系數(shù)<b class='flag-5'>測量</b>的<b class='flag-5'>三種方法</b>

    【世說設(shè)計】噪聲系數(shù)測量三種方法

    本文介紹了測量噪聲系數(shù)的三種方法:增益法、Y系數(shù)法和噪聲系數(shù)測試儀法。這三種方法的比較以表格的形式給出。在無線通信系統(tǒng)中,噪聲系數(shù)(NF)或者相對應(yīng)的噪聲因數(shù)(F)定義了噪聲性能和對接
    的頭像 發(fā)表于 05-19 10:38 ?1110次閱讀
    【世說設(shè)計】噪聲系數(shù)<b class='flag-5'>測量</b>的<b class='flag-5'>三種方法</b>

    pwm產(chǎn)生的三種方法

    pwm產(chǎn)生的三種方法 PWM(Pulse Width Modulation)是一常用的控制技術(shù),可以通過調(diào)節(jié)開關(guān)管的通斷時間,通過改變輸出波形的占空比來實現(xiàn)對電路的控制。在現(xiàn)代工業(yè)控制中,PWM
    的頭像 發(fā)表于 09-02 10:25 ?7707次閱讀

    三種方法實現(xiàn)串口接收不定長度的數(shù)據(jù)

    下面三種方式都親測可用,實際使用時應(yīng)采用第三種方法,更有效率。
    的頭像 發(fā)表于 09-14 16:16 ?1.1w次閱讀
    <b class='flag-5'>三種方法</b>實現(xiàn)串口接收不定長度的數(shù)據(jù)

    修復(fù)鋰電池的三種方法

    電子發(fā)燒友網(wǎng)站提供《修復(fù)鋰電池的三種方法.doc》資料免費下載
    發(fā)表于 11-15 10:40 ?5次下載
    修復(fù)鋰電池的<b class='flag-5'>三種方法</b>

    傳統(tǒng)激光功率衰減的三種方法

    傳統(tǒng)激光功率衰減通常使用以下三種方法,分別為中性密度衰減片衰減法、偏振衰減法、鍍膜光學(xué)鏡片衰減法。
    的頭像 發(fā)表于 01-20 10:42 ?1787次閱讀
    傳統(tǒng)激光功率衰減的<b class='flag-5'>三種方法</b>