팩토리오 끊었더니 금단현상이 와서 이딴거나 하고있음..;;;

아무튼 CPU 설명



일단 RAM임.

사진에는 1, 2, 3만 있지만 최대 21억까지 무한히 붙이면됨. 아마 음수도 가능할거임. 근데 0은 안됨.

사진에는 1, 2, 3 이렇게 3개가 있으므로 주소 1, 2, 3에 하나씩 총 3개의 수를 저장 가능함.


초록색으로 I(알파벳 아이) 신호로 인풋 인덱스를 받으면 중간의 비교기는 꺼지고 맨 오른쪽의 비교기는 켜짐.

인풋 인덱스와 동시에 들어온 점 신호 인풋 데이터는, 이 겨진 오른쪽의 비교기를 통해 들어와 1틱 후 중간의 되먹임 비교기에 저장됨.

(저장하는데 1틱걸림)


O 신호 아웃풋 인덱스를 주면 맨 왼쪽의 비교기가 작동하며 출력됨.

역시 저장과 똑같이 1틱걸림.





다음은 ALU임.

점 신호와 [1] 신호를 받아 각자 연산을 함.

그리고 오른쪽에서 들어가는 A신호에 따라 특정 연산기에서 내놓은 결과만 나가게 됨.


그리고 레지스터가 있는데

팩토리오는 틱 단위로 모든 것이 정확하게 돌아가기 때문에

실제 컴퓨터처럼 값을 계속 저장할 필요가 없고

딱 값이 필요한 그 순간에 정확히 맞춰서 값을 쏴주기만 하면 됨.

그래서 레지스터는 영구 저장 기능이 없음.


점 신호 입력은 레지스터를 그냥 통과하고

또 1틱후에 점 신호와 같은 값인 [1] 신호를 출력시킴.


레지스터의 출력과 ALU의 입력이 바로 연결되어 있고 레지스터는 RAM에서 입력을 받는데

그러면 RAM에서 1틱째에 어떤 점 신호 ?1을 쏘고 2틱때에 어떤 점 신호 ?2를 쏴주면

1틱째엔 ?1이 점 신호 그대로 들가고

2틱째엔 아까의 ?1이 레지스터를 거쳐 [1] 신호로 들가고 ?2가 점 신호 그대로 들감.

그럼 그때 ALU에서 점 신호와 [1] 신호의 계산이 이루어지고 3틱쨰에 A신호를 ALU로 쏴서 원하는 연산값을 뽑으면됨.




마지막으로 제어부임.

우선 카운터를 보면,

카운터에 점 신호를 쏴주면 점 신호만큼 그대로 증가하는걸 볼 수 있음.

즉 명령어 점프임.

카운터에 E 신호를 쏴주면 점 신호가 초기화됨.

즉 프로그램 종료임.

카운터에 F 신호를 쏴주면 저장되어 있던 점 신호가 출력되고 또 점 신호가 1 출력되어

최종적으로는 저장되어 있던 점 신호 + 1이 출력되고,

또 저장되어 있던 신호는 1 증가함.



명령어 저장소를 보면 점 신호에 따라 일정 신호 조합기에 있는 신호들을 내보내는걸 볼수있음.


디코더는 그냥 + 0 이라는 의미없는 연산을 통해 들어온 신호들을 정해진 틱만큼 늦춘 후에 원하는 장소로 쏴줌.




그래서 이걸 이으면 이렇게 되는데,

저 그림에는 없지만 일단 외부에서 시동을 걸어야 하는데 카운터에 F신호를 1틱동안 1 보내야함.

그럼 카운터엔 점 신호 0이 저장되어 있으므로 점 신호가 0 + 1 = 1이 출력되어 명령어 저장소로 감.

또 카운터에 저장되어 있던 점 신호는 1이 더해져 1이 됨.


명령어 저장소엔 점 신호 1이 들어갔으므로 1에 해당하는 명령어들이 디코더로 갈거임.


그럼 디코더에서는 그 명령어들을 CPU가 잘 돌아가도록 일정 틱동안 지연시켜서 다른 여러 장치에 뿌릴거임.


예를 들어서 1틱째에 RAM에 OI신호를 2, 2틱째에 RAM에 OI신호를 3 뿌리면

