接口综合lab3:实现数组的RTL接口
概述
这个练习说明了在函数中的数组参数,你可以实现不同种类的RTL端口
步骤1:创建和打开工程
1.在先前的lab中用VivadoHLS命令提示符,更改为lab3目录
2.键入vivado_hls -f run_hls.tcl来创建新的Vivado HLS工程
3.键入vivado_hls –parray_io_prj 来打开vivado HLS 用户界面工程
4.打开源代码如图69
此设计具有一个输入数组和一个输出数组。在C源代码中的注释说明了输入数组中的数据是如何有序作为一个通道和通道是怎么被计算的。
理解设计,您还可以查看试验平台和文件result.golden.dat的输入和输出数据。
Figure 69: C Code for Interface SynthesisLab 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并且VivadoHLS 能确定必须只能用单端口,会使用单端口覆盖双端口规范。
在这个设计,如果你想用多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(inDirctive)
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的全分区
或者,您可以删除d_i指定资源的指令。如果阵列被划分为单独的元素,指定了一个内存资源的资源指令将被忽略。
指令标签展示了应用在设计中的指令
8.综合设计
9.当报告在信息窗口中打开,查看接口摘要,注意以下:
• 设计有标准的时钟、复位、和块级I/O端口
• 数组参数d_o已经综合成32个分离的FIFO接口
• 用32个分离的表口对参数d_i 的已经,因为为输入默认接没有I/O协议。他们有I/O协议ap_none
尽管该教程的焦点在专门的I/O接口上,在这一点上是值得研究四种解决方案在性能上的差异。
10.从工具栏里选择比较报告,或从工程菜单中打开方案的比较
11.在SolutionSelection Dialog框中,为四种解决方案中每种添加选择方案框如图81
12.点击OK
打开解决方案的比较报告(图82),它表明solution4,为每个阵列元素试用了唯一的端口,比以前的解决方案快得多。内部逻辑可以尽可能快的获得数据,只要它需要访问数据。(这里是因为端口的访问没有性能瓶颈。)
鼠标滑轮往下滑查看比较报告(图83),并注意与更多的I / O端口解决方案(解决方案2,3和4),允许更多的并行处理但也用相当多的资源
在接下来的练习中,用端口和资源之间的最佳平衡,您将实现同样的设计。除了实现这个优化,接下来的练习中展示了如何把AXI4接口添加到设计中。
13.退出Vivado HLS界面并返回到命令提示符。