ChatGPT와 메타버스 시대를 역행하는 16비트 CPU, A.K.E.E CPU








개요




<-- ALU

A.K.E.E CPU는 자작 16비트 CPU 입니다. A,B 레지스터를 포함하여 4개의 레지스터, 128KB의 RAM과 ROM을 가지고 있고, 곱셈/나눗셈 전용 회로와 자체적인 명령어 집합을 가지고 있습니다. 현재 LOGISIM을 지원하며 추후 마인크래프트 레드스톤으로도 구현할 계획입니다.




제작 동기





(NandGame 플레이 화면)

논리 회로 조합 게임인 NandGame을 하다가 CPU 제작 레벨을 클리어했고, 그 이후 CPU 제작이 흥미가 되어 만들었습니다. 그렇기에 ROM에서 명령어를 가지고 오는 등 전체적인 구조는 NandGame의 것과 유사합니다.



(본격적으로 설계하기 전 노트에 전체적인 구조를 스케치했습니다.)

작동 영상










A.K.E.E CPU 전용 어셈블러(자바스크립트를 사용하였습니다)


코드
순서
명령어
HEX

0
0000000000000000
0000
새로운 코드 추가
마지막 코드 제거
클립보드에 코드 복사
HEX로 복사
조립하기
0 번 코드를 편집 중
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
A값 지정(0 ~ 32767)
예상되는 결과 : A = 0
명령어 블럭

명령어 사용 여부
A값 지정(0 ~ 32767)
명령어 사용하기


실행할 명령어
A + B
A - B
B - A
A + 1
A - 1
B + 1
B - 1
A
B
-A
-B
-1
1
0
A AND B
A OR B
A XOR B
NOT A
NOT B
SHIFT A >>
SHIFT A <<
SHIFT B >>
SHIFT B <<
A * B
A / B
B / A
현재 메모리 주소에 있는 메모리 값 가져오기


계산 결과 목적지
A
B
RAM
점프 주소 레지스터
RAM 주소 레지스터

주의: ram과 ram 주소에 동시에 보낼 시 동기화 안됨

결과물:
목적지 없음


점프 조건
점프 안함
0보다 작으면
0보다 크면
0이면
0이 아니면
0보다 작거나 같으면
0보다 크거나 같으면
무조건 점프

1-1. 자작 CPU를 만들게 된 동기

2학년 때 전가산기와 2의 보수법을 이용해서 2진수 덧셈 뻴셈 계산기를 만든 적이 있었는데 곱셈 나눗셈도 계산할 수 있는 장치를 만들고 싶었는데 곱셈, 나눗셈을 추가하려고 보니 논리 회로 퍼즐 게임인 "NandGame" 을 플레이 하면서 'ALU 제작' 레벨을 클리어했던 경험이 있어서 4개의 연산만 지원하는 장치를 만들기보단 아예 ALU를 만들어 보면 좋을 것 같았습니다. 그런데 마찬가지로 "NandGame"에서 "컴퓨터 제작" (간단한 8 비트 컴퓨터를 실제로 제작하는 레벨입니다) 을 클리어했던 경험이 있어서 생각해보니 "만약 우리가 메모리에 ALU에 실행시키고 싶은 코드를 순서대로 저장해 놓고, ALU로 가져올 메모리의 주소값을 카운터와 클록으로 연결해서 클록이 깜빡일 때마다 카운터가 올라가면서 메모리의 코드를 순서대로 ALU로 가져와서 실행시킨 뒤, 점프 기능도 만들어서 ALU가 점프 명령어를 쓸 때마다 카운터 값을 점프 주소로 바꿔서 그 주소에 있는 코드를 실행시키게 한다면 원시적인 CPU라고 할 수 있지 않을까?" 라는 생각이 들어서 그냥 ALU를 만들기보단 자작 CPU를 만든다는 계획을 세우게 되었습니다.

1-2. 자작 CPU를 위한 어셈블러를 만들게 된 동기

자작 CPU를 만들 때, 그에 대한 명령어 집합도 만들어서 기계어 코딩을 할 수 있게 했는데, 기계어 코딩이 정말 귀찮다고 느꼈습니다. 명령어의 연산자부, 번지부, 점프 여부 등에 따라 직접 노트에 적어 놓은 매뉴얼을 확인 해야 했는데 그 과정이 번거롭고 시간이 많이 걸렸기 때문에 기계어에 1대1 대응되어 빠르게 코딩할 수 있는 어셈블러를 만들고 싶었습니다. 원래는 A = A + B와 같은 어셈블리를 번역하여 기계어로 바로 바꿔주는 텍스트 기반 어셈블러를 만들려고 했지만 기계어 코드를 살펴보니 기계어 코드가 ALU의 연산을 결정하는 "연산자부", 연산 결과를 보내 저장할 "번지부", 연산 결과가 조건에 맞을 때 점프시킬 "점프 조건" 으로 이루어져 있는게 블록을 조립하는 것과 유사하다고 느꼈고, 텍스트만으로 기계어 코드에 1대1 대응되는 기존의 어셈블리어가 아닌, 블록 코딩 기반의 어셈블러를 만들어서 블록을 마우스로 끌어당겨 조립하는 식으로 쉽게 기계어 코드를 만들 수 있다면 좋을 것 같다고 느꼈습니다.

