FPGA: Aufwärts zählen oder abwärts zählen?

Ich lerne, ein FPGA (Papilio-Entwicklungsboard, das ein xilinx spartan3e hat, mit vhdl) zu verwenden.

Ich muss einen eingehenden Impuls durch eine (fest codierte) Zahl teilen.

Ich kann 3 Optionen sehen - ungefähr als Pseudocode (am Beispiel von 10 Zählungen):

  1. Auf 0 initialisieren, bei steigender Flanke am Eingang um 1 erhöhen, vergleiche mit 10; wenn sie gleich sind, auf 0 zurücksetzen und Ausgangsimpuls auslösen
  2. Auf 10 initialisieren, bei steigender Eingangsflanke um 1 verringern, mit 0 vergleichen; wenn sie gleich sind, auf 10 zurücksetzen und Ausgangsimpuls auslösen
  3. Initialisieren Sie auf 9, aber stellen Sie sicher, dass mindestens 1 führendes "0"-Bit vorhanden ist, das mein Ausgangsbit ist. Bei steigender Flanke des Eingangs um 1 verringern. Bei steigender Flanke des Ausgangsbits zurücksetzen.

Die Einschaltdauer ist unwichtig.

Ist einer davon besser als die anderen? Gibt es eine noch bessere Methode, an die ich nicht gedacht habe?

Gibt es einen "Standard"-Weg, der dem Compiler die besten Chancen zur Optimierung gibt?

Das sind nur drei Optionen :-) ... Aber im Ernst, das spielt in einem FPGA wirklich keine Rolle. Die einzelnen Logikelemente sind allgemein genug, dass sie ungefähr die gleiche Anzahl von Ressourcen benötigen und Ihnen die gleiche Leistung bieten, egal wie Sie es tun. Die Entscheidung hängt davon ab, ob es an anderer Stelle im Design nützlich ist, die Zahlen nach oben oder unten oder nach einem anderen Muster zu zählen.
4. Option: 10-Bit-Kreisschieberegister, das mit "1000000000" geladen und bei einer steigenden Flanke verschoben wird. Verwenden Sie ein Bit des Schieberegisters als Freigabe für das, was Sie tun.
Als Randnotiz - Ihr Compiler/Fitter-GUI-Tool sollte nach Abschluss des Jobs eine Option haben, die Ihnen die tatsächliche Schaltung zeigt, die es auf verschiedenen Abstraktionsebenen bis hin zu Gattern erstellt hat, sodass Sie sehen können, wie das Tool zu Ihrer Schaltung passt und dann können Sie entsprechende Änderungen an der Quelle vornehmen.

Antworten (4)

Die Optimierung auf dieses Niveau wird Ihnen das Herz brechen. Das Ergebnis kann sich aufgrund der Technologie des von Ihnen verwendeten FPGAs, anderer Faktoren im FPGA, aber auch aufgrund von Faktoren außerhalb Ihrer Kontrolle ändern, einschließlich des Zufallszahlen-Seeds des Installateurs.

Trotzdem glaube ich, dass Option 3 die beste sein wird. Die Optionen 1 und 2 haben einen Komparator/ODER-Gatter zwischen den Zählern, um zu signalisieren, dass die Zielzahl erreicht wurde. Option 2 ist möglicherweise etwas schneller als 1, da alles ohne Inverter direkt ODER verknüpft werden kann, aber auch hier stoßen Sie auf kleine technologische Unterschiede, bei denen es möglicherweise schneller zu AND oder XOR geht.

Option 3 überspringt den Vergleich für die geringen Kosten eines zusätzlichen Bits im Zähler. Das sollte sich lohnen, es sei denn, Sie sind in Flip-Flops stark eingeschränkt.

Eine lustige Tatsache über Zähler ist, dass sie dazu neigen, innerhalb eines Logikblocks in einer gerätespezifischen Größe gruppiert zu werden, und Sie werden sehen, dass sich das Timing stärker als erwartet ändert, wenn dieses zusätzliche Bit Sie aus dieser Gruppe drängt.

+1, abgesehen von Taktraten, die die Grenzen der Technologie überschreiten, sollte man sich vom Timing-Bericht bei der Timing-Optimierung leiten lassen. Hunderte von Pikosekunden auf einem Spartan 3e oder einem beliebigen FPGA ohne Grund zu jagen, ist im Allgemeinen Zeitverschwendung.

Eine andere Option wäre, den Zähler auf 6 (= 2 4 - 10) zu initialisieren, hochzuzählen und dann zurückzusetzen, wenn der Übertragsausgang aktiviert wird (dh die FFs sind alle Einsen).

Der Vorteil davon ist, dass kein zusätzlicher FF erforderlich ist und viele FGPAs über eine dedizierte Hilfslogik verfügen, um diese Art von Übertragsoperation in einer Zähler- oder Addiererschaltung zu beschleunigen.

Hängt davon ab. Zum Beispiel: Die Laufzeitverzögerung des Flipflops für 0→1 und 1→0 kann unterschiedlich sein, und daher können die Übergangsverzögerungen eines Zählers für 000→001 und 001→000 leicht unterschiedlich sein. Sie kann höher oder niedriger sein, abhängig von der im FPGA verwendeten CMOS-Technologie. Sie müssen also synthetisieren und herausfinden, welche die bessere Timing-Leistung hat.

Aus der Sicht eines Compiler-Autors: Wenn Sie verwenden integer, ist die interne Darstellung undefiniert, und der Compiler kann die effizienteste Implementierung frei wählen.

Wenn Sie eine bestimmte interne Darstellung erzwingen, wird der Optimierer immer noch versuchen, sie zu verbessern, aber er beginnt von einem etwas schlechteren Standpunkt aus.

Einige FPGAs verfügen über "Vorlade"-Fähigkeiten, bei denen Register auf beliebige Werte initialisiert werden können, wobei in diesem Fall die Initialisierung auf erfolgt N 1 , ist das Herunterzählen und Verwenden des obersten Übertragsbits als Ausgabe und Zurücksetzen (im nächsten Zyklus) effizienter als das Implementieren sowohl eines Addierers als auch eines Komparators. Ohne Vorspannung könnte ein Addierer besser sein.

Es sei denn, Sie kennen die interne Struktur, die Ressourcen, die einer anderen Logik zugewiesen sind (viele FPGAs haben eine dedizierte Gleitkomma-Multiplizier-Addier-Logik, die Sie auch verwenden können, um einen Zähler zu implementieren, wenn Sie übrig gebliebene Einheiten haben) und absolut sicher sind, dass Sie nicht wechseln werden zu einem anderen Modell lautet die Antwort "nicht darüber nachdenken".