0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

如何在FPGA上实现HDL代码完成MATLAB转换

454398 ? 来源:MATLAB微信公众号 ? 作者:MATLAB微信公众号 ? 2020-11-08 10:36 ? 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

如果您正在使用 MATLAB 建模数字信号处理(DSP)或者视频和图像处理算法,并且最终将其用于 FPGAASIC,本文可能将为你带来帮助。

从 MATLAB 生成 HDL 代码
FPGA 在通用处理器(GPP)和专用集成电路(ASIC)之间提供了很好的折中方案。GPP 是完全可编程的,但在功率和性能方面效率较低;ASIC 可实现专用的功能,并展现出最佳的功率和性能特性,但需要极其昂贵的设计验证和实现周期。FPGA 也用于 ASIC 工作流中的原型设计,以进行硬件验证和早期软件开发。

由于在运行高吞吐量、高性能的应用程序时,性能有了大幅度的提高,算法设计者越来越多地使用 FPGA 而不是传统的处理器来原型化和验证创新。然而,由于 MATLAB 简单易用的编程模型和丰富的分析和可视化能力,许多算法都是在其中实现的。当针对 FPGA 或 ASIC 时,这些 MATLAB 算法必须手动转换为 HDL。

对于许多精通软件编程的算法开发人员来说,掌握 FPGA 设计工作流是一项挑战。与软件算法开发不同,硬件开发要求并行思想。存在的其他障碍包括:学习 VHDL 或 Verilog 语言,掌握 FPGA 供应商的 IDE,理解深奥的术语,如“多周期路径”和“延迟平衡”等。

在这篇文章中,我将介绍一个从 MATLAB 转换为 FPGA 的简单路径。我将展示如何从 MATLAB 算法自动生成 HDL 代码,在 FPGA 上实现 HDL 代码,并使用 MATLAB 来验证您的 HDL 代码。

MATLAB 到硬件工作流
将 MATLAB 设计转换为硬件的过程包括以下步骤:
1. 在 MATLAB 中建模您的算法——使用 MATLAB 来模拟、调试、迭代测试并优化设计。
2. 生成 HDL 代码——自动创建用于 FPGA 原型的 HDL 代码。
3. 验证 HDL 代码——重用您的 MATLAB test bench 来验证生成的 HDL 代码。
4. 创建和验证 FPGA 原型——在 FPGA 上实现和验证您的设计。

将 MATLAB 转换为硬件存在一些独特的挑战。MATLAB 代码是过程性的,可以高度抽象;它可以使用浮点数据,并且没有时间概念。复杂的循环可以从矩阵运算和工具箱函数推断出来。

在硬件中实现 MATLAB 代码包含以下操作:

将浮点 MATLAB 代码转换为具有优化位宽的定点 MATLAB 代码,以实现高效的硬件生成。

识别程序结构并将其映射到并发的经过面积和速度优化的硬件操作上。

通过添加时钟和时钟率来调度硬件中的操作,引入时间的概念。

创建资源共享架构来实现昂贵的操作符,如乘数和 for 循环体。

将大型持久化数组映射到硬件中的块RAM

HDL Coder? 可通过工作流自动化简化上述任务。

MATLAB 算法示例
让我们用MATLAB函数来实现直方图均衡化并完成此工作流。该算法在 MATLAB 中实现,通过变换灰度像中的值来增强图像对比度,使输出图像的直方图近似平坦。
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,用于验证算法是否对示例图像起作用。(注意,此 testbench 使用 Image Processing Toolbox 的内置函数来读取原始图像,并在均衡后绘制转换的图像。)
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');

我们来仿真一下此算法,看看结果。

mlhdlc_heq_tb

HDL Workflow Advisor
HDL Workflow Advisor(请参见下面的快照)有助于自动执行步骤,并提供从MATLAB到硬件的引导。您可以在 Workflow Advisor 的左窗格中看到工作流的以下关键步骤:
1. 定点转换
2. HDL 代码生成
3. HDL 验证
4. HDL 综合与分析

我们来详细看看工作流中的每个步骤。

