Bangun jam digital di Wireworld

32

Terinspirasi oleh pertanyaan Game of Life ini .

Wireworld mensimulasikan "elektron" yang mengalir melalui "kabel", pengaturan sederhana yang menghasilkan perilaku gerbang logika yang khas.

Saya menantang Anda untuk membuat jam digital dalam otomat seluler Wireworld. Jam Anda harus dihitung dari 00:00 hingga 23:59 dengan cara yang biasa, atau hingga 11:59 dengan indikator AM / PM, lalu reset.

Entri Anda harus dibagi menjadi dua bagian. Bagian A harus berisi semua logika non-tampilan, semua bagian yang terlibat dalam penambahan dan perulangan digit. Bagian B akan menjadi tampilan dan logika yang menggerakkannya. Satu-satunya koneksi antara dua bagian ini adalah 16 kabel yang mewakili empat digit waktu dalam BCD (dengan satu kabel opsional untuk indikator AM / PM, dan satu kabel opsional untuk saluran jam sinyal jika sinyal Anda tidak kontinu). (EDIT: selalu-nol kabel dapat dihilangkan)

Waktu perilaku jam harus konsisten. Simulasi harus mengambil jumlah kutu yang sama untuk masing-masing 1440 transisi antar negara. Setiap elektron pada 16 kabel harus dipancarkan dari bagian A pada saat yang sama dan memulai perjalanannya secara paralel.

Ini adalah kompetisi kode-golf. Skor Anda adalah area kotak pembatas sumbu rata yang mengelilingi bagian A.

Dengan analogi, jika ini adalah bahasa tekstual, skor Anda akan menjadi ukuran fungsi manajemen jam yang menghasilkan empat output 4-bit, yang berisi loop dan logika untuk 4 penghitung, bukan fungsi yang menerjemahkan dan mencetak output tersebut.

Bagian B Anda bisa sebesar atau sekecil yang Anda inginkan. Ini hanya diperlukan agar output dari kiriman Anda dapat dilihat oleh seseorang yang menjalankannya, karena tidak ada cara mudah untuk hanya "men-debug" output dari sirkuit wireworld. Ada beberapa sirkuit BCD-> 7 yang tersedia secara online. Jangan ragu untuk menggunakan yang mana saja yang Anda suka, atau buat sendiri jika Anda membutuhkan garis sinyal clock, dan tampilkan indikator AM / PM Anda pada skala yang mirip dengan digit.

EDIT: Bagian B sekarang opsional. Jika Anda hanya memiliki output BCD dari bagian A Anda, jangan ragu untuk mengirimkannya. Akan lebih membosankan untuk mengkonfirmasi jam bekerja, tetapi saya bisa membaca deretan bit dengan baik dalam simulasi yang dijeda.

Sparr
sumber
Ini adalah simulator online kecil.
NonlinearFruit
Saya sudah mengerjakan ini tetapi hanya melihatnya minggu lalu jadi saya mungkin akan kehilangan karunia. Saya tidak dapat menemukan versi 4-kawat dari wireworld bcd-> 7-segment; membangun konverter 4-ke-2 di depan perangkat 2-segmen 7-kawat yang populer (seperti yang datang dengan bagus) mungkin merupakan cara yang tepat. Satu masalah dengan perangkat itu adalah bahwa, meskipun terlihat bagus, lambat untuk diperbarui, yang akan menggembungkan ukuran Bagian A karena dapat memompa angka keluar lebih cepat daripada yang dapat ditampilkan dan harus diperlambat secara artifisial.
wyldstallyns
Saya memiliki 150.000 sel yang bekerja, Bagian A yang dapat saya buktikan, tetapi saat ini tidak memiliki Bagian B. yang mematuhi aturan.
wyldstallyns
Saya tidak berharap bagian B menjadi sulit. Seberapa jauh elektron Anda berada di bagian A?
Sparr
1
@wyldstallyns Ini ditutup pada 16/12/2016 03: 30: 35Z (Anda dapat mengarahkan 'besok' untuk mendapatkan waktu yang tepat). Keberuntungan terbaik untuk Anda. Saya benar-benar menyukai jam Anda. Ini adalah ide yang sederhana dan elegan dan eksekusi yang sangat baik. Saya harus mengakui bahwa saya juga terkejut dengan seberapa banyak ruang yang akhirnya saya ambil pada akhirnya. Dan saya akan tertarik untuk melihat perbaikan apa pun yang dapat Anda lakukan di dalam diri Anda. Jadi,
selamat

Jawaban:

36

Menempel Jam

Nilai - 53.508 (dimana hanya 36.828 digunakan secara aktif karena desain berbentuk L)

