《Verilog设计与验证》中的一章——【如何写好状态机】里面说了状态机有三种写法:
- 用一个时序always块写的,状态跳转和输出都在里面处理。
- 用一个时序always块和一个组合always块写。有两个状态变量——当前状态
CS
和后续状态NS
,组合块里面对NS
进行状态跳转和输出,时序块里是简单的对CS
做时钟同步赋值为NS
。 - 用两个时序always块和一个组合always块写。状态变量也是两个,只是把【2】里面组合块里的输出转到另外的一个时序always块里。
书里对三种写法的评价是:【1】是不推荐的,理由是不利于写大规模状态机、代码不容易规范、不利于时序约束、不利于综合布线;【2】和【3】都是推荐的,简洁度【2】是最高的,但是输出是组合逻辑的,会有毛刺出现。
看了这个之后只觉得自己孤陋寡闻。我之前用的都是写法【1】,没出过什么岔子,这主要还是没有涉及到复杂的状态机。【2】的写法其实我也见到过的,verilog的C-c C-t S
出来的就是这种状态机,项目的代码里面也看到过,当时只是觉得有点奇怪,也没多想。。。水了。。。总的说来还是【3】的写法最完美,比【2】多了点代码但是是没有弊端了。对于有多个输出的情形,【3】必然是最好的选择,只是这个时候的always块就不止是这么多了。
书里提到了“将时序逻辑和组合逻辑分开描述”这样一种代码分格,让我很有感触。这个使用场合其实不局限在状态机了,或者说活用这个的话,很多过程都可以用状态机来解决,这样verilog的抽象能力是不是有有了升级呢?
一直一来我觉得verilog对复杂控制的设计能力很捉鸡,原来是我的状态机水平不行而已。