Побудуйте цифровий годинник у Wireworld


32

Натхненний цим питанням гри про життя .

Wireworld імітує "електрони", що проходять через "дроти", прості розташування яких виробляють типову логічну поведінку воріт.

Я закликаю вас створити цифровий годинник в стільниковому автоматі Wireworld. Ваш годинник повинен рахувати вгору з 00:00 до 23:59 звичайним способом або до 11:59 з індикатором AM / PM, а потім скинути.

Ваш запис повинен бути видимо розділений на дві частини. Частина А повинна містити всю логіку, що не відображає, всі частини, що беруть участь у збільшенні та циклічному розряді цифр. Частина B буде відображенням та логікою, яка її керує. Єдиним з'єднанням між цими двома частинами має бути 16 проводів, що представляють чотири цифри часу в BCD (з одним необов'язковим проводом для індикатора AM / PM та одним додатковим дротом для лінії сигналу, якщо ваші сигнали не є безперервними). (EDIT: дріти завжди нульові можна опустити)

Час поведінки годинника повинен бути узгодженим. Моделювання повинно взяти однакову кількість тиків для кожного з 1440 переходів між станами. Будь-які електрони на 16 дротах повинні випромінюватися одночасно з частини А і починати паралельно їх відключення.

Це змагання з кодового гольфу. Ваш бал - це область осі, що вирівнює обмежувальну коробку навколо оточуючої частини А.

За аналогією, якби це була текстова мова, ваш рахунок був би розміром функції управління тактовою системою, що виробляє чотири 4-бітні виходи, що містить цикл і логіку для 4 лічильників, а не функцію, яка розшифровує та друкує цей вихід.

Ваша частина B може бути такою великою чи маленькою, як ви хочете. Це потрібно лише для того, щоб результат вашої подання бачив хтось, хто працює ним, оскільки не існує простого способу просто "налагодити" виходи з ланцюга дротяного світу. В Інтернеті доступні кілька мікросхем BCD-> 7 сегментів. Не соромтеся використовувати той, який вам захочеться, або зробити свій власний, якщо вам потрібна тактована лінія сигналу, і відобразити індикатор AM / PM в деякій шкалі, подібній до цифр.

EDIT: Частина B тепер не обов’язкова. Якщо у вас просто є вихід BCD зі своєї частини A, сміливо подайте це. Підтвердження роботи годинника буде більш стомлюючим, але я можу прочитати ряд біт просто чудово в призупиненому моделюванні.


Ось невеликий онлайн-тренажер.
нелінійний

Я працював над цим, але бачив це лише минулого тижня, тому, мабуть, пропущу щедрість. Я не можу знайти 4-провідної версії bcd-> 7-сегмента Wireworld; побудова перетворювача 4 на 2 перед популярним 2-провідним 7-сегментним пристроєм (як той, що постачається з голлі) може бути дорогою. Одна з проблем цього пристрою полягає в тому, що, хоча він виглядає приємно, він повільно оновлюється, що збільшить розмір частини А, оскільки він може викачувати числа швидше, ніж вони можуть відображатися, і їх потрібно штучно сповільнювати.
wyldstallyns

У мене є 150000 осередку робоча частина А , що я можу довести , працює , але в даний час не вистачає правило, відповідає Частина B.
wyldstallyns

Я не очікував, що частина B буде важкою. Наскільки далеко один від одного ваші електрони в частині А?
Спарр

1
@wyldstallyns Закривається о 16.12.2016 03: 30: 35Z (ви можете навести курсор на "завтра", щоб отримати точний час). Вам дуже удача. Мені справді подобається ваш годинник. Це елегантно проста ідея та відмінне виконання. Мушу визнати, що я також був здивований тим, скільки місця закінчилося в минулому. І мені було б цікаво побачити будь-які поліпшення, які ви можете придумати у своїх. Тож, удача :)
niemiro

Відповіді:


36

Засувний годинник

Оцінка - 53 508 (з них активно використовується 36 828 завдяки L-подібній конструкції)

Годинник працює

