VHDL的结构非常适合编写状态机,而且编写方式不唯一,电路的集成也会随着编写的方式而改变。状态机的设计主要用到case when 和if else 两种语句。Case when 用来指定并行的行为,而if then else 用来设计优先度的编码逻辑。 分析状态机有如下特点:
1. 对于状态的描述一般先声明一个枚举数据类型,语句如下:
Type state_type is(idle,tap1,tap2,tap3,tap4);
2. 对于存储当前状态的对象一般用是一个信号,即:
Signal state: state_type;
3. 对于状态机的下一个状态的判断一般是通过对时钟上升沿判断的if then else 语句内嵌
case when 语句
4. 对于状态机的输出则可以用一个条件或者选择信号声明语句,或者再用一个case语句来
实现信号输出。 状态机分为三大类型:
1. Moore状态机:次态=f(现状),输出=f(现状),即输出信号是直接由状态寄存器译码得到 2. Mealy状态机:次态=f(现状,输入),输出=f(现状,输入),即以现时的输入信号结合即
将变成次态的现状编码成信号输出。 3. 混合型状态机
我们用一个序列信号发生器的实例来做练习。(状态机将在以后的很多实例中加以运用,请掌握其编写方法)
序列信号就是一些串行的周期性信号,这些信号在每个循环周期内1和0数码按一定的规则顺序排列。下面所讲解的序列发生器能够按规定输出8位’0’,’1’序列。 代码如下:
逐行解释:
10:清零复位信号,高电平复位清零。
12:序列信号输出。因为是8位的端口,但序列信号是串行的,所以相当于有8路的序列信号,任取一位端口就是一个序列信号输出。
17:用type声明一种枚举类型。共8中状态,每个状态都对应唯一的一种输出,至于在什么状态输出什么信号则由程序决定。
18:定义一个state类型信号量,其初始的状态为s0。
19-26:用constant定义一些常量,这些常量将作为在不同状态时的输出信号。 32-34:清零复位时执行的动作。33,输出为value0,34,状态为s0。
35-65:用case语句实现状态的变换。在上升沿的驱动下,状态从s0->s1->s2->s3->s4->s5->s6->s7->s0循环。61-63,若状态机跑飞,及时将状态置为为s0,这样状态机就能恢复正常了。
其状态机转换图:
仿真波形图:
可任取seq_sig的一位作为序列信号的输出,如若选择seq_sig[7]作为序列信号输出,则为“01000111”,若选择seq_sig[6作为序列信号输出,则为“01000011”。 还可参考串口的发送模块uart_t,串口的接收模块uart_r和spi中的相关操作。