学习VivadoHLS第4章 例程中文版

更新时间:2023-11-11 06:28:01 阅读量: 教育文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

学习Vivado第4章lab1——接口综合

概述

接口综合是将RTL接口添加到C设计的过程。另外还把物理接口添加到RTL设计中,接口综合包括了相关联的I/O协议,容许数据通过接口传输并自动与内部优化的逻辑同步。 本教程由4实验练习组成涵盖的主要功能和接口综合。 ?Lab1: 查看函数的返回和块级协议

?Lab2: 理解默认端口的I/O协议,并学会怎么选择I/O协议 ?Lab3: 查看一下数组端口实现,可以进行分区。 ?Lab4: 为设计创建一个优化的实现并添加AXI4接口

教程设计描述

从xilinx网站下载教程的设计文件,参考信息中获取教程设计。 本教程使用教程目录中的设计文件

Vivado_HLS_Tutorial\\ Interface_Synthesis。

关于实验

?使用前两个实验室在本教程中的示例的设计很简单,这有助于将焦点保持在接口。 ?最后两个实验练习使用多通道累加器。

?本教程介绍如何实现采用高层次综合实现I/O端口和协议。 ?在实验4中,创建一个在Lab3中使用最优实现的设计 接口综合 lab1:块级I/O协议

概述

这个实验解释了什么是块级I/O协议,并控制它们 重点:在本教程中的图片和命令假定了教程数据目录

Vivado_HLS_Tutorial被解压并放置在c:\\vivado_HLS_Tutorial

如果教程数据路径解压到不同的位置,或者在linux系统上,调整路径名称指向你选择放置Vivado_HLS_Tutorial目录位置。

步骤1:创建并打开工程

1.打开Vivado HLS 命令提示符

a.在windows系统中,采用Start>All Programs>Xilinx Design Tools>Vivado2014.2>Vivado HLS>Vivado HLS 2014.2 Command Prompt,如下图

b.在linux系统下,打开新的shell,

2. 用命令提示符窗口,如图55,把接口综合教程的路径变为lab1

3. 执行TCL并建立vivado HLS Project,采用的是vivado_hls–f run_hls.tcl如图55所示

4. 当vivado HLS 完成,在用户界面里打开工程。用vivado_hls–p vivado_hls–p adders_prj命令打开,如图56

步骤2:创建和查看默认的块级I/O协议

1. 在源文件夹中双击adders.c,打开源代码,并查看如图57

这个例子用了一个简单的设计,把焦点集中在I/O实现上(在设计中没有逻辑)这段代码的重要点如下: ?编译格式的指令被添加到源代码中,为了防止任何I/O协议被综合成为一些数据结构(inA,inB,和inC),I / O端口的协议将在接下来的实验练习中复习。

?这个函数返回一个值并且从这个函数中只有唯一的输出。正如在后面的练习,不是所有的函数都返回一个值。在本实验练习中讨论该函数返回创建的端口。

2. 用工具栏中的按钮执行Run C Synthesis命令,或Solution菜单 当综合完成,综合报告会自动打开

3. 查看RTL接口,滚动到综合报告摘要的结尾处。接口摘要和Outline选项卡如图58

有三种类型的端口可以查看

?设计完成花费超过一个时钟周期,因此时钟和复位已经添加到设计中:ap_clk和ap_rst.这两个信号都是一位输入。 ?块级I/O协议为了控制RTL设计已经添加端口:ap_start,ap_done,ap_idle和ap_ready。这些端口随后会被详细说明 ?设计还有4个数据端口

?输入端口In1,In2和In3,都是32位输入,和指定I/O协议的ap_done(如在图58中指定的指令) ?该设计还具有对函数返回一个32位的输出端口,ap_return。

块级I / O协议允许通过附加的端口、独立数据I / O端口对RTL设计进行控制。但此I / O协议是与函数本身相关联,不与任何数据端口相关联。默认的块级I/O协议被称为ap_ctrl_hs。图58显示了这个协议是与函数的返回值相关联(即 使函数中的代码没有指定返回值这也可以) 表1概括了用于块级I / O协议ap_ctrl_hs的信号的行为。

