本期主题:
HLS的接口类型定义
往期链接:
目录
IP可通过Vitis HLS来生成,IP需要与其他模块通信,一般来说有两种方式:
1.软件控制:通过
寄存器的方式,通过在ARM处理器上运行应用程序,这些程序来访问操作寄存器,从而实现操作IP的目的;
2.自同步:这种模式下,IP将公开所有信号,这些信号用来启动/停止内核,这些信号其他IP和系统的控制;
Vivado IP 流程支持 存储器、串流和寄存器 接口范例,其中每个范例都支持不同接口协议与外部世界进行通信,这些都是AXI4接口,包括:
- 存储器范例 (m_axi):内核通过存储器(如 DDR、HBM、PLRAM/BRAM/URAM)来访问数据;
- 串流范例 (axis):数据从其它串流源(例如,视频处理器或其它内核)串流至内核中,也可从该内核流出;
- 寄存器范例 (s_axilite):内核通过寄存器接口来访问数据,软件则通过寄存器读/写来访问数据;
更为详细的描述如下:
| 范例 | 描述 | 接口类型 |
|---|---|---|
| 存储器 | 内核通过存储器(如 DDR、HBM、PLRAM/BRAM/URAM 支持的接口协议)来访问数据 | ap_memory、BRAM、AXI4 存储器映射 (m_axi) |
| 串流 | 受支持的接口数据将从其它串流源(如视频处理器或其它内核)串流至内核,并且可从内核流出 | ap_fifo, AXI4-Stream (axis) |
| 寄存器 | 内核通过寄存器读取和写入所执行的寄存器接口来访问数据 | ap_none、ap_hs、ap_ack、ap_ovld、ap_vld和 AXI4-Lite 适配器 (s_axilite) |
| C语言实参类型 | 受支持范例 | 默认范例 |
|---|---|---|
| 标量变量(通过值来传递) | 寄存器 | 寄存器 |
| 数组 | 存储器、串流 | 存储器 |
| 指针 | 存储器、串流 、寄存器 | 寄存器 |
| 参考值 | 寄存器 | 寄存器 |
| hls::stream | 串流 | 串流 |
在vivado IP流程中,默认执行流程是由寄存器来控制IP的。寄存器是通过s_axilite接口,默认的控制协议为 ap_ctrl_hs 。
s_axilite接口可提供下列功能特性:
- 控制协议:采用 块级控制协议 中的块控制协议;
- 标量实参:顶层函数的实参映射到s_axilite接口,ARM可对此寄存器空间执行读/写操作;
- 偏移规则:指定寄存器的偏移地址;
- 捆绑规则:使用s_axilite接口指定多个捆绑,为每个捆绑创建一个独立的接口适配器;
示例code:
#include <stdio.h>
void example(char *a, char *b, char *c)
{
#pragma HLS INTERFACE s_axilite port=a bundle=BUS_A
#pragma HLS INTERFACE s_axilite port=b bundle=BUS_A
#pragma HLS INTERFACE s_axilite port=c bundle=BUS_A
#pragma HLS INTERFACE s_axilite port=return bundle=BUS_A
*c += *a + *b;
}
综合结果如下图所示:

AXI4存储器映射(m_axi)允许内核在全局存储器(DDR、HBM和PLRAM)内读写数据。
看一个例子:
void example(volatile int *a) {
//Port a is assigned to an AXI4 master interface
#pragma HLS INTERFACE mode=m_axi depth=50 port=a
....
}
综合出的结果为:

一般来说,axilite会和m_axi组合起来使用,HLS中axilite适合用来去配置寄存器,m_axi适合对全局存储器进行读写执行。

AXI4-Stream 是专为传输任意单向数据而设计的协议。其中:
- TDATA是按照时钟周期来传输的数据;
- TVALID是生产者发出的此时数据有效的信号;
- TREADY是使用者回复的信号,代表此时可以进行数据接收;
- TLAST 信号表明这是串流的最后一个字节;
生产者、使用者的交互图如下:

