1. 程式人生 > >學會System Generator(13)Vivado HLS呼叫C/C++程式碼

學會System Generator(13)Vivado HLS呼叫C/C++程式碼

本文是該系列的第13篇。Vivado HLS是Xilinx FPGA開發套件中的一款軟體,可以使用C/C++語言進行設計,並轉換為RTL級模型。System Generator中的Vivado HLS block可以將HLS開發軟體設計的C/C++程式碼整合到Simulink環境中,利用Simulink強大的模擬特性對設計進行模擬測試。

ug948中提供的官方例程為影象的中值濾波,該設計將一副256*256大小的RGB影象,新增噪聲後提取出其中的Y通道,使用C++語言完成中值濾波。該設計將在Simulink環境下進行模擬。本文將完成改該設計,藉此介紹上述功能。

Vivado HLS完成中值濾波設計

中值濾波是一種常見的影象濾波方法,選取一個核(本設計為3*3)在影象上滑動,取核的中間值作為核中心畫素點的值。中值濾波在濾除椒鹽噪聲的同時模糊效應會明顯低於線性平滑濾波。Xilinx提供的C++設計原始檔程式碼清單如下:

#include "MedianFilter.h"
#define WINDOW_SIZE  3
typedef unsigned char PixelType;

#define PIX_SWAP(a,b) { PixelType temp=(a);(a)=(b);(b)=temp; }
#define PIX_SORT(a,b) { if ((a)>(b)) PIX_SWAP((a),(b)); }
PixelType OptMedian9(PixelType * p) { PIX_SORT(p[1], p[2]) ; PIX_SORT(p[4], p[5]) ; PIX_SORT(p[7], p[8]) ; PIX_SORT(p[0], p[1]) ; PIX_SORT(p[3], p[4]) ; PIX_SORT(p[6], p[7]) ; PIX_SORT(p[1], p[2]) ; PIX_SORT(p[4], p[5]) ; PIX_SORT(p[7], p[8]) ; PIX_SORT(p[0], p[3]) ; PIX_SORT(p[5], p[8
]) ; PIX_SORT(p[4], p[7]) ; PIX_SORT(p[3], p[6]) ; PIX_SORT(p[1], p[4]) ; PIX_SORT(p[2], p[5]) ; PIX_SORT(p[4], p[7]) ; PIX_SORT(p[4], p[2]) ; PIX_SORT(p[6], p[4]) ; PIX_SORT(p[4], p[2]) ; return(p[4]) ; } PixelType Mean(PixelType* buffer) { PixelType i, j, min; unsigned int sum; for (i = 0;i<9; i++) { sum+=buffer[i]; } sum/=(WINDOW_SIZE*WINDOW_SIZE); return sum; } PixelType Min(PixelType* buffer) { PixelType i, j, min; min = buffer[0]; for (i = 1;i<9; i++) { if (min>buffer[i]) min = buffer[i]; } return min; } void MedianFilter(PixelType row1, PixelType row2, PixelType row3, PixelType* V) { #pragma AP PIPELINE II=1 /* * Create a local Pixel Buffer based on WindowSize */ static PixelType pixelWindowBuffer[WINDOW_SIZE*WINDOW_SIZE]; PixelType sortBuffer[WINDOW_SIZE*WINDOW_SIZE]; /* * Each Iteration Interval Update the Pixel Buffers */ for(int i = 0;i<WINDOW_SIZE;++i) { for(int j=0;j<(WINDOW_SIZE-1);++j) { pixelWindowBuffer[WINDOW_SIZE*i + (WINDOW_SIZE-j-1)] = pixelWindowBuffer[WINDOW_SIZE*i + (WINDOW_SIZE-j-1)-1]; } } /* * Update the first Pixel of each row */ pixelWindowBuffer[0] = row1; pixelWindowBuffer[3] = row2; pixelWindowBuffer[6] = row3; for(int k = 0;k<9;++k) { sortBuffer[k] = pixelWindowBuffer[k]; } *V = OptMedian9(sortBuffer); };

可以自己建立HLS工程,如對HLS的使用不熟悉也可以在Xilinx官網搜尋“ug948-design-files.zip”下載,其中有示例工程。

右鍵Solution->C Synthesis->Active Solution,綜合設計原始檔。完成後,再右鍵Solution->Export RTL,Format Selection選擇為“System Generator for DSP”,點選OK將設計原始檔打包為System Generator可以使用的形式。

這裡寫圖片描述

將HLS設計匯入System Generator

新增一個Vivado HLS block,雙擊開啟該block:
這裡寫圖片描述
點選Browse,將路徑指定到HLS工程的Solution資料夾下。如果路徑選擇錯誤,或者HLS工程綜合或匯出失敗導致solution資料夾下沒有可用的System Generator檔案,軟體會提示錯誤。

設定完畢後,block埠也會隨之改變,部分埠名稱以ap_開頭,表示與block之間的ap_hs通訊協議。model的整體連線圖如下:
這裡寫圖片描述

其中包含幾個子系統,各子系統及其作用如下:

  • Noisy Image:匯入一副256*256的影象,轉換為一維資料,併為其新增椒鹽噪聲;
  • RGB2Y:將R、G、B通道轉換為Y通道(Y=0.299*R+0.587*G+0.114*B,可以簡化為只用兩個乘法器的形式Y=0.299*(R-G)+0.114*(B-G)+G);
  • LineBuffer:快取器儲存資料;
  • Noisy Input Image/Filtered Image:快取資料,將一維資料轉換為二維影象顯示。

模擬測試

在Noisy Image子系統下,開啟Image From File這個block(屬於Computer Vision System Toolbox庫)。點選Browse,將路徑指向一副256*256大小的彩色圖片。將模擬時間設定為256*256*2,確保可以完成一次影象濾波。執行結果如下:
這裡寫圖片描述
可以看到經過中值濾波後,很好地濾除了影象中的椒鹽噪聲。

Vivado HLS block詳解

該block支援C、C++和System C三種設計原始檔。使用是首先需要在Vivado HLS開發環境下將設計原始檔打包到Solution目錄下,然後在block中指向該目錄,將設計匯入到System Generator設計中。
這裡寫圖片描述
點選“Edit”可以開啟與該solution對應的Vivado HLS工程,允許設計者修改;修改後點選“Refresh”更新block的埠資訊。

block預設採用RTL-model進行模擬,如果HLS中包含C模擬模型,可以選中“Use C simulation model if available”,選擇C模擬模型。

當選中“Display signal types”時,輸入和輸出的資料型別會顯示在圖示上,設計者可以根據該提示設定向此block輸入的資料,如下圖:
這裡寫圖片描述
C/C++資料型別和System Generator資料型別之間的轉換關係如下表:
這裡寫圖片描述
在Vivado HLS中進行設計時有如下限制:

  • 設計不能是純組合邏輯,綜合到RTL設計後必須包含一個時鐘和時鐘使能輸入訊號;
  • 頂層模組中不能包含C/C++模板語法;
  • C模擬模型與block通訊時支援ap_hs通訊協議,但不支援ap_memory和ap_bus介面。