注:解释一下使用术语“交易”。在高层次综合的情况下,一个事务是相当于一个执行C函数(或在综合RTL设计中的等效操作)

应用 ap_start 描述 该信号控制模块执行,逻辑为1时设计开始运行。 它应保持逻辑1直到相应的输出握手ap_ready被置位。当ap_ready变高时,决定了是否继续保持ap_start置位并执行其他事物或设置ap_start为逻辑0,当前事务的结束时允许设计暂停,。 如果在ap_ready为逻辑1 之前ap_start被置为低,设计有可能没有把所有输入端口读完,并可能拖延下一个输入读取操作。 这个输出信号表明设计已经准备好接受新数据 当准备好接受新的输入时,ap_ready信号设置为逻辑1。表明所有为这次事物的输入读已经完成。 如果设计不是流水线操作,直到下一次事物才开始执行新的读。 这个信号是用来决定何时在端口上用新的值,决定是否用一个ap_start输ap_ready 入信号来启动一个新的事务。 如果ap_start信号没有被设置为高,当设计在当前事务完成中所有的操作,这个信号变为低电平。 ap_done 这个信号表明设计在当前的事务中完成所有的操作。输出逻辑1表明设计已经完成了这个事务的所有操作。因为在事务结束时,该信号为逻辑1还表示ap_return端口上的数据是有效的。 不是所有的函数都有函数返回值,因此并非所有的RTL设计都有一个ap_return端口 这个信号表示设计正在操作或闲置状态(无操作)。 输出端口上用逻辑1表明是空闲状态。一旦设计开始运行,该信号为低电平。 该信号为高电平时,设计完成操作,未进行任何进一步的操作。 ap_idle 您可以通过查看由RTL协同仿真生成的跟踪文件,观察这些信号的行为。这是在教程的RTL验证所讨论的,但图59示出了用于当前合成的结果的波形。

图59的波形图,表现了块级I/O信号的行为 ?设计直到ap_start设置为逻辑1才开始启动。 ?通过设置端口ap_idle为低,表明设计不再空闲

?展示了五个事务,首先3个输入值(10,20,和30)被各自用在端口in1,in2和in3. ?输出信号ap_ready变为高表明设计准备好在下个时钟下接受新输入。

?输出信号ap_done表明设计结束,输出端口ap_return的值是有效(首先输出值 60,是三个输入的和) ?因为ap_start保持高电平,下一次事务开始于下一个时钟周期。

注意:在RTL的协同仿真,所有的设计和端口输入控制信号始终处于启用状态。例如,在图59的信号ap_start始终是高的。

在第二个事务,观察ap_return端口,在这个端口上第一个输出的值是70,直到ap_done信号为高电平这个结果才有效。

步骤3:改变块级I/O协议

默认的块级I/O协议是ap_ctrl_hs协议(控制握手协议),在这一步中,您可以创建新的解决方案和改变这个协议。 1. 从工具栏或者工程菜单选择新解决方案(New Solution)来创建一个新的解决方案。 2. 保持所有新解决方案对话框所有设定,这些设定都是默认的,点击完成 3. 在信息窗口中选择C源代码标签(或如果C源代码关闭重新打开) 4. 激活指令选项卡(Directives tab),选择顶层函数,如图60所示

因为块级I/O协议与函数相关联,您必须通过选定顶层函数来指定他们。

5. 在指令选项卡中,鼠标移到顶层函数adders上,右键单击,然后选择插入指令Insert Directives。 打开指令编辑器对话框。

图61展示的对话框,对话框中的下拉菜单为了激活接口模式。

下来菜单为块级接口协议展示了三种选择

?ap_ctrl_none: 没有块级I/O控制协议

?ap_ctrl_hs: 块级I/O控制握手协议,我们已经采用的

?ap_ctrl_chain: 块级I/O协议的控制链。这个I/O协议主要是用于把流水线块链接在一起。

块级I/O协议ap_ctrl_chain不包含在这个教程中。这个协议与ap_ctrl_hs协议类似,但增加了额外的输入信 号,ap_continue,它必须为高,当ap_done为了继续下次事务被置位时。这允许下游模块在系统上施加回压,并进一步停止处理,这是不能接受 新的数据。