定点转换
信号处理应用程序通常使用 MATLAB 中的浮点运算来实现。但是,出于功耗、成本和性能的原因,在面向硬件时,需要将这些算法转换为使用定点运算。定点转换非常具有挑战性并且非常耗时,通常需要占用整个设计和实施时间的 25% 到 50%。HDL Coder? 中用于浮点到定点自动转换的工作流可以极大地简化和加速转换过程。

浮点到定点转换工作流包括以下步骤:
1. 验证浮点设计与代码生成兼容。
2. 根据计算范围,通过模拟 test bench 或通过静态分析(将传播设计范围以计算所有变量的派生范围)提出定点类型。
3. 通过应用建议的定点类型生成定点 MATLAB 代码。
4. 验证生成的定点代码,并将生成的定点代码的数值精度与原始浮点代码进行比较。

请注意,此步骤是可选的。如果您的 MATLAB 设计已在定点实现,则可以跳过此步骤。

HDL 代码生成
HDL 代码生成步骤通过定点 MATLAB 代码生成 HDL 代码。您可以生成实现 MATLAB 设计的 VHDL 或 Verilog 代码。除了生成可综合的HDL代码外,HDL Coder? 还可生成各种报告,包括可帮助您在 MATLAB 代码和生成的 HDL 代码之间导航的可跟踪报告,以及在算法级别显示实现设计所需硬件资源(加法器、乘法器和 RAM)的资源利用率报告。

在代码生成期间,您可以指定各种优化选项来探索设计空间,而无需修改算法。在下面的“设计空间探索和优化选项”部分中,您可以看到如何修改代码生成选项以及如何针对速度或面积来优化设计。

HDL 验证
独立 HDL test bench 的生成:
HDL Coder? 可通过您的 MATLAB 脚本生成 VHDL 和 Verilog test bench,以快速验证生成的 HDL 代码。您可以使用将激励应用于 HDL 代码的多个选项来自定义 HDL test bench。您还可以生成脚本文件,以自动执行在 HDL 模拟器中编译和模拟代码的过程。这些步骤有助于确保 MATLAB 仿真的结果与 HDL 仿真的结果相匹配。

HDL Coder? 还与 HDL Verifier 一起使用,以自动生成两种类型的协同仿真 test bench:

基于 HDL 协同仿真的验证可与 MentorGraphics? ModelSim? 和 QuestaSim? 配合使用,其中 MATLAB 和 HDL 仿真可前后相接。

FPGA 在环仿真允许您与 FPGA 电路板严格同步地运行 MATLAB 仿真。您可以使用 MATLAB 将实际的数据输入到 FPGA 的设计中,并确保该算法在硬件中实现时能够达到预期的性能。

HDL 综合
除了与语言相关的挑战外,FPGA 编程还需要使用复杂的 EDA 工具。从 HDL 设计中生成比特流并对 FPGA 进行编程可能是一项艰巨的任务。HDL Coder? 通过为 Xilinx? 和 Altera? 创建用生成的HDL代码配置的项目文件,可在此处提供自动化。您可以使用工作流步骤在MATLAB 环境中综合 HDL 代码,查看综合结果,并迭代 MATLAB 设计以改善综合结果。

设计空间探索和优化选项
HDL Coder? 提供以下优化,以帮助您探索如何在设计空间的面积和速度之间进行权衡。您可以使用这些选项来探索各种架构并进行各种权衡,而不必手动重写算法。

速度优化

流水线:为了提高设计的时钟频率,HDL Coder 使您可以在设计中的各个位置插入流水线寄存器。例如,您可以在设计的输入和输出处以及在算法中给定 MATLAB 变量的输出处插入寄存器。

分布式流水线:HDL Coder 还提供了基于重定时的优化,可通过设计中的组合路径将延迟降到最小,以此自动移动插入的流水线寄存器,从而最大化时钟频率。

面积优化

RAM 映射:HDL Coder? 将矩阵映射到硬件中的导线或寄存器。如果将持久性矩阵变量映射到寄存器,则它们会占用大量的FPGA面积。HDL Coder?会自动将持久性矩阵映射到块RAM,以提高面积效率。将MATLAB矩阵映射到块RAM的挑战在于,硬件中的块RAM通常具有一组有限的读写端口。HDL Coder? 通过自动划分和调度矩阵读写来满足块 RAM 的端口限制,同时仍然遵循设计中的其他控制依赖性和数据依赖性来解决此问题。

