- 博客(878)
- 收藏
- 关注
原创 范式组合优化
3.为了实现高性能硬件,HLS 工具必须基于顺序代码推断并行度,并利用它来实现更高的性能。4.图像或者阵列或者矩阵的逐像素运算是FPGA中最乐见的架构,这个是FPGA擅长处理的。控制驱动的 TLP 适用于并行度建模,它依靠 C++ 的顺序语义,而非连续运行的线程。较小的模块化组件的优势在于,可以按需进行赋值,从而提升并行性。3.循环主体的迭代是FPGA最乐见其成的范式,这个可以利用属性来提高并行度,四、控制驱动的任务级并行度和数据驱动的任务级并行度。1.数据驱动的任务级并行度。2.控制驱动的任务级并行度。
2026-05-08 14:47:32
8
原创 可编程范式架构
其中,使用 FIFO 缓冲器的主要优势在于,只要生产者将数据插入缓冲器,使用者进程就可以立即在 FIFO 缓冲器内部开始访问数据。也就是ap_start1和ap_done1与后续的ap_start2以及ap_done2之间关系不大,这个就造成他们。因为上下游多个hls ip模块使用ap_ctrl_hs,他们自己的ap_start和ap_done时机不一样,是在ap_ctrl_hs协议的基础上加上了一个ap_continue信号,用于后级别模块,个缓冲器中,生产者进程则正在创建新(部分)版本的数据。
2026-05-08 13:36:03
175
原创 zynq-7000 PS+PL交互访问
如果FPGA(PL)通过 HP 接口往DDR写数据,CPU读取时通常需要手动调用 flush_cache() 或 invalidate_cache() 同步数据,或者干脆将这部分DDR映射为Non-Cacheable(性能略降,但更安全)。如果CPU开启了Cache,它可能读取的是L2 Cache里的“过期数据”,而不是FPGA刚刚写入的最新数据。当CPU访问外设(I/O)的寄存器或控制状态空间(MMIO)时,必须使用非缓存(Non-Cacheable)或强序(Strongly-Ordered)访问。
2026-05-08 11:09:20
214
原创 PC架构访问外设 + Cache讨论
这是因为外部设备(如显卡、键盘)的数据是动态变化的,如果CPU把这些设备数据缓存到Cache里,可能会读到过时的“脏数据”,导致设备无法正常工作。无论是访问独立显卡的显存/寄存器,还是访问鼠标、键盘的I/O端口,它们的目标地址并不是主存空间(DRAM),而是属于“I/O地址空间”或特殊的“设备内存映射区域”(MMIO)。流程3:CPU核 ➜ FSB/QPI总线 ➜ 北桥IOH ➜ DMI总线 ➜ 南桥ICH ➜ LPC总线 ➜ SIO ➜ 鼠标/键盘/USB接口及设备。
2026-05-08 10:15:59
29
原创 FPGA并行设计思想
理解启动间隔(II)的概念,II=1 表示每个时钟周期都能处理一个新输入,是实现最高吞吐率的关键。数组分割 (ARRAY_PARTITION):为了同时读取多个数据(例如,在一次处理中读取多个系数和移位寄存器的值),需要使用数组分割来增加存储器的读写端口。1.FPGA 开发的本质是利用空间上的并行性(Spatial Parallelism),这要求开发者从习惯的“顺序思维”切换到“并行思维”5.FPGA 架构设计的核心所在,也是“空间换时间”和“时间换空间”思想的直接体现。5.LUT查找表映射。
2026-05-07 17:47:37
30
原创 FPGA架构说明--空间计算的极致主义者
在空间计算的FPGA世界里,虽然绝对延迟可能不如CPU,但设计的首要目标是榨取吞吐率 (Throughput)。3.FPGA的核心是进行时空交换处理,可以将庞大、高速的片上存储资源和海量可编程逻辑单元,看作是时间与空间“交易”的筹码。---高主频,高主频来提升处理速度。1.逻辑资源紧张的情况下,减少并行度,复用一个单元,分时复用处理多路数据,这样吞吐率降低了,但是节省了资源。注意复制相同的逻辑处理不同的数据,才能实现任务的并行;1.通过复制多份相同的计算逻辑,让这些逻辑处理不同的数据,从而实现任务的并行。
2026-05-07 14:26:49
291
原创 FPGA发展路线
毕竟软件和硬件的功能实现存在非常大的差别。即便是平行程序执行,也是通过OS 的任务调度CPU 的资源。宏观上是并发执行,而微观上仍然是顺序占用CPU 执行的。另一方面,基于FPGA 硬件逻辑,如果没有上下文关联,完全可以并行运行。在没有特别语法规则下,讲C语言程序转换成为硬件逻辑,并且尽量实现硬件的并行执行是有难度的。6.利用c/c++和VHDL/Verilog的差异性,做基本架构和模块库,IP库联合设计。创建工程--编写coding---c仿真--c综合--c/rtl协同仿真--rtl导出。
2026-05-07 14:02:24
334
原创 双线性插值算法
2.二阶偏导:回答“灰度的变化本身变化有多快?”(变化加速度),能精确锁定边缘的中心,并判断边缘的过渡类型。3.在水平方向上对这四个点进行两次线性插值,得到两个中间值(R1 和 R2)。2.找到该浮点坐标周围的四个最近邻像素点(Q11、Q12、Q21、Q22)。4.在垂直方向上对 R1 和 R2 再次进行线性插值,得到目标像素的最终值。4.最近邻插值是找最近的一个点,双线性插值是找最近的四个点。1.将目标图像的像素位置映射到原始图像的浮点坐标位置。2.最近邻插值是只需要找点后直接赋值,不需要计算的。
2026-05-07 13:12:43
242
原创 IP Interrupt Status Register (Read/TOW)中断状态寄存器说明
它不是让你去写0或1来设置状态,而是说:当你向某个位写 1 时,硬件会将该位清 0(清除中断)。如果你写 0,该位状态不变。当 HLS 任务完成(ap_start 发起的任务执行完毕后),硬件自动将此位置 1,表示 "任务完成中断" 发生。寄存器地址、访问属性(Read/TOW)、位域定义(bit0 ap_done, bit1 ap_ready)
2026-05-06 21:35:07
380
原创 video模式案例-设计
但凡看到Estimated的时钟比较小,你就要注意,代码逻辑很多出现错误或者被优化掉了。// 无限循环:每个时钟周期执行一次,II=1。// 静态变量必须在循环外部声明(保持状态)上述代码是存在问题的,具体如何修正?
2026-05-06 09:27:05
386
原创 边沿信号产生-利用赋值做文章
/if (de == 1)//hsync被优化设计。// de 无效时,不输出数据,循环自动进入下一周期。// 当 de 有效时,输出像素并更新计数。// 无限循环:每个时钟周期执行一次,II=1。// 静态变量必须在循环外部声明(保持状态)// 静态变量必须在循环外部声明(保持状态)// 静态变量必须在循环外部声明(保持状态)// vsync 上升沿处理。// de 上升沿处理。//step2:寄存器打拍。//step2:寄存器打拍。//step1:产生边沿。//step1:产生边沿。
2026-05-05 14:59:40
395
原创 ERROR: [COSIM 212-366] Cannot delete directory ‘sim/verilog‘: it is being used by another program.
协同仿真,如果打开了vivado查看波形,没有关闭,然后又进行rtl仿真,就会存在两个vivado冲突。关闭vivado就可以了。
2026-05-05 13:32:16
11
原创 图像格式转换设计-高层次综合设计二
/ 产生递增像素(仅有效区域才真正使用)// 每个时钟周期调用一次函数(硬件行为)// // 检查 tuser(仅帧首第一个有效像素为 1)//if (de == 1)//hsync被优化设计。// // 检查 tlast(每行最后一个像素)// 时序参数(应与 frame_top.h 中的定义一致)// de 上升沿处理。// 视频时序参数(可根据需要调整)// // 检查数据值。// 模拟一帧视频时序。// // 检查总像素数。
2026-05-05 12:58:28
348
原创 图像格式转换设计-高层次综合设计
/ 行末置位 TLAST。// hls::stream<pixel_t> &data_feed, // 输出像素数据(由测试平台驱动到模块输入)// // 这里的 DUT 是组合路径:in_data, vsync, hsync, de -> output_stream。// // 为了正确驱动,我们需要在每个时钟周期设置 in_data, vsync, hsync, de,然后等待一个周期。
2026-05-05 12:35:05
292
原创 无限循环 while (1) 可综合,但是不可仿真
用户可能想设计为free-run设计,free-run设计可不是while循环。// de 无效时,不输出数据,循环自动进入下一周期。// 当 de 有效时,输出像素并更新计数。因为,这个无限循环是没有退出条件的,就类似无限递归;虽然可综合,但是c仿真和rtl仿真都是会出问题!// 无限循环:每个时钟周期执行一次,II=1。// vsync 上升沿处理。上述代码设计,看似合理,实际上是存在问题的!// de 上升沿处理。上述代码while(1)是死循环!
2026-05-04 11:50:54
37
原创 video_to_axi_stream
第二条:使用 ap_ctrl_none 时,函数像一个无限循环自由运行,无法定义任务间隔,HLS 不会将其综合为 II=1 的可流水线化任务(因为输入是 ap_none 且内部有状态,通常综合为顺序逻辑,但没有开始/完成握手,无法以任务模型衡量 II)。修改为ap_ctrl_hs,也是解决不了问题的,仿真可能还是出问题的,需要你认真分析代码设计的问题,解决了问题才行,并不是ap_Ctrl_none不行,你直接改为ap_Ctrl_hs就行,有时候你可以这么干,有时候不行,这个要具体问题具体分析!
2026-05-04 11:27:50
323
原创 宏观颗粒度数据流设计总结
3.对于废标量变量,例如,数组,这个在dataflow区域,可以被指定为FIFO,前提是数组的访问是顺序的。2.对应scalar标量变量,这个再dataflow区域会被综合为depth比较小的FIFO;上述数组可以指定为FIFO或者RAM,但是这里要注意,你指定为FIFO,会存在一个问题,4.对于数组,在dataflow区域优化,如果是随机访问的,被指定乒乓PIPO缓存。1.应用dataflow指令的区域,各个子模块之间的通信全部综合为通道;虽然这个被指定为RAM,关闭FIFO,但是综合还是FIFO。
2026-05-04 10:02:56
317
原创 vivado hls工具高亮设置操作
如果你不小心关掉了“Solution”面板、移动了“Console”,或界面变得杂乱,此操作可将所有窗口恢复到初始位置和大小,无需重启软件--23。操作命令: 重置工程:在 Tcl 控制台输入 reset_project-。重置字体和颜色 (Fonts & Colors) 作用:将代码编辑器字体、字号、语法高亮等外观设置恢复到默认状态。重置Solution 作用:仅重置当前选中的 Solution,清除其包含的综合和仿真结果。操作路径:在主菜单点击 Solution → Reset Solution。
2026-05-03 22:42:50
20
原创 C-simulation
2.Clean-Build模式用于清理之前的日志和结果,重新编译和仿真。3.都不勾选,都不勾选,就之间进行c仿真设计。1.launch-debug模式在线调试。Optim complie模式。launch-debug模式。Clean-Build模式。build-only模式。
2026-05-03 20:16:51
19
原创 循环索引数据类型的位宽要设置合理
这种设计的时候,一定要注意,TAP这个常量值的数据所占的位宽大小一定要小于i设置的数据类型的位宽,否则,你出问题,你喊爹喊娘了。其实这种情况,你进来把类型位宽设置大点,这个在综合后的布局布线会自己优化的,你不要担心,所以这个位宽你搞大点,免得出问题!如果TAP=8,那么i的类型你不能设置为ap_uint<3>,你至少要设置ap_uint<4>才会不出问题,你查半天,也不会找到原因的。我这个地方出问题,我思索了好久,差不多找这个问题,找了半个小时才解决的!那么i的值可能为:0,1,2,3,4,5,6,7;
2026-05-03 20:03:49
163
原创 array_reshape & array_map & array_partition
/ 例如:若要每个周期同时读/写 2 个 ap_uint<I_DW*TAP> 字(即 2*TAP 像素),一、关于一维数组使用array_reshape & array_map & array_partition。二、关于多维数组使用array_reshape & array_map & array_partition。my_array[10][6][4]表示3维,有4个bank;my_array[10][6]表示2维,有6个bank;my_array[10]表示1维,有10个bank;
2026-05-03 10:57:17
104
原创 ap_vld & ap_ack & ap_hs使用
in_data + out_ack模型,这个是单向反馈,只有Acknowledge应答信号,这个协议的数据可靠性比较高,保证输入的数据被采集到。valid + data的配合使用,但是这个作为综合工具中的输入参数,传输效率比较高,保证数据不丢的,因为只有在valid拉高的时刻取数据,才可以被准确的采集的;发送端产生in_data数据的时候,需要发送端需要得到确认,防止数据丢失。关于ap_ack和ap_hs在何种情况下使用,用户可以自己去尝试和判断。一、ap_vld & ap_ack & ap_hs的使用。
2026-05-02 16:53:53
134
原创 总线接口说明
因为从DDR读取的数据是需要缓存的,或者说往DDR中写的数据也是需要缓存的,所以都是需要本地缓存的。2.如果AXI4总线,你只用读,那么就可以将写的参数设置到比较小的情况,用于节约资源;3.如果AXI4总线,你只用写,那么就可以将读的参数设置到比较小的情况,用于节约资源;这个是AXI读占用的FIFO的大小,可以依据这个计算,会用到多大的block ram。这个是AXI写占用的FIFO的大小,可以依据这个计算,会用到多大的block ram。这个表示请求总线的延时,一般不用,当然,你可以依据设计需要来使用。
2026-05-02 16:24:24
110
原创 ap_uint 有构造函数,不能在 union 中使用
错误原因是ap_uint类型有用户声明的构造函数,在C++中,如果union成员有非平凡构造函数,union的默认构造函数会被删除,编译器报错。这在普通的 C/C++ 程序中是常见的技巧,但在 Vivado HLS 中不被允许,因为 HLS 对 C++ 的支持是有限制的,它要求代码能够被综合成硬件电路。简单说就是:在 C++ 中,联合体不允许包含“有构造函数”的类对象,而 ap_uint<8> 和 ap_uint<32> 恰好是包含构造函数的类。// ... 其他构造函数、运算符重载。
2026-05-01 22:58:57
68
原创 数组访问的瓶颈
注意,使用stable的前提是,你不能在顶层使用axilite同时优化这个数组,因为是不兼容的,如果你使用了axilite,你不能使用。所以这个时候,需要使用array_partition进行分组,分成多个小的RAM,这样port就变得很大,能够让你的设计更加合理。这个axi_bram是一个单口的,注意axi_bram只能是一个单口RAM,如果你想多个,那么,你就得分成多个数组了。1.当axilite修饰数组的时候,在顶层接口的数组不再是被综合为接口,而是被综合为一个axi_bram了,
2026-05-01 22:44:27
18
原创 solution说明
script.tcl 是 Vivado HLS 为每个 Solution 自动生成的核心 Tcl 脚本,记录了该 Solution 的工程配置(如器件型号、时钟频率、顶层函数名和源文件列表等),本质上是一个可以随时复现整个工程的“蓝图”--3。它的核心作用是在 C/C++ 算法层面验证设计功能的正确性,是 HLS 开发流程中的第一步验证.script.tcl脚本用于打开工程,创建工程,工程的编译和运行,使用这个脚本可以恢复和建立vivado hls工程。1.constraints约束。
2026-05-01 22:25:46
23
原创 stable编译指令使用
• 如果 A 由 proc2 写入,那么执行 dataflow_region 时,任何其它进程或调用上下文在定义写入的内存位置前都。如果不使用 stable 编译指示,并假定 A 由 proc2 读取,那么 proc2 会成为其所在位置的数据流区域内执行的初始。• 如果 A 由 proc2 读取,那么执行 dataflow_region 时,任何其它进程或调用上下文都不会覆盖读取的内存位。上述代码不使用stable来修饰数组的情况,proc1和proc2需要做同步,来确认A的读取功能。
2026-05-01 21:35:22
18
原创 综合案例设计描述和分析
关键是:HLS 的数据流协议会假定,如果一根 FIFO 一直没被读取,生产者就可能无法继续写后面的数据(如果 FIFO 是同步握手)。当 extra_info 的生产者想发送“配置结束”信号时,发现 FIFO 还是满的,它就会被阻塞住。整个数据流的“最慢一拍”被这个阻塞拖住,可能导致前面的 read_pixels 也无法正常向后传递数据,因为数据流是全局同步启动和关闭的。虽然语法上你可能只是把 cfg 当成函数参数,但 HLS 在数据流区域中,会把所有非标量的参数都实现成 FIFO 通道,包括这个数组。
2026-05-01 21:07:24
184
原创 综合设计步骤和分析
如果在数据流管道中间读取这个值,可能会导致管线停顿,因为生产者可能尚未写完,消费者已在读取。从后续日志看,line_buff_V 确实被实现为分布式 RAM(RAM_2P_LUTRAM),因为深度或位宽不大。说明设计中很可能使用了浮点常量或运算,HLS 在不影响功能的前提下,默认移除了对 NaN/带符号零的处理,以节省资源。2.D:/xxx/vivado_hls.bat D:/xxx/solution1/csynth.tcl运行综合的tcl文件。4.opening project打开工程。
2026-05-01 13:11:45
27
原创 GUI设置
Explorer浏览器,这个是project列表,包括include,source,test bench,solution等。-add_files添加文件,包括h文件和c文件,json文件,tcl文件等。-config_array_partion配置数组打散分离。achive project打包工程,压缩为zip。-close project关闭工程。-config_bind配置绑定操作。Errors错误Message。Preferences偏好设置。1.welcom欢迎界面。
2026-05-01 12:34:58
227
原创 配置路径 + 数据路径架构
框架二的设计是基于框架一设计,对cache设计部分做了优化,将cache变成了pingpang_cache,这样,提高了串流模块的读取cache数据的速度;上述框架设计的瓶颈在axi_bram,这里的axi_bram是一个单口RAM,所以这里的并行度比较小,数据的读取latency就比较大,II也会有影响。1.目前的rtl设计的逻辑,几乎都可以归结为配置路径加数据路径的架构,下面对配置路径和数据路径的架构进行说明。框架三的设计是在框架二的基础上进行了优化设计,解决了axi_bram的瓶颈问题。
2026-05-01 10:30:08
125
原创 协同仿真解析说明
当一个事务完成时,日志会即刻打印一条信息,此时上一个事务的内部进度变为 100%,但日志中通常记录的是下一个事务刚刚开始的状态,因此 Intra-Transaction Progress 显示为 0.00%。彼此的差异仅为 1000 ps 左右,相对误差小于 0.00001%,说明 RTL 设计是完全时序确定性的,没有随机延迟,每次事务处理的时钟周期数完全一致。当最后一个事务完成时,整个仿真即将结束,此时打印的是“3/3”的状态,并且因为此时第三个事务已经完成,其内部进度自然为 100.00%。
2026-04-30 21:46:39
356
原创 双口RAM和单口RAM的综合设计
综合工具认为,你这要求的双口RAM没啥用啊,你在上面for循环中赋值,这种顺序的方式进行赋值,就是当单口RAM用啊,综合工具并不总是按照用户的方式进行综合和会有,你的优化指令只是指导和告知综合工具的作用,至于综合工具会不会。方案二的核心代码不变的情况下,你对顶层接口怎么优化,都是端口RAM,因为你的优化并不会被综合工具采纳。你却让我综合为双口RAM,不好意思啊,我不按照你的搞了,忽略你的综合指令。方案二:下面代码的设计方案,综合工具只会将你的设计综合为单口RAM。
2026-04-30 16:14:35
271
原创 Vivado HLS 提供了 C++ 模板类 hls::stream<>
当你调用顶层函数时,程序会停在函数入口,等待它返回。不管你是纯C的前仿真,还是C/RTL协同仿真,Testbench(C/C++侧)里的 hls::stream 都被当作一个容量无限的软件队列。C 仿真和协同仿真中,testbench 是软件代码,hls::stream 类在软件侧实现为一个 std::queue 等容器,具有无限容量,从而简化了测试。这个你在写激励的时候应该有体会,你声明的hls::stream变量,可以容纳一张图像,在你没有指定hls::stream的depth的情况下,可以容纳一个。
2026-04-30 11:11:24
423
原创 II为NA问题说明
II 是ap_ready 信号之间的周期数,设计会使用该值来请求新输入。如果你想看到Interval不再显示NA,那么你需要进行多轮仿真才行,单轮仿真是没办法看到II的。在非pipiline设计中,C/RTL协同仿真的ap_start和ap_done之间的。在流水线设计中,在传输事务完成之前可能存在多次ap_start和ap_ready的。ap_ready 信号之间的周期数,设计会使用该值来请求新输入。在流水线设计中,设计可能在第一项传输事务完成之前读取新输入;三、为何你的设计中的报告II始终为NA?
2026-04-29 15:29:56
182
原创 数据流转换模块设计核心要点
1.串流模型中,函数中有两块逻辑,这两块逻辑是串行执行的,第一块逻辑没有执行完成,就会一直阻塞着,类似rtl中。状态机的触发条件,如果条件没有触发,那么就一直阻塞着,直到条件满足,进入下一个状态流程。这样的好处是是,减少两个逻辑块的进入和退出开销;当然也要视情况而定!1.如果不对上述进行赋初始值,会存在综合的rtl代码的初始值为X态。2.rtl协同仿真中叶可以看到X标红的状态,不利于设计查看和分析。2.可以将串流的两个逻辑部分合并为一个逻辑。方式一:判定帧头设计,检测帧头。方式二:判定帧头设计,检测帧头。
2026-04-29 14:57:19
143
原创 ram,rom,fifo,stable,数组,axilite
s_axilite 是块级协议:它为整个模块添加一个AXI总线从接口,将所有控制信号(包括试图用ap_stable标记的信号)都映射到该总线接口的内部寄存器中,通过地址进行访问。被动连线模型(ap_stable):HLS工具假设信号在模块运行期间本身是稳定的,因此只需一根导线被动地将电平传递进去,无需任何握手确认,也无需寄存器保存数据,以最小化硬件开销。所以FIFO必须每帧图像都做数据更新才行,但是RAM不需要,RAM只需要你确实CPU要更新参数的时候,才会进行处理,所以这个是RAM的优势了,
2026-04-29 13:48:16
627
原创 axilite + ap_memory约束数组-突破单口RAM限制
2.只不过这个RAM对外,这里的对外指的是CPU或者ARM,对外的接口是axilite,通过axilite来访问RAM的地址,从而实现对RAM的读写操作。使用上面的两条约束指令,从而将一个单口RAM变成两个单口RAM,同时操作两个RAM这样来实现乒乓访问,从而能够提高吞吐量,也就是II变小,但是。1.在这种情况下,会将接口数组综合为内部RAM,不再是单纯的接口了,而是实实在在的要消耗资源的。2.可以将一个RAM变成两个RAM,从而得到类似或者近似双口RAM的功能。1.首先,实现不了双口RAM。
2026-04-28 13:49:55
16
原创 宏观颗粒度流水设计-子函数之间
本案例中,默认这些参数都被综合为depth比较小的FIFO,上述代码中的width和height全部都被综合为FIFO,其中mem除外,2.这三个子模块在不进行约束的时候是串行执行的,使用dataflow优化后,就是并行执行的;3.模块之间传递的参数变量全部变成管道,管道的类型为FIFO或者pingpang ram;1.使用dataflow优化,注意hls::stream变量,需要使用static修饰。1.上述代码架构为dataflow设计的比较常见的案例,核心实现模块中有三个子模块;
2026-04-28 13:41:18
315
原创 axilite + ap_memory修饰数组
最终综合出的 RTL,CPU 看到的始终是一块平铺开的、可随机访问的、但同一时刻只能进行读或写操作的存储空间。这个自动生成的适配器,才是单端口RAM限制的根源。即使 HLS 允许你强制将这个阵列的内部存储设为双端口(比如用 #pragma HLS RESOURCE variable=arr core=RAM_2P),从外部 CPU 看来,它依然是一个单端口的效果。同时指定了接口模式为 'bram' 和 's_axilite',但这两个是冲突的,工具丢弃了 'bram' 模式,保留 's_axilite'。
2026-04-28 11:22:53
319
pcie windows info信息工具
2024-10-16
基于VHDL实现axi接口的uart
2024-10-15
工业相机CameraLink v2.0协议文档
2024-08-30
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