mikrocontroller.net

Forum: FPGA, VHDL & Co. Werden hier Latches erzeugt?


Autor: Pat Rik (patrik)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Leute,
ich habe ein Problem mit meinen Signalen, vermutlich wegen Latches.
Also ich habe drei Module, MemoryOrganizer, Linearizer und 
ControlCenter.
Linearizer holt sich Werte vom Memoryorganizer und gibt diese an 
ControlCenter weiter. ControlCenter verbindet diese zwei Module und gibt 
die Werte vom Linearizer auf Leds aus.
Hier die Code-Ausschnitte:

MemoryOrganizer:
  value <= value_int;

  process(mem_clock, reset)
  begin
    if reset = '1' then
      value_int <= "0000000000";
    elsif mem_clock'event and mem_clock = '1' then
      if address = "000111111100010011100000" then
        value_int <= "0000000" & count_int;
      else
        value_int <= "1111111" & count_int;
      end if;

    end if;
  end process;

  process(reset, clk)
  begin
    if reset = '1' then
      mem_clk_fsm <= clk_wait_for_start;
      ready <= '1';
      DONE <= '0';
      mem_clock_last <= '0';
    elsif clk'event and clk = '1' then
      case mem_clk_fsm is
        when clk_wait_for_start =>
          int_clk <= "000";
          done <= '0';

          if start = '1' then
            count_int <= count;
            ready <= '0';
            mem_clk_fsm <= clk_processing;
          else
            ready <= '1';
          end if;
        when clk_processing =>
          int_clk <= int_clk + 1;

          mem_clock_last <= mem_clock;

          if mem_clock = '1' and mem_clock_last = '0' then
            count_int <= count_int - '1';
            done <= '1';
          else
            done <= '0';
          end if;

          if count_int = "000" then
            mem_clk_fsm <= clk_wait_for_start;
          end if;
      end case;
    end if;
  end process;


----------------------------------------------------------------------

Linearizer:


  MEM_VALUE_1A <= mem_value_a_int;


  process(clk, reet)
  begin
  if reset = '1' then
  .
  .
  elsif clk'event and clk = '1' then
    .
    .
    when wait_for_mem1 =>
      if mem_done = '1' then
        main_fsm <= wait_for_mem2;
        -- hier testweise an mem_value_a_int zugewiesen
        if address = "000111111100010011100000" then
          mem_value_a_int <= MEM_VALUE;
        end if;
      end if;
    .
    .
    when wait_for_mem4 =>
      if mem_done = '1' then
        if address = "000111111100010011100000" then
          MEM_VALUE_1B <= MEM_VALUE;
        end if;
        main_fsm <= wait_for_mem5;
      end if;
    .
    .
    when wait_for_mem7 =>
      if mem_done = '1' then
        if address = "000111111100010011100000" then
          MEM_VALUE_1C <= MEM_VALUE;
        end if;
        main_fsm <= wait_for_mem8;
      end if;
    .
    .
    when wait_for_mem10 =>
      if mem_done = '1' then
        main_fsm <= wait_for_mem11;
        if address = "000111111100010011100000" then
          MEM_VALUE_1D <= MEM_VALUE;
        end if;
        IS_ZERO <= '0';
        IS_POSITIVE <= '1';
      end if;
    .
    .
  end if
  end process;

------------------------------------------------------------------------

ControlCenter:
leds <=  MEM_VALUE_1A(7 downto 0);

------------------------------------------------------------------------

Gewünscht ist, dass MEM_VALUE_1A(7 downto 0) den Wert "00000110" hat. 
Tatsächlich, wenn mem_value_a_int <= MEM_VALUE; im Linearizer aufgerufen 
wird, hat MEM_VALUE den korrekten Wert "0000000110"(habe ich am Osci 
gemessen). Allerdings behält mem_value_a_int und damit auch MEM_VALUE_1A 
diesen Wert nicht, sonder ändert sich sobald MEM_VALUE an MEM_VALUE_1B, 
MEM_VALUE_1C oder MEM_VALUE_1D zugewiesen wird. Und am Ende haben alle 
Signale den Wert von MEM_VALUE_1D. Es sieht für mich nach Latches, hier 
die Meldungen von der Synthese:

