Forum: FPGA, VHDL & Co. Problem mit modelsim


von fresh (Gast)


Lesenswert?

Hallo
Habe ein kleines Problem beim Simulieren! Es kommt immer folgende Fehler 
Meldung:

# ** Error: (vsim-3601) Iteration limit reached at time 0 ps.

Ich weis auch was es heißt aber ich sehe den Fehler im Code nicht! 
Vielleicht sieht ihn ja jemand von euch!

Danke im vorhinein!

MFG Fresh

entity transmit_unit is

  port (
    clk        : in  std_logic;
    reset      : in  std_logic;
    data_in    : in  transmit_data;
    enable_out : out std_logic := '1';
    data_out   : out std_logic);

end transmit_unit;


architecture twoproc of transmit_unit is

  signal r, rin      : transmit_reg_type;
  signal tmp_data_in : std_logic := '1';
begin  -- twoproc


  -- purpose: combinatorial process of the two-process design
  -- type   : combinational
  -- inputs : data_in, r
  -- outputs: data_out, rin
  comb: process(data_in.transmit_en, r)
    variable tmp      : transmit_reg_type;
    variable databit  : std_logic := '0';
    variable prebit   : std_logic := '0';
  begin  -- process comb
    tmp := r;
    if data_in.transmit_en = '1' then
      if (tmp.precount = precount_value) then
        databit := data_in.data;
        --look if bit Stuffing is enable
        if (data_in.bit_stuff_en = '1') then
          --send the data or the stuffing bit
          if(tmp.bitnumber = conv_std_logic_vector(6,3)) then
            databit := not prebit;
            enable_out <= '1';
            tmp.bitnumber := (others => '0');
          else
            prebit := databit;
          end if;
          --compare if the the prebit and the databit are the same
          if (databit = prebit) then
            tmp.bitnumber := tmp.bitnumber + 1;
          else
            tmp.bitnumber := (others => '0');
          end if;
          --control the bitnumber if it reached the value 5
          if (tmp.bitnumber = bitstuffing_value) then
            enable_out <= '0';
            tmp.bitnumber := conv_std_logic_vector(6,3);
          end if;
        end if;

        tmp_data_in <= databit;
        tmp.precount := (others => '0');
      else
        tmp.precount := tmp.precount + 1;
      end if;
    else
      tmp.precount := precount_value;
    end if;
    rin <= tmp;
  end process comb;

  data_out <= tmp_data_in;

  -- purpose: sequential process or the two-process design
  -- type   : sequential
  -- inputs : clk, reset, rin
  -- outputs: r
  seq: process (clk, reset)
  begin  -- process seq
    if reset = '0' then                 -- asynchronous reset (active 
low)
      r.bitnumber <= (others => '0');
      r.precount  <= precount_value;
    elsif clk'event and clk = '1' then  -- rising clock edge
      r <= rin;
    end if;
  end process seq;

end twoproc;

von Falk B. (falk)


Lesenswert?

@ fresh (Gast)

>Habe ein kleines Problem beim Simulieren! Es kommt immer folgende Fehler
>Meldung:

># ** Error: (vsim-3601) Iteration limit reached at time 0 ps.

Uhhh, das sieht komisch aus. Diese tmp.irgendwas Scheibweise kenn ich 
gar nicht. Du kommst aus der prgrammierer-Ecke, nicht wahr?

Ich sag mal, für das Problem brauch man keine Variablen. Machs mal ohne. 
Und lass diese komsichen tmp.irgendwas Dinger weg. Normale Signale tuns 
locker.

MFG
Falk

von Roger S. (edge)


Lesenswert?

@ Falk Brunner

> Uhhh, das sieht komisch aus. Diese tmp.irgendwas Scheibweise kenn ich
> gar nicht. Du kommst aus der prgrammierer-Ecke, nicht wahr?

und was du nicht kennst ist schlecht?

> Und lass diese komsichen tmp.irgendwas Dinger weg. Normale Signale tuns
> locker.

tmp wird wohl ein record sein. ideal um Signale zu gliedern => code wird 
uebersichtlicher und weniger schreibaufwand.

Cheers, Roger

von Falk B. (falk)


Lesenswert?

@ Roger Steiner (edge)

>> Uhhh, das sieht komisch aus. Diese tmp.irgendwas Scheibweise kenn ich
>> gar nicht. Du kommst aus der prgrammierer-Ecke, nicht wahr?

