如果您正在使用 MATLAB 建模數(shù)字信號(hào)處理(DSP)或者視頻和圖像處理算法,并且最終將其用于 FPGA 或 ASIC,本文可能將為你帶來幫助。
從 MATLAB 生成 HDL 代碼
FPGA 在通用處理器(GPP)和專用集成電路(ASIC)之間提供了很好的折中方案。GPP 是完全可編程的,但在功率和性能方面效率較低;ASIC 可實(shí)現(xiàn)專用的功能,并展現(xiàn)出最佳的功率和性能特性,但需要極其昂貴的設(shè)計(jì)驗(yàn)證和實(shí)現(xiàn)周期。FPGA 也用于 ASIC 工作流中的原型設(shè)計(jì),以進(jìn)行硬件驗(yàn)證和早期軟件開發(fā)。
由于在運(yùn)行高吞吐量、高性能的應(yīng)用程序時(shí),性能有了大幅度的提高,算法設(shè)計(jì)者越來越多地使用 FPGA 而不是傳統(tǒng)的處理器來原型化和驗(yàn)證創(chuàng)新。然而,由于 MATLAB 簡(jiǎn)單易用的編程模型和豐富的分析和可視化能力,許多算法都是在其中實(shí)現(xiàn)的。當(dāng)針對(duì) FPGA 或 ASIC 時(shí),這些 MATLAB 算法必須手動(dòng)轉(zhuǎn)換為 HDL。
對(duì)于許多精通軟件編程的算法開發(fā)人員來說,掌握 FPGA 設(shè)計(jì)工作流是一項(xiàng)挑戰(zhàn)。與軟件算法開發(fā)不同,硬件開發(fā)要求并行思想。存在的其他障礙包括:學(xué)習(xí) VHDL 或 Verilog 語言,掌握 FPGA 供應(yīng)商的 IDE,理解深?yuàn)W的術(shù)語,如“多周期路徑”和“延遲平衡”等。
在這篇文章中,我將介紹一個(gè)從 MATLAB 轉(zhuǎn)換為 FPGA 的簡(jiǎn)單路徑。我將展示如何從 MATLAB 算法自動(dòng)生成 HDL 代碼,在 FPGA 上實(shí)現(xiàn) HDL 代碼,并使用 MATLAB 來驗(yàn)證您的 HDL 代碼。
MATLAB 到硬件工作流
將 MATLAB 設(shè)計(jì)轉(zhuǎn)換為硬件的過程包括以下步驟:
1. 在 MATLAB 中建模您的算法——使用 MATLAB 來模擬、調(diào)試、迭代測(cè)試并優(yōu)化設(shè)計(jì)。
2. 生成 HDL 代碼——自動(dòng)創(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è)計(jì)。
將 MATLAB 轉(zhuǎn)換為硬件存在一些獨(dú)特的挑戰(zhàn)。MATLAB 代碼是過程性的,可以高度抽象;它可以使用浮點(diǎn)數(shù)據(jù),并且沒有時(shí)間概念。復(fù)雜的循環(huán)可以從矩陣運(yùn)算和工具箱函數(shù)推斷出來。
在硬件中實(shí)現(xiàn) MATLAB 代碼包含以下操作:
將浮點(diǎn) MATLAB 代碼轉(zhuǎn)換為具有優(yōu)化位寬的定點(diǎn) MATLAB 代碼,以實(shí)現(xiàn)高效的硬件生成。
識(shí)別程序結(jié)構(gòu)并將其映射到并發(fā)的經(jīng)過面積和速度優(yōu)化的硬件操作上。
通過添加時(shí)鐘和時(shí)鐘率來調(diào)度硬件中的操作,引入時(shí)間的概念。
創(chuàng)建資源共享架構(gòu)來實(shí)現(xiàn)昂貴的操作符,如乘數(shù)和 for 循環(huán)體。
將大型持久化數(shù)組映射到硬件中的塊RAM
HDL Coder? 可通過工作流自動(dòng)化簡(jiǎn)化上述任務(wù)。
MATLAB 算法示例
讓我們用MATLAB函數(shù)來實(shí)現(xiàn)直方圖均衡化并完成此工作流。該算法在 MATLAB 中實(shí)現(xiàn),通過變換灰度像中的值來增強(qiáng)圖像對(duì)比度,使輸出圖像的直方圖近似平坦。
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 示例
下面是一個(gè) test bench,用于驗(yàn)證算法是否對(duì)示例圖像起作用。(注意,此 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(請(qǐng)參見下面的快照)有助于自動(dòng)執(zhí)行步驟,并提供從MATLAB到硬件的引導(dǎo)。您可以在 Workflow Advisor 的左窗格中看到工作流的以下關(guān)鍵步驟:
1. 定點(diǎn)轉(zhuǎn)換
2. HDL 代碼生成
3. HDL 驗(yàn)證
4. HDL 綜合與分析
我們來詳細(xì)看看工作流中的每個(gè)步驟。
定點(diǎn)轉(zhuǎn)換
信號(hào)處理應(yīng)用程序通常使用 MATLAB 中的浮點(diǎn)運(yùn)算來實(shí)現(xiàn)。但是,出于功耗、成本和性能的原因,在面向硬件時(shí),需要將這些算法轉(zhuǎn)換為使用定點(diǎn)運(yùn)算。定點(diǎn)轉(zhuǎn)換非常具有挑戰(zhàn)性并且非常耗時(shí),通常需要占用整個(gè)設(shè)計(jì)和實(shí)施時(shí)間的 25% 到 50%。HDL Coder? 中用于浮點(diǎn)到定點(diǎn)自動(dòng)轉(zhuǎn)換的工作流可以極大地簡(jiǎn)化和加速轉(zhuǎn)換過程。
浮點(diǎn)到定點(diǎn)轉(zhuǎn)換工作流包括以下步驟:
1. 驗(yàn)證浮點(diǎn)設(shè)計(jì)與代碼生成兼容。
2. 根據(jù)計(jì)算范圍,通過模擬 test bench 或通過靜態(tài)分析(將傳播設(shè)計(jì)范圍以計(jì)算所有變量的派生范圍)提出定點(diǎn)類型。
3. 通過應(yīng)用建議的定點(diǎn)類型生成定點(diǎn) MATLAB 代碼。
4. 驗(yàn)證生成的定點(diǎn)代碼,并將生成的定點(diǎn)代碼的數(shù)值精度與原始浮點(diǎn)代碼進(jìn)行比較。
請(qǐng)注意,此步驟是可選的。如果您的 MATLAB 設(shè)計(jì)已在定點(diǎn)實(shí)現(xiàn),則可以跳過此步驟。
HDL 代碼生成
HDL 代碼生成步驟通過定點(diǎn) MATLAB 代碼生成 HDL 代碼。您可以生成實(shí)現(xiàn) MATLAB 設(shè)計(jì)的 VHDL 或 Verilog 代碼。除了生成可綜合的HDL代碼外,HDL Coder? 還可生成各種報(bào)告,包括可幫助您在 MATLAB 代碼和生成的 HDL 代碼之間導(dǎo)航的可跟蹤報(bào)告,以及在算法級(jí)別顯示實(shí)現(xiàn)設(shè)計(jì)所需硬件資源(加法器、乘法器和 RAM)的資源利用率報(bào)告。
在代碼生成期間,您可以指定各種優(yōu)化選項(xiàng)來探索設(shè)計(jì)空間,而無需修改算法。在下面的“設(shè)計(jì)空間探索和優(yōu)化選項(xiàng)”部分中,您可以看到如何修改代碼生成選項(xiàng)以及如何針對(duì)速度或面積來優(yōu)化設(shè)計(jì)。
HDL 驗(yàn)證
獨(dú)立 HDL test bench 的生成:
HDL Coder? 可通過您的 MATLAB 腳本生成 VHDL 和 Verilog test bench,以快速驗(yàn)證生成的 HDL 代碼。您可以使用將激勵(lì)應(yīng)用于 HDL 代碼的多個(gè)選項(xiàng)來自定義 HDL test bench。您還可以生成腳本文件,以自動(dòng)執(zhí)行在 HDL 模擬器中編譯和模擬代碼的過程。這些步驟有助于確保 MATLAB 仿真的結(jié)果與 HDL 仿真的結(jié)果相匹配。
HDL Coder? 還與 HDL Verifier 一起使用,以自動(dòng)生成兩種類型的協(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è)計(jì)中,并確保該算法在硬件中實(shí)現(xiàn)時(shí)能夠達(dá)到預(yù)期的性能。
HDL 綜合
除了與語言相關(guān)的挑戰(zhàn)外,F(xiàn)PGA 編程還需要使用復(fù)雜的 EDA 工具。從 HDL 設(shè)計(jì)中生成比特流并對(duì) FPGA 進(jìn)行編程可能是一項(xiàng)艱巨的任務(wù)。HDL Coder? 通過為 Xilinx? 和 Altera? 創(chuàng)建用生成的HDL代碼配置的項(xiàng)目文件,可在此處提供自動(dòng)化。您可以使用工作流步驟在MATLAB 環(huán)境中綜合 HDL 代碼,查看綜合結(jié)果,并迭代 MATLAB 設(shè)計(jì)以改善綜合結(jié)果。
設(shè)計(jì)空間探索和優(yōu)化選項(xiàng)
HDL Coder? 提供以下優(yōu)化,以幫助您探索如何在設(shè)計(jì)空間的面積和速度之間進(jìn)行權(quán)衡。您可以使用這些選項(xiàng)來探索各種架構(gòu)并進(jìn)行各種權(quán)衡,而不必手動(dòng)重寫算法。
速度優(yōu)化
流水線:為了提高設(shè)計(jì)的時(shí)鐘頻率,HDL Coder 使您可以在設(shè)計(jì)中的各個(gè)位置插入流水線寄存器。例如,您可以在設(shè)計(jì)的輸入和輸出處以及在算法中給定 MATLAB 變量的輸出處插入寄存器。
分布式流水線:HDL Coder 還提供了基于重定時(shí)的優(yōu)化,可通過設(shè)計(jì)中的組合路徑將延遲降到最小,以此自動(dòng)移動(dòng)插入的流水線寄存器,從而最大化時(shí)鐘頻率。
面積優(yōu)化
RAM 映射:HDL Coder? 將矩陣映射到硬件中的導(dǎo)線或寄存器。如果將持久性矩陣變量映射到寄存器,則它們會(huì)占用大量的FPGA面積。HDL Coder?會(huì)自動(dòng)將持久性矩陣映射到塊RAM,以提高面積效率。將MATLAB矩陣映射到塊RAM的挑戰(zhàn)在于,硬件中的塊RAM通常具有一組有限的讀寫端口。HDL Coder? 通過自動(dòng)劃分和調(diào)度矩陣讀寫來滿足塊 RAM 的端口限制,同時(shí)仍然遵循設(shè)計(jì)中的其他控制依賴性和數(shù)據(jù)依賴性來解決此問題。
資源共享:此優(yōu)化可以識(shí)別并共享 MATLAB 代碼中具有等效功能的乘法器操作。您可以控制設(shè)計(jì)中的乘數(shù)器共享量。
循環(huán)流:MATLAB 的 for 循環(huán)可在 VHDL 中創(chuàng)建一個(gè) FOR_GENERATE 循環(huán)。循環(huán)主體在硬件中的復(fù)制次數(shù)與循環(huán)迭代次數(shù)相同。這會(huì)導(dǎo)致面積使用的低效。循環(huán)流優(yōu)化會(huì)創(chuàng)建循環(huán)體的單個(gè)硬件實(shí)例,該實(shí)例在循環(huán)迭代之間進(jìn)行時(shí)間多路復(fù)用。
常數(shù)乘法器優(yōu)化:此設(shè)計(jì)級(jí)別的優(yōu)化使用正則有符號(hào)數(shù)(CSD)技術(shù)將常數(shù)乘法器轉(zhuǎn)換為移位和加法運(yùn)算。
最佳實(shí)踐方法
現(xiàn)在,我們來看幾個(gè)在面向 FPGA 來編寫 MATLAB 代碼時(shí)的最佳實(shí)踐方法。
編寫 MATLAB 設(shè)計(jì)時(shí):
使用支持 HDL 代碼生成的 MATLAB 代碼生成子集。
使頂層接口盡可能簡(jiǎn)單。頂層功能的大小、類型和復(fù)雜性決定了在硬件中實(shí)現(xiàn)的芯片接口。
不要將大量并行數(shù)據(jù)傳遞到設(shè)計(jì)中。并行數(shù)據(jù)需要芯片上的大量 IO 引腳,并且可能無法綜合。在典型的圖像處理設(shè)計(jì)中,您應(yīng)該將像素輸入串行化,并在算法內(nèi)部緩沖它們。
編寫 MATLAB test bench 時(shí):
從 test bench 函數(shù)調(diào)用設(shè)計(jì)。
徹底執(zhí)行設(shè)計(jì)。這對(duì)于浮點(diǎn)到定點(diǎn)轉(zhuǎn)換尤為重要,其中 HDL Coder? 會(huì)根據(jù) test bench 分配給變量的值來確定算法中變量的范圍。您可以重復(fù)使用此測(cè)試工作臺(tái)來生成 HDL test bench,以測(cè)試所生成的硬件。
在代碼生成之前用 test bench 對(duì)設(shè)計(jì)進(jìn)行仿真,以確保沒有仿真錯(cuò)誤,并確保所有必需的文件都在路徑中。
結(jié)論
HDL Coder? 提供了在 FPGA 中實(shí)現(xiàn)算法的無縫工作流。在本文中,我向您展示了如何采用 MATLAB 圖像處理算法、將其轉(zhuǎn)換為定點(diǎn)、生成 HDL 代碼、使用 test bench 驗(yàn)證生成的 HDL 代碼,以及最終綜合設(shè)計(jì)并在硬件中實(shí)現(xiàn)它。
通過本文對(duì) HDL Coder? 以及 MATLAB 轉(zhuǎn) HDL 代碼生成和驗(yàn)證框架的簡(jiǎn)要介紹,我們希望能助您了解如何開始快速實(shí)施 MATLAB 設(shè)計(jì)和目標(biāo) FPGA。
編輯:hfy
-
FPGA
+關(guān)注
關(guān)注
1630文章
21777瀏覽量
604756 -
matlab
+關(guān)注
關(guān)注
185文章
2980瀏覽量
230745 -
asic
+關(guān)注
關(guān)注
34文章
1205瀏覽量
120611 -
數(shù)字信號(hào)處理
+關(guān)注
關(guān)注
15文章
562瀏覽量
45927 -
HDL
+關(guān)注
關(guān)注
8文章
327瀏覽量
47419
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論