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_outputsut 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;
……