当前位置: 首页 > news >正文

axilite + ap_memory修饰数组

一、指令优化设计案例一
#pragma HLS INTERFACE bram port=xxx
#pragma HLS INTERFACE s_axilite port=return bundle=CONTROL_BUS
#pragma HLS INTERFACE s_axilite port=xxx bundle=CONTROL_BUS
上述指令约束后,产生单口的axilite_bram

xxx_top_CONTROL_BUS_s_axi
#(
.C_S_AXI_ADDR_WIDTH( C_S_AXI_CONTROL_BUS_ADDR_WIDTH ),
.C_S_AXI_DATA_WIDTH( C_S_AXI_CONTROL_BUS_DATA_WIDTH ))
xxx_top_CONTROL_BUS_s_axi_U
(
.AWVALID(s_axi_CONTROL_BUS_AWVALID),
.AWREADY(s_axi_CONTROL_BUS_AWREADY),
.AWADDR(s_axi_CONTROL_BUS_AWADDR),
.WVALID(s_axi_CONTROL_BUS_WVALID),
.WREADY(s_axi_CONTROL_BUS_WREADY),
.WDATA(s_axi_CONTROL_BUS_WDATA),
.WSTRB(s_axi_CONTROL_BUS_WSTRB),
.ARVALID(s_axi_CONTROL_BUS_ARVALID),
.ARREADY(s_axi_CONTROL_BUS_ARREADY),
.ARADDR(s_axi_CONTROL_BUS_ARADDR),
.RVALID(s_axi_CONTROL_BUS_RVALID),
.RREADY(s_axi_CONTROL_BUS_RREADY),
.RDATA(s_axi_CONTROL_BUS_RDATA),
.RRESP(s_axi_CONTROL_BUS_RRESP),
.BVALID(s_axi_CONTROL_BUS_BVALID),
.BREADY(s_axi_CONTROL_BUS_BREADY),
.BRESP(s_axi_CONTROL_BUS_BRESP),
.ACLK(ap_clk),
.ARESET(ap_rst_n_inv),
.ACLK_EN(1'b1),
.ap_start(ap_start),
.interrupt(interrupt),
.ap_ready(ap_ready),
.ap_done(ap_done),
.ap_idle(ap_idle),
.param_mem_V_address0(param_mem_V_address0),
.param_mem_V_ce0(param_mem_V_ce0),
.param_mem_V_q0(param_mem_V_q0)
);
使用axilite和bram来约束顶层数组,顶层数组综合不再只是一个ram接口了,而是内部产生了一个RAM了。

二、指令优化设计案例二
//#pragma HLS INTERFACE bram port=xxx//注释掉后默认就是ap_memory
#pragma HLS INTERFACE s_axilite port=return bundle=CONTROL_BUS
#pragma HLS INTERFACE s_axilite port=xxx bundle=CONTROL_BUS
上述指令约束后,产生单口的axilite_bram
xxx_top_CONTROL_BUS_s_axi
#(
.C_S_AXI_ADDR_WIDTH( C_S_AXI_CONTROL_BUS_ADDR_WIDTH ),
.C_S_AXI_DATA_WIDTH( C_S_AXI_CONTROL_BUS_DATA_WIDTH ))
xxx_top_CONTROL_BUS_s_axi_U
(
.AWVALID(s_axi_CONTROL_BUS_AWVALID),
.AWREADY(s_axi_CONTROL_BUS_AWREADY),
.AWADDR(s_axi_CONTROL_BUS_AWADDR),
.WVALID(s_axi_CONTROL_BUS_WVALID),
.WREADY(s_axi_CONTROL_BUS_WREADY),
.WDATA(s_axi_CONTROL_BUS_WDATA),
.WSTRB(s_axi_CONTROL_BUS_WSTRB),
.ARVALID(s_axi_CONTROL_BUS_ARVALID),
.ARREADY(s_axi_CONTROL_BUS_ARREADY),
.ARADDR(s_axi_CONTROL_BUS_ARADDR),
.RVALID(s_axi_CONTROL_BUS_RVALID),
.RREADY(s_axi_CONTROL_BUS_RREADY),
.RDATA(s_axi_CONTROL_BUS_RDATA),
.RRESP(s_axi_CONTROL_BUS_RRESP),
.BVALID(s_axi_CONTROL_BUS_BVALID),
.BREADY(s_axi_CONTROL_BUS_BREADY),
.BRESP(s_axi_CONTROL_BUS_BRESP),
.ACLK(ap_clk),
.ARESET(ap_rst_n_inv),
.ACLK_EN(1'b1),
.ap_start(ap_start),
.interrupt(interrupt),
.ap_ready(ap_ready),
.ap_done(ap_done),
.ap_idle(ap_idle),
.param_mem_V_address0(param_mem_V_address0),
.param_mem_V_ce0(param_mem_V_ce0),
.param_mem_V_q0(param_mem_V_q0)
);
可见,还是产生的axilite_1port_bram单口BRAM


三、指令优化设计案例三
//#pragma HLS INTERFACE bram port=xxx//注释掉后默认就是ap_memory
#pragma HLS RESOURCE variable=param_mem core=RAM_T2P_BRAM
#pragma HLS INTERFACE s_axilite port=return bundle=CONTROL_BUS
#pragma HLS INTERFACE s_axilite port=xxx bundle=CONTROL_BUS
上述指令约束后,产生单口的axilite_bram
xxx_top_CONTROL_BUS_s_axi
#(
.C_S_AXI_ADDR_WIDTH( C_S_AXI_CONTROL_BUS_ADDR_WIDTH ),
.C_S_AXI_DATA_WIDTH( C_S_AXI_CONTROL_BUS_DATA_WIDTH ))
xxx_top_CONTROL_BUS_s_axi_U
(
.AWVALID(s_axi_CONTROL_BUS_AWVALID),
.AWREADY(s_axi_CONTROL_BUS_AWREADY),
.AWADDR(s_axi_CONTROL_BUS_AWADDR),
.WVALID(s_axi_CONTROL_BUS_WVALID),
.WREADY(s_axi_CONTROL_BUS_WREADY),
.WDATA(s_axi_CONTROL_BUS_WDATA),
.WSTRB(s_axi_CONTROL_BUS_WSTRB),
.ARVALID(s_axi_CONTROL_BUS_ARVALID),
.ARREADY(s_axi_CONTROL_BUS_ARREADY),
.ARADDR(s_axi_CONTROL_BUS_ARADDR),
.RVALID(s_axi_CONTROL_BUS_RVALID),
.RREADY(s_axi_CONTROL_BUS_RREADY),
.RDATA(s_axi_CONTROL_BUS_RDATA),
.RRESP(s_axi_CONTROL_BUS_RRESP),
.BVALID(s_axi_CONTROL_BUS_BVALID),
.BREADY(s_axi_CONTROL_BUS_BREADY),
.BRESP(s_axi_CONTROL_BUS_BRESP),
.ACLK(ap_clk),
.ARESET(ap_rst_n_inv),
.ACLK_EN(1'b1),
.ap_start(ap_start),
.interrupt(interrupt),
.ap_ready(ap_ready),
.ap_done(ap_done),
.ap_idle(ap_idle),
.param_mem_V_address0(param_mem_V_address0),
.param_mem_V_ce0(param_mem_V_ce0),
.param_mem_V_q0(param_mem_V_q0)
);
加入#pragma HLS RESOURCE variable=param_mem core=RAM_T2P_BRAM真双口RAM优化,还是产生的axilite_1port_bram单口BRAM


四、说明
1.上述各种指定接口数组使用各种优化,看综合报告,最终还是被综合为axilite+ap_memory
INFO: [RTGEN 206-500] Setting interface mode on port 'xxx_top/param_mem_V' to 's_axilite & ap_memory'.

2.bram + axilite接口,bram接口优化被丢弃
"WARNING: [XFORM 203-803] Dropped interface mode 'bram' on 'param_mem.V' as it is incompatible with its interface mode 's_axilite'"
同时指定了接口模式为 'bram' 和 's_axilite',但这两个是冲突的,工具丢弃了 'bram' 模式,保留 's_axilite'。

3.axilite + ap_memory修饰数组,只可能被综合为单口RAM

五、为什么axilite + ap_memory修饰数组,只可能被综合为单口RAM?
s_axilte和ap_memory组合,作为一个混合接口,数组的数据部分通过类似BRAM的模式进行传输。
axilite主设备,也就是ARM或者CPU在单个时钟周期内,是没有办法对ap_memory接口来发起一次
读和写的,只能是要么发起读操作,或者要么发起写操作;虽然axilite的读写通道是独立的,理论
上是可以并发的,但是ap_memory访问在hls中是FSM装天气控制,状态机一次只能执行一个C语句,也
就是一次内存操作,这就限制了同一个周期内无法从PS端发起两次独立的访问。ap_memory和s_axilite理论上可以共存,
因为一个管数据路径,一个管控制路径。然而共存时,数据路径的并发性就受限于AXI-Lite从接口的响应能力。
在这种使用场景下,工具分析不出需要双口的并发访问,或者说生成的双口功能实际上无法被AXI-Lite主设备有效利用。


六、axilite + ap_memory修饰数组,只可能被综合为单口RAM的结论?
1.当你在顶层数组接口上同时使用 s_axilite 和 ap_memory 时,它被综合成单端口RAM几乎是必然的
这个主要是ap_memory和axilite组合机制来决定的。
2.ap_memory 接口:是一个更通用、更简单的 RAM 接口。它生成像 q0、d0、addr0、ce0、we0 这样的低层级、无握手的并行信号。因为简单,它可以被 HLS 内部的 AXI-Lite 适配器“消化”掉。
3.当 ap_memory 和 s_axilite 并存时,它们不冲突,因为工作在不同层级:
对外物理接口:完全就是一个 AXI4-Lite 从接口。CPU 只能看到一组寄存器地址。内部数据搬运:HLS 会自动生成一个适配器模块,将 AXI4-Lite 的事务“翻译”成一组启动 ap_memory 阵列所需的内部信号。这个自动生成的适配器,才是单端口RAM限制的根源。
4.为什么综合只能是单口RAM呢?
因为数据从 CPU 的 AXI4-Lite 总线流向这个阵列时,必须经过翻译,这个过程丢失了双端口的意义。
即使 HLS 允许你强制将这个阵列的内部存储设为双端口(比如用 #pragma HLS RESOURCE variable=arr core=RAM_2P),从外部 CPU 看来,它依然是一个单端口的效果。

原因一:AXI4-Lite 协议的天然限制
这是最致命的一点。AXI4-Lite 总线本身不支持同时读写。它的 5 个通道中,读地址和写地址通道虽然独立,但 AXI-Lite 规范严格限制所有事务必须按顺序完成。一个读事务必须等待上一个写事务的响应完成后才能发起。CPU 在单个时钟周期内,绝不可能通过一条 AXI-Lite 总线对此设备进行“同时读写”。

原因二:适配器是“单线程”状态机
HLS 生成的 AXI-Lite 适配器是一个顺序执行的状态机。它接收一个 AXI 请求,然后驱动一次内部的 RAM 访问,再返回响应。这个状态机一次只能处理一个请求,无法生成两个独立的“读”和“写”的内部启动信号。

原因三:代码分析阶段的逻辑冲突
既然 HLS 已经明确知道这个接口是 s_axilite,它会认为顶层这个数组的访问源是单线程的 CPU。在分析你的函数代码时,即使里面有机会并发的循环,综合工具也会因为顶层接口的访问限制,而放弃推断出需要双端口。最终综合出的 RTL,CPU 看到的始终是一块平铺开的、可随机访问的、但同一时刻只能进行读或写操作的存储空间。

七、如何解决双口RAM的问题
一旦选择了 s_axilite + ap_memory 这个组合,双口 RAM 的所有好处就都被 AXI-Lite 的串行协议和适配器抹平了。

如果你想实现真正的,硬件层面并发读写的双口 RAM,必须回归到纯硬件逻辑。路径非常明确:
放弃 s_axilite,将数组接口指定为 bram 并正确编写并行的 C/C++ 代码,或直接强制 core=RAM_2P。

http://www.jsqmd.com/news/716289/

相关文章:

  • 管好PPT的“骨架”:用Python控制页面与文档属性
  • WASM容器化部署不香了?Docker 26.0+原生支持WASM Runtime,90%工程师还不知道的5个技术拐点
  • 告别人工质检:用PatchCore、DRAEM这些SOTA模型,5步搞定工业缺陷检测
  • 百度网盘命令行终极指南:告别图形界面,用终端掌控云端文件
  • 宏观颗粒度流水设计-子函数之间
  • 舆情监控:如何让AI自动抓取新闻资讯,并生成每日摘要报告?
  • 5大核心功能解析:BongoCat如何成为你的终极跨平台桌面伴侣?
  • C++数据结构与算法的基础知识和经典算法汇总
  • 5分钟精通暗黑破坏神2存档编辑器:打造你的完美角色体验
  • 实测!用HALCON 23.05 + OpenVINO 2021.4,让你的Intel Arc显卡在工业视觉里跑起来
  • 别光看理论!用LTSPICE亲手仿真一次MOS管的米勒效应,看完波形就懂了
  • 2026 中小企业 AI 工具实测:5 款高性价比 AI 超级员工选型全攻略
  • 2026小程序公司十大名单大盘点,前十分享+避坑指南 - 企业数字化改造和转型
  • OpenBLAS 从源码编译安装教程(Linux 用户)
  • Jetson Orin NX到手后,别急着装CUDA!先搞懂SDK Manager刷机流程(避坑指南)
  • 给TMS320F28335的PIE中断配个‘管家’:从原理图到代码的保姆级配置指南
  • 中小企业多层级 RAG 办公知识库系统探讨(一)____风起
  • SAP MIGO批次管理实战:如何用隐式增强自动填充批次特性值(附完整ABAP代码)
  • 【无人机控制】城市无人机混合多速率自适应扰动估计与稳定控制Matlab实现
  • 为什么大模型在理解长文本的时候会出现幻觉,RAG可以解决幻觉问题吗?
  • 从 0 到 1 搭建客服 AI Agent Harness Engineering:意图识别、知识检索与对话管理完整实战
  • 野火STM32H750双W25Q256 Flash实战:CubeMX配置与驱动修改避坑指南
  • 从机械硬盘到SSD:深入聊聊SATA NCQ与NVMe队列的异同与演进
  • 分子级代码注入攻击:原理、危害与软件测试中的对抗策略
  • 3分钟搞定缠论分析:ChanlunX让通达信自动识别中枢与买卖点
  • 别再只当注册中心了!Nacos配置中心实战:从权限开启到YAML动态刷新,一篇搞定
  • 镀金空心光纤的热光学特性
  • 19.AI开发感悟
  • 别再只会改字体了!用FontCreator 14.0从零设计一套自己的英文字体(附赠常用字形模板)
  • 如何突破8位MCU性能瓶颈?GRBL_for_STM32嵌入式系统移植指南