十二 · 2021年10月26日

兄弟,要几段?

从事逻辑设计的小伙伴对状态机这个词并不陌生,什么两段、三段状态机耳熟能详,摩尔、米利状态机型倒背如流。然而不得不承认的是读别人的RTL代码真的是一件痛苦的事情,那状态机可否更优雅的呈现呢?

状态机那些事儿

做逻辑设计的小伙伴都写过状态机,写法也都是大同小异,照着描述就OK了,看下下面这个状态机设计:

af2e19f2443879c98233cba7cfb9da31.png
功能很简单,手动实现一个Verilog版的状态机并不复杂,无非这么来搞:
188ef09d5eb48fe9b6bedc8b40451a1b.png
这只是一个简单的状态机,读代码的话相对来说还算容易,而当我们状态机较大时状态机的维护和阅读就有点儿费力了。

那么我的状态及能否这么来描述呢?

 title=

是否有一种读伪代码的感觉呢?

做真正的状态描述

很遗憾,上述写法并不是伪代码,而是可生成RTL电路的SpinalHDL代码结构。

在SpinalHDL里,其提供了StateMachine类来管理状态机逻辑:

val myFsm = new StateMachine{

其中提供了下面两个函数:

096a52ae0cb2e6b1790d669ba813a522.png

而针对状态机中的状态,SpinalHDL里封装提供了下面的工具辅助描述:

f173758e3d294407c743e1eb2a750da9.png

基于此,我们便可以方便快捷的去描述状态机,以一种更优雅的方式去实现状态机描述,而对于他人阅读来讲也是相当OK的。

等等,还有更好玩儿的。

在SpinalHDL里,定义了四种可以声明状态的类型:

  • State(基本类型)
  • StateDelay
  • stateFsm
  • stateParallelFsm

一探究竟~

StateDelay

StateDelay新增了一个whenCompleted方法,包含了State的所有属性,而新增的whenCompleted方法中的逻辑内容会在进入该状态延迟指定cycle后进行执行,如下例所示:

val stateG : State = new StateDelay(cyclesCount=40){
  whenCompleted{
    goto(stateH)
  }
}

stateG定义为StateDelay,因此状态机将会在进入该状态10个时钟周期后执行whenCompleted中的内容,即跳转到stateH。

StateFsm

StateFsm主要用于状态机嵌套,允许我们在一个状态机中等待另一个状态机动作的完成。如下例所示:

val stateC = new StateFsm(fsm=internalFsm()){
  whenCompleted{
    goto(stateD)
  }
}
def internalFsm() = new StateMachine {
  val counter = Reg(UInt(8 bits)) init (0)

  val stateA: State = new State with EntryPoint {
    whenIsActive {
      goto(stateB)
    }
  }

  val stateB: State = new State {
    onEntry (counter := 0)
    whenIsActive {
      when(counter === 4) {
        exit()
      }
      counter := counter + 1
    }
  }
}

stateC被声明为StateFsm,因此进入该状态后会执行internalFsm中的内容。等待internalFsm状态机执行结束后,stateC中的whenCompleted中的内容将会被执行,状态跳转至stateD。

StateParallelFsm

相较于StateFsm,StateParallelFsm中允许同时执行多个状态机,等所有状态机都跳转执行完毕后whenCompleted中的内容方会执行:

val stateD = new StateParallelFsm (internalFsmA(), internalFsmB()){
  whenCompleted{
    goto(stateE)
  }
}

这里状态机跳转到stateD后,将会执行internalFsmA、internalFsmB两个状态机,当两个状态机都执行完毕退出时,whenCompleted中的内容将会被执行,跳转至stateE。

写在最后


SpinalHDL里状态机的描述相较于Verilog更具有伪代码般的阅读体验,阅读这种代码对于我们来讲相对更容易理解些,想想维护同事的Verilog代码,是否有很挠头的赶脚~。

当然,在转换成RTL代码时,状态机的样子还是和我们手写的差不多的。

END

作者:玉骐
原文链接:https://mp.weixin.qq.com/s/DkeW\_jxepbQpXX8y2v0JtA
微信公众号:
 title=

推荐阅读

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