如何解决组合逻辑,输出反馈到输入,形成一个循环?

时间:2013-11-02 22:13:31

标签: loops vhdl fsm

我在FSM的代码中有这个警告:

WARNING:Xst:2170 - Unit P22_MustangSecuentialTailLight_Structural : the following signal(s) form a combinatorial loop: Lights<5>, U1/next_state_cmp_eq0000, next_state_int<0>, pres_state_int<0>.

WARNING:Xst:2170 - Unit P22_MustangSecuentialTailLight_Structural : the following signal(s) form a combinatorial loop: Lights<4>, next_state_int<1>, pres_state_int<1>.

WARNING:Xst:2170 - Unit P22_MustangSecuentialTailLight_Structural : the following signal(s) form a combinatorial loop: next_state_int<2>, U1/next_state_cmp_eq0003, Lights<3>, pres_state_int<2>.

WARNING:Xst:2170 - Unit P22_MustangSecuentialTailLight_Structural : the following signal(s) form a combinatorial loop: next_state_int<3>, pres_state_int<4>, U1/next_state_cmp_eq0013, pres_state_int<3>, Lights<2>, next_state_int<4>.

它用于代码中的循环,即我的图enter image description here

的图像

但是,更新下一个状态逻辑块需要嵌入信号(pres_state_int)。代码:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use work.States.all;

entity P22_MustangSecuentialTailLight_Structural is
    Port  ( Lturn     : in   STD_LOGIC;
           Rturn     : in   STD_LOGIC;
           Hazard    : in   STD_LOGIC;
           Rst       : in   STD_LOGIC;
              Break     : in   STD_LOGIC;
           Clk100MHz : in   STD_LOGIC;
           Lights    : out  STD_LOGIC_VECTOR (5 downto 0));
end P22_MustangSecuentialTailLight_Structural;

architecture Behavioral of P22_MustangSecuentialTailLight_Structural is

    component NextStateLogic
        port ( 
                BLRH       : in   STD_LOGIC_VECTOR (3 downto 0); 
                pres_state : in   STD_LOGIC_VECTOR (4 downto 0);
                next_state : out  STD_LOGIC_VECTOR (4 downto 0));
        end component;

    component CurrentStateRegister
        port ( 
                pres_state_b : out   STD_LOGIC_VECTOR (4 downto 0);
                next_state_b : in  STD_LOGIC_VECTOR (4 downto 0);
                Rst          : in STD_LOGIC;
                Clk          : in STD_LOGIC );
        end component;

    component OutputLogic
        port ( 
                pres_state_c : in   STD_LOGIC_VECTOR (4 downto 0);
                Lights     : out  STD_LOGIC_VECTOR (5 downto 0));
        end component;  

    component Clk1Hz
        port (
              Rst       : in    STD_LOGIC;
           Clk_in    : in    STD_LOGIC;
           Clk_out   : out   STD_LOGIC);
    end component;

    --Embedded signal declaration
    signal LRH_int        : STD_LOGIC_VECTOR (3 downto 0);
    signal next_state_int : state_values := ST0;
    signal pres_state_int : state_values := ST0;
    signal Clk1Hz_int     : STD_LOGIC;

    begin 
    LRH_int <= Break & Lturn & Rturn & Hazard;


    U1 : NextStateLogic 
    port map(
        BLRH       => LRH_int,
        pres_state => pres_state_int,
        next_state => next_state_int
        );

    U2 : CurrentStateRegister 
    port map(
        pres_state_b => pres_state_int,
        next_state_b => next_state_int,
        Rst => Rst,
        Clk => Clk1Hz_int
        );

    U3 : OutputLogic 
    port map(
        pres_state_c => pres_state_int,
        Lights     => Lights
        );

    U4 : Clk1Hz
    port map(
              Rst      => Rst,
           Clk_in   => Clk100MHz,
           Clk_out  => Clk1Hz_int
        );      

end Behavioral;

接下来是用于编码代码的包用途:

library IEEE;
use IEEE.STD_LOGIC_1164.all;

package States is

      subtype state_values is std_logic_vector(4 downto 0);
  constant ST0: state_values := "00000";
  constant ST1: state_values := "00001"; 
  constant ST2: state_values := "00010";
  constant ST3: state_values := "00011";
  constant ST4: state_values := "00100";
  constant ST5: state_values := "00101";
  constant ST6: state_values := "00110";
  constant ST7: state_values := "00111";
  constant ST8: state_values := "01000";
  constant ST9: state_values := "01001";
  constant ST10: state_values := "01010";
  constant ST11: state_values := "01011";
  constant ST12: state_values := "01100";
  constant ST13: state_values := "01101";
  constant ST14: state_values := "01110";
  constant ST15: state_values := "01111";
  constant ST16: state_values := "10000";
  signal pres_state, next_state: state_values;


end States;

NextStateLogic组件代码:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use work.States.all;


entity NextStateLogic is
            Port(   BLRH       : in   STD_LOGIC_VECTOR (3 downto 0); 
                pres_state : in   STD_LOGIC_VECTOR (4 downto 0);
                next_state : out  STD_LOGIC_VECTOR (4 downto 0));
end NextStateLogic;

architecture NextStateLogicl of NextStateLogic is

begin 