INFO:Xst:2261 - The FF/Latch <value_int_3> in Unit <MemoryOrganiser> is 
equivalent to the following 6 FFs/Latches, which will be removed : 
<value_int_4> <value_int_5> <value_int_6> <value_int_7> <value_int_8> 
<value_int_9>

INFO:Xst:2261 - The FF/Latch <MEM_VALUE_1C_0> in Unit <Linearizer> is 
equivalent to the following 4 FFs/Latches, which will be removed : 
<MEM_VALUE_1B_0> <MEM_VALUE_1D_0> <leds_0> <mem_value_a_int_0>

INFO:Xst:2261 - The FF/Latch <MEM_VALUE_1C_1> in Unit <Linearizer> is 
equivalent to the following 4 FFs/Latches, which will be removed 
:<MEM_VALUE_1B_1> <MEM_VALUE_1D_1> <leds_1> <mem_value_a_int_1>

INFO:Xst:2261 - The FF/Latch <MEM_VALUE_1C_2> in Unit <Linearizer>
is equivalent to the following 4 FFs/Latches, which will be removed :
<MEM_VALUE_1B_2> <MEM_VALUE_1D_2> <leds_2> <mem_value_a_int_2>

INFO:Xst:2261 - The FF/Latch <MEM_VALUE_1C_3> in Unit <Linearizer>
is equivalent to the following 4 FFs/Latches, which will be removed :
<MEM_VALUE_1B_3> <MEM_VALUE_1D_3> <leds_3> <mem_value_a_int_3>

INFO:Xst:2261 - The FF/Latch <MEM_VALUE_1C_4> in Unit <Linearizer>
is equivalent to the following 4 FFs/Latches, which will be removed :
<MEM_VALUE_1B_4> <MEM_VALUE_1D_4> <leds_4> <mem_value_a_int_4>

INFO:Xst:2261 - The FF/Latch <MEM_VALUE_1C_5> in Unit <Linearizer>
is equivalent to the following 4 FFs/Latches, which will be removed :
<MEM_VALUE_1B_5> <MEM_VALUE_1D_5> <mem_value_a_int_5> <leds_5>

INFO:Xst:2261 - The FF/Latch <MEM_VALUE_1C_6> in Unit <Linearizer>
is equivalent to the following 4 FFs/Latches, which will be removed :
<MEM_VALUE_1B_6> <MEM_VALUE_1D_6> <mem_value_a_int_6> <leds_6>

INFO:Xst:2261 - The FF/Latch <MEM_VALUE_1C_7> in Unit <Linearizer>
is equivalent to the following 3 FFs/Latches, which will be removed :
<MEM_VALUE_1B_7> <MEM_VALUE_1D_7> <mem_value_a_int_7>

INFO:Xst:2261 - The FF/Latch <MEM_VALUE_1C_8> in Unit <Linearizer>
is equivalent to the following 3 FFs/Latches, which will be removed :
<MEM_VALUE_1B_8> <MEM_VALUE_1D_8> <mem_value_a_int_8>

INFO:Xst:2261 - The FF/Latch <MEM_VALUE_1C_9> in Unit <Linearizer>
is equivalent to the following 3 FFs/Latches, which will be removed :
<MEM_VALUE_1B_9> <MEM_VALUE_1D_9> <mem_value_a_int_9>

Und jetzt meine Fragen, sind es Latches, wenn ja warum und wie kann ich 
sie beseitigen?

Danke
Patrik

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zur Beruhigung:
Das sind keine Latches.
Irgendwas in der Beschreibung verleitet den Synthesizer dazu, 
anzunehmen, dass MEM_VALUE_1C = MEM_VALUE_1B = MEM_VALUE_1D = leds = 
mem_value_a_int. Wie sieht denn die Adressdecodierung komplett aus?


