Bauen Sie in Wireworld eine Digitaluhr


32

Inspiriert von dieser Game of Life-Frage .

Wireworld simuliert "Elektronen", die durch "Drähte" fließen, deren einfache Anordnungen ein typisches Logikgatterverhalten erzeugen.

Ich fordere Sie auf, eine Digitaluhr im Wireworld-Zellularautomaten zu bauen. Ihre Uhr muss wie gewohnt von 00:00 bis 23:59 Uhr aufwärts zählen oder mit einer AM / PM-Anzeige auf 11:59 Uhr, um dann zurückgesetzt zu werden.

Ihr Eintrag sollte sichtbar in zwei Teile geteilt sein. Teil A sollte die gesamte Nichtanzeigelogik und alle Teile enthalten, die an der Inkrementierung und Schleifenbildung der Ziffern beteiligt sind. Teil B wird das Display und die Logik sein, die es ansteuert. Die einzige Verbindung zwischen diesen beiden Teilen sollte aus 16 Kabeln bestehen, die die vier Stellen der Zeit in BCD darstellen (mit einem optionalen Kabel für die AM / PM-Anzeige und einem optionalen Kabel für eine Signaltaktleitung, wenn Ihre Signale nicht kontinuierlich sind). (BEARBEITEN: immer Null Drähte können weggelassen werden)

Das Timing des Uhrverhaltens sollte konsistent sein. Die Simulation sollte für jeden der 1440 Übergänge zwischen Zuständen dieselbe Anzahl von Ticks aufweisen. Alle Elektronen auf den 16 Drähten sollten gleichzeitig von Teil A emittiert werden und ihre Reise parallel beginnen.

Dies ist ein Code-Golf-Wettbewerb. Ihre Punktzahl ist der Bereich des achsenausgerichteten Begrenzungsrahmens, der Teil A umgibt.

Wenn dies eine Textsprache wäre, würde Ihre Punktzahl der Größe der Taktverwaltungsfunktion entsprechen, die vier 4-Bit-Ausgaben erzeugt, die eine Schleife und die Logik für 4 Zähler enthält, und nicht die Funktion, die diese Ausgabe decodiert und druckt.

Ihr Teil B kann so groß oder klein sein, wie Sie möchten. Es ist nur erforderlich, damit die Ausgabe Ihrer Übermittlung von jemandem gesehen werden kann, der sie ausführt, da es keine einfache Möglichkeit gibt, Ausgaben von einem Wireworld-Schaltkreis einfach zu "debuggen". Es sind mehrere BCD-> 7-Segment-Schaltkreise online verfügbar. Verwenden Sie einfach eine beliebige Option, oder erstellen Sie eine eigene, wenn Sie eine getaktete Signalleitung benötigen, und zeigen Sie Ihre AM / PM-Anzeige in einer Skala an, die den Ziffern ähnlich ist.

BEARBEITEN: Teil B ist jetzt optional. Wenn Sie nur die BCD-Ausgänge von Teil A haben, können Sie diese gerne einreichen. Es wird mühsamer sein, zu bestätigen, dass die Uhr funktioniert, aber ich kann in einer angehaltenen Simulation eine Reihe von Bits gut lesen.


Hier ist ein kleiner Online-Simulator.
NonlinearFruit

Ich habe daran gearbeitet, habe es aber erst letzte Woche gesehen, also werde ich wahrscheinlich das Kopfgeld verpassen. Ich kann keine 4-Draht-Version eines Wireworld-BCD-> 7-Segments finden. Der Bau eines 4-zu-2-Wandlers vor dem beliebten 2-Draht-7-Segment-Gerät (wie dem, das mit Golly geliefert wird) könnte der richtige Weg sein. Ein Problem mit diesem Gerät ist, dass es zwar gut aussieht, aber langsam aktualisiert wird, wodurch die Größe von Teil A aufgebläht wird, da es Zahlen schneller herauspumpen kann, als sie angezeigt werden können, und künstlich verlangsamt werden muss.
Wyldstallyns

Ich
besitze

Ich hatte nicht erwartet, dass Teil B schwierig wird. Wie weit sind Ihre Elektronen in Teil A voneinander entfernt?
Sparr

1
@wyldstallyns Es schließt am 16/12/2016 03: 30: 35Z (Sie können den Mauszeiger über das "Morgen" halten, um die genauen Zeiten zu erhalten). Ich wünsche Ihnen viel Glück. Ich mag deine Uhr wirklich. Es ist eine elegant einfache Idee und eine hervorragende Ausführung. Ich muss zugeben, dass ich auch überrascht war, wie viel Platz ich am Ende einnahm. Und ich würde mich über Verbesserungen freuen, die Sie an Ihren vornehmen können. Also viel Glück :)
niemiro

