此箫非彼箫,不竹不丝不石。
肉音别自唔咿。
流苏瑟瑟纱垂,辨不出宫商角徵。
一点樱桃欲绽,纤纤十指频移。
课吞添吐两情痴,不觉悟灵犀味美
推荐小说《回到明朝当王爷》,也有动漫,但小说改国漫通病,小说中杀伐果断人设极好的男主,到了动漫里就变成犹犹豫豫优柔寡断的废材,参见《元龙》。
本文作为SpinalHDL学习笔记第十二篇,记录使用SpinalHDL一些代码错误的修复方法。
SpinalHDL学习笔记总纲链接如下:
目录:
11.作用域违例 (Scope violation)
12.Spinal 无法克隆类 (Spinal can’t clone class)
13.未赋值的寄存器 (Unassigned register)
14.无法访问的 is 语句 (Unreachable is statement)
15.位宽不匹配 (Width mismatch)
11.作用域违例 (Scope violation)
SpinalHDL 将会检查有没有信号会在超出其定义的作用域之外被赋值使用。这个错误不容易触发,因为它需要一些特定的元硬件描述技巧。
示例:
class TopLevel extends Component {
val cond = Bool()
var tmp : UInt = null
when(cond) {
tmp = UInt(8 bits)
}
tmp := U"x42"
}
会报错:
SCOPE VIOLATION : (toplevel/tmp : UInt[8 bits]) is assigned outside its␣
,→declaration scope at
***
Source file location of the tmp := U"x42" via the stack trace
***
一个可能的修复方法是:
class TopLevel extends Component {
val cond = Bool()
var tmp : UInt = UInt(8 bits)
when(cond) {
}
tmp := U"x42"
}
12.Spinal 无法克隆类 (Spinal can’t clone class)
当 SpinalHDL 想要通过 cloneOf 函数创建一个新的数据类型实例,但做不到这一点时,就会出现此错误。出现这种情况的原因几乎都是因为它无法检索 Bundle 的构造参数。
示例1:
// cloneOf(this) isn't able to retrieve the width value that was used to construct␣
,→itself
class RGB(width : Int) extends Bundle {
val r, g, b = UInt(width bits)
}
class TopLevel extends Component {
val tmp = Stream(new RGB(8)) // Stream requires the capability to cloneOf(new␣
,→RGB(8))
}
会报错:
*** Spinal can't clone class spinal.tester.PlayDevMessages$RGB datatype
*** You have two way to solve that :
*** In place to declare a "class Bundle(args){}", create a "case class Bundle(args)
,→{}"
*** Or override by your self the bundle clone function
***
Source file location of the RGB class definition via the stack trace
***
一个可能的修复方法是:
case class RGB(width : Int) extends Bundle {
val r, g, b = UInt(width bits)
}
class TopLevel extends Component {
val tmp = Stream(RGB(8))
}
示例2:
case class Xlen(val xlen: Int) {}
case class MemoryAddress()(implicit xlenConfig: Xlen) extends Bundle {
val address = UInt(xlenConfig.xlen bits)
}
class DebugMemory(implicit config: Xlen) extends Component {
val io = new Bundle {
val inputAddress = in(MemoryAddress())
}
val someAddress = RegNext(io.inputAddress) // -> ERROR␣
,→*****************************
}
会报错:
[error] *** Spinal can't clone class debug.MemoryAddress datatype
在这种情况下,一种解决方案是覆盖克隆函数以传递隐式参数:
case class MemoryAddress()(implicit xlenConfig: Xlen) extends Bundle {
val address = UInt(xlenConfig.xlen bits)
override def clone = MemoryAddress()
}
Note:我们需要克隆的是硬件的单元,而不是最终在其中赋值的值。
13.未赋值的寄存器 (Unassigned register)
SpinalHDL 将检查所有影响设计的寄存器是否已在某处被赋值。
示例:
class TopLevel extends Component {
val result = out(UInt(8 bits))
val a = Reg(UInt(8 bits))
result := a
}
会报错:
UNASSIGNED REGISTER (toplevel/a : UInt[8 bits]), defined at
***
Source file location of the toplevel/a definition via the stack trace
***
一个可能的修复方法是:
class TopLevel extends Component {
val result = out(UInt(8 bits))
val a = Reg(UInt(8 bits))
a := 42
result := a
}
只有初始化 (init) 的寄存器
在某些情况下,由于设计参数化,生成一个没有赋值而只有 init 语句的寄存器可能是有意义的。
示例:
class TopLevel extends Component {
val result = out(UInt(8 bits))
val a = Reg(UInt(8 bits)) init(42)
if(something)
a := somethingElse
result := a
}
会报错:
UNASSIGNED REGISTER (toplevel/a : UInt[8 bits]), defined at
***
Source file location of the toplevel/a definition via the stack trace
***
要修复这个问题,如果寄存器有一个 init 语句但没有赋值,你可以让 SpinalHDL 将该未赋值的寄存器转换为组合逻辑:
class TopLevel extends Component {
val result = out(UInt(8 bits))
val a = Reg(UInt(8 bits)).init(42).allowUnsetRegToAvoidLatch
if(something)
a := somethingElse
result := a
}
14.无法访问的 is 语句 (Unreachable is statement)
SpinalHDL 将确保 switch 中的所有 is 语句均可访问。
示例:
class TopLevel extends Component {
val sel = UInt(2 bits)
val result = UInt(4 bits)
switch(sel) {
is(0){ result := 4 }
is(1){ result := 6 }
is(2){ result := 8 }
is(3){ result := 9 }
is(0){ result := 2 } // Duplicated is statement!
}
}
会报错:
UNREACHABLE IS STATEMENT in the switch statement at
***
Source file location of the is statement definition via the stack trace
***
一个可能的修复方法是:
class TopLevel extends Component {
val sel = UInt(2 bits)
val result = UInt(4 bits)
switch(sel) {
is(0){ result := 4 }
is(1){ result := 6 }
is(2){ result := 8 }
is(3){ result := 9 }
}
}
15.位宽不匹配 (Width mismatch)
SpinalHDL 将检查赋值左侧和右侧的运算操作和信号具有相同的位宽。
赋值示例:
class TopLevel extends Component {
val a = UInt(8 bits)
val b = UInt(4 bits)
b := a
}
会报错:
WIDTH MISMATCH on (toplevel/b : UInt[4 bits]) := (toplevel/a : UInt[8 bits]) at
***
Source file location of the OR operator via the stack trace
***
一个可能的修复方法是:
class TopLevel extends Component {
val a = UInt(8 bits)
val b = UInt(4 bits)
b := a.resized
}
运算操作示例:
class TopLevel extends Component {
val a = UInt(8 bits)
val b = UInt(4 bits)
val result = a | b
}
会报错:
WIDTH MISMATCH on (UInt | UInt)[8 bits]
- Left operand : (toplevel/a : UInt[8 bits])
- Right operand : (toplevel/b : UInt[4 bits])
at
***
Source file location of the OR operator via the stack trace
***
一个可能的修复方法是:
class TopLevel extends Component {
val a = UInt(8 bits)
val b = UInt(4 bits)
val result = a | (b.resized)
}
标签:下篇,修复,val,SpinalHDL,UInt,result,extends,bits,class
From: https://blog.csdn.net/m0_59092412/article/details/140334792