FSM: process (pres_state, BLRH)
  begin
    case pres_state is

      when "00000" => 
        case BLRH is
          when "0000"  => next_state <= "00000";--ST0; -- All off
          when "0010"  => next_state <= "00100";--ST4; -- Right Turn
          when "0100"  => next_state <= "00111";--ST7; -- Left Turn
             when "0110"  => next_state <= "00101";--ST5; -- All off
          when others  => next_state <= "00001";--ST1; -- Hazard
        end case;
      when "00001"         => next_state <= "00010";--ST2;
        when "00010"         => next_state <= "00011";
        when "00011"         => 
            case BLRH is
          when "1000"  => next_state <= "00011"; -- Break
          when "1110"  => next_state <= "00011"; -- 
          when "1010"  => next_state <= "01101"; -- Right Turn & Break
             when "1100"  => next_state <= "01010"; -- Left Turn & Break
          when others  => next_state <= "00000"; -- Hazard
        end case;
      when "00100"         => next_state <= "00101";
      when "00101"         => next_state <= "00110";
      when "00110"         => next_state <= "00000";
      when "00111"         => next_state <= "01000";
      when "01000"         => next_state <= "01001";    
      when "01001"         => next_state <= "01010";
        when "01010"        => next_state <= "01011";
        when "01011"        => next_state <= "01100";
        when "01100"        => 
            case BLRH is
          when "1100"  => next_state <= "01111"; -- Right Turn & Break
          when "1010"  => next_state <= "10000"; -- Left Turn & Break
          when others  => next_state <= "00000"; 
        end case;
        when "01101"        => next_state <= "01110";
        when "01110"        => next_state <= "01100";
        when "01111"        => next_state <= "01010";
        when "10000"        => next_state <= "01101";

 -- Include when others to avoid latches  
      when others      => next_state <= "00000";
    end case;
  end process FSM;




end NextStateLogicl;

CurrentStateRegister组件代码:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity CurrentStateRegister is
            Port( 
                pres_state_b : out   STD_LOGIC_VECTOR (4 downto 0);
                next_state_b : in  STD_LOGIC_VECTOR (4 downto 0);
                Rst          : in STD_LOGIC;
                Clk          : in STD_LOGIC
                );
end CurrentStateRegister;

architecture CurrentStateRegister of CurrentStateRegister is

begin

StateReg: process (Clk,Rst,next_state_b)
  begin
    if (Rst = '1') then 
      pres_state_b <= "00000";
    elsif Clk = '1' then
      pres_state_b <= next_state_b;
        else
        pres_state_b<= "00000";
    end if;
  end process StateReg;




end CurrentStateRegister;

OutputLogic组件代码:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity OutputLogic is
Port( 
                pres_state_c : in   STD_LOGIC_VECTOR (4 downto 0);
                Lights     : out  STD_LOGIC_VECTOR (5 downto 0));

end OutputLogic;

architecture OutputLogic of OutputLogic is

begin 

Outputs: process (pres_state_c)
  begin
    case pres_state_c is

      when "00000" => Lights <= "000000";
        ----------------------------------------------- Hazard
        when "00001" => Lights <= "001100";
      when "00010" => Lights <= "011110";
      when "00011" => Lights <= "111111";
      -----------------------------------------------   Right Turn  
      when "00100" => Lights <= "000100";
      when "00101" => Lights <= "000110";
      when "00110" => Lights <= "000111";
        ----------------------------------------------- Left Turn
      when "00111" => Lights <= "001000";
      when "01000" => Lights <= "011000";
      when "01001" => Lights <= "111000";
        ----------------------------------------------- Right Turn & Break
        when "01010" => Lights <= "001111";
      when "01011" => Lights <= "011111";
        -----------------------------------------------
      when "01111" => Lights <= "000111";
        when "01100" => Lights <= "111111"; -- Common Case
        when "10000" => Lights <= "111000";
        ----------------------------------------------- Left Turn & Break
      when "01101" => Lights <= "111100";
      when "01110" => Lights <= "111110";

      when others => Lights <= "000000";
   end case;
  end process Outputs;



end OutputLogic;

最后是Clk1Hz组件代码:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity Clk1Hz is

        port (
              Rst       : in    STD_LOGIC;
           Clk_in    : in    STD_LOGIC;
           Clk_out   : out   STD_LOGIC);
end Clk1Hz;

architecture Clk1Hz of Clk1Hz is
-- Definition of embedded signals and constants
  -- Constants used for frequency division
  constant Fosc    : integer := 100000000;   --Frecuencia del oscilador de tabletas NEXYS 3
  constant Fdiv    : integer := 5;           --Frecuencia deseada del divisor
  constant CtaMax  : integer := Fosc / Fdiv; --Cuenta maxima a la que hay que llegar
  -- Signal used by the frequency division process
  signal Cont      : integer range 0 to CtaMax;

begin
  -- Frequency divider to obtain a 2Hz signal from
  -- the 100 MHz board oscillator
  FreqDiv: process (Rst, Clk_in)
  begin
    if Rst = '1' then
       Cont <= 0;
     elsif (rising_edge(Clk_in)) then
       if Cont = CtaMax - 1 then
        Cont      <= 0;
        Clk_out    <= '1';
      else        
         Cont      <= Cont + 1;
          Clk_out    <= '0';
        end if;
    end if;
  end process FreqDiv;




end Clk1Hz;
我失踪了什么?还有另一种方法可以实现组件NextStateLogic吗?

谢谢:d

1 个答案:

答案 0 :(得分:2)

在CurrentStateRegister中,您需要测试rising_edge(clk)而不是clk = '1'。您当前的代码推断锁存器而不是寄存器,导致clk = '1'时出现循环。此外,在ControlStateRegister模块中丢失最后的else

StateReg: process (Clk,Rst,next_state_b)
  begin
    if (Rst = '1') then 
      pres_state_b <= "00000";
    elsif (rising_edge(Clk)) then
      pres_state_b <= next_state_b;
    end if;
  end process StateReg;