Wireworld에서 디지털 시계 구축


32

이 Game of Life 질문에서 영감을 얻었습니다 .

Wireworld는 "와이어"를 통해 흐르는 "전자"를 시뮬레이션합니다. 간단한 배열은 일반적인 논리 게이트 동작을 생성합니다.

Wireworld 셀룰러 오토 마톤에서 디지털 시계를 제작해야합니다. 시계는 일반적인 방식으로 00:00부터 23:59까지 또는 AM / PM 표시기를 사용하여 11:59까지 증가한 다음 재설정해야합니다.

출품작은 크게 두 부분으로 나뉩니다. 파트 A에는 숫자를 증가시키고 루핑하는 데 관련된 모든 비 디스플레이 논리가 포함되어야합니다. 파트 B는 디스플레이와이를 구동하는 논리입니다. 이 두 부분 사이의 유일한 연결은 BCD 에서 시간의 네 자리 숫자를 나타내는 16 개의 전선이어야합니다 (신호가 연속적이지 않은 경우 AM / PM 표시기의 경우 옵션 와이어 1 개, 신호 클럭 라인의 경우 옵션 와이어 1 개). (편집 : 항상 제로 전선을 생략 할 수 있습니다)

클럭 동작의 타이밍은 일정해야합니다. 시뮬레이션은 상태 간 1440 개의 전환 각각에 대해 동일한 수의 틱을 가져야합니다. 16 와이어의 모든 전자는 동시에 A 부분에서 방출되어야하고 병렬로 트립을 시작해야합니다.

이것은 코드 골프 경쟁입니다. 점수는 파트 A를 둘러싸는 축 정렬 경계 상자의 영역입니다.

유사하게, 이것이 텍스트 언어 인 경우, 점수는 4 개의 4 비트 출력을 생성하는 클록 관리 기능의 크기이며, 여기에는 해당 출력을 디코딩하고 인쇄하는 기능이 아니라 4 개의 카운터에 대한 루프와 논리가 포함됩니다.

파트 B는 원하는만큼 크거나 작을 수 있습니다. wireworld 회로의 출력을 간단히 "디버깅"할 수있는 방법이 없기 때문에 제출 한 사람이 제출 한 결과를 볼 수 있도록하기 위해서만 필요합니다. 온라인으로 여러 BCD-> 7 세그먼트 회로를 사용할 수 있습니다. 원하는 신호를 자유롭게 사용하거나 클록 신호 라인이 필요한 경우 직접 만들고 AM / PM 표시기를 숫자와 비슷한 스케일로 표시하십시오.

편집 : 이제 파트 B는 선택 사항입니다. 파트 A의 BCD 출력 만 있다면 자유롭게 제출하십시오. 시계가 작동하는지 확인하는 것이 더 지루하지만, 일시 정지 된 시뮬레이션에서 한 줄의 비트 만 읽을 수 있습니다.


여기 작은 온라인 시뮬레이터가 있습니다.
NonlinearFruit

나는이 일을하고 있었지만 지난 주에만 보았 기 때문에 현상금을 놓칠 것입니다. wireworld bcd-> 7-segment의 4- 와이어 버전을 찾을 수 없습니다. 널리 사용되는 2 선 7 세그먼트 장치 (예 : golly와 함께 제공되는 장치) 앞에 4 대 2 변환기를 구축하는 것이 좋습니다. 이 장치의 한 가지 문제점은보기에 좋지만 업데이트 속도가 느리기 때문에 표시 할 수있는 것보다 더 빠르게 숫자를 펌핑 할 수 있고 인위적으로 느려 져야하기 때문에 파트 A의 크기가 팽창한다는 것입니다.
wyldstallyns

나는 작품을 증명할 수 있지만 현재 규칙을 준수하는 파트 B가없는 150,000 개의 셀 A를 가지고 있습니다.
wyldstallyns

나는 파트 B가 어려울 것으로 기대하지 않았습니다. 파트 A에서 전자가 얼마나 멀리 떨어져 있습니까?
Sparr

1
@wyldstallyns 2016 년 12 월 16 일 03 : 30 : 35Z에 닫힙니다 (정확한 시간을 얻으려면 '내일'을 가리킬 수 있습니다). 당신에게 행운을 빕니다. 나는 당신의 시계를 정말로 좋아합니다. 우아하고 간단한 아이디어이며 훌륭한 실행입니다. 나는 또한 내 공간이 결국 얼마나 많은 공간을 차지하는 지에 놀랐 음을 인정해야한다. 그리고 나는 당신이 당신에게 올 수있는 개선 사항을보고 싶습니다. 행운을 빕니다 :)
niemiro