6. 在Directives Editor对话框中的DestinationEditor部分中,选择Source File

默认情况下,指令被放置在directives.tcl文件。在这个例子中,该指令被放置在现有的I / O指令的源文件中。 7. 从下拉菜单中选择ap_ctrl_none

8. 点击OK

源文件现在有新的指令,在源文件代码和指令选项卡中都是高亮的。如图62

新指令表示与函数参数/接口相关联被称为返回。所有接口指令与函数参数相连接。对于块级I/O协议,返回参数被用于具体的块级接口。如果函数在源代码里没有返回参数也是可能的。

Figure 62: Block-Level Interface Directive ap_ctrl_none

在工具栏里点击Run C Synthesis按钮,或者用菜单Solution>Run C Synthesis来综合设计。

在源文件中添加的指令改变的源文件。图62所示源文件名为*adders.c。这个标记表明文件已经更改,但没有保存。 10. 点击YES 来接受对源文件的更改。 当报告打开时,接口概述出现,如图63

Figure 63: Interface summary for ap_ctrl_none

当接口协议ap_ctrl_none被采用时,没有块级接口协议被添加到设计中。仅有诸如clock、reset和data端口。 注意,也没有ap_done信号,consumer模块接收来自ap_return的数据,当数据有效时,ap_return端口现在不能表明

另外,RTL协同仿真的功能需要一个块级I/O协议,为了自动协同仿真安排测试平台和RTL设计。任何试图用RTL协同仿真的结果在下面的错误信息中,停止RTL协同仿真(理解上有误差)

@E [SIM-345] Cosim only supports the following 'ap_ctrl_none' designs: (1) combinational designs; (2) pipelined design with task interval of 1; (3) designs with array streaming or hls_stream ports. @E [SIM-4] *** C/RTL co-simulation finished: FAIL *** 退出vivado HLS GUI返回命令提示框

学习Vivado第4章lab2——接口I/O协议 概述

这个实验解释了怎么指定具体的端口I/O协议。

1. 在lab1中用Vivado HLS命令提示符,更改为lab2目录,如图64 2. 键入vivado_hls -f run_hls.tcl来创建新的Vivado HLS工程

Figure 64: Setup for Interface Synthesis Lab 2

3. 键入vivado_hls -p adders_io_prj 来打开vivado HLS 用户界面工程 4. 打开源代码如图65

Figure 65: C Code for Interface Synthesis Lab 2

本练习的源代码是与lab1类似。出于同样的原因使用简单的代码,它有助于聚焦在接口的行为,而不是核心逻辑。 这一次,代码没有一个函数的返回,取代函数输出的是通过指针参数* in_out1输出。这也提供了机会,探索双向(输入输出)端口的接口选项。

I / O协议的类型,你可以通过接口综合添加到C函数的参数取决于参数类型。这些选项在Vivado高层次综合用户指南(UG902)有完整描述。

在本实施例中的指针参数既是输入和输出的功能。在RTL设计中,该参数被实现为单独的输入和输出端口。 对于图65所示的代码,每个函数参数可能的选项在下表中被描述

函数参数 In1 和 In2 I/O协议选择 按值传递的参数都可以用下面的I / O协议来实现 ? Ap_none:没有I/O协议,这个是默认的输入 ? Ap_stable:无I/O协议 ? Ap_ack:实现与相关的输出端口确认 ? Ap_val:实现与相关的输入有效端口 ? Ap_hs:实现了两个输入有效和输出端口确认。 按引用传递的输出可以用下面的I/O协议实现 ?Ap_none:没有I/O协议,这个是默认的输入 ?Ap_stable:无I/O协议 ?Ap_ack:实现与相关的输出端口确认 ?Ap_val:实现与相关输出的有效端口,这个是默认的输出 ?ap_ovld:实现与相关输出有效端口,(任何INOUT端口的输入部分没有有效的端口) ?ap_hs:实现所有输入有效端口和输出响应端口 ?ap_fifo:FIFO接口与相关输出写入,输入FIFO满端口 ?ap_bus:Vivado HLS总线接口协议 In_out1 在实验1中应用的端口指令实际上不是必需的,因为AP_NONE是使用这些C参数的默认I/ O协议。在这个练习中给出了指令,以避免处理任何默认或不是默认的I / O端口协议的行为。 在本练习中,您将实现一系列的I / O协议。 步骤2:端口具体的I/O协议 1. 保证能在信息窗口中看见C源代码

