网上看到许多讲三段式状态机写法的,大多数的格式都一样,如下
//第一个进程,同步时序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; //阻塞赋值
...
endcase
end
//第三个进程,同步时序always模块,格式化描述次态寄存器输出
always @ (posedge clk or negedge rst_n)
...//初始化
case(next_state)
S1:
out1 <= 1'b1; //注意是非阻塞逻辑
S2:
out2 <= 1'b1;
default:... //default的作用是免除综合工具综合出锁存器。
endcase
end
问题来了:第三个always @ (posedge clk or negedge rst_n),但是里面的case用的是next_state条件,ISE11.2中综合总是会报错无法通过,如果将第三个always中敏感变量改为next_state就可以通过综合。但是问题是第三个always中用next_state驱动就不是每个时钟周期下都有效,有些场合下又需要每个时钟都进入状态赋值,那应该怎么办呢?为什么大家都说第三个always中的敏感变量用clk和rst是可以的呢?