2016-07-02 21 views
0

Ich habe den Fehler "Iterationslimit erreicht" in einem einfachen FSM. Dies ist ein Teil einer größeren FSM, die ich für eine Klassenzuweisung machen muss, und ich habe das Problem in diesem speziellen Teil verfolgt. Der FSM steuert einen Zähler, der Status IDLE wartet auf Eingaben, ZERO setzt den Zähler auf Null und der INCREMENT-Status erhöht den Zähler um eins.Iterationslimit erreicht - einfacher Zähler in VHDL FSM

Bei der Simulation tritt der Fehler auf, wenn der Eingang "inc" zum ersten Mal hoch ist und die Uhr ansteigt. Wenn ich die Anweisung ändern "temp: = temp + 1;" für "temp: = irgendetwas" wird der Fehler beendet. Ich weiß wirklich nicht, was falsch sein kann, denn was ich gefunden habe, tritt dieser Fehler auf, wenn Signale in der Prozessempfindlichkeitsliste innerhalb des Prozesses selbst geändert werden.

Ich verwende Quartus II für die Simulation.

Entschuldigung für englische Fehler.

library ieee; 
use ieee.std_logic_1164.all; 
use ieee.std_logic_unsigned.all; 
use IEEE.NUMERIC_STD.all; 

entity fsm is 
    port 
    (
     clock:  in std_logic; 
     reset:  in std_logic; 

     inc:   in std_logic; 

     count:  out std_logic_vector (13 downto 0); 
     cur_state: out std_logic_vector (1 downto 0) 
    ); 
end fsm; 

architecture behaviour of fsm is 
    type state_type is (IDLE, INCREMENT, ZERO); 
    signal PS, NS: state_type; 

begin  
    sync_proc: process (clock, reset) 
    begin 
     if (reset = '1') then 
      PS <= ZERO; 
     elsif (rising_edge(clock)) then 
      PS <= NS;   
     end if; 
    end process sync_proc; 

    comb_proc: process (PS, inc) 
     variable temp: unsigned (13 downto 0); 
    begin 
     case PS is 
      when IDLE => 
       if (inc = '1') then 
        NS <= INCREMENT; 
       else 
        NS <= IDLE; 
       end if;    
      when INCREMENT => 
       temp := temp + 1; 
       NS <= IDLE; 
      when ZERO => 
       temp := "00000000000000"; 
       NS <= IDLE; 
      when others => 
       NS <= IDLE; 
     end case; 

     count <= std_logic_vector(temp); 
    end process comb_proc; 

    with PS select 
     cur_state <= "00" when IDLE, 
          "01" when INCREMENT, 
          "10" when ZERO, 
          "11" when others; 
end behaviour; 
+0

Ihr Code simuliert erfolgreich mit einer hinzugefügten Testbench [fsm_tb.png] (http://i.stack.imgur.com/uPgib.png). Beachten Sie, dass das Zurücksetzen PS = NULL verursacht, wodurch die Temperatur initialisiert wird. Bitte zeigen Sie Ihre aktuelle Fehlermeldung an und zeigen Sie Ihre Simulation an. Ein [MCVE] (http://stackoverflow.com/help/mcve) wäre hilfreich. – user1155120

+0

Beachten Sie auch, dass die Use-Klausel 'ieee.std_logic_unsigned.all verwenden;' nicht benötigt wird. – user1155120

+0

Eine Simulation nach der Synthese könnte eine kombinatorische Schleife mit Temp basierend auf dem Fehlen einer sequentiellen Schaltung Inferenz (Es gibt keine Taktflanke, um Temp zu inkrementieren). Wenn "PS" ein einzelner heißer Zustand ist, gibt es keine Möglichkeit kombinatorischer Störimpulse für die Verwendung "INCREMENT" als eine Latch-Aktivierung. Aber immer dann, wenn "INCREMENT" wahr ist, wird der Temp-Latch aktualisiert und er stellt eine Rückkopplungsschleife bereit, die auf das Iterationslimit treffen kann. Dies entspricht dem von Ihnen beschriebenen Verhalten, ist jedoch nicht auf den von Ihnen bereitgestellten Verhaltenscode anwendbar. – user1155120

Antwort

1

Sie haben einen sehr schwerwiegenden konzeptionellen Fehler in Ihrer Fallaussage. Da es eine kombinatorische Schaltung (den kombinatorischen Teil Ihrer FSM) erzeugt, hat es keinen Speicher, so dass es die Gleichung "temp: = temp + 1" nicht implementieren kann (weil es keinen Speicher hat, weiß es nicht was der Wert von Temp ist).

Sie können mehr darüber in Kapitel 11 von "Finite State Machines in Hardware ...", von V. Pedroni, veröffentlicht von MIT.