You're reading an pre-release version of this documentation.
For the latest stable release version, please have a look at master.

寄存器部分赋值(Partially assigned register)

简介

SpinalHDL 会进行检查:当寄存器被条件赋值时,其所有位都必须至少被赋值一次。若某些位未被赋值,可能导致意外的硬件行为,例如生成锁存器或出现不可预测的值。

此错误发生于以下情况:

  • 寄存器在条件块内( when / switch )赋值

  • 寄存器只有部分比特被赋值

  • 该分支上,其他位未被赋值

示例

下面的代码:

class TopLevel extends Component{

  val io = new Bundle {
    val condition = in Bool()
    val result = out UInt( 8 bits )
  }

  val myReg = Reg(UInt( 8 bits ))

  when(io.condition){
    myReg(3 downto 0) := 0xF   // Only lower 4 bits assigned
    // Upper 4 bits are not assigned!
  }

  io.result := myReg
}

会报错:

PARTIALLY ASSIGNED REGISTER (toplevel/myReg :  UInt[8 bits]), unassigned bit mask is 11110000, defined at
***
Source file location of the toplevel/myReg definition via the stack trace
***

修复方法

有以下几种方法可修复此错误:

方法一:完整赋值寄存器

class TopLevel extends Component{

  val io = new Bundle {
    val condition = in Bool()
    val result = out UInt(8 bits)
  }

  val myReg = Reg(UInt( 8 bits ))

  when(io.condition){
    myReg(7 downto 0) := 0x0F   // Assign all 8 bits

  }

  io.result := myReg
}

方法二:显式处理所有位

class TopLevel extends Component{

  val io = new Bundle {
    val condition = in Bool()
    val result = out UInt(8 bits)
  }

  val myReg = Reg(UInt(8 bits))

  when(io.condition){
    myReg(3 downto 0) := 0xF   // Explicitly keep upper bits
    myReg(7 downto 4) := myReg(7 downto 4)

  }

  io.result := myReg
}

方法三:提供默认值

class TopLevel extends Component{

  val io = new Bundle {
    val condition = in Bool()
    val result = out UInt(8 bits)
  }

  val myReg = Reg(UInt(8 bits))

  when(io.condition){
    myReg(3 downto 0) := 0xF
    // Upper bits will retain their value from previous cycle
  }.otherwise {
    myReg := myReg // Explicitly maintain value
  }

  io.result := myReg
}