详细的AXI4-stream的介绍可查看官方文档(UG1307)
如果我们要用vitis_hls中的接口来描述axis,那么就需要通过接口定义TDATA、TVALID、TREADY信号。
AXIS在HLS中的结构体定义如下:
template <typename T, size_t WUser, size_t WId, size_t WDest> struct axis
{ .. };
其中,
- T:代表串流的数据类型
- Wuser:TUSER的信号宽度
- Wid:TID的信号宽度
- Wdest:Tdest信号的宽度
去除了AXI4的旁路元素(即Wuser、Wid、Wdest参数设置为0),这种就是不含旁路的AXI4-stream,也称为hls::stream,这种信号只有数据信息。
重点:
- hls::axis、ap_axiu、ap_axis的使用仅限于顶层函数接口,因为它包含着AXI4-STREAM的旁路信息,这种信号无法在内部函数或变量上使用;
对于内部串流,必须使用 hls::stream 信号
我正在尝试设置一个puppet节点,但rubygems似乎不正常。如果我通过它自己的二进制文件(/usr/lib/ruby/gems/1.8/gems/facter-1.5.8/bin/facter)在cli上运行facter,它工作正常,但如果我通过由rubygems(/usr/bin/facter)安装的二进制文件,它抛出:/usr/lib/ruby/1.8/facter/uptime.rb:11:undefinedmethod`get_uptime'forFacter::Util::Uptime:Module(NoMethodError)from/usr/lib/ruby
我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer
我想向我的Controller传递一个参数,它是一个简单的复选框,但我不知道如何在模型的form_for中引入它,这是我的观点:{:id=>'go_finance'}do|f|%>Transferirde:para:Entrada:"input",:placeholder=>"Quantofoiganho?"%>Saída:"output",:placeholder=>"Quantofoigasto?"%>Nota:我想做一个额外的复选框,但我该怎么做,模型中没有一个对象,而是一个要检查的对象,以便在Controller中创建一个ifelse,如果没有检查,请帮助我,非常感谢,谢谢
我已经从我的命令行中获得了一切,所以我可以运行rubymyfile并且它可以正常工作。但是当我尝试从sublime中运行它时,我得到了undefinedmethod`require_relative'formain:Object有人知道我的sublime设置中缺少什么吗?我正在使用OSX并安装了rvm。 最佳答案 或者,您可以只使用“require”,它应该可以正常工作。我认为“require_relative”仅适用于ruby1.9+ 关于ruby-主要:Objectwhenrun
我可以得到Infinity和NaNn=9.0/0#=>Infinityn.class#=>Floatm=0/0.0#=>NaNm.class#=>Float但是当我想直接访问Infinity或NaN时:Infinity#=>uninitializedconstantInfinity(NameError)NaN#=>uninitializedconstantNaN(NameError)什么是Infinity和NaN?它们是对象、关键字还是其他东西? 最佳答案 您看到打印为Infinity和NaN的只是Float类的两个特殊实例的字符串
我不确定传递给方法的对象的类型是否正确。我可能会将一个字符串传递给一个只能处理整数的函数。某种运行时保证怎么样?我看不到比以下更好的选择:defsomeFixNumMangler(input)raise"wrongtype:integerrequired"unlessinput.class==FixNumother_stuffend有更好的选择吗? 最佳答案 使用Kernel#Integer在使用之前转换输入的方法。当无法以任何合理的方式将输入转换为整数时,它将引发ArgumentError。defmy_method(number)
我有一些代码在几个不同的位置之一运行:作为具有调试输出的命令行工具,作为不接受任何输出的更大程序的一部分,以及在Rails环境中。有时我需要根据代码的位置对代码进行细微的更改,我意识到以下样式似乎可行:print"Testingnestedfunctionsdefined\n"CLI=trueifCLIdeftest_printprint"CommandLineVersion\n"endelsedeftest_printprint"ReleaseVersion\n"endendtest_print()这导致:TestingnestedfunctionsdefinedCommandLin
我有一个只接受一个参数的方法:defmy_method(number)end如果使用number调用方法,我该如何引发错误??通常,我如何定义方法参数的条件?比如我想在调用的时候报错:my_method(1) 最佳答案 您可以添加guard在函数的开头,如果参数无效则引发异常。例如:defmy_method(number)failArgumentError,"Inputshouldbegreaterthanorequalto2"ifnumbereputse.messageend#=>Inputshouldbegreaterthano
我使用Ember作为我的前端和GrapeAPI来为我的API提供服务。前端发送类似:{"service"=>{"name"=>"Name","duration"=>"30","user"=>nil,"organization"=>"org","category"=>nil,"description"=>"description","disabled"=>true,"color"=>nil,"availabilities"=>[{"day"=>"Saturday","enabled"=>false,"timeSlots"=>[{"startAt"=>"09:00AM","endAt"=>
有时我需要处理键/值数据。我不喜欢使用数组,因为它们在大小上没有限制(很容易不小心添加超过2个项目,而且您最终需要稍后验证大小)。此外,0和1的索引变成了魔数(MagicNumber),并且在传达含义方面做得很差(“当我说0时,我的意思是head...”)。散列也不合适,因为可能会不小心添加额外的条目。我写了下面的类来解决这个问题:classPairattr_accessor:head,:taildefinitialize(h,t)@head,@tail=h,tendend它工作得很好并且解决了问题,但我很想知道:Ruby标准库是否已经带有这样一个类? 最佳