Holen Sie sich die Anzahl der gesetzten Bits in der digitalen Logik


9

Als Übung versuche ich, eine Implementierung von Conways Spiel des Lebens in einfacher digitaler Logik zu entwerfen. Ich könnte das Ganze tun, indem ich eine 9-Variablen-Funktion minimiere, aber ich stelle mir vor, dass das immer noch ziemlich groß sein wird. Eines der Kernelemente des Algorithmus ist die Bestimmung, wie viele Ihrer 8 Nachbarn "leben".

Was ist bei 8 Eingängen der einfachste Weg, um festzustellen, wie viele eingestellt sind? Insbesondere brauche ich einen Ausgang, der hoch ist, wenn 2 eingestellt sind, und einen Ausgang, der hoch ist, wenn 3 eingestellt sind.

Meine Hauptidee besteht jetzt aus einem PISO-Schieberegister, einem Zähler und einem 3: 8-Decoder, aber ich brauche so ziemlich einen Mikrocontroller, um all das anzutreiben. Es scheint nicht so kompliziert von einer Funktion zu sein. Vielleicht würde auch ein 256x2-ROM funktionieren, aber meine Suche hat keinen solchen Teil ergeben.

Ich weiß, dass jedes Bild mit 10 IO dies trivial tun kann, aber ich möchte es so minimal wie möglich implementieren.

Antworten:


13

Möglicherweise finden Sie die verschiedenen Algorithmen zur schnellen Bitzählung aufschlussreich. Die letzten beiden: Nifty Parallel Count und MIT HAKMEM Count lassen sich möglicherweise leicht in Gates umwandeln. Auf dieser Seite finden Sie eine gute Erklärung der Funktionsweise.

Sie können dies mit Gates-Hardware tun. Verwenden Sie vier 1-Bit-Addierer, um Bitpaare zu addieren. Dies gibt Ihnen vier 3-Bit-Zahlen. Fügen Sie diese paarweise mit zwei 3-Bit-Addierern hinzu. Dies gibt Ihnen zwei 4-Bit-Zahlen, die Sie mit einem einzigen 4-Bit-Addierer hinzufügen können. Dadurch erhalten Sie einen 5-Bit-Wert, aber Sie können das oberste Bit ignorieren. Verwenden Sie dann zwei 4-Bit-Komparatoren, um die Werte 2 und 3 zu testen.

Warum nicht analog?

Erstellen Sie einen Spannungsteiler mit einem Widerstand oben und Ihren 8 Eingängen, die über 8 Widerstände parallel mit dem Boden verbunden sind. Verwenden Sie dann einfach zwei eingestellte Komparatoren, um die Spannungspegel zu ermitteln, die 2 oder 3 Bit erzeugen. Das sind nur 6 Teile:

Bitzählungsdetektor

Das 8-Widerstands-Netzwerk erzeugt eine Spannung zwischen 0 V (für 0-Bit-Sätze) und 5 V (für 8-Bit-Sätze). 2 Bits erzeugen 0,5 V. 3 Bits erzeugen 1,56 V.

  • Bei 0 oder 1 Bit ist der Ausgang 00.
  • Bei 2 oder 3 Bits ist der Ausgang 01.
  • Bei 4 oder mehr Bits beträgt die Ausgabe 11.

Hinzugefügt:

Vielen Dank an DavidCary für einen hervorragenden Vorschlag. Nach vielen Berechnungen habe ich wahrscheinlich eine Reihe von Widerständen gefunden, die funktionieren, aber Sie sollten zuerst meine Berechnungen sorgfältig überprüfen. Hier verwende ich Komparatoren mit Open-Drain-Ausgängen und ich denke, ich habe es geschafft, einen einzigen Ausgang zu erhalten. Niedrig bedeutet tot in der nächsten Runde, Hoch bedeutet lebendig in der nächsten Runde.

Conways Spiel des Lebens Kreislauf 2

Das Schöne ist, dass diese Schaltung nur zwei Komponenten mehr hat als die andere Schaltung. Es sind alles Widerstände der E8-Serie, daher sollte es möglich sein, sie zu erreichen. Außerdem sollte R6 ein höherer Wert sein, wie 4,7 KB oder so.


4
+1, nur weil Ihre Antwort nicht "Mikrocontroller verwenden" lautet . Das scheint hier der Standardmodus zu sein.
Connor Wolf

@FakeName: Die erste Referenz bezieht sich auf Softwarelösungen. Natürlich müssen Sie sie nicht auf einem Mikrocontroller implementieren, Sie können auch einen Supercomputer verwenden :)
Federico Russo

@FedericoRusso - Ich habe diese Verweise auf Softwarelösungen gegeben, die einen Einblick geben, wie er sie in Hardware implementieren könnte.
Raketenmagnet