Antworten:


36

Verriegelungsuhr

Partitur - 53.508 (von denen nur 36.828 aufgrund des L-förmigen Designs aktiv verwendet werden)

Uhr läuft

Aufnahme in hoher Qualität - https://1drv.ms/u/s!ArQEzxH5nQLKhvt_HHfcqQKo2FODLQ
Golly-Muster - https://1drv.ms/u/s!ArQEzxH5nQLKhvwAmwCY-IPiBuBmBw

Leitprinzipien -

  • Da ich zum ersten Mal einen zellularen Automaten verwendete, vermied ich es, große vorgefertigte Komponenten miteinander zu verbinden. Ein gültiger Ansatz, den ich nicht gewählt habe, wäre ein Binäraddierer, der bei Null beginnt und kontinuierlich eins zum letzten Ausgang addiert, gefolgt von einem Binär-BCD-Wandler, einem Display-Demultiplexer, einem 7-Segment-Decoder und einer 7-Segment-Anzeige.
  • Es sollte möglich sein, die Uhr kalt zu starten. Ich habe mir die zusätzliche Einschränkung auferlegt, dass ein einzelner Elektronenkopf, der an einer bestimmten Leiterzelle platziert ist, die Uhr korrekt starten soll. Ich wollte nicht vor Beginn der Simulation eine sorgfältige manuelle Synchronisation vieler unterschiedlicher Flip-Flops und einzelner Zeitsteuerungselemente erfordern.

Teil I: Der Minutenzähler

Mathematik

Das Zählen von 0 bis 9 im Binärformat (für die am wenigsten signifikante Minutenziffer) geht wie folgt vor sich:

0 - 0000
1 - 0001
2 - 0010
3 - 0011
4 - 0100
5 - 0101
6 - 0110
7 - 0111
8 - 1000
9 - 1001

Lesen Sie, dass als Spalten der niedrigstwertige (2 ^ 0-Einheiten-Bitstrom) 01010101, der 2 ^ 1-Einheiten-Strom 0011001100, der 2 ^ 2-Einheiten-Strom 0000111100 und der 2 ^ 3-Einheiten-Strom 0000000011 lautet.

Der erste ist einfach - nur Flip-Flip 01 für immer. Der dritte ist ein Strom von vier Einsen, sechs Nullen, phasenverschoben um sechs Nullen. Der vierte ist ein Strom von acht Nullen und zwei Einsen.

Die zweite ist etwas schwieriger, da sie eine unangenehme Asymmetrie aufweist. Allerdings stelle ich fest, dass (wo. Concat Operator ist):

0011001100. 0011001100 = 0011001100. NOT (1100110011) = 00110011001100110011 XOR 00000000001111111111 = 5 (0011) XOR 000000000011111111

(Übrigens, wie später angedeutet, läuft der Großteil meiner Uhr auf einem 60-Takt-Ticker. Die 00000000001111111111-Welle mit doppelter Länge ist der Punkt, an dem der 120-Takt-Ticker benötigt wird.)

Design

Die Ausgabe-Streams von oben nach unten erfolgen in Einheiten von Minuten (2 ^ 0, 2 ^ 1, 2 ^ 2, 2 ^ 3) und dann in Zehnern von Minuten (2 ^ 0, 2 ^ 2, 2 ^ 1). Beachten Sie, dass die beiden unteren Drähte gekreuzt sind.

