十二 · 2021年11月10日

如何“千辛万苦”地生成一个Latch

如何骗过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生成:

ded022522c0f8e79c7c032649c0396aa.png

这里之所以能够生成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
微信公众号:
 title=

推荐阅读

更多SpinalHDL技术干货请关注Spinal FPGA专栏。
推荐阅读
关注数
1581
内容数
133
用SpinalHDL提升生产力
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息