Висока якість запису - https://1drv.ms/u/s!ArQEzxH5nQLKhvt_HHfcqQKo2FODLQ
Golly pattern - https://1drv.ms/u/s!ArQEzxH5nQLKhvwAmwCY-IPiBuBmBw

Керівні принципи -

  • Оскільки це був мій перший раз, коли я використовував стільниковий автомат, я уникав з'єднання великих компонентів, що виготовляються попередньо. Одним правильним підходом я не був би двійковий суматор, що починається з нуля і постійно додає його до останнього виходу, а потім бінарний конвертер BCD, демультиплексор дисплея, 7-сегментний декодер і 7-сегментний дисплей.
  • Потрібно мати можливість холодного запуску годинника. Я наклав на себе додаткове обмеження, що одна головка електронів, розміщена на певній осередку провідника, повинна правильно запускати годинник. Я не хотів вимагати ретельної ручної синхронізації багатьох розрізнених тригерів та окремих елементів часу перед початком моделювання.

Частина I: Лічильник хвилин

Математика

Підрахунок від 0 до 9 у двійкових (за найменш значущим числом хвилин) йде наступним чином -

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

Читаючи, що як стовпчики, найменш значимий (2 ^ 0 одиниць бітовий потік) йде 01010101, потік 2 ^ 1 одиниць йде 0011001100, потік 2 ^ 2 одиниці йде 0000111100, а потік 2 ^ 3 одиниці йде 0000000011.

Перший легкий - просто переверніть 01 назавжди. Третій - потік з чотирьох 1s, шести 0s, фаза зміщена на шість нулів. Четвертий - це потік з восьми 0 і двох 1.

Другий трохи складніше, оскільки він має неприємну асиметрію. Однак я помічаю, що (де. Є оператор concat):

0011001100. 0011001100 = 0011001100. НЕ (1100110011) = 00110011001100110011 XOR 00000000001111111111 = 5 (0011) XOR 00000000001111111111

(Між іншим, як згадувалося пізніше, більшість моїх годин працює на 60-тиразовому тикері. Хвиля подвійної довжини 00000000001111111111 - це те, де виникає потреба у 120-тиразовому тикері).

Дизайн

Вихідні потоки зверху вниз йдуть Одиниці хвилин (2 ^ 0, 2 ^ 1, 2 ^ 2, 2 ^ 3), а потім Десятки хвилин (2 ^ 0, 2 ^ 2, 2 ^ 1). Зверніть увагу, що два нижні дроти перехрещені.

