(原創聲明:該文是作者的原創,面向對象是FPGA入門者,后續會有進階的高級教程。宗旨是讓每個想做FPGA的人輕松入門,作者不光讓大家知其然,還要讓大家知其所以然!每個工程作者都搭建了全自動化的仿真環境,只需要雙擊top_tb.bat文件就可以完成整個的仿真(前提是安裝了modelsim),降低了初學者的門檻。如需整個工程請留言(WX:Blue23Light),不收任何費用,但是僅供參考,不建議大家獲得資料后從事一些商業活動!)
頻率計可以采集外部周期信號的頻率,當然實現方法有很多種,這兒我們用FPGA采樣計數來實現。
如果用FPGA采樣計數實現頻率計,那FPGA的采樣頻率一定要遠大于輸入信號的頻率。這個從直觀上是很明確的,你不可能用低頻率采樣高頻信號,就如拿磚頭取打天上的飛機,根本打不到的。用相近頻率采集輸入信號也不可以,因為非常容易錯過采集信號的跳變沿,漏過很多采樣的信號;只要采樣頻率遠遠大于采集信號的頻率,才能不會漏過采集信號的跳變細節,得到近似的頻率值。
為什么我們不敢保證一定能得到外部輸入信號的準確頻率值,因為輸入信號和FPGA的系統時鐘是異步信號,FPGA采集的點有可以巧合錯過一個跳變沿,所以我們設計的頻率計會有1-2個時鐘周期的誤差.這個誤差可以通過長時間的采集求平均值來減小。
如下所示是FPGA實現頻率計的波形示意圖,sys_clk是系統時鐘,freq_clk是要采集的時鐘,flag是設定時間段進行freq_clk時鐘數的統計。建議將flag設置成2冪次方秒,這樣直接將計數值右移即可,避免了除法的運算。
用系統時鐘sys_clk采集輸入時鐘freq_clk,所以要先把freq_clk同步到sys_clk時鐘域,再進行時鐘數的統計。所以FPGA的設計也是非常簡單的。這里sys_clk時鐘頻率設置為1MHz,主要是為了減少計數值,方便快速仿真。
設置了一個參數CNT=4000000,就是4秒的時間進行頻率計數,然后停4秒,再進行4秒的頻率計數,以此反復,用meter_flag進行標識。
freq_flag用來標識采樣點,完成輸入周期信號freq_clk到sys_clk的同步。
在meter_flag拉高的時候,對freq_clk進行計數,通過采集freq_clk的上升沿,最終得計數值通過右移2位實現除4的操作。
在仿真文件中設置freq_clk是128Hz,仿真結果是128,結果正確。
設置freq_clk是100KHz,仿真結果是100_000,結果正確。
設置freq_clk是128KHz,仿真結果是128.008,有8個時鐘的偏差,原因一是128KHz頻率和1MHz比已經相差不大了,而且128KHz不是1MHz的整數倍,所以測量可能就會有偏差的。
還有一個重要的原因就是仿真產生的時鐘周期freq_clk不是剛剛好的128KHz,可能會有偏差。我們測量一下freq_clk的頻率,確實是128008Hz。
這節課只是簡單的介紹頻率計的FPGA實現,如果要提高頻率計的精度,有多種方法可以改進,比如用兩個計數器,一個上升沿計數,一個下降沿計數,相加求平均;再比如將N個連續的頻率值相加求平均等等,有興趣的讀者可以自己設計來試一下。