Minute Counter Annotated

  1. 120 Takt Hauptuhr.
  2. Wo soll ein Elektron für einen Kaltstart platziert werden? Ohne Elektronenschwanz spaltet es sich in zwei Richtungen, aber die Diode direkt darüber fängt eines dieser Elektronen auf und ergibt ein schönes zyklisches Elektron, das die 120-Takt-Schleife umrundet.
  3. 12-Takt Sekundäruhr.
  4. Die Spule aus Leiter + Diode startet den sekundären 12-Takt. Worte können nicht beschreiben, wie fummelig dieses kleine Stück zu synchronisieren war. Sie müssen die 120- und 60-Takt-Takte synchronisieren, dann die 12-Takt- und die 24-Takt-Pseudotakte des Frequenzhalbierers synchronisieren und anschließend den 24-Takt-Takt mit dem 120-Takt-Takt zurückbinden, da sonst das XOR-Gatter nicht funktioniert .
  5. Phasenverschiebung.
  6. Flip Flops. Ein einzelnes Elektron am Eingang trifft zuerst auf die eingestellte Linie und dann nach einer bestimmten Zeit auf die Rücksetzlinie, wobei genau ein Impuls eingeht, ein Impuls ausgeht.
  7. Das Hinzufügen von Buckeln hier - auf der Rücksetzleitung erhöht die Verzögerung zwischen dem Setzen und dem Zurücksetzen auf dem Flip-Flop. Jeder zusätzliche Buckel gibt einen zusätzlichen Impuls. Das Flip-Flop darunter hat neun zusätzliche Buckel, also zehn Impulse zwischen Setzen und Zurücksetzen.
  8. XOR-Gatter für meine knifflige 2 ^ 1-Minuten-Zeile.
  9. AND-NOT Gate und sehr spezifische Teillängen bedeuten, dass sich jeder Elektronenpuls, der vorbei kommt, auf sich selbst verdoppelt und das dahinter liegende Elektron vernichtet. Frequenz halver. Erstellt eine 24-Takt-Clock aus der 12-Takt-Sekundärquelle.
  10. 60-Takt Sekundäruhr, die eigentlich den größten Teil der Arbeit erledigt. Es ist einfach einfacher, eine schnelle Uhr von einer langsameren zu starten, daher ist die langsamste Uhr (120 Beats) der Master, obwohl sie kaum benutzt wird. Die 60-Takt-Uhr ist das Herzstück dieser Sache.
  11. Rückkopplungskabel, das nur dann Elektronen transportiert, wenn die 60-Takt-Uhr tickt. Es wird in Verbindung mit einem UND-NICHT-Gatter verwendet, um zu verhindern, dass die Uhr vom 120-Takt-Master wiederholt neu gestartet wird. Ansonsten passieren viele schreckliche Dinge und Strg-Z ist der Retter.
  12. Die Diode, von der aus die 60-Takt-Uhr gestartet wird.
  13. Dieses ganze Gerät ist ein Flip-Flop, ein UND-Gatter und ein UND-NICHT-Gatter kombiniert. Es gibt einen Riegel. Ein Puls in startet es, ein Puls in stoppt es.
  14. Drahtschleife zum Kalibrieren des Signalspeichers auf 10 Impulse ein, 10 Impulse aus für einen 1: 10-Impulseingang. Ohne sie bekommen wir 12 Impulse an, 8 Impulse aus. Diese Zehn-auf-Zehn-Aus-Latches bilden die Grundkomponenten der Zehn-Minuten-Blöcke in der gleichen Weise wie die 6-Mikrometer- (1-Puls-) Flip-Flops die Grundkomponenten der Minuteneinheiten bildeten.
  15. Der Kaltstart-Startimpuls verursachte alle Arten von Problemen, einschließlich der Tatsache, dass er mit den Takten, die er startet, zwei Schläge phasenverschoben war. Dies bringt die Laschen durcheinander. Dieses UND-Gatter fängt nicht synchronisierte Impulse ein und entsorgt sie - insbesondere den Startimpuls.
  16. Dies ist ein Teil des Designs, den ich im Nachhinein etwas bedauere. Es nimmt ein Elektron, spaltet es in fünf auf und vernichtet die fünf dahinter liegenden Elektronen, wobei es 111111 bis 100000 nimmt.
  17. Dies nimmt ein Elektron und stickt es auf die Vorderseite. Zwei Phasen voraus, um genau zu sein. Es dauert 100000 und macht 101000. Kombiniert mit Teil 16 erhalten wir 111111 -> 100000 -> 101000. Im Nachhinein wünschte ich, ich hätte 111111 -> 101010 -> 101000 getan; es hätte den gleichen Effekt auf weniger Raum erzielt.
  18. Die obigen Muster werden dann in die untere Verriegelung gedrückt, um 20 Ein, 40 Aus zu erreichen. Dies wird aufgeteilt, die Hälfte wird um 20 Einheiten phasenverschoben, und dann bilden diese die zwei Bitströme höherer Ordnung von einigen zehn Minuten.

Teil II: Der Stundenzähler

Erläuterung

Der Eingang zum Stundenzähler ist ein Einzelelektronenimpuls, einmal pro Stunde. Der erste Schritt besteht darin, diesen einmal alle zwölf Stunden auf einen einzelnen Elektronenimpuls zu reduzieren. Dies wird mit mehreren "Latch & Catch" -Primitiven erreicht.

Ein "Latch" ist ein 6-Mikrometer-Flip-Flop, das mit einem UND-NICHT-Gatter und einem UND-Gatter verbunden ist, um ein 6-Mikrometer-Ein / Aus-Latch zu erhalten. Ein "Fang" nimmt einen kontinuierlichen Strom von Elektronen als Eingang, lässt das erste durch und vernichtet dann jedes andere dahinter liegende Elektron, bis der Strom endet, an welchem ​​Punkt sich der Fang zurücksetzt.

