如果您正在使用 MATLAB 建模數(shù)字信號處理(DSP)或者視頻和圖像處理算法,并且最終將其用于 FPGA 或 ASIC,本文可能將為你帶來幫助。
從 MATLAB 生成 HDL 代碼
FPGA 在通用處理器(GPP)和專用集成電路(ASIC)之間提供了很好的折中方案。GPP 是完全可編程的,但在功率和性能方面效率較低;ASIC 可實(shí)現(xiàn)專用的功能,并展現(xiàn)出最佳的功率和性能特性,但需要極其昂貴的設(shè)計驗(yàn)證和實(shí)現(xiàn)周期。FPGA 也用于 ASIC 工作流中的原型設(shè)計,以進(jìn)行硬件驗(yàn)證和早期軟件開發(fā)。
由于在運(yùn)行高吞吐量、高性能的應(yīng)用程序時,性能有了大幅度的提高,算法設(shè)計者越來越多地使用 FPGA 而不是傳統(tǒng)的處理器來原型化和驗(yàn)證創(chuàng)新。然而,由于 MATLAB 簡單易用的編程模型和豐富的分析和可視化能力,許多算法都是在其中實(shí)現(xiàn)的。當(dāng)針對 FPGA 或 ASIC 時,這些 MATLAB 算法必須手動轉(zhuǎn)換為 HDL。
對于許多精通軟件編程的算法開發(fā)人員來說,掌握 FPGA 設(shè)計工作流是一項(xiàng)挑戰(zhàn)。與軟件算法開發(fā)不同,硬件開發(fā)要求并行思想。存在的其他障礙包括:學(xué)習(xí) VHDL 或 Verilog 語言,掌握 FPGA 供應(yīng)商的 IDE,理解深奧的術(shù)語,如“多周期路徑”和“延遲平衡”等。
在這篇文章中,我將介紹一個從 MATLAB 轉(zhuǎn)換為 FPGA 的簡單路徑。我將展示如何從 MATLAB 算法自動生成 HDL 代碼,在 FPGA 上實(shí)現(xiàn) HDL 代碼,并使用 MATLAB 來驗(yàn)證您的 HDL 代碼。
MATLAB 到硬件工作流
將 MATLAB 設(shè)計轉(zhuǎn)換為硬件的過程包括以下步驟:
1. 在 MATLAB 中建模您的算法——使用 MATLAB 來模擬、調(diào)試、迭代測試并優(yōu)化設(shè)計。
2. 生成 HDL 代碼——自動創(chuàng)建用于 FPGA 原型的 HDL 代碼。
3. 驗(yàn)證 HDL 代碼——重用您的 MATLAB test bench 來驗(yàn)證生成的 HDL 代碼。
4. 創(chuàng)建和驗(yàn)證 FPGA 原型——在 FPGA 上實(shí)現(xiàn)和驗(yàn)證您的設(shè)計。
將 MATLAB 轉(zhuǎn)換為硬件存在一些獨(dú)特的挑戰(zhàn)。MATLAB 代碼是過程性的,可以高度抽象;它可以使用浮點(diǎn)數(shù)據(jù),并且沒有時間概念。復(fù)雜的循環(huán)可以從矩陣運(yùn)算和工具箱函數(shù)推斷出來。
在硬件中實(shí)現(xiàn) MATLAB 代碼包含以下操作:
將浮點(diǎn) MATLAB 代碼轉(zhuǎn)換為具有優(yōu)化位寬的定點(diǎn) MATLAB 代碼,以實(shí)現(xiàn)高效的硬件生成。
識別程序結(jié)構(gòu)并將其映射到并發(fā)的經(jīng)過面積和速度優(yōu)化的硬件操作上。
通過添加時鐘和時鐘率來調(diào)度硬件中的操作,引入時間的概念。
創(chuàng)建資源共享架構(gòu)來實(shí)現(xiàn)昂貴的操作符,如乘數(shù)和 for 循環(huán)體。
將大型持久化數(shù)組映射到硬件中的塊RAM
HDL Coder? 可通過工作流自動化簡化上述任務(wù)。
MATLAB 算法示例
讓我們用MATLAB函數(shù)來實(shí)現(xiàn)直方圖均衡化并完成此工作流。該算法在 MATLAB 中實(shí)現(xiàn),通過變換灰度像中的值來增強(qiáng)圖像對比度,使輸出圖像的直方圖近似平坦。
type mlhdlc_heq.m
% Histogram Equalization Algorithm
function [pixel_out] = mlhdlc_heq(x_in, y_in, pixel_in, width, height)
persistent histogram
persistent transferFunc
persistent histInd
persistent cumSum
if isempty(histogram)
histogram = zeros(1, 2^8);
transferFunc = zeros(1, 2^8);
histInd = 0;
cumSum = 0;
end
% Figure out indices based on where we are in the frame
if y_in histInd = pixel_in + 1;
elseif y_in == height && x_in == 0 % first column of height+1
histInd = 1;
elseif y_in >= height % vertical blanking period
histInd = min(histInd + 1, 2^8);
elseif y_in histInd = 1;
end
%Read histogram
histValRead = histogram(histInd);
%Read transfer function
transValRead = transferFunc(histInd);
%If valid part of frame add one to pixel bin and keep transfer func val
if y_in histValWrite = histValRead + 1; %Add pixel to bin
transValWrite = transValRead; %Write back same value
cumSum = 0;
elseif y_in >= height %In blanking time index through all bins and reset to zero
histValWrite = 0;
transValWrite = cumSum + histValRead;
cumSum = transValWrite;
else
histValWrite = histValRead;
transValWrite = transValRead;
end
%Write histogram
histogram(histInd) = histValWrite;
%Write transfer function
transferFunc(histInd) = transValWrite;
pixel_out = transValRead;
MATLAB Test Bench 示例
下面是一個 test bench,用于驗(yàn)證算法是否對示例圖像起作用。(注意,此 testbench 使用 Image Processing Toolbox 的內(nèi)置函數(shù)來讀取原始圖像,并在均衡后繪制轉(zhuǎn)換的圖像。)
type mlhdlc_heq_tb.m
%% Test bench for Histogram Equalization Algorithm
clear mlhdlc_heq;
testFile = 'office.png';
RGB = imread(testFile);
% Get intensity part of color image
YCBCR = rgb2ycbcr(RGB);
imgOrig = YCBCR(:,:,1);
[height, width] = size(imgOrig);
imgOut = zeros(height,width);
hBlank = 20;
% make sure we have enough vertical blanking to filter the histogram
vBlank = ceil(2^14/(width+hBlank));
for frame = 1:2
disp(['working on frame: ', num2str(frame)]);
for y_in = 0:height+vBlank-1
%disp(['frame: ', num2str(frame), ' of 2, row: ', num2str(y_in)]);
for x_in = 0:width+hBlank-1
if x_in pixel_in = double(imgOrig(y_in+1, x_in+1));
else
pixel_in = 0;
end
[pixel_out] = mlhdlc_heq(x_in, y_in, pixel_in, width, height);
if x_in imgOut(y_in+1,x_in+1) = pixel_out;
end
end
end
end
% Make color image from equalized intensity image
% Rescale image
imgOut = double(imgOut);
imgOut(:) = imgOut/max(imgOut(:));
imgOut = uint8(imgOut*255);
YCBCR(:,:,1) = imgOut;
RGBOut = ycbcr2rgb(YCBCR);
figure(1)
subplot(2,2,1); imshow(RGB, []);
title('Original Image');
subplot(2,2,2); imshow(RGBOut, []);
title('Equalized Image');
subplot(2,2,3); hist(double(imgOrig(:)),2^14-1);
title('Histogram of original Image');
subplot(2,2,4); hist(double(imgOut(:)),2^14-1);
title('Histogram of equalized Image');
我們來仿真一下此算法,看看結(jié)果。
mlhdlc_heq_tb
HDL Workflow Advisor
HDL Workflow Advisor(請參見下面的快照)有助于自動執(zhí)行步驟,并提供從MATLAB到硬件的引導(dǎo)。您可以在 Workflow Advisor 的左窗格中看到工作流的以下關(guān)鍵步驟:
1. 定點(diǎn)轉(zhuǎn)換
2. HDL 代碼生成
3. HDL 驗(yàn)證
4. HDL 綜合與分析
我們來詳細(xì)看看工作流中的每個步驟。
定點(diǎn)轉(zhuǎn)換
信號處理應(yīng)用程序通常使用 MATLAB 中的浮點(diǎn)運(yùn)算來實(shí)現(xiàn)。但是,出于功耗、成本和性能的原因,在面向硬件時,需要將這些算法轉(zhuǎn)換為使用定點(diǎn)運(yùn)算。定點(diǎn)轉(zhuǎn)換非常具有挑戰(zhàn)性并且非常耗時,通常需要占用整個設(shè)計和實(shí)施時間的 25% 到 50%。HDL Coder? 中用于浮點(diǎn)到定點(diǎn)自動轉(zhuǎn)換的工作流可以極大地簡化和加速轉(zhuǎn)換過程。
浮點(diǎn)到定點(diǎn)轉(zhuǎn)換工作流包括以下步驟:
1. 驗(yàn)證浮點(diǎn)設(shè)計與代碼生成兼容。
2. 根據(jù)計算范圍,通過模擬 test bench 或通過靜態(tài)分析(將傳播設(shè)計范圍以計算所有變量的派生范圍)提出定點(diǎn)類型。
3. 通過應(yīng)用建議的定點(diǎn)類型生成定點(diǎn) MATLAB 代碼。
4. 驗(yàn)證生成的定點(diǎn)代碼,并將生成的定點(diǎn)代碼的數(shù)值精度與原始浮點(diǎn)代碼進(jìn)行比較。
請注意,此步驟是可選的。如果您的 MATLAB 設(shè)計已在定點(diǎn)實(shí)現(xiàn),則可以跳過此步驟。
HDL 代碼生成
HDL 代碼生成步驟通過定點(diǎn) MATLAB 代碼生成 HDL 代碼。您可以生成實(shí)現(xiàn) MATLAB 設(shè)計的 VHDL 或 Verilog 代碼。除了生成可綜合的HDL代碼外,HDL Coder? 還可生成各種報告,包括可幫助您在 MATLAB 代碼和生成的 HDL 代碼之間導(dǎo)航的可跟蹤報告,以及在算法級別顯示實(shí)現(xiàn)設(shè)計所需硬件資源(加法器、乘法器和 RAM)的資源利用率報告。
在代碼生成期間,您可以指定各種優(yōu)化選項(xiàng)來探索設(shè)計空間,而無需修改算法。在下面的“設(shè)計空間探索和優(yōu)化選項(xiàng)”部分中,您可以看到如何修改代碼生成選項(xiàng)以及如何針對速度或面積來優(yōu)化設(shè)計。
HDL 驗(yàn)證
獨(dú)立 HDL test bench 的生成:
HDL Coder? 可通過您的 MATLAB 腳本生成 VHDL 和 Verilog test bench,以快速驗(yàn)證生成的 HDL 代碼。您可以使用將激勵應(yīng)用于 HDL 代碼的多個選項(xiàng)來自定義 HDL test bench。您還可以生成腳本文件,以自動執(zhí)行在 HDL 模擬器中編譯和模擬代碼的過程。這些步驟有助于確保 MATLAB 仿真的結(jié)果與 HDL 仿真的結(jié)果相匹配。
HDL Coder? 還與 HDL Verifier 一起使用,以自動生成兩種類型的協(xié)同仿真 test bench:
基于 HDL 協(xié)同仿真的驗(yàn)證可與 MentorGraphics? ModelSim? 和 QuestaSim? 配合使用,其中 MATLAB 和 HDL 仿真可前后相接。
FPGA 在環(huán)仿真允許您與 FPGA 電路板嚴(yán)格同步地運(yùn)行 MATLAB 仿真。您可以使用 MATLAB 將實(shí)際的數(shù)據(jù)輸入到 FPGA 的設(shè)計中,并確保該算法在硬件中實(shí)現(xiàn)時能夠達(dá)到預(yù)期的性能。
HDL 綜合
除了與語言相關(guān)的挑戰(zhàn)外,F(xiàn)PGA 編程還需要使用復(fù)雜的 EDA 工具。從 HDL 設(shè)計中生成比特流并對 FPGA 進(jìn)行編程可能是一項(xiàng)艱巨的任務(wù)。HDL Coder? 通過為 Xilinx? 和 Altera? 創(chuàng)建用生成的HDL代碼配置的項(xiàng)目文件,可在此處提供自動化。您可以使用工作流步驟在MATLAB 環(huán)境中綜合 HDL 代碼,查看綜合結(jié)果,并迭代 MATLAB 設(shè)計以改善綜合結(jié)果。
設(shè)計空間探索和優(yōu)化選項(xiàng)
HDL Coder? 提供以下優(yōu)化,以幫助您探索如何在設(shè)計空間的面積和速度之間進(jìn)行權(quán)衡。您可以使用這些選項(xiàng)來探索各種架構(gòu)并進(jìn)行各種權(quán)衡,而不必手動重寫算法。
速度優(yōu)化
流水線:為了提高設(shè)計的時鐘頻率,HDL Coder 使您可以在設(shè)計中的各個位置插入流水線寄存器。例如,您可以在設(shè)計的輸入和輸出處以及在算法中給定 MATLAB 變量的輸出處插入寄存器。
分布式流水線:HDL Coder 還提供了基于重定時的優(yōu)化,可通過設(shè)計中的組合路徑將延遲降到最小,以此自動移動插入的流水線寄存器,從而最大化時鐘頻率。
面積優(yōu)化
RAM 映射:HDL Coder? 將矩陣映射到硬件中的導(dǎo)線或寄存器。如果將持久性矩陣變量映射到寄存器,則它們會占用大量的FPGA面積。HDL Coder?會自動將持久性矩陣映射到塊RAM,以提高面積效率。將MATLAB矩陣映射到塊RAM的挑戰(zhàn)在于,硬件中的塊RAM通常具有一組有限的讀寫端口。HDL Coder? 通過自動劃分和調(diào)度矩陣讀寫來滿足塊 RAM 的端口限制,同時仍然遵循設(shè)計中的其他控制依賴性和數(shù)據(jù)依賴性來解決此問題。
資源共享:此優(yōu)化可以識別并共享 MATLAB 代碼中具有等效功能的乘法器操作。您可以控制設(shè)計中的乘數(shù)器共享量。
循環(huán)流:MATLAB 的 for 循環(huán)可在 VHDL 中創(chuàng)建一個 FOR_GENERATE 循環(huán)。循環(huán)主體在硬件中的復(fù)制次數(shù)與循環(huán)迭代次數(shù)相同。這會導(dǎo)致面積使用的低效。循環(huán)流優(yōu)化會創(chuàng)建循環(huán)體的單個硬件實(shí)例,該實(shí)例在循環(huán)迭代之間進(jìn)行時間多路復(fù)用。
常數(shù)乘法器優(yōu)化:此設(shè)計級別的優(yōu)化使用正則有符號數(shù)(CSD)技術(shù)將常數(shù)乘法器轉(zhuǎn)換為移位和加法運(yùn)算。
最佳實(shí)踐方法
現(xiàn)在,我們來看幾個在面向 FPGA 來編寫 MATLAB 代碼時的最佳實(shí)踐方法。
編寫 MATLAB 設(shè)計時:
使用支持 HDL 代碼生成的 MATLAB 代碼生成子集。
使頂層接口盡可能簡單。頂層功能的大小、類型和復(fù)雜性決定了在硬件中實(shí)現(xiàn)的芯片接口。
不要將大量并行數(shù)據(jù)傳遞到設(shè)計中。并行數(shù)據(jù)需要芯片上的大量 IO 引腳,并且可能無法綜合。在典型的圖像處理設(shè)計中,您應(yīng)該將像素輸入串行化,并在算法內(nèi)部緩沖它們。
編寫 MATLAB test bench 時:
從 test bench 函數(shù)調(diào)用設(shè)計。
徹底執(zhí)行設(shè)計。這對于浮點(diǎn)到定點(diǎn)轉(zhuǎn)換尤為重要,其中 HDL Coder? 會根據(jù) test bench 分配給變量的值來確定算法中變量的范圍。您可以重復(fù)使用此測試工作臺來生成 HDL test bench,以測試所生成的硬件。
在代碼生成之前用 test bench 對設(shè)計進(jìn)行仿真,以確保沒有仿真錯誤,并確保所有必需的文件都在路徑中。
結(jié)論
HDL Coder? 提供了在 FPGA 中實(shí)現(xiàn)算法的無縫工作流。在本文中,我向您展示了如何采用 MATLAB 圖像處理算法、將其轉(zhuǎn)換為定點(diǎn)、生成 HDL 代碼、使用 test bench 驗(yàn)證生成的 HDL 代碼,以及最終綜合設(shè)計并在硬件中實(shí)現(xiàn)它。
通過本文對 HDL Coder? 以及 MATLAB 轉(zhuǎn) HDL 代碼生成和驗(yàn)證框架的簡要介紹,我們希望能助您了解如何開始快速實(shí)施 MATLAB 設(shè)計和目標(biāo) FPGA。
編輯:hfy
-
FPGA
+關(guān)注
關(guān)注
1642文章
21917瀏覽量
611854 -
matlab
+關(guān)注
關(guān)注
187文章
2990瀏覽量
232788 -
asic
+關(guān)注
關(guān)注
34文章
1240瀏覽量
121699 -
數(shù)字信號處理
+關(guān)注
關(guān)注
16文章
567瀏覽量
46416 -
HDL
+關(guān)注
關(guān)注
8文章
330瀏覽量
47716
發(fā)布評論請先 登錄
相關(guān)推薦
如何使用MATLAB實(shí)現(xiàn)一維時間卷積網(wǎng)絡(luò)

OptiSystem應(yīng)用:用MATLAB組件實(shí)現(xiàn)振幅調(diào)制
如何在MATLAB中使用DeepSeek模型

助力AIoT應(yīng)用:在米爾FPGA開發(fā)板上實(shí)現(xiàn)Tiny YOLO V4
基于FPGA實(shí)現(xiàn)數(shù)碼管顯示

FPGA Verilog HDL代碼如何debug?
FPGA芯片架構(gòu)和資源有深入的理解,精通Verilog HDL、VHDL
如何在DRA821U上使用Linux實(shí)現(xiàn)快速引導(dǎo)

如何在FPGA中實(shí)現(xiàn)按鍵消抖
如何在FPGA中實(shí)現(xiàn)隨機(jī)數(shù)發(fā)生器

使用PYNQ訓(xùn)練和實(shí)現(xiàn)BNN

評論