2-1. 자작 CPU 설명

자작 CPU의 이름은 "A.K.E.E CPU" 입니다. 16비트로 작동하고 레지스터는 연산할때 쓰는 A,B 레지스터와 RAM의 값을 불러오거나 변경할때 쓰는 레지스터, ROM에 연결된 PC의 값을 점프시킬 때 쓰는 레지스터 가 있습니다. 또한 자작이기 때문에 다른 x86,ARM 계열 CPU와 다르게 자체적인 명령어 집합을 가집니다. 만들때 사용한 프로그램 이름은 LOGISIM이며, CPU의 전체적인 구조 스케치는 학교에서 노트에 연필로 그렸습니다.(전 패드가 없거든요)

2-2. 블록코딩 기반 어셈블러

HTML과 자바스크립트 기반으로 돌아가는 어셈블러는 최대 3가지 부분으로 이루어져 있는데, 코드 메뉴 분과 조립 부분, 명령어 블럭 창고 부분입니다. 메뉴 부분에서는 지금까지 만든 코드를 확인하거나 새로운 코드를 추가/삭제 할 수 있습니다. 코드는 순서에 따라 리스트에 표시되며, 이진수와 HEX 둘 다 보여줍니다. 또한 지금까지 만든 모든 코드를 클립보드에 복사해서 저장할 수 있게 만들었습니다. 조립 부분에서는 블록코딩 형식으로 기계어 코드를 만듭니다. 메뉴에서 코드를 선택하면 자동으로 그 코드를 읽어들여 이진수를 보여 주고, 그 밑에 그 이진수 코드가 무슨 의미인지 설명하는 "예상되는 결과" 와 그 코드를 시각화해주는 블록들이 나옵니다. 코드를 편집하려면 명령어 블록 창고 에서 바꾸고 싶은 부분에 해당하는 명령어를 드래그해서 해당하는 색상의 코드에 올려 놓아 교체하면 됩니다. 블록을 교체할 때 마다 해당하는 이진수 코드가 실시간으로 바뀌게 해놓았으며, 그 역으로 이진수 코드를 직접 편집할때도 해당하는 블록의 내용이 실시간으로 바뀝니다. (최상위 비트가 0일 시에는 A 레지스터에 값을 저장하는 코드로 무조건 고정입니다. 다른 명령어를 사용하기 위해서는 최상위 비트를 클릭해 '1'로 바꾸거나 명령어 블록 창고의 '명령어 사용 여부'에서 '명령어 사용하기' 블록을 드래그하여 조립 부분의 'A값 지정' 블록과 교체해야 합니다.)

3-1. CPU 제작 소감

일단 CPU 제작을 하면서 느낀 점은 이 모든 레지스터와 ALU, RAM ROM 등등의 작동이 논리 회로와 클록의 순차적 연산으로 이루어졌다는 것이 놀라웠고 제작 하고 나서 "컴퓨터 구조" 책(정기철 지음)에서 CPU의 작동 방식 부분을 보니 알고 보니 제작한 CPU가 폰 노이만 구조에서 돌아가고 있었다는 것이 신기했습니다.

3-2. 어셈블러 제작 소감

이제 자작 CPU를 가지고 놀 때 번거롭고 힘들게 기계어 코딩을 하지 않아도 된다는 것이 좋은 것 같습니다. 또한 자바스크립트는 처음 써보는 것인데 결과가 잘 작동해서 좋았습니다.

4-1. 제언(CPU)

지금 만든 CPU는 정말 기초적인 기능만을 지원하는 것이기 때문에 나중에 더 많은 기능을 지원하는 (스택, 데이터 버스 등등) CPU를 만들어 보고 싶습니다.

4-2. 제언(어셈블러)

이 어셈블러는 HTML과 자바스크립트로 만들어졌기 때문에, 나중에 개인용 서버를 만든다면 웹사이트에 어셈블러를 올려서 어디서든 코딩 할 수 있게 하고 싶습니다.