>und was du nicht kennst ist schlecht?

Was der Bauer nicht kennt, frisst er nciht. ;-)

>tmp wird wohl ein record sein. ideal um Signale zu gliedern => code wird
>uebersichtlicher und weniger schreibaufwand.

Schon klar, hab ich aber bei VHDL noch nie gesehen und auch nie was 
drüber gelesen. Modelsim scheint es auch nicht zu bekommen, obwohl es 
das kennt. Wahrscheinlich kommte es in eine endlose Rekursion beim 
Durchhangeln der Records. Und übersichtlich die DER Code weiss Gott 
nicht.

MFg
Falk

von damicha (Gast)


Lesenswert?

Hallo

@fresh:
Da hat mal einer schön die Zwei Prozess Methode benutzt! Du hast Dir 
aber ne ganz Hand voll Latche gebaut. Z.B.: tmp_data_in wird nur in 
einem der if-else Zweige gesetzt. Entweder Du weißt überall zu oder du 
setzt einen Default-Wert.

Dein Problem ist aber wahrscheinlich ein anderes.
Poste doch mal die Testbench, vieleicht gibt es dort ein Zweig in einem 
der Prozesse, der kein wait oder wait until oder ähnliches enthält. Da 
kann es dann schnell mal zu einem Loop kommen.

Gruß DaMicha.

von fresh (Gast)


Lesenswert?

Hallo
Ich habe in der Testbench mal nur den ClockProcess drinnen aber auch 
dann kommt der Fehler! Nehme nicht an das an diesen Prozess hängt oder?

 clk: process
  begin  -- process clk
    clk_i <= '0';
    wait for 25ns;
    clk_i <= '1';
    wait for 25ns;
  end process clk;

von Falk B. (falk)


Lesenswert?

Das passt schon.

von fresh (Gast)


Lesenswert?

Hallo Beim Process für den Takt hat bei den wait for Anweisungen der 
Abstand zwischen 25 und ns gefehlt! Aber der hat leider mein 
ursprüngliches Problem nicht gelöst! Habe nun den ausdruck enable_out <= 
'1'; aus der if schleife genommen damit ein latch weniger entsteht! 
Sollte man zum latcher vermeiden solche konstrukte:

if (test = '1') then
   tmp := '1';
else
   tmp := tmp;
end if;

verwenden oder kann man den ausdruck im else zweig weglassen?

comb: process(data_in.transmit_en, r)
    variable tmp      : transmit_reg_type;
    variable databit  : std_logic := '0';
    variable prebit   : std_logic := '0';
  begin  -- process comb
    tmp := r;
    if data_in.transmit_en = '1' then
      if (tmp.precount = precount_value) then
        databit := data_in.data;
        --look if bit Stuffing is enable
        if (data_in.bit_stuff_en = '1') then
          enable_out <= '1';
          --send the data or the stuffing bit
          if(tmp.bitnumber = conv_std_logic_vector(6,3)) then
            databit := not prebit;
            tmp.bitnumber := (others => '0');
          else
            tmp.bitnumber := tmp.bitnumber;
            prebit := databit;
          end if;
          --compare if the the prebit and the databit are the same
          if (databit = prebit) then
            tmp.bitnumber := tmp.bitnumber + 1;
          else
            tmp.bitnumber := (others => '0');
          end if;
          --control the bitnumber if it reached the value 5
          if (tmp.bitnumber = bitstuffing_value) then
            enable_out <= '0';
            tmp.bitnumber := conv_std_logic_vector(6,3);
          end if;
        end if;

        tmp_data_in <= databit;
        tmp.precount := (others => '0');
      else
        tmp.precount := tmp.precount + 1;
      end if;
    else
      tmp.precount := precount_value;
    end if;
    rin <= tmp;

von Falk B. (falk)


Lesenswert?

@ fresh (Gast)

>Hallo Beim Process für den Takt hat bei den wait for Anweisungen der
>Abstand zwischen 25 und ns gefehlt!

Da meckert Modelsim aber vorher drüber.

>ursprüngliches Problem nicht gelöst! Habe nun den ausdruck enable_out <=
>'1'; aus der if schleife genommen damit ein latch weniger entsteht!

Es dürfen KEINE Latches entstehen, sonst schiesst du dir ins Knie.

>Sollte man zum latcher vermeiden solche konstrukte:

>if (test = '1') then
>   tmp := '1';
>else
>   tmp := tmp;
>end if;

Kann man machen.