답변:


36

래칭 시계

점수-53,508 점 (L 형 디자인으로 인해 36,828 명만 적극적으로 사용됨)

시계 달리기

고품질 녹음 - https://1drv.ms/u/s!ArQEzxH5nQLKhvt_HHfcqQKo2FODLQ
골리 패턴 - https://1drv.ms/u/s!ArQEzxH5nQLKhvwAmwCY-IPiBuBmBw

지도 원리-

  • 이것이 셀룰러 오토 마톤을 사용한 것은 처음 이었으므로 큰 사전 제작 된 구성 요소를 묶는 것을 피했습니다. 내가 취하지 않은 한 가지 유효한 접근법은 0에서 시작하여 마지막 출력에 하나를 계속 추가하는 이진 가산기, 이진 대 BCD 변환기, 디스플레이 디멀티플렉서, 7 세그먼트 디코더 및 7 세그먼트 디스플레이입니다.
  • 시계를 콜드 스타트 ​​할 수 있어야합니다. 특정 컨덕터 셀에 배치 된 단일 전자 헤드가 클럭을 올바르게 시작해야한다는 추가 제한 사항이 있습니다. 시뮬레이션을 시작하기 전에 여러 개별 플립 플롭과 개별 타이밍 요소를 수동으로 신중하게 동기화하고 싶지 않았습니다.

1 부 : 분 카운터

수학

이진수로 0에서 9까지의 카운트는 (최하위 자리 수 자릿수) 다음과 같습니다.

0 - 0000
1 - 0001
2 - 0,010
3 - 0,011
4 - 0,100
5 - 0,101
6 - 0,110
7 - 0,111
8 - (1000)
9 - 1001

열로 표시하면 최하위 (2 ^ 0 단위 비트 스트림)는 01010101, 2 ^ 1 단위 스트림은 0011001100, 2 ^ 2 단위 스트림은 0000111100, 2 ^ 3 단위 스트림은 0000000011이됩니다.

첫 번째는 쉽습니다-그냥 플립 플립 01을 영원히하십시오. 세 번째는 4 개의 1, 6 개의 0, 6 개의 0으로 위상이 이동 된 스트림입니다. 네 번째는 8 개의 0과 2 개의 스트림입니다.

두 번째는 심한 비대칭 성을 가지기 때문에 조금 더 어렵습니다. 그러나 (.는 concat 연산자입니다.)

