格雷码的特点是任意相邻两个数据之间只有一位不同,这一特点使得采用格雷码表示状态值的状态机,可以在很大程度上消除由延时引起的过渡状态.将例1改进之后的程序如例2.
例2 采用格雷码表示状态值的状态机.
library ieee;
use ieee.std_logic_1164 all;
entity example is
port(clk:in std_logic;
mach_input:in std_logic;
mach_outputs:out std_logic_vector(0 to 1));
end example;
architecture behave of example is
constant st0:std_logic_vector(0 to 1):="00";
constant st1 :std_logic_vector(0 to 1):="01";
constant st2:std_logic_vector(0 to 1):="11";
constant st3:std_logic_vector(0 to 1):="10";
signal current_state,next_state:std_logic
vector(0to1);
begin
……
endbebave;
采用该方法,寄存器的状态在相邻状态之间跳转时,只有一位变化,产生过渡状态的概率大大降低.但是当一个状态到下一个状态有多种转换路径时,就不能保证状态跳转时只有一位变化,这样将无法发挥格雷码的特点.
2.3 定义“ONEHOT”风格的状态值编码
虽然VHDL语言的目标之一是远离硬件,但是到目前为止并没有完全实现,所以VHDL程序在针对不同的器件综合时,仍然会有很大差异.特别是FPGA器件,当我们采用格雷表示状态值,描述一个简单的状态机时,就可能出现不稳定结果.在针对FPGA器件写程序时,我们可以将状态值定义为“ONEHOT”风格的状态码,将上例稍作修改,见例3.
例3 采用“ONEHOT”编码的状态机
library ieee;
use ieee std_logic_1164.all;
entity example is
port(clk:in std_logic;
mach_input:in std_logic;
mach_outputs:out std_logic_vector(0 to 1));
endexample;
architecture behave of example is
constant st0:std_logic_vector(0 to 3):="0001";
constant st1:std_logic_vector(0 to 3):="0010";
constant st2:std_logic_vector(0 to 3):="0100";
constant st3:std_logic_vector(0 to 3):="1000";
signal current_state,next_state:std_logic vector(0 to 3);
begin
……
对FLEX10K系列器件综合后的仿真结果如图3所示.
图3 采用“ONEHOT”编码的状态机综合后的波形
如图3所示,在输入信号稳定以后,状态机的输出信号也稳定下来,定义这种风格的状态码来设计基于FPGA的状态机是一种不错的选择.
然而在输入信号跳变时,电路还是会出现不稳定现象.此时我们已不能只从状态值编码方式寻找解决方法.回头看看状态机的原理框图不难发现:状态寄存器的输出值是必须符合建立保持时间约束关系的.在上述状态机中虽然采用了各种不同的编码方式但都不能彻底消除这种过渡状态,我们将电路结构稍作改进,一种更好的结构如图4所示.这种结构的状态机可有效抑制过渡状态的出现.这是因为输出寄存器只要求状态值在时钟的边沿稳定.将上述程序改进之后的程序如图4.
……
architecture behave of example1is
type states is(st0,st1,st2,st3); 定义states为枚举类型
signal current_state,next_state:states;
signal temp:std_logic_vector(0 to 1); 定义一个信号用于引入输出寄存器
begin
state_change:process(clk) --状态改变进程
begin
wait until clk'eventandclk='1';
current_state<=next_state;
mach_outputs<=temp;
end process state_change;
……
图5 改进后的状态机综合后的波形
显然这种结构的状态机稳定性优于一般结构的状态机,但是它占用的逻辑资源更多,电路的速度可能下降,在设计时应综合考虑.
另外,为防止电路进入非法状态,可以设计成自启动结构,在VHDL描述的状态机中添加一个“when others”语句是行之有效的.
3 选择不同编码方式、不同结构的状态机的技巧
3.1 针对不同结构器件选择不同编码风格
基于乘积项结构的CPLD器件适合于设计全编码状态机,在全编码状态机中采用格雷码表示状态值.这对于逻辑资源较少的器件是一种不错的优化方法.
基于查找表结构的FPGA器件适合于设计成“ONEHOT”方式编码的状态机,这种结构状态机只用一位二进制数表示一个状态,可提高稳定性,但要占用更多的逻辑资源.
3.2 根据逻辑资源大小选择状态机结构
当设计的状态机状态转换次序出现多路径时,采用格雷码表示状态值不会有任何作用,因为此时有些相邻状态不只是一位不同.在逻辑资源允许的情况下,可以考虑在状态机后级增加一级输出寄存器,可确保输出不产生毛刺,使状态机输出稳定可靠的信号.
评论
查看更多