Jam Berjalan

Rekaman Kualitas Tinggi - https://1drv.ms/u/s!ArQEzxH5nQLKhvt_HHfcqQKo2FODLQ
Pola hebat - https://1drv.ms/u/s!ArQEzxH5nQLKhvwAmwCY-IPiBuBmBww

Prinsip Panduan -

  • Karena ini adalah pertama kalinya saya menggunakan otomat seluler, saya menghindari merangkai komponen premade besar. Salah satu pendekatan yang valid yang tidak saya ambil adalah penambah biner mulai dari nol dan terus menambahkan satu ke keluaran terakhir, diikuti oleh konverter biner ke BCD, demultiplexer layar, decoder 7-segmen, dan layar 7-segmen.
  • Seharusnya memungkinkan untuk memulai jam dengan dingin. Saya memaksakan pada diri saya batasan tambahan bahwa kepala elektron tunggal yang ditempatkan pada sel konduktor tertentu harus memulai jam dengan benar. Saya tidak ingin memerlukan sinkronisasi manual yang hati-hati dari banyak flip-flop yang berbeda dan elemen waktu individual sebelum memulai simulasi.

Bagian I: Penghitung Menit

Matematika

Menghitung dari 0 hingga 9 dalam biner (untuk digit menit paling signifikan) berlaku sebagai berikut -

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

Membaca itu sebagai kolom, yang paling signifikan (2 ^ 0 unit bit stream) pergi 01010101, aliran 2 ^ 1 unit pergi 0011001100, aliran 2 ^ 2 unit pergi 0000111100 dan aliran 2 ^ 3 unit pergi 0000000011.

Yang pertama mudah - cukup flip-flip 01 selamanya. Yang ketiga adalah aliran empat 1s, enam 0s, fase digeser oleh enam nol. Yang keempat adalah aliran delapan 0s dan dua 1s.

Yang kedua sedikit lebih sulit karena punya asimetri yang buruk. Namun, saya perhatikan (di mana. Adalah operator concat):

0011001100. 0011001100 = 0011001100. TIDAK (1100110011) = 00110011001100110011 XOR 0000000000111111111111 = 5 (0011) XOR 0000000000111111111111

(Kebetulan, seperti disinggung kemudian, sebagian besar jam saya berjalan pada ticker 60-beat. Gelombang panjang ganda 00000000001111111111 adalah di mana kebutuhan untuk ticker 120-beat masuk).

Desain

Output mengalir dari atas ke bawah pergi Unit Menit (2 ^ 0, 2 ^ 1, 2 ^ 2, 2 ^ 3) kemudian Puluhan Menit (2 ^ 0, 2 ^ 2, 2 ^ 1). Perhatikan bahwa dua kabel terbawah disilangkan.

