Zbuduj zegar cyfrowy w Wireworld

32

Zainspirowany tym pytaniem Game of Life .

Wireworld symuluje „elektrony” przepływające przez „druty”, których proste układy wytwarzają typowe zachowanie bramki logicznej.

Wzywam was do zbudowania zegara cyfrowego w automacie komórkowym Wireworld. Twój zegar musi liczyć w górę od 00:00 do 23:59 w zwykły sposób lub do 11:59 ze wskaźnikiem AM / PM, a następnie zresetować.

Wpis powinien być wyraźnie podzielony na dwie części. Część A powinna zawierać całą logikę nie wyświetlającą się, wszystkie części zaangażowane w inkrementację i zapętlanie cyfr. Część B będzie wyświetlaczem i logiką, która je napędza. Jedynym połączeniem między tymi dwiema częściami powinno być 16 przewodów reprezentujących cztery cyfry czasu w BCD (z jednym opcjonalnym przewodem dla wskaźnika AM / PM i jednym opcjonalnym przewodem dla linii zegara sygnału, jeśli sygnały nie są ciągłe). (EDYCJA: zawsze można zerować przewody)

Czas zachowania zegara powinien być spójny. Symulacja powinna przyjąć taką samą liczbę tyknięć dla każdego z 1440 przejść między stanami. Wszelkie elektrony na 16 drutach powinny jednocześnie emitować z części A i rozpocząć swoją podróż równolegle.

To zawody w golfa. Twój wynik to obszar wyrównanej do osi ramki ograniczającej otaczającej część A.

Analogicznie, gdyby był to język tekstowy, twój wynik byłby wielkością funkcji zarządzania zegarem wytwarzającej cztery 4-bitowe wyjścia, które zawierają pętlę i logikę dla 4 liczników, a nie funkcję dekodującą i drukującą to wyjście.

Twoja część B może być tak duża lub mała, jak chcesz. Jest to wymagane tylko po to, aby wynik twojego przesłania był widoczny dla kogoś, kto go uruchomi, ponieważ nie ma łatwego sposobu na po prostu „debugowanie” wyjść z obwodu wireworld. Istnieje wiele obwodów BCD-> 7segmentowych dostępnych online. Możesz użyć dowolnego, który chcesz, lub stworzyć własny, jeśli potrzebujesz taktowanej linii sygnałowej i wyświetlać wskaźnik AM / PM w skali podobnej do cyfr.

EDYCJA: Część B jest teraz opcjonalna. Jeśli masz tylko wyjścia BCD z części A, możesz je przesłać. Potwierdzenie, że zegar działa, będzie bardziej nużące, ale potrafię dobrze odczytać rząd bitów w wstrzymanej symulacji.

Sparr
źródło
Oto mały symulator online.
NonlinearFruit,
Pracowałem nad tym, ale widziałem to tylko w zeszłym tygodniu, więc prawdopodobnie przegapię nagrodę. Nie mogę znaleźć 4-przewodowej wersji wireworld bcd-> 7-segmentowej; zbudowanie konwertera 4 na 2 przed popularnym 2-przewodowym 7-segmentowym urządzeniem (takim jak ten, który jest wyposażony w golly) może być dobrym rozwiązaniem. Jednym z problemów z tym urządzeniem jest to, że chociaż ładnie wygląda, jest powolny w aktualizacji, co spowoduje powiększenie rozmiaru części A, ponieważ może wypompowywać liczby szybciej niż mogą być wyświetlane i musi być sztucznie spowolniony.
wyldstallyns,
Mam 150 000 komórek pracujących w części A, które mogę udowodnić, ale obecnie brakuje zgodnej z przepisami części B.
wyldstallyns,
Nie spodziewałem się, że część B będzie trudna. Jak daleko są twoje elektrony w części A?
Sparr,
1
@wyldstallyns Zamyka się o 16.12.2016 03: 30: 35Z (możesz najechać kursorem na „jutro”, aby uzyskać dokładne godziny). Powodzenia. Naprawdę podoba mi się twój zegar. To elegancko prosty pomysł i doskonałe wykonanie. Muszę przyznać, że byłem również zaskoczony, ile miejsca ostatecznie zajęła moja kosmos. Byłbym zainteresowany, aby zobaczyć wszelkie ulepszenia, które możesz wymyślić w swoim. Powodzenia :)
niemiro

Odpowiedzi:

36

Zatrzaskowy zegar

Wynik - 53.508 (z czego tylko 36.828 jest aktywnie wykorzystywanych ze względu na kształt litery L)

Zegar działa

