如何骗过SpinalHDL生成Latch。
关于Latch
对于熟悉数字电路设计的小伙伴而言,关于Flip-Flop和Latch皆已悉知,而在电路设计里老生常谈的也是不要在设计中使用Latch。在SpinalHDL里,SpinalHDL将会对电路描述是否产生Latch进行检查,若监测到有Latch则会报错。像下面这段代码:
class TopLevel extends Component {
val cond = in(Bool)
val a = UInt(8 bits)
when(cond) {
a := 42
}
}
则会报错:
LATCH DETECTED from the combinatorial signal (toplevel/a : UInt[8 bits]), defined at
***
Source file location of the toplevel/io_a definition via the stack trace
***
而正确的写法应该是:
class TopLevel extends Component {
val cond = in(Bool)
val a = UInt(8 bits)
a := 0
when(cond) {
a := 42
}
}
然而在一些场景里,确实需要Latch(如门控时钟),而SpinalHDL对于Latch又是深恶痛绝的,想要达到效果便只能瞒天过海了~
用错误掩盖错误
经尝试,目前只有下面这种代码可以“骗过”SpinalHDL生成器生成Latch:
case class latchDemo() extends Component{
val a=in UInt(2 bits)
val b=out UInt(8 bits)
b.noCombLoopCheck
when(a<1){
b:=3
}otherwise{
b:=b
}
}
生成的代码在综合时会提示有Latch生成:
这里之所以能够生成Latch是利用了SpinalHDL另外一项检查:Combinatorial loop。这里我们声明b为“Wire”类型,而在otherwise里我们将b赋值给自己,这里将会产生Combinatorial loop,正常情况下SpinalHDL会检测到这种错误并报错,但在上述代码里通过“noCombLoopCheck”让编译器放弃对信号b Combinatorial loop的检查,从而能够生成一个Latch,即用一种错误掩盖了另一个错误。
写在最后
不要在代码里使用Latch,尤其FPGA设计!!!(ASIC我就不知道了)
☆ END ☆
作者:玉骐
原文链接:https://mp.weixin.qq.com/s/O6RNZ1G5Oy5UTwG5WEBjEw
微信公众号:
推荐阅读
更多SpinalHDL技术干货请关注Spinal FPGA专栏。