You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Chisel中SInt*SInt变UInt*SInt:卷积加速器FIR模块计算异常

卷积加速器FIR模块集成后符号乘法异常排查与解决

问题现象

  • 基于Chisel开发卷积神经网络加速器,卷积单元采用3个一维FIR滤波器实现
  • FIR模块独立测试时结果正确,但集成到DLA后出现乘法运算异常:原本应为SInt*SInt的运算被错误处理为UInt*SInt,例如输入-29(8位SInt)被当作227(8位UInt)参与乘法,导致计算结果完全错误
  • 所用FIR模块的Chisel实现代码如下:
class OneDemConvGen(wgh_num:Int=3, ipt_wid:Int = 8, wgh_wid:Int=8, psum_wid:Int=32) extends Module{
  val io = IO(new Bundle() {
    val in = Input(SInt(ipt_wid.W))
    val weights = Input(Vec(wgh_num, SInt(wgh_wid.W)))

    val psum = Output(SInt(psum_wid.W))
  })

  val muls = Seq.fill(wgh_num)(Wire(SInt(psum_wid.W))).zip(io.weights).map({case (p, w) => p := io.in*w; p})
  val sum = muls.fold(0.S)((a, b) => RegNext(a+b, 0.S))
  io.psum := sum
}

可能原因

  1. 顶层信号类型不匹配:DLA顶层连接FIR模块io.in的信号被错误定义为UInt,或连接时发生了隐式类型转换。Chisel中UInt赋值给SInt会直接按位复制,符号位被当作数据位,导致有符号数被解析为无符号数。
  2. 信号路径的位宽处理错误:输入信号在传递到FIR模块前,被执行了无符号扩展(zext)或截断操作,破坏了原有的符号信息。
  3. 累加环节的类型隐式转换:集成后累加路径中混入UInt类型信号,导致RegNext处理时出现类型异常。

解决方案

  1. 检查顶层信号连接:确认DLA顶层中传递给FIRio.in的信号类型为SInt(ipt_wid.W)。若顶层使用UInt信号,需显式转换为SInt:
    // 示例:将UInt信号转换为SInt后连接到FIR输入
    firModule.io.in := topUIntSignal.asSInt()
    
  2. 修正信号路径的位宽扩展方式:追踪输入信号到FIR模块的完整路径,将所有无符号扩展(zext)替换为符号扩展(sext),确保符号位正确保留。
  3. 显式指定乘法操作的符号类型:在乘法语句中显式扩展操作数的位宽并指定符号类型,避免隐式转换问题:
    // 修改乘法语句,确保按有符号位宽处理
    p := (io.in.sext(psum_wid.W) * w.sext(psum_wid.W)).asSInt
    
  4. 明确累加器的位宽与类型:将fold的初始值显式指定位宽,确保类型一致性:
    val sum = muls.fold(0.S(psum_wid.W))((a, b) => RegNext(a+b, 0.S(psum_wid.W)))
    

验证步骤

  • 抓取集成后FIR模块io.in的波形,确认其值是否为预期的有符号数(例如-29的补码是否被正确识别为SInt)
  • 检查DLA中是否存在对输入信号的截取、拼接等操作导致符号位丢失

内容的提问来源于stack exchange,提问作者Shuo Ran

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 21:57:48