Wenn Sie eine Verriegelung gefolgt von einer Verriegelung hintereinander platzieren, wird ein Elektron einge- schaltet -> die Verriegelung wird eingeschaltet, ein Elektron am anderen Ende (der Rest wird von der Verriegelung eingefangen). Dann zweites Elektron ein -> Latch ausschalten, still fangen, zurücksetzen. Nettoeffekt: Das erste Elektron geht durch, das zweite Elektron wird vernichtet und so weiter und so fort, unabhängig davon, wie lange die Verzögerung zwischen diesen Elektronen dauert .

Verketten Sie nun zwei "Latch & Catch" -Elektronen in Reihe, und Sie haben nur jedes vierte Elektron im Durchgang.

Nehmen Sie als nächstes ein drittes "Latch and Catch", aber binden Sie dieses Mal ein ganzes viertes Latch ein und fangen Sie an der Flip-Flop-SET-Leitung zwischen dem AND-NOT-Gatter und dem Flip-Flop-SET. Ich überlasse es Ihnen, darüber nachzudenken, wie dies funktioniert, aber dieses Mal passiert nur eines von drei Elektronen, unabhängig davon, wie lange die Verzögerung zwischen diesen Elektronen dauert .

Nehmen Sie zum Schluss eines von vier Elektronen und eines von drei, kombinieren Sie sie mit einem UND-Gatter, und nur eines von zwölf Elektronen tritt durch. Dieser ganze Abschnitt ist das chaotische Kräuseln der Pfade links oben im Stundenzähler unten.

Nehmen Sie als nächstes alle zwölf Stunden das Elektron und teilen Sie es jede Stunde wieder auf, aber geben Sie es jeweils auf einen anderen Leiterdraht aus. Dies wird mit dem langen Wendelleiter mit dreizehn Austrittspunkten erreicht.

Nehmen Sie diese Elektronen - eine Stunde lang auf verschiedenen Leitern - und treffen Sie eine Flip-Flop-SET-Leitung. Die RESET-Leitung auf demselben Flip-Flop wird dann von dem Leiter der nächsten Stunde getroffen, wobei 60 Impulse pro Draht pro Stunde abgegeben werden.

Schließlich - nimm diese Impulse und lasse sie in siebeneinhalb Bytes ROM (Nur-Lese-Speicher) laufen, um die korrekten BCD-Bitströme auszugeben. Weitere Informationen zu WireWorld ROM finden Sie hier: http://www.quinapalus.com/wires6.html

Design

Stundenzähler mit Anmerkungen versehen

  1. Ein Elektron pro Stunde.
  2. Erster Riegel.
  3. Erster Fang.
  4. "Latch & Catch" eingebettet in eine äußere SET-Zeile "Latch & Catch".
  5. UND Tor.
  6. AM / PM-Verriegelung (einmal alle zwölf Stunden ein- / ausgeschaltet).
  7. Jede Drahtschleife ist 6x60 = 360 Einheiten lang.
  8. Flip / Flop drehte sich auf die Seite, um ein kleineres Profil zu erstellen.
  9. Siebeneinhalb Bytes ROM.

Anmerkungen

  1. Aufgrund des 6-Mikrometer-Designs mit einem Elektron pro Minute kann die Simulation für eine Echtzeituhr mit sechs Generationen pro Minute (eine Generation alle 10 Sekunden) ausgeführt werden.
  2. Die AM / PM-Leitung ist für AM hoch (1), für PM niedrig (0). Dies mag ein wenig ungewöhnlich erscheinen, aber es gibt eine Rechtfertigung. Während eines Kaltstarts der Uhr ist die AM / PM-Leitung anfangs natürlich niedrig (0). Sobald die AM / PM-Linie hochgezogen ist (1), zeigt dies an, dass die Zählung um 12:00 Uhr begonnen hat. Alle Ausgaben vor diesem Punkt sollten ignoriert werden. Alle Ausgaben nach diesem Punkt werden als sinnvoll angesehen.

Nützliche Links


geänderte Anforderungen, so dass immer Null-Ausgänge weggelassen werden können. Die 4s und 8s Bits für die zehn Stunden werden niemals verwendet, und die 8s Bits für die zehn Minuten.
Sparr

Solide! Echte Technik. Wäre eines der anderen Logikgatter nützlich gewesen? Ich bin dabei, einige zu brachialisieren.
Wyldstallyns

1
Das ist wunderschön
Sparr

