Forum: FPGA, VHDL & Co. Frage zu Latch vor Register geschaltet


von Ledger (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

beim Schreiben eines komplexeren VHDL Programms (ohne viel Erfahrung ;) 
) bin ich auf der Suche nach einer extrem schnellen Schaltung auf 
folgende Konstruktion gestoßen:
**********************************************
entity Latch_Register is
 port (
        clk:    in std_logic;
  sel:    in std_logic_vector(1 downto 0);
  input : in std_logic_vector(127 downto 0);
  output: out std_logic_vector(31 downto 0)
       );
end Latch_Register;

architecture Behavioral of Latch_Register is
 signal intern : std_logic_vector(31 downto 0);
begin
 intern <= input(127 downto 96)  when sel = "00" else
     input(95 downto 64)  when sel = "01" else
     input(63 downto 32)  when sel = "10";

 proc1 : process (clk)
  begin
   if rising_edge(clk) and sel /= "11" then
    output <= intern;
   end if;
  end process;

end Behavioral;
*****************************************************

Offensichtlich synthetisiert Xilinx das zu einem Latch (resultierend aus 
dem unvollständigen Multiplexer) mit einem hintergeschaltenen Register.
In meiner Schaltung ergibt eine solche Konstruktion einen Zeitgewinn von 
etwa 40% bezüglich der maximalen Frequenz. Es funktioniert auch 
einwandfrei auf meinem FPGA (der Latches unterstützt).

Meine Frage ist nun: Wie genau funktioniert diese Schaltung?
Und, falls es jemand weiß: Warum ist sie um so vieles schneller als eine 
LUT oder eine vergleichbare Schaltung ohne zwischengeschaltetem Latch 
(zumindest theoretisch)?

Vielen Dank für Antworten im Voraus,
Latcher/Ledger ;)

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> Meine Frage ist nun: Wie genau funktioniert diese Schaltung?
Genauso wie du sie beschrieben hast: Wenn sel="11" ist, soll der Wert 
des Signals "intern" gehalten werden (deshalb das Latch).

Würdest du es so schreiben:
1
intern <= input(127 downto 96) when sel = "00" else
2
          input(95 downto 64)  when sel = "01" else
3
          input(63 downto 32);
dann bräuchtest du das Latch nicht, und wärst noch schneller. Du 
müsstest nur dafür sorgen, dass der verbotene Zustand sel="11" nicht 
auftritt.

EDIT:
Schreib statt
1
 proc1 : process (clk)
2
  begin
3
   if rising_edge(clk) and sel /= "11" then
4
    output <= intern;
5
   end if;
6
  end process;
besser
1
 proc1 : process (clk)
2
  begin
3
   if rising_edge(clk) then
4
      if sel /= "11" then
5
        output <= intern;
6
      end if;
7
   end if;
8
  end process;

BTW:
Du solltest Latches und ähnliche asynchrone Kombinatorik soweit möglich 
vermeiden. Damit würdest du dir das Leben einfacher machen   ;-)

von Jan M. (mueschel)


Lesenswert?

Ergänzend zu Lothar:
Wenn du dir den Timing-Report ansiehst, siehst du, dass es nicht das 
Latch ist, das deinen Code schneller macht, sondern das Clockenable des 
FF das das Design langsamer macht. Das siehst du auch daran, dass es von 
der Geschwindigkeit her keinen Unterschied macht, ob der Mux vollständig 
ist oder nicht.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> In meiner Schaltung ergibt eine solche Konstruktion einen Zeitgewinn von
> etwa 40% bezüglich der maximalen Frequenz.
Ich habe da ein kleines Problem:
1) bei meiner Beschreibung sagt die Synthese (ohne Latch)
   Minimum period: No path found
2) bei deiner Schaltungsbeschreibung (mit Latch)
   Minimum period: No path found

Weil nur 1 getaktetes Element in der Beschreibung ist, kann von der 
Synthese gar keine Frequenz berechnet werden.
Woher hast du also deine 40%?

von Ledger (Gast)


Lesenswert?

Erstmal vielen Dank für die vielen Antworten!

Genau das ist das Komische! Wenn ich den Latch über fehlendes
1
"when sel = "10";"
reinprogrammiere, bin ich doppelt so schnell wie wenn ich
1
"when sel = "10";"
 einfüge - In meinem Projekt.

