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

HLS高层次综合设计--if(j == 0)引发的c/rtl协同仿真异常

一、注意问题出现阶段
1.下属异常代码在C综合阶段功能是正确的;
2.下属异常代码在RTL综合阶段是能够正常综合的;
3.下属异常代码在RTL综合后进行C/RTL协同仿真是失败的。

一、if(j == 0)引发的c/rtl协同仿真代码案例一

void fuction
(

)
{

static ap_uint<24> win_buff[10];
#pragma HLS ARRAY_PARTITION variable=win_buff complete dim=0

for(ap_uint<16> i=0; i<height; i++) {

for(ap_uint<16> j=0; j<(cols+1); j++) {
#pragma HLS pipeline II=1

srctemp = src.read();

// ================= 错误代码 =================
for(ap_uint<4> k = 0; k < 10; k++) {
#pragma HLS UNROLL
if(j==0){
win_buff[k] = srctemp;
win_buff[k + 1] = srctemp;
win_buff[k + 2] = srctemp;
win_buff[k + 3] = srctemp;
win_buff[k + 4] = srctemp;
}
else{
win_buff[k] = win_buff[k + 1];
win_buff[k + 1] = win_buff[k + 2];
win_buff[k + 2 = win_buff[k + 3];
win_buff[k + 3] = win_buff[k + 4];
win_buff[k + 4] = srctemp;
}

}

// ==========================================================


}
}
}

二、if(j == 0)引发的c/rtl协同仿真代码案例二
void fuction
(

)
{

static ap_uint<24> win_buff[10];
#pragma HLS ARRAY_PARTITION variable=win_buff complete dim=0

for(ap_uint<16> i=0; i<height; i++) {

for(ap_uint<16> j=0; j<(cols+1); j++) {
#pragma HLS pipeline II=1

srctemp = src.read();

// ================= 错误代码 =================
if(j==0){
for(ap_uint<4> k = 0; k < 10; k++) {
#pragma HLS UNROLL

win_buff[k] = srctemp;
win_buff[k + 1] = srctemp;
win_buff[k + 2] = srctemp;
win_buff[k + 3] = srctemp;
win_buff[k + 4] = srctemp;


}
}
else{
for(ap_uint<4> k = 0; k < 10; k++) {
#pragma HLS UNROLL

win_buff[k] = win_buff[k + 1];
win_buff[k + 1] = win_buff[k + 2];
win_buff[k + 2] = win_buff[k + 3];
win_buff[k + 3] = win_buff[k + 4];
win_buff[k + 4] = srctemp;

}

}


// ==========================================================


}
}
}

三、正确的案例
void fuction
(

)
{

static ap_uint<24> win_buff[10];
#pragma HLS ARRAY_PARTITION variable=win_buff complete dim=0

for(ap_uint<16> i=0; i<height; i++) {

for(ap_uint<16> j=0; j<(cols+1); j++) {
#pragma HLS pipeline II=1

srctemp = src.read();

// ================= 错误代码 =================
for(ap_uint<4> k = 0; k < 10; k++) {
#pragma HLS UNROLL

win_buff[k] = win_buff[k + 1];
win_buff[k + 1] = win_buff[k + 2];
win_buff[k + 2] = win_buff[k + 3];
win_buff[k + 3] = win_buff[k + 4];
win_buff[k + 4] = srctemp;


}

// ==========================================================


}
}
}

四、失败的原因分析
1.失败的日志
Vivado Simulator 2018.3
ERROR: [Simtcl 6-50] Simulation engine failed to start: Failed to launch child process (child exe not found).
Please see the Tcl Console or the Messages for details.
ERROR: [COSIM 212-303] Aborting co-simulation: RTL simulation failed.
ERROR: [COSIM 212-344] Rtl simulation failed.
INFO: [COSIM 212-211] II is measurable only when transaction number is greater than 1 in RTL simulation. Otherwise, they will be marked as all NA. If user wants to calculate them, please make sure there are at least 2 transactions in RTL simulation.
could not read "xxx/solution1/sim/tv/rtldatafile/sim/report/cosim.log": no such file or directory
while executing
"source xxx/solution1/cosim.tcl"
invoked from within
"hls::main xxx/solution1/cosim.tcl"
("uplevel" body line 1)
invoked from within
"uplevel 1 hls::main {*}$args"
(procedure "hls_proc" line 5)
invoked from within
"hls_proc $argv"
Finished C/RTL cosimulation.
这段异常从因为日志看是说综合工具和综合工具仿真器有问题,或者是环境设置有问题,推荐电脑重启或者关机,或者重新安装软件。
我试了试这些方法都不行,实际上我发现就是那个if j==0那段代码造成的异常。后面仔细分析了一下,是这段代码片剖坏了移位寄存器功能,造成综合工具在仿真的时候出现了二义性,从而报错。

2.失败的原因分析
上述失败代码中if(j == 0) 不是简单加了一个边界判断,而是破坏了 HLS 原代码的规则移位寄存器结构和流水线时序,导致 C 综合/RTL 生成失败,最终 C/RTL 仿真启动时找不到 RTL 仿真可执行文件。

五、去掉static修饰wind_buffer也可也解决问题

void fuction
(

)
{

// static ap_uint<24> win_buff[10];//c/rtl协同仿真异常

static ap_uint<24> win_buff[10];//c/rtl协同仿真正常
#pragma HLS ARRAY_PARTITION variable=win_buff complete dim=0

for(ap_uint<16> i=0; i<height; i++) {

for(ap_uint<16> j=0; j<(cols+1); j++) {
#pragma HLS pipeline II=1

srctemp = src.read();

// ================= 错误代码 =================
if(j==0){
for(ap_uint<4> k = 0; k < 10; k++) {
#pragma HLS UNROLL

win_buff[k] = srctemp;
win_buff[k + 1] = srctemp;
win_buff[k + 2] = srctemp;
win_buff[k + 3] = srctemp;
win_buff[k + 4] = srctemp;


}
}
else{
for(ap_uint<4> k = 0; k < 10; k++) {
#pragma HLS UNROLL

win_buff[k] = win_buff[k + 1];
win_buff[k + 1] = win_buff[k + 2];
win_buff[k + 2] = win_buff[k + 3];
win_buff[k + 3] = win_buff[k + 4];
win_buff[k + 4] = srctemp;

}

}


// ==========================================================


}
}
}

static修饰win buffer造成win buffer是移位寄存器,并且初始化在bitstream加载过程初始化,然后if的两种判断,破坏了结构;

去掉static后,变成普通的变量,设计就变得正确了。

这个试验是个很好的案例,我差不多花费了一个小时,才把这段逻辑推导成功和分析明白。

六、总结

1.当使用 static 修饰时:
HLS 认为 win_buff 是一个持久状态变量,需要在 FPGA 上电或复位时恢复到特定状态(通常是 0)。
当您在循环中加入 if(j==0) 的复杂逻辑时,工具不仅要处理上述的 MUX 逻辑,还要处理静态变量的复位逻辑。这导致生成的 RTL 代码极其复杂。Vivado 2018.3 版本在处理这种“带条件复位的复杂状态机”时,可能生成了某种边界条件的 RTL 代码,导致仿真器编译失败。

2.当移除 static 后:
win_buff 变成了一个局部变量。
在 RTL 硬件实现中,局部变量通常没有全局复位需求。它只是一个随算法逻辑状态变化的寄存器组。
移除 static 后,HLS 不再生成复杂的初始化/复位电路,逻辑负载减轻。虽然移位逻辑依然因为 if-else 变得复杂(不如纯移位高效),但由于去掉了复位逻辑的“负赘”,仿真器得以勉强完成编译并运行。


3.失败原因:if(j==0) 的分支逻辑破坏了移位寄存器推断,生成了巨大的 MUX 逻辑,导致 RTL 综合或仿真引擎崩溃。

4.移除 static 成功的原因:移除静态属性去掉了复位逻辑的负担,使工具勉强完成了编译,但这只是“治标不治本”,硬件效率依然很低。


5.最佳实践:保持正确代码的写法。不要在流水线循环内部对移位寄存器做复杂的条件初始化,利用输出延迟(j > delay)来自然过滤无效数据。

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

相关文章:

  • HBuilderX彻底卸载指南:深度清理残留文件与配置,解决编译慢、内存溢出问题
  • AI智能体事故追踪:从数据模型到工程落地的全链路实践
  • 零基础读懂 HTTP 与 API:一篇文章打通你的第一次接口调用
  • 双栈实现队列:数据结构转换与摊还时间复杂度解析
  • 【2026年上海寄大件选哪家物流最划算?实测省钱攻略】 - 快递物流资讯
  • 2026年上海旧房翻新:质保期长短写进合同,口头承诺不受法律保护 - 优家闲谈
  • 《走出对话框,迎接工作流——AI Agent赋能桌面自动化》第一章:行业痛点与破局之道
  • C/C++中const关键字与指针、引用的位置关系全解析
  • 辊压成形技术:从原理到实践,掌握金属塑性成形的核心工艺
  • DOTween动画:TweenManager深度解析
  • AI 可以替我读完一本书,但不能替我经历阅读
  • 每天 100 积分,第 7 天 1000:我把 WorkBuddy 签到做成了「全自动」
  • 2026甄选:南京搬家市场中专业团队与高性价比服务公司的务实选择 - 卓企推荐
  • IntelliJ IDEA构建报错java.lang.IllegalArgumentException: MALFORMED排查指南
  • 深入解析x86汇编DIV指令:从整数除法原理到溢出规避实战
  • Windows 10下nvidia-smi命令失效的全面诊断与修复指南
  • 2026 年更新:韶山可靠的短视频获客推广公司哪家靠谱,靠这招,居然让门店客流转手翻了3倍?做实体的都该看看 - 行业推荐官[官方】--
  • 基于scrcpy构建安卓设备矩阵投屏控制中心:原理、架构与实现
  • SpaceMind:相机引导式模态融合如何革新VLM空间推理能力
  • AI总乱改代码?一个规则文件帮你搞定!99%的人都没设置!附万能模板!
  • 医院数字食堂开放平台API设计:HIS对接与数据交换实践
  • Python开发实战:从环境管理到项目分发的全流程命令指南
  • Docker部署达梦数据库字符集冲突:从GBK到GB18030的编码问题解决
  • Windows打印机错误0x00000709:从驱动到权限的全面排查与修复指南
  • OpenClaw会话管理:4种隔离模式与修剪机制详解
  • Mac开发者必备:Homebrew安装配置与高效使用全攻略
  • 2026 年更新:仙桃比较好的MMA彩色防滑供应商哪家**,你见过能让老人小孩再也不打滑的地坪材料吗?看完才知道有多实用-光大生态工程技术 - 行业严选官
  • 《VLA 系列》Human-to-Robot Transfer | 人类视频共训练 | 跨本体涌现迁移 | 论文解析
  • 卡诺电池冷热电联产系统动态建模与优化实践
  • 完全不会写开题报告,有哪些专业的AI写作辅助软件推荐?