3
Vielleicht: Fügen Sie einen 9. "Summierwiderstand" von 20 kOhm vom aktuellen Zustand der zentralen Zelle zum Summierpunkt "+" des Operationsverstärkers in der Schaltung von Rocketmagnet hinzu - geben Sie der zentralen Zelle ein Gewicht von 1 und den 8 benachbarten Zellen ein Gewicht von 2. Dann den Spannungsteiler so einstellen, dass "Geburt" (zentrale tote Zelle mit 3 lebenden Nachbarn; Summe = 6) und "am Leben bleiben" (zentrale tote Zelle am Leben mit 2 oder 3 lebenden Nachbarn, Summe = 5 oder 7) gibt Ausgänge von "01"; und alle anderen Fälle (in denen die zentrale Zelle stirbt oder tot bleibt) ergeben Ausgaben von "00" oder "11". Dann gibt ein XOR-Gatter den nächsten Zustand der zentralen Zelle an.
Davidcary

1
Ein paar Dinge, die ich beim Experimentieren gefunden habe: Die Widerstände sind nicht ganz richtig. Ich habe ein paar bessere Kombinationen gefunden, aber ich versuche immer noch zu optimieren. Wenn Sie ein Gitter daraus erstellen, fließt der Strom durch die Summierwiderstände zurück und bringt die Dinge durcheinander. Dioden auf den Interlinks sind eine Möglichkeit, dies zu verhindern.
Captncraig

6

Was ist minimal? Der Mikrocontroller besteht nur aus einem Teil und kann das Ergebnis mit einer minimalen Verzögerung (<1 s) erzeugen . Mit 54 Cent ist der ATTiny20 der billigste Mikrocontroller mit 10 E / A bei Digikey. μ

Die Nachschlagetabelle besteht ebenfalls nur aus einem Teil und ist schneller als der Mikrocontroller. Vergessen Sie parallele EEPROMs, sie sind teuer. Verwenden Sie einen byteweiten parallelen Flash . Dieser ist 512 kByte, das ist 2000-mal mehr als das, was Sie brauchen, aber es ist die billigste Lösung (1 Dollar). Und Sie können 6 weitere 1-Bit-Funktionen zum gleichen Preis hinzufügen.

Sie können auch eine CPLD verwenden . Schreiben Sie die Funktion in VHDL oder Verilog als eine lange SOP-Anweisung (Sum Of Products) und lassen Sie den Synthesizer die Logik erstellen.

Das Schieberegister ist in Ordnung, wenn Sie auf das Ergebnis warten können. Dies ist die langsamste Lösung.

Schließlich können Sie dies mit Logikgattern tun , aber Sie werden viel Zeit damit verbringen, die SOP auf ihre minimale Form zu reduzieren, wenn Sie alle grundlegenden Funktionen ausführen möchten. Rocketmagnet hat die richtige Idee, Addierer zu verwenden, aber seine Zahlen sind falsch: Ein 1-Bit-Halbaddierer ergibt 2 Bit, nicht 3. Das Addieren der Ausgänge der Halbaddierer zwei mal zwei erfordert also zwei 2-Bit-Halbaddierer, was zwei 3- ergibt. Bit Ergebnisse. Verwenden Sie einen 3-Bit-Halbaddierer, um das 4-Bit-Ergebnis zu erhalten. Bei Verwendung von 1-Bit-Volladdierern benötigen Sie nur einen 2-Bit-Addierer.


1

Hybride parallel-sequentielle Schaltungen sind tendenziell viel kompakter als rein parallele Schaltungen. Wenn Sie beispielsweise die Regeln so anpassen, dass eine 3x3-Box die Zelle in der Mitte tot macht, wenn weniger als drei lebende Zellen oder mehr als vier vorhanden sind, und sie live dreht, wenn genau drei lebende Zellen vorhanden sind (das Verhalten unter diesen) neue Regeln stimmen mit dem Original überein), man kann die Logik vereinfachen, indem man eine zweistufige Sequenz ausführt:

tempVal [x, y] = orig [x-1, y] + orig [x, y] + orig [x + 1, y] 'Zwei-Bit-Summe von drei Ein-Bit-Zahlen
orig [x, y] = LiveDeadFunc (orig [x, y], tempval [x, y-1] + tempVal [x, y] + tempVal [x, y + 1])

Das Array tempVal[x,y]hat zwei Bits pro Zelle; Die letztere Operation summiert drei solcher Zahlen, um einen Wert von 0 bis 9 zu erzeugen (obwohl alle Werte über vier gleichwertig sind), der dann verwendet werden kann, um einen Einzelbit-Live / Dead-Status für die nächste Generation zu berechnen.

Übrigens wäre eine Alternative zum Berechnen einer arithmetischen Summe in der zweiten Stufe und zum Untersuchen des Werts, TempVal [x, y] in eine One-Hot-Darstellung umzuwandeln und dann explizit nach einer der neun Wertekombinationen zu suchen, die drei ergeben würden Zellen oder eine der zwölf, die vier ergeben würde.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.