寄存器部分赋值(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
}