Penghitung Menit Beranotasi

  1. 120-beat jam utama.
  2. Tempat meletakkan elektron sebagai awal yang dingin. Tanpa ekor elektron, ia terbagi dalam dua arah tetapi dioda tepat di atas menangkap salah satu dari ini memberikan elektron siklus yang bagus berputar-putar 120-beat loop.
  3. Jam sekunder 12-beat.
  4. Coil of conductor + diode memulai clock 12-beat sekunder. Kata-kata tidak dapat menjelaskan seberapa serakah bagian kecil ini untuk disinkronkan. Anda harus menyinkronkan 120 dan 60 jam ketukan, lalu menyinkronkan dalam pseudo 24-beat jam 12-ketuk dan frekuensi, diikuti dengan mengikat kembali jam 24-ketuk ke jam 120-ketukan jika tidak gerbang XOR tidak berfungsi .
  5. Pergeseran fasa.
  6. Flip-flop. Satu elektron pada input menyentuh garis yang ditetapkan terlebih dahulu kemudian setelah waktu yang sangat spesifik, mengenai garis reset memberikan tepat satu pulsa masuk, satu pulsa keluar.
  7. Menambahkan punuk di sini - pada baris reset, meningkatkan penundaan antara set dan reset pada flip-flop. Setiap punuk tambahan memberikan denyut ekstra. Flip-flop di bawah ini memiliki sembilan punuk tambahan, jadi sepuluh pulsa antara set dan reset.
  8. Gerbang XOR untuk garis 2 ^ 1 unit menitku yang sulit.
  9. Gerbang AND-NOT dan panjang bagian yang sangat spesifik berarti setiap pulsa elektron yang datang berlipat ganda pada dirinya sendiri dan memusnahkan elektron di belakang. Frekuensi halver. Membuat clock 24-beat dari sumber sekunder 12-beat.
  10. 60-beat clock sekunder, yang sebenarnya melakukan sebagian besar pekerjaan. Lebih mudah untuk memulai jam cepat dari yang lebih lambat, jadi jam paling lambat (120-denyut) adalah master, meskipun itu hampir tidak digunakan. Jam 60-beat adalah jantung dari hal ini.
  11. Kawat umpan balik yang membawa elektron hanya ketika clock 60-beat berdetak. Ini digunakan bersama dengan gerbang AND-NOT untuk menghentikan jam yang dihidupkan ulang berulang kali dari master 120-beat. Kalau tidak, banyak hal buruk yang terjadi & Ctrl-Z adalah penyelamat.
  12. Dioda tempat 60-beat clock dimulai.
  13. Seluruh perangkat ini adalah flip flop, gerbang AND, dan gerbang AND-NOT digabungkan. Ini memberi kait. Satu pulsa masuk, satu pulsa berhenti itu.
  14. Loop kawat untuk mengkalibrasi kait ke 10 pulsa aktif, 10 pulsa mati untuk input satu dari sepuluh pulsa. Tanpa itu kita mendapatkan 12 pulsa, 8 pulsa. Sepuluh kait lepas sepuluh ini membentuk komponen dasar dari blok sepuluh menit dengan cara yang sama flip-flop 6 mikron (1 pulsa) membentuk komponen dasar unit menit.
  15. Denyut jantung awal yang dingin menyebabkan segala macam masalah termasuk menjadi dua ketukan dari fase dengan jam itu dimulai. Ini mengacaukan kait. Gerbang AND ini menangkap dan membuang pulsa yang tidak sinkron - khususnya pulsa awal.
  16. Ini adalah bagian dari desain yang agak saya sesalkan dalam retrospeksi. Dibutuhkan sebuah elektron, membaginya menjadi lima dan memusnahkan lima elektron di belakang, mengambil 111111 hingga 100000.
  17. Ini mengambil elektron dan menjahitnya di bagian depan. Dua fase di depan tepatnya. Dibutuhkan 100000 dan menghasilkan 101000. Digabungkan dengan bagian 16 kita mendapatkan 1.11111 -> 100.000 -> 101000. Dalam retrospeksi saya berharap saya telah melakukan 111111 -> 101010 -> 101000; itu akan mencapai efek yang sama dalam ruang yang lebih sedikit.
  18. Pola di atas kemudian didorong ke kait bawah untuk mencapai 20 on, 40 off. Ini dibagi, setengah fase dialihkan oleh 20 unit, dan kemudian ini membentuk dua aliran bit orde tinggi dari puluhan menit.

Bagian II: Penghitung Jam

Penjelasan

Input ke penghitung jam adalah pulsa elektron tunggal, satu jam sekali. Langkah pertama adalah mengurangi ini menjadi satu pulsa elektron, sekali setiap dua belas jam. Ini dicapai dengan menggunakan beberapa primitif "latch & catch".

"Kait" adalah flip-flop 6 mikron yang terhubung ke gerbang AND-NOT dan AND untuk memberikan kait on / off 6 mikron. "Tangkapan" mengambil aliran elektron yang kontinu sebagai input, memungkinkan yang pertama melalui, kemudian memusnahkan setiap elektron lainnya di belakang, sampai aliran berakhir pada saat titik tangkapan diatur ulang.

Menempatkan kait, diikuti oleh tangkapan, secara seri, menghasilkan satu elektron di -> mengaktifkan kait, satu elektron keluar dari ujung lainnya (sisanya ditangkap oleh tangkapan). Kemudian elektron kedua di -> mematikan kait, menangkap ulang diam-diam. Efek bersih: elektron pertama melewati, elektron kedua dimusnahkan, dan seterusnya, terlepas dari berapa lama penundaan di antara elektron-elektron tersebut .

Sekarang rantai dua "kait & tangkap" secara seri, dan Anda hanya memiliki satu dari empat elektron yang melewatinya.

Selanjutnya, ambil "kait dan tangkap" ketiga, tetapi kali ini sematkan kait keempat dan tangkap pada garis SET flip-flop, antara gerbang AND-NOT dan SET flip-flop. Saya akan meninggalkan Anda untuk memikirkan bagaimana ini bekerja, tetapi kali ini hanya satu dari tiga elektron yang melewati, terlepas dari berapa lama penundaan di antara elektron tersebut .

Akhirnya, ambil satu dari empat elektron, dan satu dari tiga, gabungkan dengan gerbang AND, dan hanya satu dari dua belas elektron yang melewatinya. Seluruh bagian ini adalah percekcokan jalur ke kiri atas penghitung jam di bawah ini.