Nagrywanie w wysokiej jakości - https://1drv.ms/u/s!ArQEzxH5nQLKhvt_HHfcqQKo2FODLQ
Wzorzec Golly - https://1drv.ms/u/s!ArQEzxH5nQLKhvwAmwCY-IPiBuBmBw

Zasady przewodnie -

  • Ponieważ po raz pierwszy użyłem automatu komórkowego, uniknąłem łączenia dużych, gotowych elementów. Jednym ważnym podejściem, którego nie podjąłem, byłby sumator binarny rozpoczynający się od zera i ciągle dodający jeden do ostatniego wyjścia, a następnie konwerter binarny na BCD, demultiplekser wyświetlacza, dekoder 7-segmentowy i wyświetlacz 7-segmentowy.
  • Powinno być możliwe zimne uruchomienie zegara. Narzuciłem sobie dodatkowe ograniczenie, że pojedyncza głowica elektronowa umieszczona w konkretnej komórce przewodnika powinna poprawnie uruchomić zegar. Nie chciałem wymagać dokładnej ręcznej synchronizacji wielu różnych przerzutników i poszczególnych elementów taktowania przed rozpoczęciem symulacji.

Część I: Licznik minut

Matematyka

Liczenie binarne od 0 do 9 (dla najmniej znaczącej cyfry minut) wygląda następująco -

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

Czytanie, że jako kolumny najmniej znaczący (strumień bitów 2 ^ 0 jednostek) to 01010101, strumień 2 ^ 1 jednostek to 0011001100, strumień 2 ^ 2 jednostek to 0000111100, a strumień 2 ^ 3 jednostek to 0000000011.

Pierwszy jest łatwy - wystarczy przerzucić flip 01 na zawsze. Trzeci to strumień czterech zer, sześć zer z przesuniętą fazą o sześć zer. Czwarty to strumień ośmiu zer i dwóch zer.

Drugi jest nieco trudniejszy, ponieważ ma nieprzyjemną asymetrię. Zauważam jednak, że (gdzie. Jest operatorem konkat):

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

(Nawiasem mówiąc, jak wspomniałem później, większość mojego zegara działa na tikrze 60-taktowym. Fala podwójnej długości 00000000001111111111 jest tam, gdzie pojawia się potrzeba tiksu 120-taktowego).

Projekt

Strumienie wyjściowe od góry do dołu to Jednostki minut (2 ^ 0, 2 ^ 1, 2 ^ 2, 2 ^ 3), a następnie Dziesiątki minut (2 ^ 0, 2 ^ 2, 2 ^ 1). Zauważ, że dolne dwa przewody są skrzyżowane.

