组合逻辑环(Combinatorial loop)
简介
SpinalHDL将检查设计中是否存在组合逻辑环。
示例
下面的代码:
class TopLevel extends Component {
val a = UInt(8 bits) // PlayDev.scala line 831
val b = UInt(8 bits) // PlayDev.scala line 832
val c = UInt(8 bits)
val d = UInt(8 bits)
a := b
b := c | d
d := a
c := 0
}
会出现:
COMBINATORIAL LOOP :
Partial chain :
>>> (toplevel/a : UInt[8 bits]) at ***(PlayDev.scala:831) >>>
>>> (toplevel/d : UInt[8 bits]) at ***(PlayDev.scala:834) >>>
>>> (toplevel/b : UInt[8 bits]) at ***(PlayDev.scala:832) >>>
>>> (toplevel/a : UInt[8 bits]) at ***(PlayDev.scala:831) >>>
Full chain :
(toplevel/a : UInt[8 bits])
(toplevel/d : UInt[8 bits])
(UInt | UInt)[8 bits]
(toplevel/b : UInt[8 bits])
(toplevel/a : UInt[8 bits])
一个可能的修复方式是:
class TopLevel extends Component {
val a = UInt(8 bits) // PlayDev.scala line 831
val b = UInt(8 bits) // PlayDev.scala line 832
val c = UInt(8 bits)
val d = UInt(8 bits)
a := b
b := c | d
d := 42
c := 0
}
误报
SpinalHDL检测组合逻辑环的算法可能是悲观的,并且可能会给出误报。如果出现误报,您可以手动禁用对某一信号的逻辑环的检查,如下所示:
class TopLevel extends Component {
val a = UInt(8 bits)
a := 0
a(1) := a(0) // False positive because of this line
}
可以通过以下方式修复:
class TopLevel extends Component {
val a = UInt(8 bits).noCombLoopCheck
a := 0
a(1) := a(0)
}
还应该指出,诸如 (a(1) := a(0))
之类的赋值可能会使一些工具如 Verilator 无法适配。在这种情况下,使用 Vec(Bool(), 8)
可能更好。