一、定义
状态机是有限状态自动机的简称,是现实事物运行规则抽象而成的一种数学模型
将电路的全部工作方式,分成几个场景,这些场景的工作方式明显不同,然后将这些场景通过数学模型表示出来
二、分类
1、摩尔Moore状态机
输出只和状态有关而与输入无关
状态表
2、米莉Mealy状态机
输出不仅和状态有关而且和输入有关系
状态表
三、简单举例
人有三个状态健康, 感冒,康复中。
触发的条件有淋雨(t1),吃药(t2),打针(t3),休息(t4)。
所以状态机就是
健康-> (t4) ->健康;
健康-> (t1) ->感冒;
感冒-> (t2) ->康复中;
感冒-> (t3) ->健康;
康复中- (t45->健康,等等。
就是这样状态在不同的条件下跳转到自己或不同状态的图。简单的讲就是状态转换图,如果学过模电的话,对于状态转换图应该比较熟悉。状态转换图如下所示:
上图所示代表,我们现有四个状态,在S0状态下我收到00那么我就跳转到S1状态,如果在S1状态下我收到10那么我们就跳转到S2。如果在S2状态如果收到10就跳转到S0,如果收到00那么就跳转到S3。
四、结构
1、状态寄存器
记忆当前状态机所处的状态——就是我当前是什么状态我就写什么状态,00就表示S1状态,01就表示S2状态。
2、产生下一状态的组合逻辑
根据输入信号和当前状态决定下一状态
3、输出逻辑
当前状态和输入信号决定当前状态的输出
五、标准
1.状态机要安全。
要求我们的状态机要 完备不能进入死循环,特别是不能进入非预知的状态。
2.状态机的设计要满足面积和速度的要求。
要求设计简洁、高效的状态机。
3.状态机的设计要清晰易懂,易维护。
六、四大概念
1、 State 状态
一个状态机至少要包含两个状态。例如自动门,有 open 和 closed 两个状态。
2、 Event 事件
事件就是执行某个操作的触发条件或者口令。对于自动门,“按下开门按钮”就是一个事件。
3、 Action 动作
事件发生以后要执行动作。例如事件是“按开门按钮”,动作是“开门”。编程的时候,一个 Action 一般就对应一个函数。
4、 Transition 变换
也就是从一个状态变化为另一个状态。例如“开门过程”就是一个变换。
七、三段式状态机
三段式状态机一般包含以下三段:当前状态、下一状态和输出。
- 一个always模块采用同步时序的方式描述状态转移
//第一个进程,同步时序always模块,格式化描述次态寄存器迁移到现态寄
存器
always @ (posedge clk or negedge rst_ n)begin
if(!rst_ n)begin
current state <= IDLE:
end
else begin
current state <= next state; //注意,使用的是非阻塞赋值
end
end
- 第二个always采用组合逻辑的方式判断状态转移条件,描述状态转移规律。
//第二个进程,组合逻辑always模块,描述状态转移条件判断
always @ (*)begin //电平触发
case(current_ state)begin
S1:begin
if...begin
next_ state= S2; //阻 塞赋值
else begin
next_ state= S1;
end
end
S2:begin
if...begin
......
default : begin //状态机要完 备
next state= IDLE;
end
endcase
end
- 其它always模块使用同步时序电路来设计每一个状态的输出。
//第三个进程,同步时序always模块,格式化描述寄存器输出
always @ (posedge clk or negedge rst_ n) begin
If(!rst_ n)begin
...//初始化
end
else if(current_ state==S1)begin
out1<= 1'b1; //注意 是非阻塞逻辑
end
else begin
out1 <='"b0;
end
end
注意事项
1.三段always模块中,第一个和第三个always模块是同步时序always,用非阻塞赋值(“<=”);第二个always模块是组合逻辑always模块,用阻塞赋值(“=”)。关于阻塞赋值的含义可查阅资料https://www.cnblogs.com/clover-toeic/p/3755360.html
2.第二部分为组合逻辑always模块,对于always的敏感列表必须采用always@ (*)的方式。
3.第二部分,组合逻辑always模块,里面判断条件一定要包含所有情况!可以用else保证包含完全。
4.需要注意:第二部分case中的条件应该为当前态( current state)。
5.三段式并不是一定要写为3个always块,如果输出更多,就不止3段了。
参考链接
https://www.bilibili.com/video/BV1Mt411i7C8?from=search&seid=3358500003755694759
https://blog.csdn.net/wordwarwordwar/article/details/78509445
https://zhuanlan.zhihu.com/p/47434856
https://baike.so.com/doc/1495045-1580947.html