2. 激活指令选项卡(Directives tab)并选择输入参数in1(input argument in1),如图66

Figure 66: Adding Port I/O Protocols

3. 右击并选择插入指令(Insert Directives)

4. 当指令编辑窗口打开,使指令下来框为INTERFACE

a. 保持目标是默认值,这次,指令被存储在directives.tcl文件中。 b. 从模式下来菜单选择ap_val c. 点击OK

5. 选择参数 in2 ,添加一个接口指令指定I/O协议为ap_ack 6. 选择参数in_out1并添加一个接口指令I/0协议为ap_hs

7. 在资源管理器窗口中,扩展约束文件夹,并双击打开directives.tcl文件,如图67

Figure 67: Directives for Lab 2

8. 综合设计

9. 当文件打开时,查看接口概述,如图68

Figure 68: Interface summary for Lab 2

?设计有时钟和复位 ?默认块级???协议信号是存在的 ?端口?in1被以数据端口而实现,并伴随输入有效信号 ?数据在in1端口上,仅读。当端口in1_ap_vld为有效高 ?端口?in2被综合为数据端口,并与输出响应信号相关联 ?当端口in2被读时,端口?in2_ap_ack将被置高 ?inout_i定义为inout1参数的输入部分,与输入有效端口inout1_i_ap_val相关联,并且输出响应端口inout1_i_ap_ack ?inout1参数输出部分定义为inout_o,与输出有效端口inout1_o_ap_val相关联,并输入响应端口inout1_o_ap_ack. 10. 退出vivado HLS GUI 并且返回命令提示口

学习Vivado第4章lab3——实现数组的RTL接口

概述

这个练习说明了在函数中的数组参数,你可以实现不同种类的RTL端口 步骤1:创建和打开工程

1.在先前的lab中用Vivado HLS命令提示符,更改为lab3目录 2.键入vivado_hls -f run_hls.tcl来创建新的Vivado HLS工程

3.键入vivado_hls –p array_io_prj 来打开vivado HLS 用户界面工程 4.打开源代码如图69

此设计具有一个输入数组和一个输出数组。在C源代码中的注释说明了输入数组中的数据是如何有序作为一个通道和通道是怎么被计算的。

理解设计,您还可以查看试验平台和文件result.golden.dat的输入和输出数据。

Figure 69: C Code for Interface Synthesis Lab 3

步骤2:综合函数参数数组为RAM端口

在这一步中,查看数组端口是怎么综合成RAM端口的。 1.综合设计,当报告打开时查看接口简介。

接口简介表明了在C 源代码中的数组参数是怎么综合成默认的RAM端口的。 ?设计有时钟,复位和默认的块级I/O协议ap_ctrl_hs(注意在报告中的时钟) ? d_o参数已经综合成RAM端口(I/O协议ap_memory) ?数据端口(d_o_d0) ?地址端口(d_o_address0)

?芯片使能控制端口(d_o_ce0)和写使能端口(do_we0)

? d_i参数已经被综合成类似RAM接口,但有输入数据端口(d_i_q0)没有写使能端口,因为接口仅读数据。

在这两种情况下,数据端宽度是在C源代码中的数据值的宽度(在这种情况下的16位整数),并且地址端口的宽度已被自动调整大小匹配到的地址必须被存取的次数(5位的为32个地址)。

把数组综合成RAM端口是默认的,您可以控制这些端口怎么用一些其他的选择去实现。在实验3中的其余步骤演示这些选项:

? 采用单端口RAM和双端口RAM接口 ? 采用FIFO接口 ? 分割成离散的端口

步骤3:采用双端口RAM和FIFO接口

