组合环(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
}
三、假阳性(false-positives)
SpinalHDL检测组合逻辑环的策略是悲观的, 因此可能出现误报的情况。假如发生了误报, 用户可以无效化对某一信号的环检测, 如:
class TopLevel extends Component {
val a = UInt(8 bits)
a := 0
a(1) := a(0) // 因为这行而发生了误报
}
可以被修复为:
class TopLevel extends Component {
val a = UInt(8 bits).noCombLoopCheck
a := 0
a(1) := a(0)
}
还应该指出, 诸如(a(1):= a(0))这样的赋值会使Verilator等工具无法匹配。在这种情况下, 使用Vec(Bool, 8)可能会更好。