RAM의 주소2와 주소3에 들어있는 수가 차례로 출력될거고

그게 레지스터를 거쳐 3틱째에 [1]신호와 점 신호가 되어 ALU로 가서

4틱째에 ALU에서 계산이 될거임.

그럼 이제 4틱째에 ALU에 A신호를 1 보냄.

그럼 그 두 수를 더한 수가 5틱째에 CPU의 OD로 출력이 됨.

이제 5틱째에 RAM에 II신호를 4 보냄.

그러면 RAM에서 II신호가 4에 ID신호가 계산값이니

주소 4에 그 값이 저장될거임.

마지막으로 6틱째에 카운터로 F신호를 1 보내면

카운터는 저장값을 1 증가시키며 다음 커멘드(즉 아까 0에서 1이 증가한 1이었으므로 1+1= 2번째 커맨드)를 실행함.



이게 기본적인 CPU원리고, 사실 이건 기능이 별로 없음.

여기다 어떤 기능들을 추가할 수 있는지 잘 보면,


4번 그림에서 출력을 하는 것들은

ALU의 OD, 디코더의 여러 출력들, RAM의 O1, O2이고 (근데 O1, O2는 같으니 O1 하나만 있는거로 치겠음)

입력을 받는 것들은

ALU의 I1, I2(역시 하나로 치겠음), RAM의 ID, OI, II, 카운터의 JC 정도가 될 거고

또 만들자면 CPU 외부로 가는 출력값도 만들 수 있을 거임. 그걸 OP라고 하겠음


정리해보면

출력- ALU:OD, DEC, RAM:O1

입력- ALU:I1, RAM:ID, RAM:OI, RAM:II, CNT:JC, OP


출력이 3개 입력이 6개가 나오는데

이 출력과 입력을 각각 하나씩 뽑아서 3번째 사진에 나온 GATE의 입력 출력으로 연결해주면 됨.

GATE의 ?신호는 디코더에서 쏴줄거고

GATE의 입력 출력 점 신호는 꼭 점 신호가 아니라 다른거여도 됨.(예: RAM:OI로 들어갈땐 O신호를 해줘야 들어갈것임)


그럼 어떻게 되냐면 평소에 GATE는 막혀있다가

디코더에서 ? 신호가 1 들어오면 그 GATE가 뚫리면서 해당 루트로 값이 전달됨.


그럼 무슨 일이 일어나냐면, 3 * 6 해서 총 18개의 게이트 중에

(근데 ALU:OD와 RAM:ID / DEC와 RAM:OI / DEC와 RAM:II / DEC와 CNT:JC 는 사진 4에서 이미 이어져있어서 필요없음, 그러면 14개)

DEC와 RAM:ID를 연결하면 디코더에서 램에 저장할 값을 직접 쏴 줄 수 있을 것임.

즉 상수를 램에 저장 가능함.

DEC와 ALU:I1을 연결하면 상수를 연산할 수 있게 되는거고

ALU:OD와 CNT:JC를 연결하면 ALU에서 계산한 값만큼 명령어를 점프할 수도 있음. 이걸로 if문을 구현할 수 있음.

아니면 RAM:OD와 CNT:JC를 연결해 램에 저장되어 있던 값만큼 점프하던가.

RAM:O1과 RAM:OI를 연결하면 램에서 뽑힌 데이터값을 다시 램에서 데이터를 뽑을 인덱스값으로 사용할 수 있음.

반대로 RAM:O1롸 RAM:II를 연결하면 램에서 뽑인 데이터값을 데이터를 저장할 인덱스값으로 사용할 수 있음.

즉 위 2개로 포인터를 사용할 수 있다는 소리임.


아무튼 이렇게 여러 입력과 출력을 게이트로 잇고

그걸 디코더에서 나오는 신호로 제어하면 됨.


디코더에서는 받은 커맨드를 특정 틱만큼 지연시켜 여러 장치로 쏴주면 되고.


아무튼 이렇게 됨.

내가 올린 글 중에 블프글이 있는데 아마 거기 cpu블프가 있을거임. 없을수도?

그거 뜯어보면서 글 보면 이해가 더 쉬울거임.

끝.