0011001100. 0011001100 = 0011001100입니다. NOT (1100110011) = 00110011001100110011 XOR 00000000001111111111 = 5 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. 도체 코일 + 다이오드는 2 차 12 비트 클록을 시작합니다. 단어는이 작은 조각이 얼마나 어리석게 동기화되었는지 설명 할 수 없습니다. 120 비트와 60 비트 클럭을 동기화 한 다음 12 비트 및 주파수 절반의 24 비트 의사 클록에서 동기화 한 다음 24 비트 클록을 120 비트 클록에 다시 연결해야합니다. 그렇지 않으면 XOR 게이트가 작동하지 않습니다 .
  5. 위상 변이.
  6. 플립 플롭. 입력의 단일 전자가 먼저 설정 라인에 도달 한 다음 매우 특정한 시간이 지나면 리셋 라인에 도달하여 정확히 하나의 펄스 입력, 하나의 펄스 출력을 제공합니다.
  7. 재설정 라인에서 혹을 추가하면 플립 플롭에서 설정과 재설정 사이의 지연이 증가합니다. 각각의 여분의 혹은 여분의 펄스를줍니다. 아래 플립 플롭에는 9 개의 추가 혹이 있으므로 설정과 재설정 사이에 10 개의 펄스가 있습니다.
  8. 나의 까다로운 2 ^ 1 분 단위의 XOR 게이트.
  9. AND-NOT 게이트와 매우 특정한 부품 길이는 각각의 전자 펄스가 스스로 배가되어 다시 전자를 전멸시키는 것을 의미합니다. 주파수 반감기. 12 비트 보조 소스에서 24 비트 클록을 만듭니다.
  10. 실제로 대부분의 작업을 수행하는 60 비트 보조 클럭. 느린 시계에서 빠른 시계를 시작하는 것이 더 쉬우므로 거의 사용하지 않더라도 가장 느린 시계 (120 비트)가 마스터입니다. 60 비트 클럭이이 핵심입니다.
  11. 60 비트 클럭이 작동하는 경우에만 전자를 전달하는 피드백 와이어. AND-NOT 게이트와 함께 사용되어 120 비트 마스터에서 클럭이 반복적으로 다시 시작되는 것을 중지합니다. 그렇지 않으면 많은 끔찍한 일이 발생하며 Ctrl-Z는 구세주입니다.
  12. 60 비트 클럭이 시작되는 다이오드입니다.
  13. 이 전체 장치는 플립 플롭, AND 게이트 및 AND-NOT 게이트 결합입니다. 래치를 제공합니다. 한 펄스 입력이 시작되고 한 펄스 입력이 중지됩니다.
  14. 10 개의 펄스 입력 중 하나에 대해 10 펄스 켜짐, 10 펄스 꺼짐으로 래치를 교정하기위한 와이어 루프. 그것없이 우리는 12 펄스, 8 펄스를 얻습니다. 이러한 10 개의 10 개의 오프 래치는 6- 미크론 (1 펄스) 플립 플롭이 미세 유닛의 기본 구성 요소를 형성하는 것과 동일한 방식으로 10 분 블록의 기본 구성 요소를 형성합니다.
  15. 콜드 스타트 ​​초기 펄스는 시작되는 클럭과 위상이 다른 두 비트를 포함하여 모든 종류의 문제를 일으켰습니다. 이것은 걸쇠를 엉망으로 만듭니다. 이 AND 게이트는 동기 펄스, 특히 시작 펄스를 포착하여 폐기합니다.
  16. 이것은 회고에서 다소 후회하는 디자인의 일부입니다. 전자를 가져다가 5 개로 나누고 5 개의 전자를 소멸시켜 111111에서 100000을 취합니다.
  17. 이것은 전자를 가져 와서 정면에 꿰맨 다. 두 단계는 정확합니다. 파트 16과 결합하여 111111-> 100000-> 101000을 얻습니다. 돌이켜 보면 111111-> 101010-> 101000; 적은 공간에서도 동일한 효과를 얻을 수있었습니다.
  18. 그런 다음 위의 패턴을 하단 래치에 밀어 넣어 20 on, 40 off합니다. 이것은 분할되고, 절반은 20 단위만큼 위상 편이되고, 이들은 수십 분의 2 개의 상위 비트 스트림을 형성한다.

2 부 : 시간 카운터

설명

시간 카운터에 대한 입력은 한 시간에 한 번의 단일 전자 펄스입니다. 첫 번째 단계는 12 시간마다 한 번씩 단일 전자 펄스로 줄이는 것입니다. 이것은 여러 "latch & catch"프리미티브를 사용하여 달성됩니다.

"래치"는 6 마이크론 온 / 오프 래치를 제공하기 위해 AND-NOT 및 AND 게이트에 연결된 6 마이크론 플립 플롭입니다. "캐치 (catch)"는 입력으로 전자의 연속적인 흐름을 취하고, 첫 번째 통과를 허용 한 다음, 캐치가 재설정되는 지점에서 스트림이 종료 될 때까지 다른 모든 전자를 뒤에서 멸절시킵니다.

래치를 배치 한 후 캐치를 직렬로 배치하면 하나의 전자가-> 래치를 켜고, 하나의 전자가 다른 쪽 끝을 빠져 나옵니다 (캐치에 걸린 나머지). 그런 다음 두 번째 전자-> 래치를 끄고 조용히 재설정하십시오. 순 효과 : 전자 사이의 지연 시간에 관계없이 첫 번째 전자는 통과하고 두 번째 전자는 소멸 됩니다.

이제 두 개의 "래치 앤 캐치"를 직렬로 연결하면 네 개의 전자 중 하나만 통과하게됩니다.

다음으로 세 번째 "래치 및 캐치"를 수행하지만 이번에는 전체 네 번째 래치를 포함하고 AND-NOT 게이트와 플립 플롭 SET 사이의 플립 플롭 SET 라인에 캐치합니다. 이것이 어떻게 작동하는지 생각해 보도록하겠습니다. 그러나 이번에 는 전자 사이의 지연 시간에 관계없이 3 개의 전자 중 하나만 통과 합니다.

마지막으로, 전자 4 개 중 1 개, 3 개 중 1 개를 AND 게이트와 결합하면 12 개 전자 중 하나만 통과합니다. 이 전체 섹션은 아래의 시간 카운터 왼쪽 상단에 지저분한 경로입니다.

