對于邏輯級數較高的路徑,常用的方法之一是在其中插入流水寄存器,將路徑打斷,從而降低邏輯延遲,這在HDL代碼中實現起來比較容易。此外,從RTL代碼風格角度講,對于關鍵模塊,設計時常將其輸入/輸出端口寄存。這起到了隔離關鍵路徑的作用。
但是,如果使用的RTL代碼是HLS轉換生成的,例如使用Vitis HLS綜合的,其可讀性較差,想要在其生成的HDL代碼中插入寄存器就變得比較困難。為此,我們想到了能否在C代碼中插入寄存器,并保證Vitis HLS綜合后的結果是寄存器。
這要解決四個問題:一是這樣的C代碼要具備一定的可復用性,比如,以模板函數的形式呈現。二是這樣的C代碼是參數化的,尤其是數據類型,因為需要寄存的數據其數據類型不盡相同。這仍然可以借助模板函數實現。三是保證這個函數不被優化合并掉。因為這個函數功能比較單一,輸出等于輸入,這就要用到INLINE的功能。四是C語言是不具備時序特征的,要實現輸出與輸入的延遲,就要借助相應的pragma,我們想到了Latency。
在此基礎上,我們構造了下面的C++代碼。不難看出,這是一個模板函數,數據類型是參數化的,使用了三個pragma。其中PIPELINE用于限定II為1,LATENCY用于限定延遲為1,INLINE用于防止該函數被合并。
看一個具體的使用案例,如下圖所示代碼。功能很簡單,就是實現兩個數的相加。這里對兩個輸入數據a和b分別做了寄存,同時對結果c也做了寄存。最終的綜合報告顯示Latency為2,和我們預期的一致。對于生成的HDL代碼,將其添加到Vivado中進行綜合,綜合后的結果也是符合預期的。
這里,我們對比一下三種情形。情形1:不添加流水寄存器;情形2:僅對輸出添加流水寄存器;情形3:輸入輸出均添加流水寄存器。Vitis HLS綜合結果以及其生成的HDL代碼在Vivado下的綜合結果對比如下圖所示。首先,可以看到Latency符合預期,同時II始終為1;其次,Vivado下綜合后的資源利用率與Vitis HLS的結果是不一致的。這一點也很容易理解,因為Vivado綜合時會有很多優化。
進一步,我們看到這里的延遲為1,如果需要兩級延遲,就要兩次調用模板函數。能否將延遲的時鐘周期也設置成參數呢?答案是肯定的,如下圖代碼所示。這里定義了L,用來管理延遲的時鐘周期個數,對應pragma Latency的min和max值。
原文標題:在C代碼中插入寄存器
文章出處:【微信公眾號:Lauren的FPGA】歡迎添加關注!文章轉載請注明出處。
責任編輯:haq
-
寄存器
+關注
關注
31文章
5363瀏覽量
121089 -
C語言
+關注
關注
180文章
7614瀏覽量
137629 -
代碼
+關注
關注
30文章
4823瀏覽量
68991
原文標題:在C代碼中插入寄存器
文章出處:【微信號:Lauren_FPGA,微信公眾號:FPGA技術驛站】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論