Der Suche nach dem nächsten im round-robin-scheduling von bit twiddling
Betrachten Sie das folgende problem. Haben Sie ein bit-string für den aktuellen geplanten slave in-one-hot-Codierung. Zum Beispiel, "00000100" (mit die am weitesten Links stehende bit #7 und am weitesten rechts liegenden #0) bedeutet, dass der slave #2 ist geplant.
Nun, ich möchte, um die nächste geplante slave in einem round-robin-scheduling-Schema, mit einem twist. Ich habe eine "Anfrage-Maske", die sagt, die Sklaven eigentlich wollen geplant werden. Der nächste slave wird wieder nur von denen, die wollen.
Einige Beispiele (angenommen, round-robin-scheduling erfolgt durch drehen nach Links).
Beispiel1:
- Aktuell: "00000100"
- Maske: "01100000"
- Nächsten Termine: "00100000" - in der normalen round-robin -, #3 und #4 kommen sollte, nach #2, aber Sie nicht verlangen, also #5 ist ausgewählt.
Beispiel2:
- Aktuell: "01000000"
- Maske: "00001010"
- Weiter: "00000010" - weil Planung ist mit dem Rad Links, und #1 ist die erste anfordernde slave-in dieser Reihenfolge.
Nun, dies kann leicht codiert in einer Schleife, die ich kenne. Aber eigentlich möchte ich, um mein Ergebnis mit einer bit-twiddling-Betrieb, ohne Schleifen. Die motivation: ich möchte, um dies zu implementieren in hardware (FPGA) in VHDL/Verilog.
Einen bonus ist ein Algorithmus, der den generische für jede Menge Sklaven N.
Übrigens, dies ist keine Hausaufgaben Frage. Es ist ein wichtiges problem ist, Wann immer man will, zu planen Sklaven in irgendeiner Art und Zustand der Planung von den Sklaven fordert. Meine aktuelle Lösung ist etwas "schwer" und ich wollte wissen, ob ich etwas fehlt offensichtlich.
- Ich habe eine hardware-zentriert digital-logic solution: stackoverflow.com/questions/480405/..., Dies war ein sehr Interessantes problem! Ich konnte es nicht weglegen 🙂
Du musst angemeldet sein, um einen Kommentar abzugeben.
Einer Schleife muss nicht schlecht sein.
Ich würde einfach das tun,
Und dann legen Sie Sie in einer Schleife generieren (dh es wird aufgerollt in hardware), die produzieren parallel-hardware für die Ausdrücke.
Anderen hier erwähnten Lösungen verwenden mehrere "-". Ich kann nur raten Sie Ihnen, wie diese erhalten Sie eine wirklich teure operation. Esp. in einem heißen, Sie kann leicht mehr als > 32 bits, die nicht so leicht umsetzbar sind, in HW, wie das ausleihen über alle bits (die deadicated carry-Logik auf bestimmte fpgas machen es zugänglich für die kleine Anzahl von bits).
Habe ich Folgendes gefunden Verilog-code für die Umsetzung der Aufgabe in die Altera erweiterte Synthese Kochbuch.
Es nutzt die Subtraktion (nur einmal, obwohl), so konzeptionell ist es ganz ähnlich wie Doug die Lösung.
Folgende Lösung funktioniert für eine beliebige Anzahl von slaves (K), und ist O(n), die in Ihrem FPGA. Für jedes bit in dem Feld, Sie benötigen drei Logik-Gatter und zwei invertern. Getestet habe ich das Konzept mit einem Logik-simulator, und es funktioniert.
Die Kette von Logik-Gattern, die zwischen aktuell und die Maske im wesentlichen erstellt eine Priorität system, das begünstigt bits "unten" in der Kette. Diese Kette geschlungen ist, an den enden, aber der aktuell bits verwendet werden, die Kette zu durchbrechen.
Visualisierung der Bedienung, stellen Sie sich vor, dass etwas 3 liegt in der aktuell - Feld, und Folgen Sie den signal nach unten im Diagramm. Die logische eins an der bit - 3 Orte einer logischen null am Eingang des ersten UND-Gatter, das garantiert, dass der Ausgang dieses UND-Gatter wird auch null sein (dies ist, wo der ODER-gate-Kette ist gebrochen). Die null am Ausgang des ersten UND-Gatter stellen Sie ein ein an den Eingang der zweiten UND-Gatter. Das macht bit - 2 von weiter direkt abhängig von bit 2 von die Maske.
Nun, die Kette der ODER-Gatter ins Spiel kommt.
Wenn bit 2 von die Maske gesetzt wurde, wird der logische Ausgang von dem ODER-Tor direkt auf der linken Seite ist es auch eine, die eine logische eins am Eingang zu dem UND-Gatter unten etwas 2 von aktuell (der gleich null sein wird, da nur ein bit in aktuell können gleichzeitig eingestellt werden). Die logische eins am Ausgang des top-gate UND stellen eine logische null am Eingang des unteren UND-Gatter, damit Sie bit 1 von weiter gleich null.
Wenn bit 2 von die Maske wurde nicht gesetzt ist, sind beide Eingänge zu dem ODER-Tor auf null, so dass der Ausgang der UND-Gatter unten etwas 2 von aktuell wäre eine null, wodurch man am Eingang zum unteren AND-Gatter, und so etwas 1 von weiter, abhängig von bit 1 von die Maske.
Dieser Logik folgt die Kette der ODER-Gatter "bis" die bits, die Umschlingung von der linken Seite wieder zur rechten Seite, zu gewährleisten, dass nur ein bit in weiter kann man. Die Schleife wird beendet, sobald es seinen Weg zurück zu bit - 3 von aktuell, als Ergebnis, dass das bit gesetzt. Dies verhindert, dass die Schaltung von einem Aufenthalt in einer ewigen Schleife.
Habe ich keine Erfahrung mit Verilog oder VHDL, also lasse ich den eigentlichen code, bis Sie und der rest von stackoverflow.
alt-text http://img145.imageshack.us/img145/5125/bitshifterlogicdiagramkn7.jpg
Hinweise:
Interessantes problem! Ich kann mir nicht helfen, aber Frage mich, wenn Sie können nicht vereinfachen Sie Ihre scheduler-Betrieb, so dass diese Art der operation notwendig wäre.
Gegeben, dass Sie wissen, VHDL, ich werde nicht ins detail gehen, aber mein Vorschlag wäre der folgende:
Verwenden Sie ein 3-bit-encoder drehen Sie den derzeit geplanten task in eine Reihe:
01000000 --> 6
Dann mit einem barrel-shifter zum drehen der Maske durch die Anzahl + 1 (zum überspringen der aktuellen Aufgabe):
00001010 --> 00010100
Dann verwenden Sie einen priority-encoder zu finden, der erste verfügbare "weiter" Aufgabe:
00010100 --> 00000100 --> 2
Dann rückwärts den Lauf-Verschiebung durch den Zusatz:
(2+7) % 8 = 1
Welche, wenn Sie re-codiert werden, geben die nächsten geplanten Aufgabe:
00000010
Sollte sehr schnell und einfach, obwohl der barrel-shifter ist "teuer" in Bezug auf realestate, aber ich sehe nicht einen einfachen Weg, das zu umgehen, im moment.
Edit: Doug die Lösung ist deutlich eleganter...
-Adam
Wieder entfernen 1 ist die grundlegende Idee hier. Es wird benutzt, um cascade leiht sich durch die bits die nächste Aufgabe zu finden.
Dies wird eine Schleife verwenden, die intern aber...
Vorausgesetzt, zweier-Komplement-Darstellung ist, rufen Sie Ihre zwei Worte
mask
undcurrent
im C:Sollte dies tun, was Sie wollen:
Grundsätzlich, duplizieren Sie die bits für die nächste Aufgabe, die Maske, maskieren der bits, die wir nicht berücksichtigen möchten, finden Sie die niedrigste gesetzte bit, Falten Sie die high-bits zurück, dann nehmen Sie das niedrigste bit gesetzt. Diese läuft in konstanter Zeit.
Edit: Update zu berücksichtigen current == 00010000 und next_mask == 00111000
Ungetestet, aber aus der Spitze von meinem Kopf, ich würde mich Wundern, wenn diese nicht produzieren ma vernünftige Synthese... Hat den Vorteil, dass Sie relativ gut lesbar (für mich jedenfalls) im Gegensatz zu den typischen bit-twiddling hacks.
Komplette parametrizable Schiedsrichter-Implementierung konfiguriert werden können für das round-robin oder Priorität der Schiedsverfahren:
https://github.com/alexforencich/verilog-axis/blob/master/rtl/arbiter.v
Dieses design verwendet ein paar von priority-Encoder zur Auswahl der nächsten Ausgabe in der Reihenfolge. Der priority Encoder verwendet werden effizient umgesetzt, wie Bäume.