혼자 공부하는 운영체제 - CPU
2024-11-03혼자 공부하는 운영체제 과목에서 CPU와 관련된 부분을 공부하였습니다.학습한 내용을 자바스크립트 코드로 구현하는 중입니다.구현하면서 느끼는 점이 확실하게 이해하지 못한 부분들에 대해서 강제로 다시 살펴보게 되는 것 같습니다.하지만 데이터 흐름을 확실히 정리하지 않고 구현을 하다 보니, 공부한 데이터 흐름과 약간 달라지는 일을 경험하였습니다. 어떻게 수정할지 고민해보아야겠습니다.고민을 조금 해봤는데 구현하는데 한세월 걸릴 것 같아서 강의 내용과 데이터 흐름을 일치시키는 것은 포기하기로 결정하였습니다.현재 구현 초반부이고, 다음 테스트만 통과시킨 상태입니다. 구현의 편의를 위해 ISA로는 1바이트 opcode, 2바이트 워드, addressing mode를 위해 1byte를 따로 마련했습니다. import { test, expect } from "@jest/globals"; import { AddressingMode, Byte, Cpu, Opcode, Register, Word } from "./cpu"; const { R1, R2 } = Register; const { LOAD, STORE, NOP, ADD } = Opcode; const { IMMEDIATE, DIRECT } = AddressingMode; test("can fetch instructions with variable length", () => { // prettier-ignore const program: Byte[] = [ LOAD, R1, DIRECT, 0x00, 0x01, // TODO: Addressing mode 구현 LOAD, R2, IMMEDIATE, 0x00, 0x02, NOP, ADD, R1, R2, STORE, R1, DIRECT, 0x00, 0x01, ]; const stack: Byte[] = []; const cpu = new Cpu(program, stack); const instructions: Word[] = []; while (cpu.programCounter < program.length) { cpu.handleClock(); instructions.push(cpu.instructionRegister); } expect(instructions).toEqual([LOAD, LOAD, NOP, ADD, STORE]) }) 구현 관련해서 참고 중인 사이트들입니다.https://github.com/pbohun/basic-cpu/tree/masterhttps://github.com/skilldrick/easy6502/blob/gh-pages/simulator/assembler.js2024-11-04CPU의 클럭과 관련해서 잘못 이해한 부분이 있었습니다.한 클럭에 fetch도 하고, decode도 하고, execute도 하는 것을 염두에 두었어야 했는데, 너무 단순화를 많이 해서 모든 것을 한 클럭 안에 담아버려서 MBR이 다음 클럭 때 쓸 데이터를 저장하는 버퍼라는 것 등을 전혀 고려하지 못했습니다.fetch, decode,execute가 동시에 일어날 수 있도록 하는 설계를 해보고 오늘 안에 할 수 있는지 확인한 후, 가능하면 고려해서 수정해보아야겠습니다.업데이트: 오늘 안에 못 끝낼 것 같습니다. 원래 해보고 싶었던 것은 다음과 같았지만, 시간 상 기존의 약간 아쉬운 방식으로 진행할 예정입니다.class Register extends Vertex { constructor() { this.state = 0; } handleClockTick(inputEdge: Edge) { this.state = inputEdge.value; } // TODO: steady state보다 나은 이름을 고려해보기 handleClockSteadyState(outputEdge: Edge) { outputEdge.value = this.state; } }업데이트: 서로 다른 Addressing mode에 대해서 다른 명령어로 구분하는 게 편한 것 같습니다. Fetch, Decode, Execute, Memory, WriteBack 사이클에 맞추려다 보니, 같은 명령어로 구현하기 불편한 부분이 많은 것 같기 때문입니다.업데이트: fetch와 decode를 조금 더 깔끔하게 나타내기 위해서 모든 명령어들의 길이를 똑같이 맞추어놓는 것이 구현하기 더 편하다는 생각이 들었습니다. 이를 위해서 0x00으로 남는 길이는 pad를 하고 decode시 이는 무시하기로 하였습니다.