Licznik minut opatrzony adnotacjami

  1. 120-taktowy zegar główny.
  2. Gdzie umieścić elektron na zimny start. Bez ogona elektronu rozchodzi się w dwóch kierunkach, ale dioda bezpośrednio nad nią łapie jeden z nich, dając ładny elektron kolarski krążący wokół pętli o 120 uderzeniach.
  3. 12-taktowy zegar wtórny.
  4. Cewka przewodnika + dioda uruchamia wtórny 12-taktowy zegar. Słowa nie potrafią opisać, jak wiernie zsynchronizowano ten mały kawałek. Musisz zsynchronizować zegary 120 i 60 taktów, a następnie zsynchronizować 24-taktowe pseudo zegary z 12-taktową częstotliwością i połową częstotliwości, a następnie przywrócić zegar 24-taktowy do zegara 120-taktowego, w przeciwnym razie bramka XOR nie będzie działać .
  5. Przesunięcie fazowe.
  6. Flip-flop. Pojedynczy elektron na wejściu najpierw uderza w ustawioną linię, a następnie po bardzo określonym czasie uderza w linię zerowania, dając dokładnie jeden impuls wejściowy, jeden impuls wyjściowy.
  7. Dodanie garbów tutaj - na linii resetowania zwiększa opóźnienie między setem a resetem na flip-flopie. Każdy dodatkowy garb daje dodatkowy puls. Poniższy flip-flop ma dziewięć dodatkowych garbów, więc dziesięć impulsów między setem a resetem.
  8. Bramka XOR dla mojej trudnej linii 2 ^ 1 jednostek minut.
  9. Bramka AND-NOT i bardzo specyficzne długości części oznaczają, że każdy impuls elektronu, który mija, podwaja się i unicestwia elektron za sobą. Połowa częstotliwości. Tworzy 24-taktowy zegar z 12-taktowego źródła wtórnego.
  10. 60-taktowy zegar wtórny, który faktycznie wykonuje większość pracy. Łatwiej jest rozpocząć szybki zegar od wolniejszego, więc najwolniejszy zegar (120 uderzeń) jest mistrzem, mimo że jest ledwo używany. 60-taktowy zegar jest sercem tej rzeczy.
  11. Drut zwrotny, który przenosi elektrony tylko wtedy, gdy tyka 60-taktowy zegar. Jest używany w połączeniu z bramką AND-NOT, aby zatrzymać ponowne uruchamianie zegara z poziomu 120-taktowego mistrza. W przeciwnym razie wydarzy się wiele okropnych rzeczy, a Ctrl-Z jest wybawicielem.
  12. Dioda, od której zaczyna się zegar 60-taktowy.
  13. Całe to urządzenie jest klapką, bramką AND i bramką AND-NOT łącznie. Daje zatrzask. Jeden impuls zaczyna, a jeden impuls zatrzymuje.
  14. Pętla drutu do kalibracji zatrzasku na 10 impulsów włączenia, 10 impulsów wyłączenia dla jednego na dziesięć impulsów wejściowych. Bez tego włączamy 12 impulsów, 8 impulsów wyłączamy. Te dziesięć na dziesięciu blokadach tworzą podstawowe elementy dziesięciominutowych bloków w taki sam sposób, w jaki przerzutniki 6 mikronów (1 puls) tworzyły podstawowe komponenty minutowych jednostek.
  15. Impuls początkowy zimnego startu spowodował różnego rodzaju problemy, w tym bicie dwóch faz poza fazą z włączonymi zegarami. To popsuwa zatrzaski. Ta bramka AND przechwytuje i pozbywa się impulsów niesynchronizowanych - w szczególności impulsu początkowego.
  16. Jest to część projektu, którego nieco żałuję z perspektywy czasu. Zajmuje elektron, dzieli go na pięć i unicestwia pięć elektronów z tyłu, przyjmując od 111111 do 100000.
  17. To zajmuje elektron i zszywa go z przodu. Dokładnie dwie fazy. Zajmuje 100000 i robi 101000. W połączeniu z częścią 16 otrzymujemy 111111 -> 100000 -> 101000. Z perspektywy czasu chciałbym zrobić 111111 -> 101010 -> 101000; osiągnąłby ten sam efekt na mniejszej przestrzeni.
  18. Powyższe wzory są następnie wciskane w dolny zatrzask, aby osiągnąć 20 wł., 40 wył. To jest podzielone, połowa jest przesunięta fazowo o 20 jednostek, a następnie tworzą one dwa strumienie bitów wysokiego rzędu z dziesiątek minut.

Część II: Licznik godzin

Wyjaśnienie

Wejście do licznika godzin to pojedynczy impuls elektronowy, raz na godzinę. Pierwszym krokiem jest zredukowanie tego do pojedynczego impulsu elektronowego, raz na dwanaście godzin. Osiąga się to za pomocą kilku operacji podstawowych „zatrzask i chwyt”.

„Zatrzask” to 6-mikronowy przerzutnik podłączony do AND-NOT i bramki AND w celu uzyskania 6-mikronowego zatrzasku. „Złap” pobiera ciągły strumień elektronów na wejściu, przepuszcza pierwszy, a następnie unicestwia każdy inny elektron za sobą, aż strumień się skończy, w którym to momencie łapanie resetuje się.

Umieszczenie zatrzasku, a następnie zatrzasku, w szeregu, powoduje, że jeden elektron wchodzi -> włącza zatrzask, jeden elektron na drugim końcu (resztę chwyta złapanie). Następnie drugi elektron w -> wyłącza zatrzask, łapanie cicho resetuje. Efekt netto: pierwszy elektron przechodzi, drugi elektron jest anihilowany, i tak dalej, i tak dalej, bez względu na to, jak długie jest opóźnienie między tymi elektronami .

Teraz połącz dwa „zatrzask i złap” szeregowo, a masz tylko jeden na cztery elektrony przechodzące.

Następnie weź trzeci „zatrzask i złap”, ale tym razem zatwierdź cały czwarty zatrzask i złap się na linii zestawu klap, między bramką AND-NOT a klapką. Pomyślę o tym, jak to działa, ale tym razem przechodzi tylko jeden na trzy elektrony, niezależnie od tego, jak długie jest opóźnienie między tymi elektronami .

Na koniec weź jeden na cztery elektrony i jeden na trzy, połącz je z bramką AND i tylko jeden na dwanaście elektronów przechodzi. Cały ten odcinek to niechlujny skręt ścieżek w lewym górnym rogu licznika godzin poniżej.

Następnie weź elektron co 12 godzin i dziel go z powrotem na jedną co godzinę, ale wysyłaj każdy na inny przewód przewodzący. Osiąga się to za pomocą długiego zwiniętego przewodu z trzynastoma punktami wyjścia.

