Kompakter Mehrzyklus-Addierer für FPGA: Addieren von 1 zum breiten Zähler

Ich möchte eine Art Ereigniszähler in meinem FPGA-Design (Vendor-A oder Vendor-X) implementieren. Ich habe mehrere Dutzend Signale: Die Hälfte ist 1-Bit und die andere Hälfte 5-Bit. Signale befinden sich in verschiedenen Teilen meines Designs.

Ich möchte die Summe aller Signale gleichzeitig zählen. Das Signal kommt mit hoher Frequenz, die Summe aller Signale sollte in ein 48- oder 64-Bit-Register oder einen Speicher geschrieben werden. In meinem FPGA ist nicht viel freier Speicherplatz, und ich möchte keinen 64-Bit-Breitaddierer verwenden, sondern etwas kompakteres finden (in Bezug auf die Anzahl der erforderlichen LUTs).

Wie soll ich meinen Addierer kompakter gestalten? Soll ich es in einen kleinen, schnell zählenden Zähler (mit 8, 12 oder 16 Bit) und einen langsamen und kompakten seriellen Addierer für die verbleibenden Bits aufteilen, der den Übertrag des kleinen Zählers verwendet? Ein kleiner Zähler sendet nicht zu oft Carry, sodass ich Hunderte von Ticks habe, um an breiteren Teilen im Multicycle-Addierer zu arbeiten. Kann ich einen seriellen Addierer mit mehreren verschiedenen kleinen Zählern verwenden?

Die meisten FPGA-Fabrics dieser Anbieter haben einen „arithmetischen Modus“ für LUTs, der die Implementierung von Volladdierern sehr billig macht, daher bin ich mir nicht sicher, ob Sie hier viel optimieren können.
Es gibt nur eine schnelle Carry-Kette in LUTs (wie viel LUT-4 von Cyclone4 werden für 64-Bit-Addierer bei 50 oder 75 MHz benötigt?). Ich denke, dass die serielle (byte-seriell, bit-seriell) Mehrzyklus-Implementierung weniger LUTs verwenden kann, als für Hochfrequenz-1-Zyklus-64-Bit-Addierer in voller Breite benötigt werden.
Sie kennen Carry-Save-Addierer? In ähnlicher Weise könnte das Register mit 48 Datenbits redundante Informationen zum Vorbestimmen des Carry-Through für große Chunks enthalten (höherwertige Bits erfahren nur eine Inkrementierung; nur ein Chunk führt eine Inkrementierung durch, die anderen werden auf Null gesetzt oder nie erreicht) oder zum Speichern eines Übertrags (was eine langsamere "Normalisierung" des Registerwerts erfordert). (Sie haben vielleicht schon darüber nachgedacht; ich bin kein Hardware-Designer, sondern nur ein Enthusiast für Computerarchitektur.)
Die Hauptschwierigkeit, die ich sehe, ist, dass Sie immer noch den aktuellen Zählerwert an den Addierer bekommen müssen. Wenn der Wert in Registern gespeichert wird, nehmen diese sowieso LUTs in Anspruch, aber Sie erhalten zusätzlichen Overhead für die Adressierung.

Antworten (1)

Sie haben es nicht gesagt, aber es scheint offensichtlich, dass Sie diesen Ereigniszähler akkumulieren, damit er für einen bestimmten Zweck aus dem FPGA ausgelesen werden kann. Das bedeutet, dass Sie einige Vorkehrungen getroffen haben, um Registerinhalte herauszubringen, vermutlich unter einer gewissen Softwaresteuerung.

Ich würde das einfach erweitern, um das Auslesen kleinerer Zähler zu ermöglichen, anstatt zu versuchen, alles in diesen riesigen Zähler zu quetschen. Platzieren Sie diese kleineren Zähler im Design dort, wo die einzelnen Ereignisse gezählt werden müssen, und lassen Sie sie dann von der Software auslesen. Software kann die Zwischensummen hervorragend addieren. Und wer weiß, vielleicht ist es von Vorteil zu wissen, was die verschiedenen Zwischensummen waren.

Ja, ich benötige eine Software-Auslesung, aber diese Auslesung soll selten (ca. 1 pro Minute) und möglicherweise nicht regelmäßig erfolgen. Meine Idee war also, die vollständigen Summen seit dem Einschalten in der Hardware zu haben und sie bei Bedarf oder per Daemon auszulesen. Einige der Ereignisse signalisieren +1 (oder +15 oder +30 im Breitsignal), um mit sehr hoher Rate zu kontern, zum Beispiel bei 1/4 oder 1/3 aller Ticks bei 50 MHz, also habe ich in 1 Minute 1 Gevents und ich brauchen mindestens 32 Bit. Ich habe bereits 20 Signalpunkte und möchte sie vergleichen und keinen davon verlieren, falls der Daemon nicht rechtzeitig vom Betriebssystem geweckt wurde, also sind 40 - 48 Bit besser.