高层次综合让你可以指定RAM接口为单端口还是双端口。如果你不做出这样的选择,Vivado HLS 会自动分析设计和选择端口的数量,以便产生最大的数据速率。

第二步用的单端口RAM接口,因为在源代码中的for循环是默认的保持不展开,该循环每次迭代依次执行: ? 读输入端口

? 从内部RAM中读累计的结果 ? 和累计并且新数据写入到内部RAM中 ? 把结果写到输出端口 ? 重复循环的下一次迭代

这确保单一输入读和输出写入以往需要。即使采用多个输入和输出时,内部逻辑可以不采用额外端口。 注意:如果你指定了双端口RAM并且Vivado HLS 能确定必须只能用单端口,会使用单端口覆盖双端口规范。 在这个设计,如果你想用多RTL端口实现数组参数,首先得事情你必须展开for循环,并容许内部操作是并行的,否则多端口没有好处:没有展开的for循环可以确保在每次读时有一个数据被读。 1. 从工具栏中选择New Solution或者从工程菜单来创建新的解决方案 2. 设置默认,点击Finish

3. 保证C源代码在信息窗口中可见

4. 在指令选项卡中,选择for循环,在for循环上并右击打开Directives Editor对话框。 a. 在指令编辑对话框中激活指令下来菜单在上部并选择展开 b. 指令编辑如图71,点击OK

下次,为输入读指定双端口RAM,资源指令指示RAM连接到接口的类型。 5. 在指令选项卡中,选择port d_i并右击打开指令编辑对话框

a. 在指令编辑中在上部激活指令下拉菜单并选择RESOURCE(in Dirctive)

b. 点击 core options 框并选择RAM_2P_BRAM c. 确认在指令编辑对话框中的设定,如图72,点击OK

使用FIFO接口实现输出端口

6. 在指令选项卡(Directive)中,选择d_o,并右击打开Directives Editor对话框 a. 在指令编辑对话框中,保持指令为Interface(接口) b. 从模式下拉菜单中,选择ap_fifo. c. 点击OK

在Directive 标签展示了指令已经应用到设计中如图73

7. 综合设计

当报告在信息窗口中打开时,接口摘要如图74 ? 设计有标准的时钟、复位、和块级I/O端口

? 数组参数d_o已经综合成16位宽数据接口的FIFO接口(d_o_din),并且有相关联的输出写(d_o_write)和输入FIFO满(d_o_full)端口

? 参数d_i 已经实现为双端口RAM接口

根据使用的双端口RAM接口,设计能接受两倍于原始设计输入数据的速率。但采用单端口FIFO接口的输出数据速率和先前的一样。

步骤4:分区RAM和FIFO阵列接口

在这步中,您可以学习到分区数组接口如何划分为任意接口数量 1. 从工具栏中选择New Solution或者从工程菜单来创建新的解决方案 2. 设置默认,点击Finish

3. 保证C源代码在信息窗口中可见

4. 在指令标签中,选择d_o并右击打开Directives Editor对话框 a. 在指令标签对话框上部激活指令下拉菜单,并选择ARRAY_PARTITION b. 点击类型下拉菜单,并选择块,为了将分布式数组综合成块 c. 在Factor对话框中,输入4值 d. 指令编辑如图75所示,点击OK

现在,输入数组分为两大块(不是4个)

5.在指令标签中,选择d_i并重复前面的步骤,但这次分区端口factor用2 指令标签展示了现在应用在设计中的指令

6.综合设计

当报告在信息窗口中打开,接口摘要如图77显示 ? 设计有标准的时钟、复位、和块级I/O端口 ? 数组参数d_o已经综合成四个分离的FIFO接口

? 参数d_i 已经实现为两个分离RAM接口,每一个都是用双端口,(如果你看到4个分离RAM接口,确认分区因素d_i是2,而不是4)。

如果输入端口d_i被划分为四个,仅需要为每个端口分配单端口RAM接口。因为输出端口只能一次输出四个值,一次读8个输入,没有什么好处。

在本教程中对数组的最后一步是完全分割的阵列。 步骤5:全分区数组接口