Weź te elektrony - jedną godzinę w dół różnych przewodników i uderz w linię SET flip-flop. Linia RESET na tym samym klapie jest następnie uderzana przez przewód następnej godziny, dając sześćdziesiąt impulsów w dół każdego drutu na godzinę.

Na koniec - weź te impulsy i przekaż je do siedmiu i pół bajtu ROM (pamięć tylko do odczytu), aby wyprowadzić prawidłowe strumienie bitów BCD. Bardziej szczegółowe wyjaśnienie ROM WireWorld znajduje się tutaj: http://www.quinapalus.com/wires6.html

Projekt

Licznik godzin z adnotacjami

  1. Wejście jednego elektronu na godzinę.
  2. Pierwszy zatrzask.
  3. Pierwszy połów
  4. „Zatrzask i zaczep” osadzony na zewnętrznej linii zestawu „zatrzask i zaczep”.
  5. I brama.
  6. Zatrzask AM / PM (włączany / wyłączany raz na dwanaście godzin).
  7. Każda pętla drutu ma długość 6 x 60 = 360 jednostek.
  8. Flip / Flop odwrócił się na bok, aby utworzyć mniejszy profil.
  9. Siedem i pół bajtu ROM.

Notatki

  1. Ze względu na swój jeden elektron na minutę, 6 mikronów, uruchom symulację z sześcioma generacjami na minutę (jedna generacja co 10 sekund) dla zegara czasu rzeczywistego.
  2. Linia AM / PM jest wysoka (1) dla AM, niska (0) dla PM. Może to wydawać się nieco nietypowym rozwiązaniem, ale istnieje uzasadnienie. Podczas zimnego startu zegara linia AM / PM jest początkowo naturalnie niska (0). Gdy tylko linia AM / PM zostanie podniesiona wysoko (1), oznacza to, że liczenie rozpoczęło się o godzinie 12:00. Wszystkie dane wyjściowe przed tym punktem powinny zostać pominięte, wszystkie dane wyjściowe po tym punkcie są uważane za znaczące.

Przydatne linki

niemiro
źródło
zmieniono wymagania, aby zawsze można było pominąć wyjścia zawsze zerowe. bity 4s i 8s przez dziesiątki godzin nigdy nie są używane, ani bity 8s przez dziesiątki minut.
Sparr
Solidny! Prawdziwa inżynieria. Czy przydałaby się jakakolwiek inna bramka logiczna? Zaraz trochę brutalnie wykorzystam.
wyldstallyns,
1
To jest piękne
Sparr
1
Och, dobry żalu, który jest już wystarczająco blisko Teraz jestem zmuszony spróbować zoptymalizować mój. Mam powtarzające się wzorce, które mogłem skrócić, aby zrobić miejsce na składanie innych.
wyldstallyns
3
Nie wiem, jak aktywnie korzystasz z meta, dlatego informuję, że nominowałem tę odpowiedź na Best of PPCG 2016 .
Peter Taylor,
5

Pamięć linii opóźniającej - 51 x 2880 = 146880

Obraz

Oddalony:

Obraz

Wyjście wychodzi z góry każdej pętli.

Za pomocą tego lua umieszczam wszystkie stany bezpośrednio na drucie, pozwalając gollyelektronom przesuwać się naprzód między bitami, abyśmy nie musieli podążać za drutem kursorem.

Użyłem tej naiwnej metody, aby ustawić bar i tor wyścigowy wireworld, golly i 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

Do testów dodałem te górne przewody i obserwowałem ich wskazówki.

Imgur

Oto skrypt, aby zebrać 4 zestawy 4-przewodowego BCD do gałki ocznej.

-- 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)

Ostateczna odpowiedź wymaga przycinania zawsze zerowych linii i kierowania pozostałych do ich prawidłowych wejść BCD.

wyldstallyns
źródło
zmieniono wymagania, aby zawsze można było pominąć wyjścia zawsze zerowe. bity 4s i 8s przez dziesiątki godzin nigdy nie są używane, ani bity 8s przez dziesiątki minut.
Sparr
2
To zabawne i niesamowite wdrożenie!
Sparr
1
Ok, zostałem pokonany innym funkcjonalnym zegarem o 11 godzinie. Zamierzam atakować najdłuższe i najkrótsze pętle różnymi sztuczkami.
wyldstallyns,
Nie zamierzam tego ściągać. Mogę zaoszczędzić 1/4 wielkości przełączając na 3 mikronowe impulsy, ale nadal nie będzie wystarczająco cewki, aby pokonać niemiro.
wyldstallyns,