그런 다음 12 시간마다 전자를 가져 와서 1 시간마다 하나씩 분리하지만 각각 다른 도체 와이어로 출력합니다. 이것은 13 개의 출구 지점이있는 긴 코일 도체를 사용하여 달성됩니다.

이 전자들을 다른 도체 아래로 1 시간 씩 내려가 플립 플롭 SET 라인에 부딪칩니다. 그런 다음 동일한 플립 플롭의 RESET 라인이 다음 시간의 도체에 닿아 시간당 각 와이어에 60 개의 펄스가 내려갑니다.

마지막으로-이 펄스를 가져 와서 7 바이트 반의 ROM (읽기 전용 메모리)에 전달하여 올바른 BCD 비트 스트림을 출력하십시오. WireWorld ROM에 대한 자세한 설명은 여기를 참조하십시오 : http://www.quinapalus.com/wires6.html

디자인

주석 처리 된 시간 카운터

  1. 시간당 하나의 전자 입력.
  2. 첫 번째 걸쇠.
  3. 첫 번째 잡기.
  4. 외부 "래치 앤 캐치"SET 라인에 "래치 앤 캐치"내장
  5. 그리고 게이트.
  6. AM / PM 래치 (12 시간마다 한 번씩 켜고 끄기).
  7. 와이어의 각 루프는 6x60 = 360 단위 길이입니다.
  8. 플립 / 플롭이 측면을 향하여 더 작은 프로파일을 만듭니다.
  9. 7 바이트 반의 ROM.

노트

  1. 분당 1 개의 전자, 6 마이크론 설계로 인해 실시간 클록에 대해 분당 6 세대 (10 초마다 1 세대)로 시뮬레이션을 실행합니다.
  2. AM / PM 라인은 AM의 경우 높음 (1), PM의 경우 낮음 (0)입니다. 이것은 약간 특이한 방법으로 선택할 수 있지만 정당성이 있습니다. 클럭 콜드 스타트 ​​동안 AM / PM 라인은 처음에는 자연스럽게 낮습니다 (0). AM / PM 라인을 높이 올리면 (1) 카운트가 오전 12시에 시작되었음을 나타냅니다. 이 시점 이전의 모든 출력은 무시해야하며이 시점 이후의 모든 출력은 의미있는 것으로 간주됩니다.

유용한 링크


항상 제로 출력을 생략 할 수 있도록 요구 사항이 변경되었습니다. 수십 시간 동안 4s 및 8s 비트는 사용되지 않으며, 수십 분 동안 8s 비트도 사용되지 않습니다.
Sparr

고체! 진정한 엔지니어링. 다른 로직 게이트가 도움이 되었습니까? 나는 일부를 무차별 대입하려고한다.
wyldstallyns

1
이것은 아름답다
Sparr

1
의 오 좋은 슬픔 단지 내가 시도하고 최적화 광산을 강요하고있어 지금 충분히 가까이. 다른 사람들을 접을 수있는 공간을 만들기 위해 짧아 질 수있는 반복되는 패턴이 있습니다.
wyldstallyns

3
나는 당신이 메타에서 얼마나 활동적인지 모르겠습니다. 이것은 내가 PPCG 2016베스트에 대한이 답변을 지명했다는 것을 알려주는 것 입니다.
피터 테일러

5

지연 라인 메모리-51 x 2880 = 146880

영상

축소 :

영상

각 루프의 상단에 출력이 나옵니다.

이 루아를 사용하여 모든 상태를 와이어에 직접 배치하여 golly비트 사이에서 전자를 앞으로 옮길 수 있으므로 커서로 와이어를 따라갈 필요가 없습니다.

나는이 순진한 방법을 사용하여 bar와 crash course wireworld, golly 및 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

테스트를 위해이 상단 와이어를 추가하고 팁을 보았습니다.

임 구르

다음은 4 와이어 BCD 4 세트를 안구에 수집하는 스크립트입니다.

-- 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 비트도 사용되지 않습니다.
Sparr

2
이것은 유쾌하고 멋진 구현입니다!
Sparr

1
Ok 11 시간에 또 다른 기능성 시계에 맞았습니다. 다른 트릭으로 가장 길고 가장 짧은 루프를 공격하겠습니다.
wyldstallyns

나는 그것을 떼지 않을 것입니다. 3 미크론 펄스로 전환하여 1/4 크기의 크기를 절약 할 수 있지만 여전히 니미로를 이길 정도로 감겨지지는 않습니다.
wyldstallyns
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.