资源共享:此优化可以识别并共享 MATLAB 代码中具有等效功能的乘法器操作。您可以控制设计中的乘数器共享量。

循环流:MATLAB 的 for 循环可在 VHDL 中创建一个 FOR_GENERATE 循环。循环主体在硬件中的复制次数与循环迭代次数相同。这会导致面积使用的低效。循环流优化会创建循环体的单个硬件实例,该实例在循环迭代之间进行时间多路复用。

常数乘法器优化:此设计级别的优化使用正则有符号数(CSD)技术将常数乘法器转换为移位和加法运算。

最佳实践方法
现在,我们来看几个在面向 FPGA 来编写 MATLAB 代码时的最佳实践方法。

编写 MATLAB 设计时:

使用支持 HDL 代码生成的 MATLAB 代码生成子集。

使顶层接口尽可能简单。顶层功能的大小、类型和复杂性决定了在硬件中实现的芯片接口。

不要将大量并行数据传递到设计中。并行数据需要芯片上的大量 IO 引脚,并且可能无法综合。在典型的图像处理设计中,您应该将像素输入串行化,并在算法内部缓冲它们。

编写 MATLAB test bench 时:

从 test bench 函数调用设计。

彻底执行设计。这对于浮点到定点转换尤为重要,其中 HDL Coder? 会根据 test bench 分配给变量的值来确定算法中变量的范围。您可以重复使用此测试工作台来生成 HDL test bench,以测试所生成的硬件。

在代码生成之前用 test bench 对设计进行仿真,以确保没有仿真错误,并确保所有必需的文件都在路径中。

结论
HDL Coder? 提供了在 FPGA 中实现算法的无缝工作流。在本文中,我向您展示了如何采用 MATLAB 图像处理算法、将其转换为定点、生成 HDL 代码、使用 test bench 验证生成的 HDL 代码,以及最终综合设计并在硬件中实现它。

通过本文对 HDL Coder? 以及 MATLAB 转 HDL 代码生成和验证框架的简要介绍,我们希望能助您了解如何开始快速实施 MATLAB 设计和目标 FPGA。

