1、FPGA頻率測(cè)量?
頻率測(cè)量在電子設(shè)計(jì)和測(cè)量領(lǐng)域中經(jīng)常用到,因此對(duì)頻率測(cè)量方法的研究在實(shí)際工程應(yīng)用中具有重要意義。
通常的頻率測(cè)量方法有三種:直接測(cè)量法,間接測(cè)量法,等精度測(cè)量法。
2、直接測(cè)量法
2.1、方法
直接測(cè)量法也叫頻率測(cè)量法,即在固定在時(shí)間t內(nèi)對(duì)被測(cè)信號(hào)的脈沖數(shù)進(jìn)行計(jì)數(shù),然后求出單位時(shí)間內(nèi)的脈沖數(shù),即為被測(cè)信號(hào)的頻率。
下圖中的信號(hào)分別為:
sys_clk:系統(tǒng)的基準(zhǔn)時(shí)鐘
gate:根據(jù)基準(zhǔn)時(shí)鐘生成的閘門信號(hào),用于生成一個(gè)固定的時(shí)間(例如1s,方便計(jì)算)
clk_fx:被測(cè)信號(hào)
gate是在基準(zhǔn)時(shí)鐘下生成的固定時(shí)間信號(hào),它持續(xù)的時(shí)間 Tg = sys_clk 計(jì)數(shù)個(gè)數(shù)N(可設(shè)置);在gate持續(xù)為高的時(shí)間內(nèi),可使用被測(cè)信號(hào)clk_fx對(duì)其進(jìn)行計(jì)數(shù),計(jì)數(shù)個(gè)數(shù)為cnt(圖中為5),則cnt個(gè)被測(cè)信號(hào)的周期即為gate時(shí)長(zhǎng)。
此種方法的本質(zhì)是:同樣的時(shí)間內(nèi)分別使用兩種時(shí)鐘計(jì)時(shí),則有 Tg = Tfx---- Tsys_clk 計(jì)數(shù)個(gè)數(shù)N = Tclk_fx cnt,公式變換后:clk_fx = cnt sys_clk / 計(jì)數(shù)個(gè)數(shù)N (其中clk_fx為待測(cè)信號(hào)頻率,sys_clk為基準(zhǔn)時(shí)鐘頻率)
2.2、誤差分析
從圖可以看出,在gate為高電平期間,被測(cè)信號(hào)實(shí)際上差不多有六個(gè)周期被囊括在內(nèi),但是因?yàn)楸粶y(cè)信號(hào)是相對(duì)與系統(tǒng)的異步信號(hào),相位不同,第一個(gè)周期無(wú)法被采樣,所以實(shí)際采樣為5,這樣造成的誤差為一個(gè)被測(cè)信號(hào)周期。可以預(yù)見(jiàn),這種測(cè)量方法帶來(lái)的測(cè)量誤差即為一個(gè)被測(cè)信號(hào)周期。
那么理論上測(cè)得的準(zhǔn)確頻率:clk_fxe = cnt sys_clk / 計(jì)數(shù)個(gè)數(shù)N----理論上cnt無(wú)誤差
實(shí)際上測(cè)量的頻率值:clk_fx= cnt±1 sys_clk / 計(jì)數(shù)個(gè)數(shù)N----cnt會(huì)存在一個(gè)周期的測(cè)量誤差
測(cè)量誤差 = |(clk_fxe -clk_fx)/clk_fxe | 100% = 1 / cnt 100%
所以測(cè)得的cnt越大,那么測(cè)出來(lái)的誤差值就小,而cnt越大則代表被測(cè)信號(hào)的頻率越高,所以可以推斷該種測(cè)量方法適合測(cè)量高頻信號(hào);此外,選擇的閘門時(shí)間越長(zhǎng)則被測(cè)信號(hào)的個(gè)數(shù)越多,同樣測(cè)量就越精確,但是增大閘門時(shí)間又會(huì)帶來(lái)測(cè)量時(shí)間過(guò)長(zhǎng)的問(wèn)題,需要依據(jù)具體需求進(jìn)行取舍。
2.3、Verilog代碼
Verilog源碼如下:
閘門時(shí)間設(shè)定為0.5s,非閘門時(shí)間也0.5s,則每1秒更新一次測(cè)量數(shù)據(jù)
使用計(jì)數(shù)器生成閘門時(shí)間,閘門時(shí)間取反得到非閘門時(shí)間
在閘門時(shí)間對(duì)被測(cè)信號(hào)計(jì)數(shù)
在非閘門時(shí)間更新測(cè)量數(shù)據(jù)
使用parameter定義參數(shù),方便調(diào)用修改
//直接測(cè)量法(高頻) modulecymometer_direct( input sys_clk,//基準(zhǔn)時(shí)鐘,設(shè)計(jì)為50M(可更改) input sys_rst_n,//復(fù)位信號(hào),低電平有效 input clk_fx,//待測(cè)信號(hào) output reg [31:0]fre//測(cè)量結(jié)果 ); parameterTIME_SYS = 20;//系統(tǒng)時(shí)鐘周期:20ns--頻率=50MHz parameterTIME_GATE = 500_000_000;//500ms閘門設(shè)置的時(shí)間,單位:ns localparamN = TIME_GATE /TIME_SYS;//生成閘門需要計(jì)數(shù)的個(gè)數(shù) reg gate;//閘門 reg [31:0] cnt_gate;//用于生成閘門的計(jì)數(shù)器 reg [31:0] cnt_fx;//閘門時(shí)間內(nèi)對(duì)被測(cè)信號(hào)計(jì)數(shù) wiregate_n;//閘門取反,用于在非閘門時(shí)輸出測(cè)得的頻率值 assigngate_n = ~gate;//閘門取反,用于在非閘門時(shí)輸出測(cè)得的頻率值 //分頻計(jì)數(shù)器,閘門時(shí)間設(shè)定為1ms,則每2ms測(cè)量一次 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 //閘門時(shí)間內(nèi)對(duì)被測(cè)信號(hào)計(jì)數(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 //在非閘門時(shí)輸出測(cè)得的頻率值 always @(posedge gate_n or negedge sys_rst_n)begin if(!sys_rst_n) fre <= 0; else //TIME_GATE/cnt_fx=規(guī)定時(shí)間/被測(cè)信號(hào)個(gè)數(shù)=被測(cè)信號(hào)周期,取倒數(shù)即為頻率 fre <= 1000_000_000/TIME_GATE * cnt_fx; end endmodule
2.4、仿真分析
Testbench:
設(shè)計(jì)被測(cè)信號(hào)周期為489*2=978ns,則其理論頻率為1/978ns=1022494.88Hz;
`timescale 1ns/1ns//時(shí)間單位/精度 //------------<模塊及端口聲明>---------------------------------------- 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; //地址位寬 //------------<例化被測(cè)試模塊>---------------------------------------- cymometer_directcymometer_direct_inst( .sys_clk(sys_clk), .sys_rst_n(sys_rst_n), .clk_fx(clk_fx), .fre (fre) ); //------------<設(shè)置初始測(cè)試條件>---------------------------------------- initial begin sys_clk = 1'b0;//初始時(shí)鐘為0 sys_rst_n <= 1'b0;//初始復(fù)位 clk_fx<= 1'b0; #5//5個(gè)時(shí)鐘周期后 sys_rst_n <= 1'b1;//拉高復(fù)位,系統(tǒng)進(jìn)入工作狀態(tài) // #2500_000 // forever#2560 clk_fx = ~clk_fx; end //------------<設(shè)置時(shí)鐘>---------------------------------------------- always #10 sys_clk = ~sys_clk;//系統(tǒng)時(shí)鐘周期20ns always #489 clk_fx = ~clk_fx;//被測(cè)信號(hào)周期489*2ns = 978ns endmodule
仿真如下圖:
上圖在閘門時(shí)間內(nèi)測(cè)得的被測(cè)信號(hào)個(gè)數(shù)cnt_fx為511248,測(cè)得被測(cè)信號(hào)頻率為1022496Hz;理論頻率=1/978ns=1022494.88Hz(MHz級(jí)別)。
可以看出這個(gè)測(cè)量結(jié)果還是比較準(zhǔn)確的。因?yàn)殚l門時(shí)間夠長(zhǎng),且被測(cè)信號(hào)自身頻率就比較高(約1Mhz)。
接下來(lái)更改一下Testbench,比較一下閘門時(shí)間對(duì)被測(cè)信號(hào)的影響以及被測(cè)信號(hào)自身頻率高低對(duì)測(cè)量的影響:
第1個(gè)模塊:被測(cè)信號(hào)頻率為1022494.88Hz(MHz級(jí)別),閘門時(shí)間0.5s
第2個(gè)模塊:被測(cè)信號(hào)頻率為1022494.88Hz(MHz級(jí)別),閘門時(shí)間0.5ms
第3個(gè)模塊:被測(cè)信號(hào)頻率為76103.5Hz(KHz級(jí)別),閘門時(shí)間0.5s
第4個(gè)模塊:被測(cè)信號(hào)頻率為21.217Hz(Hz級(jí)別),閘門時(shí)間0.5s
//多變量對(duì)比測(cè)試 `timescale 1ns/1ns//時(shí)間單位/精度 //------------<模塊及端口聲明>---------------------------------------- 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è)閘門時(shí)間1ms //------------<例化被測(cè)試模塊>---------------------------------------- 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) ); //------------<例化被測(cè)試模塊>---------------------------------------- //------------<設(shè)置初始測(cè)試條件>---------------------------------------- initial begin sys_clk = 1'b0;//初始時(shí)鐘為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個(gè)時(shí)鐘周期后 sys_rst_n <= 1'b1;//拉高復(fù)位,系統(tǒng)進(jìn)入工作狀態(tài) end //------------<設(shè)置時(shí)鐘>---------------------------------------------- always #10 sys_clk = ~sys_clk;//系統(tǒng)時(shí)鐘周期20ns always #489 clk_fx1 = ~clk_fx1;//被測(cè)信號(hào)周期489*2ns,理論頻率1022494.88Hz(MHz級(jí)別) always #489 clk_fx2 = ~clk_fx2;//被測(cè)信號(hào)周期489*2ns,理論頻率1022494.88Hz(MHz級(jí)別) always #6570 clk_fx3 = ~clk_fx3;//被測(cè)信號(hào)周期6570*2ns,理論頻率76103.5Hz(KHz級(jí)別) always #23565678 clk_fx4 = ~clk_fx4;//被測(cè)信號(hào)周期23565678*2ns,理論頻率21.217Hz(Hz級(jí)別) endmodule
測(cè)量結(jié)果如下:
將測(cè)量結(jié)果整理成下表:
閘門時(shí)間 | 理論頻率(Hz) | 實(shí)際測(cè)量頻率(Hz) | 測(cè)量誤差 | |
模塊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% |
從上表的測(cè)試結(jié)果可以對(duì)直接測(cè)量法做出如下總結(jié):
閘門時(shí)間越長(zhǎng),測(cè)量結(jié)果越精準(zhǔn),但是也會(huì)導(dǎo)致單次測(cè)量時(shí)間過(guò)長(zhǎng)
直接測(cè)量法適合測(cè)量高頻信號(hào),測(cè)量誤差與閘門時(shí)間及被測(cè)信號(hào)頻率相關(guān)
3、間接測(cè)量法
3.1、方法
間接測(cè)量法也叫周期測(cè)量法,即在一個(gè)被測(cè)信號(hào)的周期內(nèi),測(cè)量基準(zhǔn)時(shí)鐘的個(gè)數(shù),得到被測(cè)信號(hào)的周期,再將其轉(zhuǎn)化為頻率。
下圖中的信號(hào)分別為:
sys_clk:系統(tǒng)的基準(zhǔn)時(shí)鐘
clk_fx:被測(cè)信號(hào)
在被測(cè)信號(hào)clk_fx為高電平的時(shí)間內(nèi),使用基準(zhǔn)時(shí)鐘進(jìn)行計(jì)數(shù),計(jì)數(shù)個(gè)數(shù)為cnt(圖中為8),則cnt基準(zhǔn)時(shí)鐘周期=半個(gè)被測(cè)信號(hào)的周期。
所以cnt/ FERQ_SYS(基準(zhǔn)時(shí)鐘頻率)=(1/2) * (1/clk_fx),化簡(jiǎn)后clk_fx =FERQ_SYS/(cnt*2)
此種方法適用于測(cè)量低頻信號(hào),但同時(shí)也會(huì)帶來(lái)測(cè)量速度過(guò)慢的問(wèn)題,誤差來(lái)自一個(gè)系統(tǒng)基準(zhǔn)時(shí)鐘。
3.2、誤差分析
從圖可以看出,在被測(cè)信號(hào)高電平期間,被測(cè)信號(hào)實(shí)際上差不多有8.5個(gè)周期被囊括在內(nèi),但是因?yàn)楸粶y(cè)信號(hào)是相對(duì)與系統(tǒng)的異步信號(hào),相位不同,所以實(shí)際采樣為8,這樣造成的誤差為1個(gè)基準(zhǔn)信號(hào)周期。可以預(yù)見(jiàn),這種測(cè)量方法帶來(lái)的測(cè)量誤差即為一個(gè)基準(zhǔn)信號(hào)周期。
那么理論上測(cè)得的準(zhǔn)確頻率:clk_fx =FERQ_SYS/(cnt*2)----理論上cnt無(wú)誤差
實(shí)際上測(cè)量的頻率值:clk_fx =FERQ_SYS/((cnt±1)*2)----cnt會(huì)存在一個(gè)周期的測(cè)量誤差
測(cè)量誤差 = |(clk_fxe -clk_fx)/clk_fxe | 100% = 1 / cnt 100%
所以測(cè)得的cnt越大,那么測(cè)出來(lái)的誤差值就小,而cnt越大則代表被測(cè)信號(hào)的頻率越低(周期越高),所以可以推斷該種測(cè)量方法適合測(cè)量低頻信號(hào)。
2.3、Verilog代碼
Verilog源碼如下:
在被測(cè)信號(hào)計(jì)數(shù)高電平期間使用基準(zhǔn)時(shí)鐘計(jì)數(shù)
在被測(cè)信號(hào)計(jì)數(shù)低電平期間更新測(cè)量數(shù)據(jù)
使用parameter定義參數(shù),方便調(diào)用修改
//間接測(cè)量法(低頻) module cymometer_indirect( input sys_clk,//基準(zhǔn)時(shí)鐘,設(shè)計(jì)為50M(可更改) input sys_rst_n, //復(fù)位信號(hào),低電平有效 //待測(cè)信號(hào) input clk_fx,//測(cè)量結(jié)果 output reg [31:0]fre ); parameterTIME_SYS = 20;//系統(tǒng)時(shí)鐘周期:20ns--頻率=50MHz reg [31:0]cnt_fx;//對(duì)被測(cè)信號(hào)高電平進(jìn)行計(jì)數(shù)的計(jì)數(shù)器 //在測(cè)信號(hào)高電平期間進(jìn)行計(jì)數(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 //在測(cè)信號(hào)低電平期輸出測(cè)量數(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依然采用在直接測(cè)量法測(cè)試用的3個(gè)頻率設(shè)置
模塊1被被測(cè)信號(hào)周期23565678*2ns,理論頻率21.217Hz(Hz級(jí)別)
模塊2被測(cè)信號(hào)周期6570*2ns,理論頻率76103.5Hz(KHz級(jí)別)
模塊3被測(cè)信號(hào)周期489*2ns,理論頻率1022494.88Hz(MHz級(jí)別)
`timescale 1ns/1ns//時(shí)間單位/精度 //------------<模塊及端口聲明>---------------------------------------- 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; //------------<例化被測(cè)試模塊>---------------------------------------- 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è)置初始測(cè)試條件>---------------------------------------- initial begin sys_clk = 1'b0;//初始時(shí)鐘為0 sys_rst_n <= 1'b0;//初始復(fù)位 clk_fx1<= 1'b0; clk_fx2<= 1'b0; clk_fx3<= 1'b0; #5//5個(gè)時(shí)鐘周期后 sys_rst_n <= 1'b1;//拉高復(fù)位,系統(tǒng)進(jìn)入工作狀態(tài) end //------------<設(shè)置時(shí)鐘>---------------------------------------------- always #10 sys_clk = ~sys_clk;//系統(tǒng)時(shí)鐘周期20ns always #23565678 clk_fx1 = ~clk_fx1;//被測(cè)信號(hào)周期23565678*2ns,理論頻率21.217Hz(Hz級(jí)別) always #6570 clk_fx2 = ~clk_fx2;//被測(cè)信號(hào)周期6570*2ns,理論頻率76103.5Hz(KHz級(jí)別) always #489 clk_fx3 = ~clk_fx3;//被測(cè)信號(hào)周期489*2ns,理論頻率1022494.88Hz(MHz級(jí)別) endmodule
仿真如下圖1:
將測(cè)量結(jié)果整理成下表:
理論頻率(Hz) | 實(shí)際測(cè)量頻率(Hz) | 測(cè)量誤差 | |
模塊1 | 21.217297 | 21 | 1.02% |
模塊2 | 76103.5 | 75987 | 0.15% |
模塊3 | 1022494.88 | 1041666 | 1.87% |
從上表的測(cè)試結(jié)果可以對(duì)間接測(cè)量法做出如下總結(jié):間接測(cè)量法適合測(cè)量低頻信號(hào),測(cè)量誤差與測(cè)信號(hào)頻率相關(guān)。
需要注意的是,輸出信號(hào)不能處理浮點(diǎn)數(shù),推薦的解決辦法是將其放大整數(shù)倍(100倍),以便實(shí)現(xiàn)小數(shù)點(diǎn)的頻率測(cè)量(不然小數(shù)點(diǎn)被截?cái)鄷?huì)帶來(lái)額外的誤差)。
將測(cè)量結(jié)果乘以1000,一定程度上消除小數(shù)截?cái)鄮?lái)的誤差,模塊1的測(cè)試結(jié)果為21.217Hz,測(cè)量誤差為1.9998e-3%,大大低于另外兩個(gè)高頻信號(hào)。(這里不給出具體的測(cè)試過(guò)程了,可以自己嘗試下)。
4、等精度測(cè)量法
4.1、概念
上述兩種方法都會(huì)產(chǎn)生±1 個(gè)被測(cè)時(shí)鐘周期的誤差,在實(shí)際應(yīng)用中有一定的局限 性;而且根據(jù)兩種方式的測(cè)量原理,很容易發(fā)現(xiàn)頻率測(cè)量法適合于測(cè)量高頻時(shí)鐘信號(hào),而周期測(cè)量法適合于低頻時(shí)鐘信號(hào)的測(cè)量,但二者都不能兼顧高低頻率同樣精度的測(cè)量要求。
等精度測(cè)量法與前兩種方式不同,其最大的特點(diǎn)是,測(cè)量的實(shí)際門控時(shí)間不是一個(gè)固 定值,它與被測(cè)時(shí)鐘信號(hào)相關(guān),是被測(cè)時(shí)鐘信號(hào)周期的整數(shù)倍。在實(shí)際門控信號(hào)下,同時(shí)對(duì)標(biāo)準(zhǔn)時(shí)鐘和被測(cè)時(shí)鐘信號(hào)的時(shí)鐘周期進(jìn)行計(jì)數(shù),再通過(guò)公式計(jì)算得到被測(cè)信號(hào)的時(shí)鐘頻率。 由于實(shí)際門控信號(hào)是被測(cè)時(shí)鐘周期的整數(shù)倍,就消除了被測(cè)信號(hào)產(chǎn)生的±1 時(shí)鐘周期的誤差,但是會(huì)產(chǎn)生對(duì)標(biāo)準(zhǔn)時(shí)鐘信號(hào)±1時(shí)鐘周期的誤差,而標(biāo)準(zhǔn)時(shí)鐘通常又是頻率極高,所以誤差較之前兩種方法就大大降低。
此種測(cè)量方法相對(duì)誤差與被測(cè)信號(hào)頻率的大小無(wú)關(guān),僅與閘門時(shí)間和基準(zhǔn)時(shí)鐘頻率有關(guān),即實(shí)現(xiàn)了整個(gè)測(cè)試頻段的等精度測(cè)量。閘門時(shí)間越長(zhǎng),基準(zhǔn)時(shí)鐘頻率越高,測(cè)頻的相對(duì)誤差越小。需要注意的是,原則上門控時(shí)間越長(zhǎng),則精度越高,但測(cè)量低頻信號(hào)(Hz級(jí)別)時(shí),建議將門控時(shí)間設(shè)置為被測(cè)信號(hào)的十幾倍即可,否則測(cè)量時(shí)間將會(huì)過(guò)長(zhǎng)。
了解了等精度測(cè)量原理之后,我們來(lái)說(shuō)明一下被測(cè)時(shí)鐘信號(hào)的計(jì)算方法:
首先通過(guò)被測(cè)信號(hào)生成實(shí)際閘門
分別對(duì)實(shí)際閘門下被測(cè)時(shí)鐘信號(hào)和標(biāo)準(zhǔn)時(shí)鐘信號(hào)的時(shí)鐘周期進(jìn)行計(jì)數(shù)。
實(shí)際閘門下被測(cè)時(shí)鐘信號(hào)周期數(shù)為 X,設(shè)被測(cè)信號(hào)時(shí)鐘周期為 Tfx,它的時(shí)鐘頻率 fx = 1/Tfx,由此可得等式:X * Tfx = X / fx = Tx(實(shí)際閘門)----這里無(wú)誤差。
實(shí)際閘門下標(biāo)準(zhǔn)時(shí)鐘信號(hào)周期數(shù)為 Y(誤差為1),設(shè)被測(cè)信號(hào)時(shí)鐘周期為 Tfs,它的時(shí)鐘頻率 fs = 1/Tfs,由此可得等式:Y * Tfs = Y / fs = Tx(實(shí)際閘門)----這里最大誤差為1個(gè)基準(zhǔn)時(shí)鐘周期。
將兩等式結(jié)合得到只包含各自時(shí)鐘周期計(jì)數(shù)和時(shí)鐘頻率的等式:X / fx = Y / fs = Tx(實(shí)際閘門),等式變換,得到被測(cè)時(shí)鐘信號(hào)時(shí)鐘頻率計(jì)算公式:fx = X * fs / Y。
將已知量標(biāo)準(zhǔn)時(shí)鐘信號(hào)時(shí)鐘頻率 fs 和測(cè)量量 X、Y 帶入計(jì)算公式,得到被測(cè)時(shí)鐘信號(hào)時(shí)鐘頻率 fx。
4.2、誤差分析
根據(jù)前文及上圖,不難發(fā)現(xiàn),誤差來(lái)源于使用基準(zhǔn)時(shí)鐘在閘門時(shí)間測(cè)量時(shí)會(huì)存在一個(gè)基準(zhǔn)時(shí)鐘周期的誤差。
那么理論上測(cè)得的準(zhǔn)確頻率:clk_fxe = X * fs / Y----理論上Y無(wú)誤差
實(shí)際上測(cè)量的頻率值:clk_fx = X * fs / Y----Y會(huì)存在1個(gè)周期的測(cè)量誤差
測(cè)量誤差 = |(clk_fxe - clk_fx)/ clk_fxe | 100% = 1 / Y 100%
所以測(cè)得的Y越大,那么測(cè)出來(lái)的誤差值就小。當(dāng)閘門時(shí)間越大,Y越大;基準(zhǔn)時(shí)鐘頻率越高,Y越大。所以通過(guò)提高基準(zhǔn)時(shí)鐘頻率或者增加閘門時(shí)間(但是會(huì)使測(cè)量過(guò)長(zhǎng),需要取舍),可以有效提高測(cè)量精度。
4.3、Verilog代碼
Verilog源碼如下:
//等精度測(cè)量法(低頻) 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; //門控時(shí)間,越大誤差越小,但測(cè)量時(shí)間也會(huì)變長(zhǎng) //reg define reg gate_fx; //門控信號(hào),被測(cè)信號(hào)域下 reg gate_fs ; //同步到基準(zhǔn)時(shí)鐘的門控信號(hào) reg gate_fs_r ; //用于同步gate信號(hào)的寄存器 reg gate_fs_d0 ; //用于采集基準(zhǔn)時(shí)鐘下gate下降沿 reg gate_fs_d1 ; //用于采集基準(zhǔn)時(shí)鐘下gate下降沿 reg gate_fx_d0 ; //用于采集被測(cè)時(shí)鐘下gate下降沿 reg gate_fx_d1 ; //用于采集被測(cè)時(shí)鐘下gate下降沿 reg [15:0] gate_cnt ; //門控計(jì)數(shù) reg [31:0] fs_cnt ; //門控時(shí)間內(nèi)基準(zhǔn)時(shí)鐘的計(jì)數(shù)值 reg [31:0] fs_cnt_temp ; //fs_cnt 臨時(shí)值 reg [31:0] fx_cnt ; //門控時(shí)間內(nèi)被測(cè)時(shí)鐘的計(jì)數(shù)值 reg [31:0] fx_cnt_temp ; //fx_cnt 臨時(shí)值 //wire define wire neg_gate_fs; //基準(zhǔn)時(shí)鐘下門控信號(hào)下降沿= wire neg_gate_fx; //被測(cè)時(shí)鐘下門控信號(hào)下降沿 //捕捉信號(hào)下降沿 assign neg_gate_fs = gate_fs_d1 & (~gate_fs_d0); assign neg_gate_fx = gate_fx_d1 & (~gate_fx_d0); //檢測(cè)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 //檢測(cè)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 //被測(cè)時(shí)鐘閘門計(jì)數(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 //被測(cè)時(shí)鐘閘門生成 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 //把閘門從被測(cè)時(shí)鐘域同步到基準(zhǔn)時(shí)鐘域 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 //在被測(cè)時(shí)鐘域?qū)Ρ粶y(cè)信號(hào)計(jì)數(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)時(shí)鐘域?qū)鶞?zhǔn)時(shí)鐘計(jì)數(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)時(shí)鐘域輸出結(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è)計(jì)被測(cè)信號(hào)周期為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; //------------<例化被測(cè)試模塊>---------------------------------------- cymometer_equal cymometer_equal_inst ( .clk_fs(clk_fs), .clk_fx(clk_fx), .fre(fre), .rst_n(rst_n) ); //------------<設(shè)置初始測(cè)試條件>---------------------------------------- initialbegin clk_fs = 1'b0; clk_fx <= 1'b0; rst_n <= 1'b0; #116 rst_n <= 1'b1; end //------------<設(shè)置時(shí)鐘>---------------------------------------------- always#10 clk_fs <= ~clk_fs; always #489 clk_fx <= ~clk_fx; endmodule
仿真結(jié)果如下所示
上圖的測(cè)量結(jié)果為1022494Hz,理論頻率為1/978ns=1022494.88Hz,可以看到這個(gè)結(jié)果相當(dāng)精確。
接下來(lái)更改一下Testbench,比較一下閘門時(shí)間對(duì)被測(cè)信號(hào)的影響以及被測(cè)信號(hào)自身頻率高低對(duì)測(cè)量的影響(為避免仿真時(shí)間過(guò)長(zhǎng),閘門時(shí)間均設(shè)為10個(gè)被測(cè)信號(hào)周期,因?yàn)榛鶞?zhǔn)時(shí)鐘頻率較高,所以閘門時(shí)間少點(diǎn)不會(huì)有什么影響)
第1個(gè)模塊:被測(cè)信號(hào)頻率為1022494.88Hz(MHz級(jí)別)
第2個(gè)模塊:被測(cè)信號(hào)頻率為76103.5Hz(KHz級(jí)別)
第3個(gè)模塊:被測(cè)信號(hào)頻率為21.217Hz(Hz級(jí)別)
仿真結(jié)果如下:
將測(cè)量結(jié)果整理成下表:
理論頻率(Hz) | 實(shí)際測(cè)量頻率(Hz) | 測(cè)量誤差 | |
模塊1 | 1022494.88 | 1022494 | 8.60e-5% |
模塊2 | 76103.5 | 76103 | 6.57e-4% |
模塊3 | 21.217297 | 21 | 1.02% |
從上表的測(cè)試結(jié)果發(fā)現(xiàn)等精度測(cè)量法同時(shí)適用于高低頻域,測(cè)量結(jié)果誤差只和基準(zhǔn)時(shí)鐘頻率有關(guān)。
這里需要注意的是,因?yàn)闇y(cè)量結(jié)果都是整數(shù)(FPGA自動(dòng)截?cái)嘈?shù)),如果被測(cè)頻率較低,那么因?yàn)樾?shù)被截?cái)?,?huì)使得誤差增大。一個(gè)比較方便的解決辦法是把計(jì)算公式都放大一定的倍數(shù),從而使得“小數(shù)點(diǎn)前移”。 將測(cè)量結(jié)果乘以1000,一定程度上消除小數(shù)截?cái)鄮?lái)的誤差,模塊3的測(cè)試結(jié)果為21.217Hz,測(cè)量誤差為1.9998e-3%,基本和另外兩個(gè)信號(hào)處于同一數(shù)量級(jí)。(這里不給出具體的測(cè)試過(guò)程了,可以自己嘗試下)。
5、總結(jié)
直接測(cè)量法適合測(cè)量高頻信號(hào);頻率越高、測(cè)量時(shí)間越長(zhǎng),測(cè)量結(jié)果越精準(zhǔn);
間接測(cè)量法適合測(cè)量低頻信號(hào),但測(cè)量精度取決于自身頻率;
等精度測(cè)量法相對(duì)誤差與被測(cè)信號(hào)頻率的大小無(wú)關(guān),僅與閘門時(shí)間和基準(zhǔn)時(shí)鐘頻率有關(guān),即實(shí)現(xiàn)了整個(gè)測(cè)試頻段的等精度測(cè)量。閘門時(shí)間越長(zhǎng),基準(zhǔn)時(shí)鐘頻率越高,測(cè)頻的相對(duì)誤差就越小。
-
FPGA
+關(guān)注
關(guān)注
1630文章
21800瀏覽量
606272 -
頻率
+關(guān)注
關(guān)注
4文章
1536瀏覽量
59401 -
測(cè)量
+關(guān)注
關(guān)注
10文章
4944瀏覽量
111850
原文標(biāo)題:FPGA頻率測(cè)量的三種方法
文章出處:【微信號(hào):gh_9d70b445f494,微信公眾號(hào):FPGA設(shè)計(jì)論壇】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
labview查看本機(jī)ip的三種方法
啟動(dòng)Redis的三種方法
LwIP協(xié)議棧開(kāi)發(fā)嵌入式網(wǎng)絡(luò)的三種方法有何關(guān)系
一種基于STM32F1 MCU測(cè)速的三種方法
噪聲系數(shù)測(cè)量的三種方法
解決電池問(wèn)題有三種方法
臺(tái)式機(jī)CMOS放電三種方法
![臺(tái)式機(jī)CMOS放電<b class='flag-5'>三種方法</b>](https://file1.elecfans.com//web2/M00/A7/24/wKgZomUMQqKALULqAAAY4WudCG0013.jpg)
單片機(jī)測(cè)量PWM占空比的三種方法
![單片機(jī)<b class='flag-5'>測(cè)量</b>PWM占空比的<b class='flag-5'>三種方法</b>](https://file.elecfans.com/web1/M00/D9/4E/pIYBAF_1ac2Ac0EEAABDkS1IP1s689.png)
【世說(shuō)設(shè)計(jì)】噪聲系數(shù)測(cè)量的三種方法
![【世說(shuō)設(shè)計(jì)】噪聲系數(shù)<b class='flag-5'>測(cè)量</b>的<b class='flag-5'>三種方法</b>](https://file.elecfans.com/web2/M00/4C/78/poYBAGKyxUaAVCbBAAAfziEvOio242.jpg)
評(píng)論