
嵌入式NPU原理基础:NPU的编译器开发——RTL仿真与软件仿真对比去年做一款轻量级NPU的编译器时,遇到一个诡异的bug:模型在软件仿真上跑出95%的精度,烧到FPGA上直接掉到62%。排查了三天,最后发现是卷积层的量化参数在RTL仿真和软件仿真之间差了1个bit的截断位置。这个经历让我意识到,搞NPU编译器开发,光懂算法和编译器没用,必须把RTL仿真和软件仿真这两套工具链焊死在脑子里。一个真实案例:那个让我熬夜三天的截断bug先说说那个bug的细节。我们的NPU支持int8量化,卷积计算单元内部有40bit累加器,最后要截断回8bit输出。软件仿真里,我按照“四舍五入+饱和钳位”的方式实现了截断逻辑,跑通了所有测试用例。但RTL仿真时,硬件团队告诉我:他们用的是“向零取整+溢出饱和”,而且饱和阈值比软件仿真少了1个LSB。问题出在哪?软件仿真里我写的是round(x),RTL里用的是trunc(x + 0.5)。看起来一样,但处理负数时完全不同。比如-3.5,round是-4,trunc+0.5是-3。这种差异在单层卷积里可能只差1个bit,但经过5层卷积后,误差累积直接让分类结果从“猫”变成了“狗”。更坑的是,软件仿真里我用了float模拟int8计算,RTL仿真里是纯定点数。float的舍入行为跟定点数根本不一样——float的尾数位是23bit,定点数只有8bit,舍入误差的分布特性完全不同。这个坑,教科书上不会写,只有被烧过FPGA的人才知道。RTL仿真:硬件工程师的“