>verwenden oder kann man den ausdruck im else zweig weglassen?

Wenn man, was ich für sinnvoll halte, das alles gleich in einen 
getakteten Prozess schreibt. Ist genauso übersichtlich, und Latches 
entstehen auf keinen Fall. Hat auch keine negativen Auswirkungen auf die 
Geschwindigkeit, die Diskussionen darüber in der Vergangenheit halte ich 
für eine Legende.

MFG
Falk

von fresh (Gast)


Lesenswert?

Hallo ich bins gleich nochmal!

Habe jetzt folgendes getestet und bekomme da auch diesen fehler mit den 
iteration limit!

comb: process(data_in.transmit_en, r)
    variable tmp      : transmit_reg_type;
    variable databit  : std_logic := '0';
    variable prebit   : std_logic := '0';
  begin  -- process comb
    tmp := r;

    rin <= tmp;
  end process comb;

  data_out <= tmp_data_in;

  seq: process (clk, reset)
  begin  -- process seq
    if reset = '0' then                 -- asynchronous reset (active 
low)
      r.bitnumber <= (others => '0');
      r.precount  <= precount_value;
    elsif clk'event and clk = '1' then  -- rising clock edge
      r <= rin;
    end if;
  end process seq;

und in der testbench:

  clk: process
  begin  -- process clk
    clk_i <= '0';
    wait for 25 ns;
    clk_i <= '1';
    wait for 25 ns;
  end process clk;

  reset_i <= '1';

wo kann da noch der Fehler aufretten?

von Falk B. (falk)


Lesenswert?

@ fresh (Gast)

>Habe jetzt folgendes getestet und bekomme da auch diesen fehler mit den
>iteration limit!

Dein Stil ist und bleibt komisch. Warum nciht ganz einfach so?
1
comb: process(clk)
2
    variable tmp      : transmit_reg_type;
3
    variable databit  : std_logic := '0';
4
    variable prebit   : std_logic := '0';
5
  begin  -- process comb
6
    elsif clk'event and clk = '1' then  -- rising clock edge
7
8
    tmp := r;
9
  
10
     -- Berechnung hier rein
11
12
     r <= tmp;
13
  
14
     data_out <= tmp_data_in;
15
16
17
    end if;
18
  end process;
19
20
und in der testbench:
21
22
  clk: process
23
  begin  -- process clk
24
    clk_i <= '0';
25
    wait for 25 ns;
26
    clk_i <= '1';
27
    wait for 25 ns;
28
  end process clk;
29
30
  reset_i <= '1';

MFG
Falk

von fresh (Gast)


Lesenswert?

Ja das wäre eine einfachere Lösung aber ich habe als Vorgabe das das 
ganze im 2 Prozess Design zu implementieren ist. aber das darf doch im 
großen und ganzen keinen wirklichen unterschied machen!

MFG Harald

von Andreas S. (andreas) (Admin) Benutzerseite


Lesenswert?

fresh wrote:
> if (test = '1') then
>    tmp := '1';
> else
>    tmp := tmp;
> end if;
>
> verwenden oder kann man den ausdruck im else zweig weglassen?

Der else-Zweig hat keine Auswirkung. Latches kannst du nur vermeiden 
indem du den Prozess entweder taktest oder so schreibst dass überhaupt 
keine speichernden Elemente benötigt werden.

von Falk B. (falk)


Lesenswert?

@ fresh (Gast)

>Ja das wäre eine einfachere Lösung aber ich habe als Vorgabe das das
>ganze im 2 Prozess Design zu implementieren ist.

Von wem? Prof? Akademiker . . .

>aber das darf doch im
>großen und ganzen keinen wirklichen unterschied machen!

Nein. Wenn du im kombinatorischen Prozess in JEDEM Zweig eine Zuweisung 
an JEDE Ausgangsvariable machst. Aber ich bleibe dabei. Schreibs mal 
einfach ohne diese Records und so weit wie möglich ohne Variablen hin.

MFG
Falk

von FPGA-Jeck (Gast)


Lesenswert?

Bringt modelsim den fehler bei jedem Code? Vielleicht ist ja das 
iteration limit zu niedrig (0 bis 10), üblich sind ein paar tausend. du 
kannst ja mal mit einem Beispiel von modelsim testen.

und vielleicht etwas spitzfindig.

wo wird clk_i aus deiner TB verwendet ?
clk: als label und signalname ist vielleicht unglücklich

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.