## 组合环(Combinatorial loop) ### 一、简介 SpinalHDL会检查设计中没有组合逻辑环的存在。 ### 二、例子 下述代码: ```Scala 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]) ``` 可能的修复方式为: ```Scala 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检测组合逻辑环的策略是悲观的, 因此可能出现误报的情况。假如发生了误报, 用户可以无效化对某一信号的环检测, 如: ```Scala class TopLevel extends Component { val a = UInt(8 bits) a := 0 a(1) := a(0) // 因为这行而发生了误报 } ``` 可以被修复为: ```Scala class TopLevel extends Component { val a = UInt(8 bits).noCombLoopCheck a := 0 a(1) := a(0) } ``` 还应该指出, 诸如(a(1):= a(0))这样的赋值会使Verilator等工具无法匹配。在这种情况下, 使用Vec(Bool, 8)可能会更好。