这一步向您展示了如何分割数组接口为单独的端口

1. 从工具栏中选择New Solution或者从工程菜单来创建新的解决方案 2. 设置默认,点击Finish。包括从solution3拷贝现存的指令 3. 保证C源代码在信息窗口中可见

4. 在指令标签中,为d_o选择已存在的分区指令 5. 右击,并选择Modify Directive

6.在指令编辑对话框中

a.激活Type下拉菜单,改变分区格式为Complete

b. 在因素(Factor)对话框中,你可以删除4,或保留。这个因素对这种分区类型没有作用。 c. 指令编辑如图79,点击OK

7.在指令标签中,选择d_i并重复前面的步骤,完成对d_i的全分区

c. 在指令标签中,选择For_loop并右击打开Directives Editor对话框。 I. 激活上部的Directives下拉菜单,并选择PIPELINE II. 保持间隔空白,让他默认为1

III. 选择enable loop rewinding(使能重复循环) IV. 点击OK

当设计顶层是循环,你可以用选择流水线重复,这个通知vivado HLS 在RTL实现中,这个循环连续运行(与功能和功能重新启动周期没有结束)。

在执行了上述步骤,指令标签如图86。检查保证所有的选择都正确的应用。如果没有,双击指令重新打开Directives Editor

6.综合设计

当报告在信息窗口中打开,确认d_i和d_o被8个独立的AXI4流接口实现

7.在设计中的性能部分,确认每个时钟周期对for循环的处理样本(间隔1)以3延迟,并且设计有比实验3解决方案2,3,或4使用的资源更小(图83)。

阵列接口和部分for循环展开的循环分区允许执行该C代码在硬件上实现八个单独的通道。 步骤3:实现AXI4-Lite接口

在这个练习中,您可以把块级I/O协议端口组成简单的AXI4 Lite接口,AXI4 Lite接口容许这些块级控制信号被控制,由CPU访问

1:从工具栏中选择New Solution或者从工程(project menu)菜单来创建新的解决方案 2:设置默认,点击Finish,包括从solution1种复制存在的指令

3:保证C源代码在信息窗口中可见

4:在指令选项卡中,选择顶层函数axi_interface并且右击打开Directives Editor对话框。 a. 在对话框上部激活Directives下来菜单,并选择INTERFACE

b. 激活mode下拉菜单,并选择s_axilite.这指定了与函数返回(块级I / O端口)被实现为一个AXI4Lite接口相关联的端口。由于默认模式为函数的返回是ap_hs,这里需要指定该I / O协议。 c. 点击OK

指令标签显示如图87

5:综合设计

当报告打开,只有RTL端口为AXI4 Slave Lite的接口出现在接口摘要

6:选择从工具栏导出RTL(Export RTL),或者解决方案(Solution)菜单来创建IP包 7:保持格式选择项为IP Catalog点击OK

您可以在solution2/impl文件夹中看见IP包如图88,因为你用vivado IP Catalog格式,这个包在ip文件夹中

Ip文件夹包括了drivers 子文件夹,如图88

当你在设计中添加了AXI4-Lite接口时,IP封装过程还创建软件驱动程序文件,使外部模块,通常一个CPU,以控制该块(启动,停止,设置端口值,检查中断状态)。

8:双击xaxi_interfaces_hw.h文件在信息窗口中打开

这显示了地址访问和控制的块级接口信号例如,设置控制寄存器从0到1,将使能ap_start端口,另外设定位7将使能自动重启动,使设计将在每个事务结束时自动重新启动。

其余C驱动程序文件是用来整合AXI4-Slave-Lite接口控制嵌入在CPU或微控制器上运行的代码,并包含在IP封装中。

结论在本教程中,您学习:

?有哪些块级I / O协议,以及如何控制它们。 ?如何指定和应用端口级的I / O协议。 ?如何指定阵列端口RAM和FIFO的接口。 ?如何划分的RAM和FIFO接口为子端口。

?如何使用两个I / O指令和优化指令来创建AXI4接口的优化设计

