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 ;)
> 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 ;-)
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.
> 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%?
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 :)
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.
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...?
> 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 :-/
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.
>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.
@ 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"
@ Jan & Lothar Ich weis. Erst denken dann reden!!! ;O) Habt recht.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.