아기 보느라 개인 시간이 하나도 없네요.

요새 고민하고 있는 부분이 micro code입니다.

약간의 힌트와 지식을 얻어서 대충 공유(?) 해보려합니다. (지적 및 조언은 감사히 받구요 ^^ )

제가 micro code를 보려는 이유는 ttl로 cpu를 만들려는 개인 취미이고요.

문제 상황은 납땜을 극히 싫어하는 뼈소남 (뼈속 부터 소프트웨어 남자)이기에.. ㅋㅋㅋ

wire wrap방식으로 만들고자 하는 것이고요. ( 왜 있잖아요, homebewcpu.com 아저씨 처럼 ㅎㅎ;; )

isa를 해석하는 control 로직에 interconnect를 줄이기 위한 일환으로 microcode 방식의 control로직을 고민하게 되었고요.

대략적으로 다음과 같더군요. 

먼저 마이크로코드는 isa (instruction set architecture) 의 수많은 명령어를 모두 하드웨어 상에 설계를 하려면 귀찮으니

보다 저급한 프리미티브한 상세 동작으로 나누어보자는 거죠.

이를 구현하기 위해선 micro sequencer로직이 필요하게 됩니다. 한 명령어를 실행하기 위해서 내부적으로는 세부명령어
여러개로 나누기 때문에 한 명령어 당 여러 세부 cycle이 발생하게 되는거죠. 
(현재 x86 아키텍쳐는 내부적으로 이 microcode architecture를 쓰고 있습니다.)

구현측면에서 바라보면 

alu로 부터 결과를 얻은 flag register로 부터 c (carray), z (zero), v (overflow), n(minus) 이전 상태 값을 얻어온 후

micro sequence마다 해당 해야 할 control logic을 내뱉는 동작..

즉.. 예로 아래는 bmow의 microcode입니다.

// BEQ
// Branch if result is zero. If Z bit of the condition codes is 0, then interpret the
// next byte of the program as a signed offset from the next instruction's PC, and jump to that
// address.
opcode: F0
z=0: T <- X // brach taken
z=1: pc++ // branch not taken
z=0: X <- MEM(PC); PC++
z=1: nextop
*: PCLO <- X + PCLO; latchCC // add delta to low byte of PC; latch carry
//if no X7 available:
// *: X <- X; latchCC
//n=0: X <- 0
//n=1: X <- 0 - 1
//c=0: PCHI <- X + PCHI + 1
//c=1: PCHI <- X + PCHI
c=0: PCHI <- X7 + PCHI + 1 // carry flag == 0 means there was a carry
c=1: PCHI <- X7 + PCHI
*: X <- T; nextop

위는 BEQ 명령 (만일 어떤 수행의 결과로 zero flag가 설정될 경우 jump하라는 명령)을 기술한 것이고,
cpu개발자는 위와 같이 microcode를 위한 자체 언어를 만들고 이를 assemble 하는 툴을 만들어서
rom에 굽게 됩니다.

위의 경우 왼편에 flag condition이 존재하고 (z=0이나 c=1이런 것들) 오른편에 실제 마이크로 코드가 보입니다.
즉 첫번째 micro sequence 구간(하드웨어에선 clock이라고 말함) 동안 z=0이면 X레지스터값을 T로 복사합니다.
nextop은 마이크로 sequence를 초기화하고 다음 instruction을 fetch하라는 종결을 의미하는 키워드입니다.
(뭐 bmow개발자가 임의로 만든 언어기 때문에 중요한 것들은 아니지만요)

이렇게 마이크로 코드를 모두 작성한 후 자신의 마이크로코드 컴파일러를 개발하여 rom에 굽게 합니다.

여기서 재미있는 매직을 하는데요. 이를 테면

명령어가 놓여져 있는 메모리에서 한 명령어를 읽어온 후

opcode가 F0 (위 기술상 BEQ에 해당)가 읽히면 해당 opcode 값 F0가 마이크로 코드가 심어져 있는 rom의 
상위비트 주소로 연결되고, 중간 비트에 micro sequence값 0~16 차례로 증가되는 값, 그리고 마지막비트들에
zvcn flag값이 역시 rom의 어드레스로 들어가게 됩니다.

물론 이미 rom에는 해당 opcode에 대해 몇번째 micro sequence step일때 그리고 이전 flag가 무슨 값일때 
어떤 control signal을 생성해야 할지 정해져있는 거고요.

예를 들면, 실행할 opcode가 F0 (BEQ)이고 seq값이 1이고 z=1인 상태이라면 
microcode rom의 입력address pin에 F014 이런 어드레스가 들어갑니다. (상위 F0, 중간 1, 마지막 비트가 zcvn순이라면 ) 
그러면 pc++을 실행하기 위해서 내부적으로는 inc_pc라는 (가정) internal control signal이 발생되어야 한다면,
microcode rom의 F014 주소의 메모리 값을 읽으면 0x0001이라는 값을 얻게 되고 inc_pc 컨트롤 신호는 rom메모리 읽은 값의 
최하위 비트를 쓰는 식입니다.
마치 소프트웨어의 해쉬테이블 처럼 말이죠.

결국 마이크로코드를 지원하기 위해서 해야할 일

- 자신의 isa를 결정
- 지원할 microcode instruction 결정
- microcode 언어 개발
- microcode 컴파일러 개발
- microcode 롬에 굽기

일단 개략적으로 동작이나 만드는 방법이 정리되는 거 같군요..

결혼하고 애낳고 하느라 근 1년 넘게 개인 취미를 못했는데, 다시 시작하려니 설레네요.

'프로젝트 > CPU 설계' 카테고리의 다른 글

VGA 테스트 성공!  (2) 2009.01.15
cpu isa design issue  (0) 2009.01.14
address/data bus issue  (2) 2008.12.22
compiler basic phase  (0) 2008.12.13
VGA programming  (2) 2008.12.09

+ Recent posts