Лічильник хвилин зазначається

  1. 120-тактний головний годинник.
  2. Де розмістити електрон для холодного пуску. Без жодного електронного хвоста він розщеплюється в двох напрямках, але діод одразу вище ловить один із них, даючи приємний велосипедний електрон, що обходить і обертає петлю з 120 ударами.
  3. 12-тактний вторинний годинник.
  4. Котушка провідника + діод запускає вторинний 12-тактний годинник. Слова не можуть описати, як чудово синхронізувався цей маленький фрагмент. Вам потрібно синхронізувати тактові частоти 120 та 60 тат, а потім синхронізувати 24-тактні псевдосигнали з 12-та та частотною частотою, після чого прив’язувати 24-татовий годинник до 120-тактного годинника, інакше ворота XOR не працюють .
  5. Фазовий зсув.
  6. Фліп-флоп. Один електрон на вході спочатку потрапляє на задану лінію, а потім через дуже конкретний проміжок часу, потрапляє на лінію скидання, даючи точно один імпульс, один імпульс назовні.
  7. Додавання сюди горбків - у рядку скидання збільшує затримку між встановленням та скиданням на тригер. Кожен зайвий горб дає додатковий імпульс. Внизу в дельфіні є дев'ять зайвих горбків, тому десять імпульсів між набором і скиданням.
  8. XOR ворота для моєї хитрої 2 ^ 1 одиниці рядків хвилин.
  9. І-НЕ затвор і дуже конкретна довжина частини означає, що кожен імпульс електрона, який проходить мимо, подвоюється назад на себе і знищує електрон позаду. Половина частоти. Створює 24-тактний годинник із вторинного джерела 12-такт.
  10. 60-ти ударний вторинний годинник, що фактично робить більшу частину роботи. Просто легше запустити швидкий годинник з повільніше, тому найповільніший годинник (120 ударів) є головним, хоча він ледь не використовується. 60-тактний годинник - серце цієї речі.
  11. Провід зворотного зв’язку, який несе електрони, лише коли тикає 60-тактний годинник. Він використовується спільно з воротами AND-NOT, щоб зупинити повторний перезапуск годинника від 120-тактного ведучого. Інакше трапляється багато жахливих речей, а Ctrl-Z - рятівник.
  12. Діод, з якого запускається 60-тактний годинник.
  13. Весь цей пристрій - це фліп-флоп, і ворота, і ворота AND-NOT разом. Це дає засувку. Один імпульс у ньому запускається, один імпульс у ньому зупиняється.
  14. Петля дроту для калібрування засувки на 10 імпульсів увімкнено, 10 імпульсів вимкнено для кожного імпульсного входу. Без нього ми отримуємо 12 імпульсів, 8 імпульсів вимикаємо. Ці десять на десяти вимкнених засувках утворюють основні компоненти десятихвилинних блоків так само, як 6-мікронні (1 імпульсні) триггери утворюють основні компоненти хвилинних одиниць.
  15. Початковий імпульс холодного старту спричинив усілякі проблеми, включаючи два удари поза фазою з тактовими годинниками. Це псує засувки. Цей затвор ТА ловить і виводить із синхронізуючих імпульсів - зокрема пусковий імпульс.
  16. Це частина дизайну, яку я дещо шкодую в ретроспективі. Він бере електрон, розбиває його на п'ять і знищує п’ять електронів позаду, приймаючи від 111111 до 100000.
  17. Це бере електрон і прошиває його на передній частині. Дві фази вперед, щоб бути точним. Це займає 100000 і складає 101000. У поєднанні з 16 частиною ми отримуємо 111111 -> 100000 -> 101000. З ретроспективою я хотів би зробити це 111111 -> 101010 -> 101000; він би досягнув такого ж ефекту за меншого простору.
  18. Описані вище шаблони потім висуваються в нижню засувку, щоб досягти 20, 40 відключення. Це розділяється, половина зміщується по фазі на 20 одиниць, а потім вони утворюють два потоки бітів високого порядку в десятки хвилин.

Частина II: Лічильник годин

Пояснення

Вхід до лічильника годин - це один імпульс електрона, раз на годину. Перший крок - звести це до одиничного імпульсу електронів, раз на дванадцять годин. Це досягається за допомогою декількох примітивів "засувка та улов".

"Засувка" - це 6-мікронний триггер, підключений до AND-NOT та AND-воріт, щоб дати 6-мікронний фіксатор. "Улов" приймає безперервний потік електронів як вхід, пропускає перший наскрізь, а потім знищує кожен другий електрон позаду, поки потік не закінчиться, в який момент скидання скидається.

Розміщення засувки з подальшим уловом послідовно призводить до того, що один електрон увімкне -> вмикає засувку, один електрон виходить на інший кінець (решта, що потрапила під улов). Тоді другий електрон у -> вимикає фіксатор, ловить мовчки скидає. Чистий ефект: перший електрон проходить через, другий електрон знищується, і так далі, і так далі, незалежно від того, яка тривалість затримки між цими електронами .

Тепер ланцюжок два "засувки і лову" в серії, і у вас є лише один з чотирьох електронів, що проходять через.

Далі візьміть третю "засувку і ловіть", але цього разу вставіть цілу четверту засувку і зачепіть за лінію SET, яка перебуває між відкидними панелями AND-NOT та SET. Я залишу вас подумати про те, як це працює, але на цей раз проходить лише кожен третій електрон, незалежно від того, як довго затримується між цими електронами .

Нарешті, візьміть один з чотирьох електронів і другий з трьох, з'єднайте їх із воротами І, і лише один з дванадцяти електронів пройде через. Весь цей розділ - це безладна вилазка доріжок ліворуч угорі лічильника години внизу.

