FSM的正确写法

《Verilog设计与验证》中的一章——【如何写好状态机】里面说了状态机有三种写法:

  1. 用一个时序always块写的,状态跳转和输出都在里面处理。
  2. 用一个时序always块和一个组合always块写。有两个状态变量——当前状态CS和后续状态NS,组合块里面对NS进行状态跳转和输出,时序块里是简单的对CS做时钟同步赋值为NS
  3. 用两个时序always块和一个组合always块写。状态变量也是两个,只是把【2】里面组合块里的输出转到另外的一个时序always块里。

书里对三种写法的评价是:【1】是不推荐的,理由是不利于写大规模状态机、代码不容易规范、不利于时序约束、不利于综合布线;【2】和【3】都是推荐的,简洁度【2】是最高的,但是输出是组合逻辑的,会有毛刺出现。

看了这个之后只觉得自己孤陋寡闻。我之前用的都是写法【1】,没出过什么岔子,这主要还是没有涉及到复杂的状态机。【2】的写法其实我也见到过的,verilog的C-c C-t S出来的就是这种状态机,项目的代码里面也看到过,当时只是觉得有点奇怪,也没多想。。。水了。。。总的说来还是【3】的写法最完美,比【2】多了点代码但是是没有弊端了。对于有多个输出的情形,【3】必然是最好的选择,只是这个时候的always块就不止是这么多了。


书里提到了“将时序逻辑和组合逻辑分开描述”这样一种代码分格,让我很有感触。这个使用场合其实不局限在状态机了,或者说活用这个的话,很多过程都可以用状态机来解决,这样verilog的抽象能力是不是有有了升级呢?

一直一来我觉得verilog对复杂控制的设计能力很捉鸡,原来是我的状态机水平不行而已。