1
Oh, gute Trauer, das ist gerade nah genug, jetzt bin ich gezwungen, meine zu optimieren. Ich habe sich wiederholende Muster, die ich kürzen könnte, um Platz für andere zu schaffen.
wyldstallyns

3
Ich weiß nicht, wie aktiv Sie bei Meta sind. Dies soll Ihnen mitteilen , dass ich diese Antwort für das Best of PPCG 2016 nominiert habe .
Peter Taylor

5

Verzögerungszeilenspeicher - 51 x 2880 = 146880

Bild

Herausgezoomt:

Bild

Die Ausgabe erfolgt am Anfang jeder Schleife.

Ich habe mit dieser Lua alle Zustände direkt auf den Draht gesetzt und gollydie Elektronen zwischen den Bits vorwärts laufen lassen, damit wir dem Draht nicht mit einem Cursor folgen müssen.

Ich habe diese naive Methode benutzt, um einen Barren- und Crashkurs zu setzen, wireworld, golly und lua.

local g = golly()

local minutes_in_day = 1440 -- 60x24
local interval = 4 -- how often to send electrons

local function bcd4(num)
    num=math.floor(num)
    local t={}
    for b=4,1,-1 do
        t[b]=math.floor(math.fmod(num,2))
        num=(num-t[b])/2
    end
    return table.concat(t)
end

local function makewire(x,y1,y2)
    for y1=1,y2 do g.setcell(x,y1,3) end
end

local function makeloop(x,y,size)
    local len = size/2 - 1
    makewire(x,y+1,len); makewire(x+2,y+1,len) -- main wires
    g.setcell(x+1,y,3); g.setcell(x+1,y+len,3) -- endcape
end

local function paint(x,y,pattern)
    for v in string.gmatch(pattern,".") do
        if v=="1" then g.setcell(x, y, 1); g.setcell(x, y-1, 2) end
        x = x + 4
    end
    g.show(pattern);g.update() -- slows things down but more interesting to watch
    for i=1,interval do g.step() end
end

for x=0,63,4 do makeloop(x,0,minutes_in_day * interval) end

for hour = 0,23 do
      for minute = 0,59 do
         paint( 0, 2, bcd4(hour/10) .. bcd4(hour%10) .. bcd4(minute/10) .. bcd4(minute%10) )
      end
end

Zum Testen habe ich diese oberen Drähte hinzugefügt und ihre Tipps angesehen.

Imgur

Hier ist das Skript, um die 4 Sätze von 4-Draht-BCD zu Augapfel zu sammeln.

-- watches 16 wires spaced 4 apart starting at (0,-4)
local ticks = 1440 -- set to match the length of your 24 hour loop
local g = golly()
local output = ""
local nums = {  ["0000"] = "0", ["0001"] = "1", ["0010"] = "2", ["0011"] = "3", ["0100"] = "4",
                ["0101"] = "5", ["0110"] = "6", ["0111"] = "7", ["1000"] = "8", ["1001"] = "9",
                ["1010"] = "A", ["1011"] = "B", ["1100"] = "C", ["1101"] = "D", ["1110"] = "E",
                ["1111"] = "F" } -- full set in case we have errors (i did)

for i=0,ticks,1 do
   local text = ""
   for i=0,48,16 do -- set your X here, change the 0 and 48
       local word = ""
       for j=0,15,4 do
            local bit = g.getcell(i+j,-4) -- set your Y here, change -4
            if bit == 0 or bit == 3 then word = word .. "0" else word = word .. "1" end
       end
       text = text .. nums[word]
   end
   g.show(text); output = output..' '..text
   g.update(); g.step();g.step();g.step();g.step()
end
g.note(output)

Die endgültige Antwort erfordert das Beschneiden der Null-Zeilen und das Weiterleiten der restlichen Zeilen an die richtigen BCD-Eingänge.


geänderte Anforderungen, so dass immer Null-Ausgänge weggelassen werden können. Die 4s und 8s Bits für die zehn Stunden werden niemals verwendet, und die 8s Bits für die zehn Minuten.
Sparr

2
Dies ist eine lustige und großartige Implementierung!
Sparr

1
Ok, ich bin um die 11. Stunde mit einer anderen funktionierenden Uhr geschlagen worden. Ich werde die längsten und kürzesten Loops mit verschiedenen Tricks angreifen.
Wyldstallyns

Ich werde es nicht schaffen. Ich kann 1/4 der Größe einsparen, indem ich auf 3-Mikrometer-Impulse umschalte, aber es wird immer noch nicht fest genug gewickelt, um niemiro zu schlagen.
Wyldstallyns
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.