1. 程式人生 > >利用Xilinx HLS實現LDPC譯碼器

利用Xilinx HLS實現LDPC譯碼器

algorithm 舉例 修正 數據 https res 變化 ram sea

1. 概述

采用Xilinx HLS快速實現的部分並行,全流水的LDPC譯碼器。

  • 環境:Vivado HLS 2018.2
  • 碼字:IEEE 802.16e 2/3A
  • 算法:Min-Sum Algorithm
  • 代碼:https://github.com/cea-wind/hls_ldpc_dec/
  • 器件:xc7k160

使用方法:

1. 從GitHub上clone代碼

2. 在終端運行命令

vivado_hls -f run_hls.tcl

3. 打開vivado hls GUI,找到生成的工程,打開即可

2. 碼字和算法

為簡單起見,采用了IEEE 802.16e標準中的2/3A碼率的碼字,並選擇1536的碼長作為具體的驗證舉例。該LDPC碼是準循環碼,每個循環子矩陣的行重為1。其校驗矩陣可以用母矩陣表示為

技術分享圖片

譯碼算法原理可參考https://www.cnblogs.com/sea-wind2/p/4282640.html,或者直接參考其實現https://www.cnblogs.com/sea-wind2/p/4268408.html。(寫得均不好,不建議參考)

譯碼算法采用修正因子為0.8125的最小和算法,為了簡便起見,沒有設置滿足校驗方程跳出的判斷。具體可參考Git repo中的MATLAB代碼,但該MATLAB代碼並沒有做量化。

3. 設計思路

為了體現FPGA的優勢,此處采用了部分並行全流水的設計。其中部分並行指設計同時開始多個行更新和列更新,全流水指行更新和列更新采用的流水線設計可以做到一個時鐘周期完成一行或一列數據的更新。

校驗矩陣中有80個不為0的循環矩陣,將其分別存儲在不同的BRAM上,一個周期內可訪問80個循環矩陣中的任意一個數據。因此在進行行更新時,可以同時更新8行,列更新時,可以同時更新24列。按此進行並行設計。

行更新采用了全流水設計,其核心在於求最小值和次小值,可以參考https://www.cnblogs.com/sea-wind/p/8384596.html的內容。實現結構類似

技術分享圖片

列更新采用了全流水設計,利用加法即可,較為簡單。

由於之前寫過一份FPGA代碼,因此行更新和列更新的HLS代碼Verilog風格較重。

4. 分析

4.1 Perference

HLS結果如下圖所示,預計頻率在250MHz以上。完一次譯碼(50次叠代)需要10020個周期。

技術分享圖片

具體耗時細節如下圖,讀取解調後軟信息需要約1539個周期,輸出結果需要約1026個周期,譯碼叠代需要7450個周期。

技術分享圖片

行更新需要的理論時間為64個clk,列更新也是如此。因此完成一次行列更新需要128個clock(行列不做流水的理論下限),綜合結果表示latency為149個周期,效率已經極高了。關於數據讀取和寫回,由於設計中沒有做特別優化,此處不做考慮。

上述結果表明,HLS綜合結果從效率和頻率上看都極其優異。

4.2 Resource

(似乎2018.2的綜合策略發生了變化,利用了大量register且資源評估時未作優化,因此該階段資源評估不準確,采用2016.3結果)

信息的存儲占用了大量的資源,共有80塊用於存儲中間信息,24塊存儲輸入的對數似然比,結果和分析一致。而行更新和列更新消耗了大量的邏輯資源。技術分享圖片

行更新和列更新具體資源細節如下圖所示

技術分享圖片

以列更新為例,列更新過程中,列重為3的更新有1個4-in的11bit加法,3個2-in的8bit減法,6次比較和3個3-to-1MUX。預計占用資源為3×11+3×8+6×3+3×8=97個LUT,加上地址控制等,其綜合結果資源耗費合理。

因此HLS的綜合結果資源占用也在合理範圍內。

5. 優化

  • 優化輸入輸出設計
  • 加入停止條件
  • 優化bram的使用,包括輸入信息的存儲和輸出信息的存儲
  • 已經有兩年沒有接觸LDPC了,Xilinx HLS也基本沒用過,如有建議還請留言指正

利用Xilinx HLS實現LDPC譯碼器