编辑:hfy

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • FPGA
    +关注

    关注

    1646

    文章

    22105

    浏览量

    621059
  • matlab
    +关注

    关注

    189

    文章

    3004

    浏览量

    235057
  • asic
    +关注

    关注

    34

    文章

    1251

    浏览量

    122793
  • 数字信号处理

    关注

    16

    文章

    567

    浏览量

    46866
  • HDL
    HDL
    +关注

    关注

    8

    文章

    330

    浏览量

    48244
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    基于MatlabFPGA的双边滤波算法实现

    前面发过中值、均值、高斯滤波的文章,这些只考虑了位置,并没有考虑相似度。那么双边滤波来了,既考虑了位置,有考虑了相似度,对边缘的保持比前几个好很多,当然实现也是复杂很多。本文将从原理入手,采用Matlab
    的头像 发表于 07-10 11:28 ?1582次阅读
    基于<b class='flag-5'>Matlab</b>与<b class='flag-5'>FPGA</b>的双边滤波算法<b class='flag-5'>实现</b>

    何在k230运行OpenCV的代码?

    何在k230运行OpenCV的代码
    发表于 06-17 06:06

    OptiSystem应用:用MATLAB组件实现振幅调制

    本案例展示了在OptiSystem中调用MATLAB代码实现振幅调制。 一、建模目标 案例中,我们生成两束功率为0dBm,频率分别为192.7THz、191THz的载波,合束之后经过自定义脉冲的调制
    发表于 06-13 08:46

    FPGA开发任务

    我想请人帮我开发一款基于FPGA的产品,把我写好MATLAB代码固化在FPGA中,实现算法加速和加密功能。有兴趣的联系我
    发表于 03-15 10:19

    如何使用MATLAB实现一维时间卷积网络

    本文对一维卷积操作进行介绍,包括一维扩展卷积和一维因果卷积,以及 MATLAB 对一维卷积的支持情况。在最后通过一个实例演示如何在 MATLAB 中将一维卷积和 LSTM 结合构建分类网络,
    的头像 发表于 03-07 09:15 ?1243次阅读
    如何使用<b class='flag-5'>MATLAB</b><b class='flag-5'>实现</b>一维时间卷积网络

    OptiSystem应用:用MATLAB组件实现振幅调制

    本案例展示了在OptiSystem中调用MATLAB代码实现振幅调制。 一、建模目标 案例中,我们生成两束功率为0dBm,频率分别为192.7THz、191THz的载波,合束之后经过自定义脉冲的调制
    发表于 02-14 09:39

    何在MATLAB中使用DeepSeek模型

    在 DeepSeek-R1(https://github.com/deepseek-ai/DeepSeek-R1) AI 模型横空出世后,人们几乎就立马开始询问如何在 MATLAB 中使用这些模型
    的头像 发表于 02-13 09:20 ?3577次阅读
    如<b class='flag-5'>何在</b><b class='flag-5'>MATLAB</b>中使用DeepSeek模型

    助力AIoT应用:在米尔FPGA开发板实现Tiny YOLO V4

    量和内存占用) 三、 获取数据集和模型可下载开源训练集或预训练模型。为了确保兼容性,建议将模型转换为 ONNX 格式,以便后续能在 FPGA 完成优化。1.下载 Tiny YOLO
    发表于 12-06 17:18

    何在反激式转换器中缓冲FET关断电压

    一期,我们介绍了如何在正向转换器导通时缓冲输出整流器的电压。现在,我们看一下如何在反激式转换器中缓冲 FET 关断电压。
    的头像 发表于 11-04 09:48 ?802次阅读
    如<b class='flag-5'>何在</b>反激式<b class='flag-5'>转换</b>器中缓冲FET关断电压

    基于FPGA实现数码管显示

    本文介绍数码管显示译码基本工作原理及Verilog HDL驱动代码编写,进一步熟练掌握FPGA入门基础知识。
    的头像 发表于 10-24 14:44 ?1960次阅读
    基于<b class='flag-5'>FPGA</b><b class='flag-5'>实现</b>数码管显示

    FPGA Verilog HDL代码如何debug?

    ,共同进步。 欢迎加入FPGA技术微信交流群14群! 交流问题(一) Q:Verilog代码如何debug?最近学习fpga,写了不少verilog,开始思考如何debug的问题!c语言是顺序执行,而
    发表于 09-24 19:16

    FPGA芯片架构和资源有深入的理解,精通Verilog HDL、VHDL

    岗位职责 1.负责FPGA的架构设计、代码编写、仿真等; 2.协同软、硬件工程师完成系统联调和测试; 3.负责项目中FPGA设计的相关文档编写及维护; 任职要求 1.硕士及以上学历,电
    发表于 09-15 15:23

    何在MSP430?实现内置振荡器的高精度定时器

    电子发烧友网站提供《如何在MSP430?实现内置振荡器的高精度定时器.pdf》资料免费下载
    发表于 09-14 11:10 ?0次下载
    如<b class='flag-5'>何在</b>MSP430?<b class='flag-5'>上</b><b class='flag-5'>实现</b>内置振荡器的高精度定时器

    FPGA Verilog HDL有什么奇技巧?

    时赋初值,而不用复位赋初值,当整个系统需要复位重启时,FPGA 只能通过重新电来获取初值,这可能比较麻烦甚至在某些系统中不可实现。 另外,在 RTL 文件中不能使用 initial 语句来赋初值给
    发表于 09-12 19:10

    何在DRA821U使用Linux实现快速引导

    电子发烧友网站提供《如何在DRA821U使用Linux实现快速引导.pdf》资料免费下载
    发表于 09-03 10:11 ?0次下载
    如<b class='flag-5'>何在</b>DRA821U<b class='flag-5'>上</b>使用Linux<b class='flag-5'>实现</b>快速引导