Selanjutnya, ambil elektron setiap dua belas jam dan pisahkan kembali menjadi satu setiap jam, tetapi output masing-masing ke kabel konduktor yang berbeda. Ini dicapai dengan menggunakan konduktor melingkar panjang dengan tiga belas titik keluar.

Ambil elektron ini - satu jam turun konduktor yang berbeda, dan tekan garis SET flip-flop. Garis RESET pada flip flop yang sama kemudian dipukul oleh konduktor jam berikutnya, memberikan enam puluh pulsa setiap kawat per jam.

Akhirnya - ambil pulsa-pulsa ini dan operasikan ke dalam tujuh setengah byte ROM (Read-Only Memory) untuk menghasilkan bitstream stream BCD yang benar. Lihat di sini untuk penjelasan lebih rinci tentang WireWorld ROM: http://www.quinapalus.com/wires6.html

Desain

Penghitung Jam Beranotasi

  1. Satu elektron per jam input.
  2. Kait pertama.
  3. Tangkapan pertama.
  4. "Latch & catch" tertanam pada baris SET "latch & catch" luar.
  5. DAN gerbang.
  6. Kait AM / PM (dihidupkan / dimatikan setiap dua belas jam sekali).
  7. Setiap loop kawat memiliki panjang 6x60 = 360 unit.
  8. Flip / Flop diputar miring untuk membuat profil yang lebih kecil.
  9. Tujuh setengah byte ROM.

Catatan

  1. Karena satu elektron per menit, desain 6-mikron, jalankan simulasi pada enam generasi per menit (satu generasi setiap 10 detik) untuk jam waktu-nyata.
  2. Garis AM / PM tinggi (1) untuk AM, rendah (0) untuk PM. Ini mungkin tampak agak aneh untuk dipilih, tetapi ada justifikasi. Selama awal yang dingin dari jam, garis AM / PM secara alami rendah (0) pada awalnya. Segera setelah garis AM / PM ditarik tinggi (1), ini menunjukkan bahwa penghitungan telah dimulai pada pukul 12:00. Semua output sebelum titik ini harus diabaikan, semua output setelah titik ini dianggap bermakna.

Tautan yang Berguna

niemiro
sumber
persyaratan diubah sehingga output selalu-nol dapat dihilangkan. bit 4s dan 8s selama puluhan jam tidak pernah digunakan, atau bit 8s selama puluhan menit.
Sparr
Padat! Rekayasa sejati. Apakah gerbang logika lainnya bermanfaat? Saya akan memaksa beberapa.
wyldstallyns
1
Ini indah
Sparr
1
Ya ampun, itu sudah cukup dekat sekarang saya terpaksa mencoba dan mengoptimalkan milik saya. Saya telah mengulangi pola yang bisa saya persingkat untuk memberi ruang bagi orang lain untuk melipatnya.
wyldstallyns
3
Saya tidak tahu seberapa aktif Anda menggunakan meta, jadi ini untuk memberi tahu Anda bahwa saya telah menominasikan jawaban ini untuk Best of PPCG 2016 .
Peter Taylor
5

Memori saluran tunda - 51 x 2880 = 146880

Gambar

Perkecil:

Gambar

Output keluar dari bagian atas setiap loop.

Saya menempatkan semua status langsung pada kabel dengan lua ini, membiarkan gollylangkah elektron maju di antara bit sehingga kita tidak harus mengikuti kawat dengan kursor.

Saya menggunakan metode naif ini untuk mengatur bar dan kursus kilat wireworld, astaga dan 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

Untuk pengujian saya menambahkan kabel top ini dan memperhatikan tip mereka.

Imgur

Berikut skrip untuk mengumpulkan 4 set BCD 4 kawat ke bola mata.

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

Jawaban akhir membutuhkan pemangkasan garis selalu nol dan perutean sisanya ke input BCD yang benar.

wyldstallyns
sumber
persyaratan diubah sehingga output selalu-nol dapat dihilangkan. bit 4s dan 8s selama puluhan jam tidak pernah digunakan, atau bit 8s selama puluhan menit.
Sparr
2
Ini adalah implementasi yang lucu dan mengagumkan!
Sparr
1
Ok saya dikalahkan dengan jam fungsional lain pada jam ke-11. Saya akan menyerang loop terpanjang dan terpendek dengan berbagai trik.
wyldstallyns
Saya tidak akan berhasil. Saya dapat menghemat 1/4 ukuran dengan beralih ke pulsa 3 mikron, tetapi masih tidak cukup kuat untuk mengalahkan niemiro.
wyldstallyns