或者,您可以删除d_i指定资源的指令。如果阵列被划分为单独的元素,指定了一个内存资源的资源指令将被忽略。 指令标签展示了应用在设计中的指令

8.综合设计

9.当报告在信息窗口中打开,查看接口摘要,注意以下: ? 设计有标准的时钟、复位、和块级I/O端口 ? 数组参数d_o已经综合成32个分离的FIFO接口

? 用32个分离的表口对参数d_i 的已经,因为为输入默认接没有I/O协议。他们有I/O协议ap_none 尽管该教程的焦点在专门的I/O接口上,在这一点上是值得研究四种解决方案在性能上的差异。 10. 从工具栏里选择比较报告,或从工程菜单中打开方案的比较

11.在Solution Selection Dialog框中,为四种解决方案中每种添加选择方案框如图81 12.点击OK

打开解决方案的比较报告(图82),它表明solution4,为每个阵列元素试用了唯一的端口,比以前的解决方案快得多。内部逻辑可以尽可能快的获得数据,只要它需要访问数据。(这里是因为端口的访问没有性能瓶颈。)

鼠标滑轮往下滑查看比较报告(图83),并注意与更多的I / O端口解决方案(解决方案2,3和4),允许更多的并行处理但也用相当多的资源

在接下来的练习中,用端口和资源之间的最佳平衡,您将实现同样的设计。除了实现这个优化,接下来的练习中展示了如何把AXI4接口添加到设计中。

13.退出Vivado HLS界面并返回到命令提示符。

学习Vivado第4章lab4——实现AXI4接口

概述

这个练习说明了在I/O端口中指定AXI4总线接口,这个练习除了增加AXI4接口外还展示了如何创建一个用接口和逻辑指令一起优化的设计。 步骤1:创建和打开工程

1.在先前的lab中用Vivado HLS命令提示符,更改为lab4目录 2.键入vivado_hls -f run_hls.tcl来创建新的Vivado HLS工程

3.键入vivado_hls -p axi_interfaces_prj 来打开vivado HLS 用户界面工程 4.打开源代码如图84

此设计用的是和Lab3一样的源代码,并在设计重命名axi_interfaces

步骤2:创建采用AXI4 流接口的一个优化设计

在这种设计最佳性能实现中,每个通道的数据将进行并行处理,每个通道以专用硬件实现。 理解的关键是如何最好地执行这种优化,是要认识到在输入和输出数组中的通道让他们自己成为循环分区。循环分区是Vivado HLS用户指南中有全面的解释(UG902,但基本上意味着每个数组元素,又存储在不同分区中。)

在本练习中,您指定的数组参数,以实现为AXI4流接口。如果该数组被划分成多个通道,你可以通过在并行设计中为每个端口元素实现相同的流接口。

最后,如果在I / O端口被配置为提供和利用通道数据时,for循环的局部展开可以为每个通道确保专用硬件处理。 首先,分区阵列:

1:保证C源代码在信息窗口中打开

2:在指令标签中,选择d_o并右击打开指令编辑对话框。 a. 选择上部Directives中的下拉菜单,并选择ARRAY_PARTITION b. 点击Type的下拉菜单,并指定为cyclic分区

c. 在Factor对话框中,输入8,创建8个分区(这个结果在8个端口中) d. 在指令编辑对话框中填充如图85,点击OK

3:在指令标签中,选择d_o并右击打开Directives Editor对话框 a. 激活上部Directives下拉菜单,选择INTERFACE b. 点击Mode下拉菜单,指定axis接口 c. 点击OK

4:在指令标签中,选择d_i并重复上述步骤2和步骤3。 a. 应用cyclic分区并且Factor为8 b. 应用axis接口

5:下一步,对for循环进行局部展开和流水线操作。

a. 在指令标签中,选择For_Loop并且右击打开Directives Editor对话框 b. 激活上部的Directives下拉菜单,选择UNROLL

I. 选择因素8(factor 8)部分展开for循环,这等同于重写C代码以每一次循环迭代中执行8个循环体的复制(其中,新的循环仅在总执行用于四次迭代,而不是32)。 II. 点击OK

本文来源:https://www.bwwdw.com/article/m1sv.html

Top