Zu Beunruhigung:
Du überquerst Taktdomänen asynchron. Viel Erfolg dabei.
    elsif mem_clock'event and mem_clock = '1' then  --### Domäne 1
      if address = "000111111100010011100000" then
        value_int <= "0000000" & count_int;  ---------
  :
  :
  process(reset, clk)
  begin
     :
    elsif clk'event and clk = '1' then --## Domäne 2
     :
            count_int <= count;     ------------------
Oder ist der mem_clock synchron zum clk?
Falls ja: warum arbeitest du dann nicht mit Clock-Enables?

Autor: Pat Rik (patrik)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was meinst du mit 'Adressdecodierung'? Falls du das Signal address 
meinst, das wird aus mehreren anderen Signalen berechnet.

mem_clock ist das dritte Bit von int_clk: std_logic_vector(2 downto 0). 
Und int_clk wird Taktsynchron hochgezählt. In diesem Fall ist also 
mem_clock 4 Takte High und 4 Takte Low.
Ich will einfach nur, dass der Linearizer ein paar Taktzycklen warten 
muss, bis er den Wert vom MemoryOrganizer bekommt. Denn MemoryOrganizer 
simuliert nur eine Schnittstelle zum Speicher, wird aber später ersetzt 
und dann wird es ein bissl dauern bis die Werte aus dem Speicher 
eingelesen werden.

Autor: Pat Rik (patrik)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Lothar Miller wrote:
> Zur Beruhigung:
> Das sind keine Latches.
> Irgendwas in der Beschreibung verleitet den Synthesizer dazu,
> anzunehmen, dass MEM_VALUE_1C = MEM_VALUE_1B = MEM_VALUE_1D = leds =
> mem_value_a_int. Wie sieht denn die Adressdecodierung komplett aus?
>

Und nicht nur dass, sondern
MEM_VALUE_1C = MEM_VALUE_1B = MEM_VALUE_1D = leds = mem_value_a_int = 
MEM_VALUE

denn wann immer sich MEM_VALUE ändert, ändern sich auch alle diese vier 
Signale.

Autor: Pat Rik (patrik)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn ich an mem_value_a_int einen konstanten Wert zuweise, behält dieses 
Signal diesen Wert. Sobald ich diesem Signal MEM_VALUE zuweise...

Autor: Pat Rik (patrik)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Noch vollständigkeitshalber, MEM_VALUE ist mit value_int verbunden.

Autor: Andreas Schwarz (andreas) (Admin) Benutzerseite Flattr this
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Schau dir doch einfach mal den erzeugten Schaltplan an, da kannst du 
schnell erkennen ob etwas unerwünschtes synthetisiert wurde oder etwas 
wichtiges fehlt.

Autor: Pat Rik (patrik)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also ich habe den Linearizer so weit wie möglich reduziert und das Modul 
sieht wie folgt aus:

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

entity Linearizer is
  PORT(
      CLK : IN STD_LOGIC;
      RESET : IN STD_LOGIC;
      MEM_DONE : in STD_LOGIC;
      MEM_VALUE : in STD_LOGIC_VECTOR(4 downto 0);
      MEM_START : out STD_LOGIC;
      RESULT : OUT STD_LOGIC_VECTOR(7 downto 0)
  );

end Linearizer ;

architecture Behavioral of Linearizer is


signal MEM_VALUE_A, MEM_VALUE_B, MEM_VALUE_C, MEM_VALUE_D :
STD_LOGIC_VECTOR(4 downto 0);

type main_fsm_type is (wait_for_start, start_mem_read1, mem_start1,
wait_for_mem1, wait_for_mem2, wait_for_mem3, wait_for_mem4,
wait_for_mem5);
signal main_fsm : main_fsm_type;

