CLK :IN STD_LOGIC;
D_OUT :OUT STD_LOGIC_VECTOR(7 DOWNTO 0); a,b:IN STD_LOGIC_VECTOR(3 DOWNTO 0); y:BUFFER STD_LOGIC_VECTOR(7 DOWNTO 0)); END mul4;
ARCHITECTURE behave OF mul4 IS
signal c0,c1,c2,c3:STD_LOGIC_VECTOR(3 DOWNTO 0); SIGNAL Q: STD_LOGIC_VECTOR(7 DOWNTO 0); BEGIN
PROCESS(a,b,c0,c1,c2,c3,clk) BEGIN
IF b(0)='0' THEN c0<=\ELSE c0<=a; end if;
IF b(1)='0' THEN c1<=\ELSE c1<=a; end if;
IF b(2)='0' THEN c2<=\ELSE c2<=a; end if;
IF b(3)='0' THEN c3<=\ELSE c3<=a; end if;
y<=(\ IF CLK'EVENT AND CLK = '1' THEN Q(0)<=y(0); FOR I IN 1 TO 7 LOOP Q(I) <= y(I-1); END LOOP; END IF;
D_OUT <= Q; END PROCESS; END behave;
仿真结果:
图5-2加D触发器后仿真结果
5.2在有限状态机的基础上采用时钟同步信号
在有限状态机的基础上采用时钟同步信号,即把时钟信号引入组合进程。状态机每一个输出信号都经过附加的输出寄存器,并由时钟信号同步,因而保证了输出信号没有毛刺。这种方法存在一些弊端:由于增加了输出寄存器,硬件开销增大,这对于一些寄存器资源较少的目标芯片是不利的,从状态机的状态位到达输出需要经过两级组合逻辑,这就限制了系统时钟的最高工作频率,由于时钟信号将输出加载到附加的寄存器上,所以在输出端得到信号值的时间要比状态的变化延时一个时钟周期[10]。
例如Mealy型状态机,其主要程序如下: LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL; ENTITY MEALY1 IS
PORT ( CLK ,DATAIN,RESET : IN STD_LOGIC;
Q : OUT STD_LOGIC_VECTOR(4 DOWNTO 0)); END MEALY1;
ARCHITECTURE behav OF MEALY1 IS
TYPE states IS (st0, st1, st2, st3,st4); SIGNAL STX : states ;
BEGIN
COMREG : PROCESS(CLK,RESET) BEGIN --决定转换状态的进程 IF RESET ='1' THEN STX <= ST0;
ELSIF CLK'EVENT AND CLK = '1' THEN CASE STX IS WHEN st0 => IF DATAIN = '1' THEN STX <= st1; END IF; WHEN st1 => IF DATAIN = '0' THEN STX <= st2; END IF;
WHEN st2 => IF DATAIN = '1' THEN STX <= st3; END IF;
WHEN st3=> IF DATAIN = '0' THEN STX <= st4; END IF; WHEN st4=> IF DATAIN = '1' THEN STX <= st0; END IF; WHEN OTHERS => STX <= st0; END CASE ; END IF;
END PROCESS COMREG ;
COM1: PROCESS(STX,DATAIN) BEGIN --输出控制信号的进程 CASE STX IS
WHEN st0 => IF DATAIN = '1' THEN Q <= \ ELSE Q<=\
WHEN st1 => IF DATAIN = '0' THEN Q <= \
ELSE Q<=\ WHEN st2 => IF DATAIN = '1' THEN Q <= \ ELSE Q<=\
WHEN st3=> IF DATAIN = '0' THEN Q <= \ ELSE Q<=\
WHEN st4=> IF DATAIN = '1' THEN Q <= \
ELSE Q<=\ WHEN OTHERS => Q<=\ END CASE ;
END PROCESS COM1 ; END behav;
其时序仿真波形如图
5-3所示:
图5-3 Mealy型有限状态机的仿真时序图
不难看出有毛刺现象,采用时钟同步信号,将输出的Q值由时钟信号锁存后在输出,改进后的Mealy型状态机,其主要程序如下: LIBRARY IEEE; --MEALY FSM USE IEEE.STD_LOGIC_1164.ALL; ENTITY MEALY2 IS
PORT ( CLK ,DATAIN,RESET : IN STD_LOGIC; Q : OUT STD_LOGIC_VECTOR(4 DOWNTO 0)); END MEALY2;
ARCHITECTURE behav OF MEALY2 IS
TYPE states IS (st0, st1, st2, st3,st4); SIGNAL STX : states ;
SIGNAL Q1 : STD_LOGIC_VECTOR(4 DOWNTO 0); BEGIN
COMREG : PROCESS(CLK,RESET) --决定转换状态的进程 BEGIN
IF RESET ='1' THEN STX <= ST0; ELSIF CLK'EVENT AND CLK = '1' THEN CASE STX IS
WHEN st0 => IF DATAIN = '1' THEN STX <= st1; END IF;
WHEN st1 => IF DATAIN = '0' THEN STX <= st2; END IF; WHEN st2 => IF DATAIN = '1' THEN STX <= st3; END IF;
WHEN st3=> IF DATAIN = '0' THEN STX <= st4; END IF; WHEN st4=> IF DATAIN = '1' THEN STX <= st0; END IF; WHEN OTHERS => STX <= st0; END CASE ; END IF;
END PROCESS COMREG ;
COM1: PROCESS(STX,DATAIN,CLK) --输出控制信号的进程 VARIABLE Q2 : STD_LOGIC_VECTOR(4 DOWNTO 0); BEGIN CASE STX IS
WHEN st0=> IF DATAIN='1' THEN Q2 :=\ WHEN st1=> IF DATAIN='0' THEN Q2 :=\ELSE Q2:=\END IF; WHEN st2=> IF DATAIN='1' THEN Q2 :=\ELSE Q2:=\END IF; WHEN st3=> IF DATAIN='0' THEN Q2 :=\ELSE Q2:=\END IF;
WHEN st4=> IF DATAIN='1' THEN Q2 :=\ELSE Q2:=\END IF; WHEN OTHERS => Q2:=\ END CASE ;
IF CLK'EVENT AND CLK = '1' THEN Q1<=Q2;
END IF;
END PROCESS COM1 ; Q <= Q1 ; END behav;
其时序仿真波形如图5-4所示,改进后毛刺不复存在。
图5-4 改进后Mealy型有限状态机的仿真时序图
5.3直接把状态机的状态码作为输出信号
直接把状态机的状态码作为输出信号,即采用状态码直接输出型状态机, 使状态和输出信号一致,使得输出译码电路被优化掉了,因此不会出现竞争冒险。这种方案,占用芯片资源少,信号与状态变化同步,因此速度快,是一种较优方案。但在设计过程中对状态编码时可能增加状态向量,出现多余状态。虽然可用CASE语句中WHENOTHERS来安排多余状态,但有时难以有效控制多余状态,运行时可能会出现难以预料的情况。因此它适用于状态机输出信号较少的场合[11]。
若对AD0809的采样控制采用状态码直接输出型状态机方案,其程序如下: LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL; ENTITY AD0809 IS
PORT (D : IN STD_LOGIC_VECTOR(7 DOWNTO 0); CLK ,EOC : IN STD_LOGIC;
ALE, START, OE, ADDA : OUT STD_LOGIC; c_state : OUT STD_LOGIC_VECTOR(4 DOWNTO 0); Q : OUT STD_LOGIC_VECTOR(7 DOWNTO 0)); END AD0809;
ARCHITECTURE behav OF AD0809 IS
相关推荐: