FPGA學習重點
1. 看代碼,建模型
只有在腦海中建立了一個個邏輯模型,理解FPGA內部邏輯結構實現的基礎,才能明白為什么寫Verilog和寫C整體思路是不一樣的,才能理解順序執行語言和并行執行語言的設計方法上的差異。在看到一段簡單程序的時候應該想到是什么樣的功能電路。
2. 用數學思維來簡化設計邏輯
學習FPGA不僅邏輯思維很重要,好的數學思維也能讓你的設計化繁為簡,所以啊,那些看見高數就頭疼的童鞋需要重視一下這門課哦。舉個簡單的例子,比如有兩個32bit的數據X[31:0]與Y[31:0]相乘。當然,無論Altera還是Xilinx都有現成的乘法器IP核可以調用,這也是最簡單的方法,但是兩個32bit的乘法器將耗費大量的資源。那么有沒有節省資源,又不太復雜的方式來實現呢?我們可以稍做修改:
將X[31:0]拆成兩部分X1[15:0]和X2[15:0],令X1[15:0]=X[31:16],X2[15:0]=X[15:0],則X1左移16位后與X2相加可以得到X;同樣將Y[31:0]拆成兩部分Y1[15:0]和Y2[15:0],令 Y1[15:0]=Y[31:16],Y2[15:0]=Y[15:0],則Y1左移16位后與Y2相加可以得到Y,則X與Y的相乘可以轉化為X1和X2 分別與Y1和Y2相乘,這樣一個32bit32bit的乘法運算轉換成了四個16bit16bit的乘法運算和三個32bit的加法運算。轉換后的占用資源將會減少很多,有興趣的童鞋,不妨綜合一下看看,看看兩者差多少。
3. 時鐘與觸發器的關系
“時鐘是時序電路的控制者”這句話太經典了,可以說是FPGA設計的圣言。FPGA的設計主要是以時序電路為主,因為組合邏輯電路再怎么復雜也變不出太多花樣,理解起來也不沒太多困難。但是時序電路就不同了,它的所有動作都是在時鐘一拍一拍的節奏下轉變觸發,可以說時鐘就是整個電路的控制者,控制不好,電路功能就會混亂。
打個比方,時鐘就相當于人體的心臟,它每一次的跳動就是觸發一個 CLK,向身體的各個器官供血,維持著機體的正常運作,每一個器官體統正常工作少不了組織細胞的構成,那么觸發器就可以比作基本單元組織細胞。
時序邏輯電路的時鐘是控制時序邏輯電路狀態轉換的“發動機”,沒有它時序邏輯電路就不能正常工作。因為時序邏輯電路主要是利用觸發器存儲電路的狀態,而觸發器狀態變換需要時鐘的上升或下降沿,由此可見時鐘在時序電路中的核心作用。
FPGA開發籠統的說可以分為兩個方向,一個是接口方向、一個是算法方向。
接口方向
接口方向可不是簡單的uart、IIC、SPI等這些簡單接口,這些東西不足以支撐一個方向,大部分都是基于serdes的高速復雜接口,例如PCIE、SATA等。還有以太網,甚至可能不太復雜的SDRAM控制接口。
這些接口簡單么? 簡單,不是都有IP核可以調用么,IP核是個好東西,節省了我們大部分的時間,要不自己寫一個試試?感覺impossible啊,看看那一堆復雜的協議,光用ip核都一大堆問題了,還敢夸口自己寫,
要是沒人帶,很難自己搞的出來。這也是我害怕搞接口的原因。之前公司有一個華為的大牛,沒有用廠家的IP核,說這個收費的IP核要多少W美刀,硬是自己寫了一個,我是一直都很佩服他的,因為這種接口如此的復雜,光理解那些協議還是英文的,我都不知道能不能理解。也許是他之前在華為搞過這個接口,但早期華為出來的人,估計大概是(03年~13年)在華為吧,真的是有很厲害,現在的華為據說分的特別細,可能一個人就負責一個模塊,好幾年都是這樣,把細節做到極致,但是人就螺絲釘化了,有好有不好吧。
因為工作的原因,現在已經接觸到了serdes以及基于serdes的jesd和cpri協議等,可以說接口方面也算是入了門的吧,但實際上也都是IP核來實現的,光ip核調試起來有時候都要磨很久了。甚至有時候光一個小問題磨你一兩個月都很常見
因為接口方向我可能是入門水準,也就不說太多了。
總之接口方向就是 復雜的接口+復雜的協議,要閱讀海量的數據手冊,跟硬件專業親密的扯皮加配合,踩過無數的坑,方能略有小成
算法方向
接下來說說算法方向,一般來說以算法作為一個方向,那么這個算法整體來說是非常復雜的。以導航的定位解算來舉例。
導航的定位解算包括:中頻信號搬頻到基帶、進行信號的捕獲(涉及相關運算、FFT等)、信號的跟蹤(數字鎖頻環、數字鎖相環、觀測量提取、電文的提取)、電文提取(信道解碼、解交織、位同步、幀同步、電文解析)、定位解算(偽距計算輸出、載波相位輸出,最小二乘法算法,星歷參數計算,統稱PVT解算(位置、速度、時間) )
這么多算法全部整合在一起,需要進行充分的驗證,如果只是用類似modelsim來仿真,那速度真是慢的想哭。那么我們需要更高級的方法,我們需要一個定點模型,matlab定點模型或者C定點模型。對于某些要做芯片的工程,一般是要做成C模型,C模型的效率比matlab更高,雖然看起來matlab更簡單直接
算法模型要做到什么程度呢,最理想的就是要做到和modelsim仿真結果一模一樣,無論是某些重要的中間結果還是最終結果,無論是數據流型的結果還是觸發型的結果,都要完全的一模一樣。因此算法模型的搭建會占用你大量的時間,但是一但搭建成功,則后面大部分驗證都完全可以通過算法模型去仿真,不在需要在用modelsim進行仿真了,因為modelsim相對于matlab或者C模型來說,實在是太慢太不方便了。
之前在那家創業公司弄GPS導航信號接收處理,捕獲部分是比較復雜的,100多個并行相關器進行短時相關+FFT的操作,我是花了很多時間用matlab做了完全一致的定點化模型,完成了之后,后面要改什么,或者要驗證什么就非常方便了,因為我可以直接在matlab模型上進行驗證了,無需通過跑modelsim,基本就知道其是否正確了
matlab做算法模型還比較好理解,但C做算法模型呢
以下這個這個例子,表示用C來實現GPS C/A碼并且進行驗證
#include
#include
#include
#include "PrnGen.h"
#include "PrnInit.h"
#include "GPSPrnTable.h"
void main(void)
{
? ? PrnGen PrnGen;
? ? int i,j,prn;
? ? int error = 0;
? ? int CodeOutI[1023];
? ? unsigned int SRegs[24];
? ? unsigned int SBuffer[6];
? ? // set 0 for GPS , G1 and G2 parallel, code length = 1023
? ? SRegs[0] = (0x3a6 << 14) | 0x204;
? ? SRegs[1] = 1023 << 14;
? ? SRegs[2] = (0x3a6 << 14) | 0x204;
? ? SRegs[3] = 1023 << 14;
? ? // check GPS L1 C/A in CodeI
? ? PrnGen.SetPoly(&(SettingRegs[0]));
? ? for (prn=1; prn<=32; prn++)
? ? {
? ? ? ? SBuffer[0] = SBuffer[2] = CAPrnInit[prn];
? ? ? ? SBuffer[4] = 0;
? ? ? ? for(i=0;i<10;i++)
? ? ? ? {
? ? ? ? ? ? PrnGen.Reset();
? ? ? ? ? ? PrnGen.LoadState(SBuffer);
? ? ? ? ? ? for(j=0; j<1023; j++)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? CodeOutI[j] = PrnGen.GetCodeI();
? ? ? ? ? ? ? ? PrnGen.ShiftCodeI();
? ? ? ? ? ? ? ? if (CodeOutI[j] != CAcode[prn-1][j])
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? error = 1;
? ? ? ? ? ? ? ? ? ? printf("error on prn%d bit%d! ", prn, j);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? ? PrnGen.DumpState(SBuffer);
? ? ? ? }
? ? }
? ? if (error == 0)
? ? ? ? printf("C/A code test passed! ");
? ? system("PAUSE");
}
上面是模擬verilog實現的功能,其實雖然C和MATLAB是順序執行的,但也是可以模擬verilog并行執行的,如下面就是模擬verilog的并行執行功能
while (1)
{
clkcnt = clkcnt +1;
delay_d3 =delay_d2;
delay_d2 = delay_d1;
delay_d1 = delay_in;
}
這個等效于verilog的下面語句
always @(POSedge clk)
begin
delay_d1 <= delay_in;
delay_d2 <=delay_d1;
delay_d3 <= delay_d2;
end
以上只是冰上一腳,以前接觸過的大型工程,甚至要做芯片去流片的C算法模型非常的龐大
總結
如果以武功來描述這兩個方向的關系,接口就是劍,算法是氣。
劍是紛繁復雜的招數,華山劍法(JESD)、嵩山劍法(PCIE)、辟邪劍法(SATA),每一個都招式繁多,但每個招式都記錄于劍譜(協議)只上,因為招式是死的,理論上只要有人手把手的教,基本都能學會。但事實上不會有人手把手的教,一般只有門派(公司)有什么才能學到什么,而且也不會有人手把手去交,老員工一般只是會稍加提點,大部分情況下要去自己勤加苦練。想學更多只能改投其他門派了,但投靠門派多了,可能各門武功都學藝不精了。
氣是深厚內力的修為,紫霞神功(數字信號處理)、吸星大法(高等數學),這些東西只有口訣,完全根據自己的悟性才能練到多少重。想想當年高等數學都理解了不,數字信號處理、信號與系統都想得明白么,想不明白,有人教也沒用,因為理解不了。第一家公司有一個清華的同事,人家理解LDCP編解碼,人家理解的那一個快呀。我是半天都看不懂,因為我高等數學差呀。。。這真的跟智商有關系呀。
以上是一些粗鄙的認識,兩個方向都不容易,接口需要對架構、協議做非常深的理解才能游刃有余,而且調接口是非常需要經驗的,高手都是踩過無數的坑而來。算法實現首先需要一些理論功底,首先必須完全理解這個算法,然后算法實現的好壞優劣也跟你實現的方式有關。所以無論是練劍還是練氣,練到極致那都是非常優秀的了。
評論
查看更多