begin


  process(clk, reset)
  begin
    if reset = '1' then
      mem_start <= '0';
      main_fsm <= wait_for_start;
      result <= "00000000";
    elsif clk'event and clk = '1' then
      case main_fsm is
        when wait_for_start =>
          main_fsm <= start_mem_read1;
        when start_mem_read1  =>
          main_fsm <= mem_start1;
          MEM_START <= '1';
        when mem_start1 =>
          MEM_START <= '0';
          main_fsm <= wait_for_mem1;
        when wait_for_mem1 =>
          if mem_done = '1' then
            MEM_VALUE_A <= MEM_VALUE;
            main_fsm <= wait_for_mem2;
          end if;
        when wait_for_mem2 =>
          if mem_done = '1' then
            MEM_VALUE_B <= MEM_VALUE;
            main_fsm <= wait_for_mem3;
          end if;
        when wait_for_mem3 =>
          if mem_done = '1' then
            MEM_VALUE_C <= MEM_VALUE;
            main_fsm <= wait_for_mem4;
          end if;
        when wait_for_mem4 =>
          if mem_done = '1' then
            main_fsm <= wait_for_mem5;
            MEM_VALUE_D <= MEM_VALUE;
          end if;
        when wait_for_mem5 =>
RESULT(4 downto 0) <=MEM_VALUE_A + MEM_VALUE_B + MEM_VALUE_C + 
MEM_VALUE_D;

          main_fsm <= wait_for_start;
      end case;
    end if;
  end process;

end Behavioral;


Was sagt die Synthese?
INFO:Xst:2261 - The FF/Latch <MEM_VALUE_D_0> in Unit <PercentualRetimer>
is equivalent to the following 3 FFs/Latches, which will be removed :
<MEM_VALUE_A_0> <MEM_VALUE_B_0> <MEM_VALUE_C_0>

INFO:Xst:2261 - The FF/Latch <MEM_VALUE_D_1> in Unit <PercentualRetimer>
is equivalent to the following 3 FFs/Latches, which will be removed :
<MEM_VALUE_A_1> <MEM_VALUE_B_1> <MEM_VALUE_C_1>

INFO:Xst:2261 - The FF/Latch <MEM_VALUE_D_2> in Unit <PercentualRetimer>
is equivalent to the following 3 FFs/Latches, which will be removed :
<MEM_VALUE_A_2> <MEM_VALUE_B_2> <MEM_VALUE_C_2>

INFO:Xst:2261 - The FF/Latch <MEM_VALUE_D_3> in Unit <PercentualRetimer>
is equivalent to the following 3 FFs/Latches, which will be removed :
<MEM_VALUE_A_3> <MEM_VALUE_B_3> <MEM_VALUE_C_3>

INFO:Xst:2261 - The FF/Latch <MEM_VALUE_D_4> in Unit <PercentualRetimer>
is equivalent to the following 3 FFs/Latches, which will be removed :
<MEM_VALUE_A_4> <MEM_VALUE_B_4> <MEM_VALUE_C_4>

Und wenn ich einen Testmodul dazu schreibe und es auf dem Spartan3E 
StarterKit Board laufen lasse und mir das Ergebnis 'Result' anschaue, 
dann wird tatsächlich alles durch MEM_VALUE_D ersetzt und als Result 
steht MEM_VALUE_D + MEM_VALUE_D + MEM_VALUE_D + MEM_VALUE_D.

Die Simualtion zeigt das korrektes Ergebnis => VERZWEIFLUNG!

Kann mir jemand erklären was ich falsch mache?

Patrik

Autor: Pat Rik (patrik)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Andreas Schwarz wrote:
> Schau dir doch einfach mal den erzeugten Schaltplan an, da kannst du
> schnell erkennen ob etwas unerwünschtes synthetisiert wurde oder etwas
> wichtiges fehlt.

Ich habe es soeben versucht und soweit ich es verstehen konnte, sind 
MEM_VALUE_A, MEM_VALUE_B und MEM_VALUE_C futsch :-(

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Der Synthesizer ist schlauer, als du denkst:
der sieht, dass diese MEM_VALUE_(A..D) nirgends verwendet werden und 
optimiert sie raus. Verwende die Signale, oder führe sie nach aussen 
(Anhang), dann klappts auch mit der Nachbarin ;-)

EDIT:
Verwenden heißt: nicht nur in einem Zustand (wait_for_mem5) verwenden.