Далі, приймайте електрон кожні дванадцять годин і розділяйте його назад на один кожні години, але виведіть кожен на інший провідник. Це досягається за допомогою довгого спірального провідника з тринадцятьма точками виходу.

Візьміть ці електрони - за годину спускайте різні провідники і натисніть на лінію SET. Лінія RESET на цьому ж відкидному флопі потім потрапляє на провідник наступної години, даючи шістьдесят імпульсів вниз на кожен провід на годину.

Нарешті - візьміть ці імпульси і перенесіть їх у сім з половиною байтів ПЗУ (пам'ять лише для читання), щоб вивести правильні бітові потоки BCD. Дивіться тут для більш детального пояснення WireWorld ROM: http://www.quinapalus.com/wires6.html

Дизайн

Погодинний лічильник Повідомлення

  1. Один електрон на годину введення.
  2. Перша засувка.
  3. Перший улов.
  4. "Latch & catch", вбудований у зовнішню лінію "засувка та улов".
  5. І ворота.
  6. Засувка AM / PM (включається / вимикається раз на дванадцять годин).
  7. Кожна петля дроту довжиною 6х60 = 360 одиниць.
  8. Фліп / Флоп повернув на бік, щоб створити менший профіль.
  9. Сім з половиною байтів ПЗУ.

Примітки

  1. Завдяки своїй електроні в хвилину, 6-мікронній конструкції, запускайте моделювання зі шістьма поколіннями на хвилину (одне покоління кожні 10 секунд) протягом годин у режимі реального часу.
  2. Лінія AM / PM висока (1) для AM, низька (0) для PM. Це може здатися дещо незвичним способом вибору, але виправдання є. Під час холодного запуску годинника лінія AM / PM початково природно низька (0). Як тільки лінія AM / PM піднімається високо (1), це вказує на те, що підрахунок розпочався о 12:00 ранку. Усі вихідні дані перед цією точкою слід ігнорувати, а всі результати після цієї точки вважаються значимими.

корисні посилання


змінилися вимоги, щоб завжди виходити з нуля виходи. біти 4s і 8s протягом десятків годин ніколи не використовуються, ні 8s біт протягом десятків хвилин.
Спарр

Солідно! Справжня інженерія. Чи були б корисні будь-які інші логічні ворота? Я збираюся грубо змусити когось.
wyldstallyns

1
Це прекрасно
Спарр

1
О гарне горе, яке досить близько, тепер я змушений спробувати оптимізувати своє. У мене є повторювані шаблони, які я міг би скоротити, щоб звільнити місця для складання інших.
wyldstallyns

3
Я не знаю, наскільки ви активні в роботі мета, тому це означає, що я висунув цю відповідь на Best of PPCG 2016 .
Пітер Тейлор

5

Пам'ять затримки ліній - 51 x 2880 = 146880

Зображення

Зменшено масштаб:

Зображення

Вихід виходить у верхній частині кожної петлі.

Я поклав усі стани прямо на дріт із цим луа, пускаючи golly переходити електрони вперед між бітами, щоб нам не доводилося слідувати за дротом курсором.

Я використовував цей наївний метод, щоб встановити смугу і зазнати краху з дротяного світу, голі та луа.

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

Для тестування я додав ці провідні дроти і спостерігав за їх порадами.

Імгур

Ось сценарій зібрати 4 набори 4-провідного BCD для очного яблука.

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

Остаточна відповідь вимагає обрізання ліній, які завжди є нульовими, та решту маршрутів до правильних даних BCD.


змінилися вимоги, щоб завжди виходити з нуля виходи. ніколи не використовуються біти 4s і 8s протягом десятків годин, а також біти 8s протягом десятків хвилин.
Спарр

2
Це весела та дивовижна реалізація!
Спарр

1
Гаразд, я був битий іншим функціональним годинником на 11-й годині. Я збираюся атакувати найдовші та найкоротші петлі різними хитрощами.
wyldstallyns

Я не збираюсь його знімати. Я можу зберегти 1/4 розміру, переключившись на 3 мкм імпульси, але він все ще не буде обмотатися досить щільно, щоб перемогти niemiro.
wyldstallyns
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.