Bless_Bigo

状态机模板(转青创科技)

0
阅读(1772)

在用Verilog编写状态机时,建议分为三个always段完成。

三段式建模描述FSM的状态机输出时,只需指定case敏感表为次态寄存器, 然后直接在每个次态的case分支中描述该状态的输出即可,不用考虑状态转移条件。 

三段式描述方法虽然代码结构复杂了一些,但是换来的优势是:使FSM做到了同步寄存器输出,消除了组合逻辑输出的不稳定与毛刺的隐患,而且更利于时序路径分组,一般来说在FPGA/CPLD等可编程逻辑器件上的综合与布局布线效果更佳。

示列如下:

//第一个进程,同步时序always模块,格式化描述次态寄存器迁移到现态寄存器

always @ (posedge clk or negedge rst_n) //异步复位

if(!rst_n)

current_state <= IDLE;

else

current_state <= next_state;//注意,使用的是非阻塞赋值

//第二个进程,组合逻辑always模块,描述状态转移条件判断

always @ (current_state)   //电平触发,现态寄存器为敏感信号

begin

    next_state = x; //要初始化,使得系统复位后能进入正确的状态

//对次态寄存器进行阻塞赋值

    case(current_state)

S1: if(...)

        next_state = S2; //阻塞赋值

     S2:if()

next_state = S3. //阻塞赋值

………….

    endcase

end 

//第三个进程,同步时序always模块,格式化描述次态寄存器输出

always @ (posedge clk or negedge rst_n)//异步复位

begin

...//初始化

case(next_state) //次态寄存器作为CASE后的表达式

S1:

     out1 <= 1'b1; //对输出进行赋值,注意是非阻塞逻辑

S2:

    out2 <= 1'b1;

………..

default:...   //default的作用是免除综合工具综合出锁存器。

endcase

end

 

有几个地方需要再注意一下:

1. 注意三个进程中使用的赋值方式:只有第二个进程中用阻塞赋值,其他的地方都用非阻塞赋值

2. 注意两个进程的case表达式:第二个进程用current_state作为表达式,第三个进程用next_state作为表达式。

这个三段式并不是说没碰状态机就需要这么写,当状态机比较小时就没有这个必要这样麻烦的去写。当然,三段式这种写法是不错的习惯,刚开始可能不太习惯,多练习,多琢磨,你就习惯了。