Autor: Pat Rik (patrik)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
also ich mache wohl etwas ganz falsch! Ich habe es mit deinem code 
versucht, funct aber nicht :(
Die Synthese bringt immer noch die Meldungen die ich hier schon gepostet 
habe.
Schaue dir  bitte das Bild im Anhang, das ist imho Müll pur!
Das ist doch result <= (((mem_value + mem_value)+ mem_value)+mem_value);

Das sehe ich nämlich auch auf den leds.

Ich benutze ISE 10.1. Kann man da nicht irgendwie einstellen, dass er 
das nicht 'wegoptimiert'?

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Was du da bekommst ist Käse :-(
Sowas habe ich mit deiner ursprünglichen Beschreibung erhalten.

Meine Zielarchitektur: Spartan 3
Die Synthese-Einstellungen: Alles auf Default
Meine SW-Version: 8.2.03i
Mein Ergebnis: Anhang

Autor: Pat Rik (patrik)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
aha, da haben es die Entwickler von ISE zu gut gemeint. Kann ich 
irgendwo die ältere ISE Version runterladen?

Aber, ich kann mir ehrlich gesagt nicht vorstellen, dass die 10.1 
Version nicht in der Lage wäre, den Code zu syntetisieren, so dass das 
richtige Ergebenis rauskommt.

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Patrik Krizan wrote:
> Aber, ich kann mir ehrlich gesagt nicht vorstellen, dass die 10.1
> Version nicht in der Lage wäre, den Code zu syntetisieren, so dass
> das richtige Ergebenis rauskommt.
Ich eigentlich auch nicht...
Sieh doch mal die Synthese-Eigenschaften durch, ob du damit was ändern 
kannst.

Autor: Pat Rik (patrik)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
folgendes funktioniert:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity Linearizer is
  PORT(
      CLK : IN STD_LOGIC;
      RESET : IN STD_LOGIC;
      MEM_DONE : in STD_LOGIC;
      MEM_VALUE : in STD_LOGIC_VECTOR(4 downto 0);
      MEM_START : out STD_LOGIC;
      RESULT : OUT STD_LOGIC_VECTOR(7 downto 0)
  );  

end Linearizer;

architecture Behavioral of Linearizer is

signal MEM_VALUE_A, MEM_VALUE_B : STD_LOGIC_VECTOR(4 downto 0);

signal is_mem_value_a, is_mem_value_b : std_logic;

type main_fsm_type is (wait_for_start, start_mem_read1, mem_start1, wait_for_mem1, wait_for_mem2, wait_for_mem3);
signal main_fsm : main_fsm_type;

begin
  
  process(clk, reset)
  begin
    if reset = '1' then
      mem_start <= '0';
      main_fsm <= wait_for_start;
      result <= "00000000";
      is_mem_value_a <= '0';
      is_mem_value_b <= '0';
    elsif clk'event and clk = '1' then
      

      case main_fsm is
        when wait_for_start =>
          is_mem_value_a <= '0';
          is_mem_value_b <= '0';
          main_fsm <= start_mem_read1;
        when start_mem_read1  =>
          main_fsm <= mem_start1;          
          MEM_START <= '1';
        when mem_start1 =>
          MEM_START <= '0';
          main_fsm <= wait_for_mem1;
          is_mem_value_a <= '1';
        when wait_for_mem1 =>
          if is_mem_value_a = '1' and mem_done = '1' then
            MEM_VALUE_A <= MEM_VALUE;
            main_fsm <= wait_for_mem2;
            is_mem_value_b <= '1';
          end if;
        when wait_for_mem2 =>
          is_mem_value_a <= '0';
          if is_mem_value_b = '1' and mem_done = '1' then
            main_fsm <= wait_for_mem3;
            MEM_VALUE_B <= MEM_VALUE;            
          end if;
        when wait_for_mem3 =>
          is_mem_value_b <= '0';
          RESULT(4 downto 0) <= MEM_VALUE_A + MEM_VALUE_B;
          main_fsm <= wait_for_start;
      end case;
    end if;
  end process;
  

end Behavioral;



gefällt mir aber nicht wirklich :-\

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.