Ich hatte zunächst Latches vermieden und mein Leben war einfach, dafür 
war das Programm so langsam ;) - Mit diesen Zusatzlatches ist es rasend 
schnell (zumindest laut Synthese). Das mit dem ClockEnable verstehe ich 
nicht so recht, da er bei mir keine Unterschiede verursacht.

Gerne würde ich euch das komplette (und nicht nur diesen 
nachprogrammierten Auszug) Programm zur Analyse zur Verfügung stellen, 
leider geht das noch nicht, da ich nicht alleine dran arbeite. (Aus 
diesem umfangreichen Programm nehme ich auch meine 40%!)

Ich habe versucht, ein anderes Beispiel zu meinem Problem zu 
programmieren, leider habe ich dort mit oder ohne Latch immer die 
gleiche Frequenz.

Ich werde mich melden, falls ich Zustimmung zur Veröffentlichung 
erhalte. Falls jemand bis dahin noch eine Idee hat, woran es liegen 
könnte, bitte schreiben :)

von Jan M. (mueschel)


Lesenswert?

Habe noch ein bisschen rumgespielt. Ich habe am Eingang und am Ausgang 
noch ein zusätzliches FF für jedes Signal eingefügt.

Das Ergebnis mit den zusätzlichen FF: 690 MHz im Spartan3 - und das im 
Pfad zwischen deinem output-FF und meinem. Der Pfad zwischen Eingang 
durch den Mux zum FF kann unmöglich so schnell sein.
So wie ich das sehe, wird der Pfad durch das Latch einfach nicht in der 
Timing- Analyse berücksichtigt, deswegen der große Unterschied.

von Ledger (Gast)


Lesenswert?

Also denkst du, es handelt sich um einen Bug im Report bzw. der Pfad in 
der restlichen Logik einfach nicht  betrachtet wird?

Könnte es auch sein, dass (da es sich bei einem Latch ja auch um ein 
Speicherelement handelt) ein Pipelining synthetisiert wird? Das würde zu 
der knapp verdoppelten Frequenz passen...?

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> ein Pipelining synthetisiert wird? Das würde zu
> der knapp verdoppelten Frequenz passen...?
Es wird kein Pipelinig (im eigentlichen Sinn) synthetisiert, aber es 
könnte sein, dass die Pfad-Berechnung "nur" von FF zu FF geht. Und 
Latches werden auch in FFs (in einem anderen Betriebsmodus) 
realisiert...
Dann könnte fälschlicherweise das Latch als Pipeline-Register angesehen 
werden, und "nur" als Latency auftauchen. Aber korrekt scheint mir diese 
Interpretation nicht :-/

von Gerd N. (mrgne)


Lesenswert?

Der Pfad wird nicht berücksichtigt weil du einen Takt mit einem and 
verknüpfst. Theoretisch müsstest du in deinem Map report wenn nicht 
schon im synthese Report ein warning finden wo drin steht das du gated 
clocks verwendest. Gated Clocks sind ein absolutes no für FPGAs da diese 
nicht über die Clocknetze geroutet werden sondern über die normalen 
Routingwires und du dadurch mit Temperaturschwangungen unterschiedliche 
Laufzeiten hast. Also vorsicht bei solchen Konstrukten.

von Jan M. (mueschel)


Lesenswert?

>Der Pfad wird nicht berücksichtigt weil du einen Takt mit einem and
>verknüpfst. Theoretisch müsstest du in deinem Map report wenn nicht
>schon im synthese Report ein warning finden wo drin steht das du gated
>clocks verwendest.

Nein, das ist keine gated clock - es ist eine der vielen akzeptierten 
Beschreibungen fuer ein Flipflop mit Clock-Enable.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

@ Gerd N. (mrgne)
> ... es ist eine der vielen akzeptierten
> Beschreibungen fuer ein Flipflop mit Clock-Enable.
Richtig, das hatten wir schonmal im 
Beitrag "Re: Variablenfehler"

von Gerd N. (mrgne)


Lesenswert?

@ Jan & Lothar

Ich weis. Erst denken dann reden!!! ;O) Habt recht.

von Ledger (Gast)


Lesenswert?

So, falls es noch wen interessiert:

Habe eine after-Place&Route Simulation gemacht, wusste nicht, dass es 
sowas gibt ;) - und siehe da, das ganze klappt natürlich nicht mit der 
hohen Frequenz.

Offensichtlich liefert der Xilinx-Synthetisierer völlig falsche Clocks, 
wenn man unter gewissen Umständen ein Latch vorschaltet.

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.