Ich arbeite an einem FPGA-Projekt, bei dem eine Host-CPU eine 10.240 x 16-Bit-Nachschlagetabelle in die FPGA-Logik schreibt. Um dies zu implementieren, habe ich einen On-Chip-Speicher verwendet, um die Werte zu speichern und sie auszulesen, wenn sie fertig sind.
Ein externer Trigger/Go-Impuls startet einen Verarbeitungszyklus, der mehrere hunderttausend Taktzyklen dauert. Sobald wir diesen Trigger erhalten, muss der Zustand der 10.240 x 16 LUT eingefroren oder zwischengespeichert werden, damit er während des Verarbeitungszyklus verwendet werden kann. Unglücklicherweise müssen die Daten ziemlich bald nach diesem "GO"-Impuls verfügbar sein, so dass nicht genügend Zeit vorhanden ist, um eine vollständige Pufferkopie durchzuführen.
Der Host muss auch in der Lage sein, einige Werte der Nachschlagetabelle kontinuierlich zu aktualisieren, während der aktuelle Zyklus ausgeführt wird, um sich für den nächsten Verarbeitungszyklus einzurichten. Um beide Fälle zu ermöglichen (den Status der Nachschlagetabelle zu speichern, aber auch den Host jederzeit aktualisieren zu lassen), denke ich, dass der Ping/Pong-Stil mit doppelter Pufferung der richtige Weg ist: Der Host schreibt in einen Puffer, bis wir dazu kommen "GO"-Befehl, dann schreibt der Host zum anderen. Die FPGA-Logik liest immer aus dem Puffer, in den nicht geschrieben wird.
Da der Host jedoch nicht alle 10.240 x 16-Werte neu schreibt, wenn er seine sporadischen Aktualisierungen durchführt, "verwirft" der Puffer, in den nicht geschrieben wird, die Aktualisierungen im Wesentlichen, während er eingefroren ist.
Gibt es eine neuartige Möglichkeit, mit diesem Szenario umzugehen? Ich denke, es muss eine Art Puffer-Resynchronisierungsprozess geben, sobald der Puffer aufgetaut ist.
Eine mögliche Strategie könnte darin bestehen, veraltete Bits zu verwenden. Keine Ahnung, ob das Standardterminologie ist, aber es ähnelt einem schmutzigen Bit. Das Schreiben eines neuen Eintrags löscht das entsprechende Stale-Bit im entsperrten Puffer und setzt das Bit im gesperrten Puffer. Lassen Sie nach dem Umschalten der Puffer eine interne Kopierroutine jeden als veraltet markierten Eintrag im nicht gesperrten Puffer aus dem gesperrten Puffer in den nicht gesperrten Puffer übertragen. Auf diese Weise werden neue Daten, die während des Kopiervorgangs geschrieben werden, nicht überschrieben, und alle alten Aktualisierungen sollten beibehalten werden. Das einzige, was Sie tun müssen, ist sicherzustellen, dass genügend Zeit für den Kopiervorgang zwischen den Pufferwechseln bleibt, oder Sie benötigen eine Art Optimierung, um zu verfolgen, welche Einträge veraltet sind, damit Sie nicht alles wiederholen müssen sie, was den Kopiervorgang beschleunigt.
Eine andere mögliche Strategie könnte darin bestehen, die aktualisierten Einträge zu speichern, während ein einzelner Puffer gesperrt ist, und dann nur diese Aktualisierungen anzuwenden, wenn er entsperrt ist. Wenn nur eine Handvoll Einträge aktualisiert werden, ist dies möglicherweise effizienter. Die Aktualisierungen könnten als verknüpfte Liste oder ähnliche Datenstruktur gespeichert werden, so dass die Liste effizient durchlaufen werden kann, während mehrere Aktualisierungen an derselben Stelle zusammengeführt werden können.
Wenn es keine Gründe gibt, dies nicht zu tun, würde ich Folgendes tun:
DonFusili