16-Bit Toy Microprocessor
특징
단순한 구조의 16비트 RISC
16비트 주소와 데이터 버스선을 가짐
하버드 아키택쳐를 사용
주소는 바이트 단위로 주어짐, 따라서 64K바이트 주소 공간을 가진다.
모든 명령어의 크기는 16비트로 고정되어 있다.
메모리 접근은 LD, ST의 두가지 만을 허용 (추가 될지 모름) + STB(바이트 단위 쓰기)
대부분의 연산은 내무 레지스터 8개에 의해서 이루어 진다.
주소모드는 5가지가 제공
4 스테이지 파이프라닝
분리된 L1 캐쉬를 제공한다.(구체적인 계획 업ㅂ음)
서브루틴의 호출, 리턴을 구현하는 명령을 제공하고 인터럽트 처리가 가능
레지스터
R0~R7 까지의 General Purpose Registers, 16비트 8개, R0는 읽기전용 값 : 0
Program Counter를 저장하는 PC, 16비트 1개
Interrupt Service Routine의 주소를 저장하는 SRA, 16비트 1개
Exception처리를 위해 PC를 백업하는 EPC, 16비트 1개
주소모드
Register mode : 명령어에 지정한 레지스터의 값이 피연산자
Immediate mode : 명령어에 지정한 상수 값이 피연산자
Pc-Relative mode : 현제 PC + 2 + 명령어에서 지정한 상수이 Effective Address
Register-indirect : 명령어에서 지정한 레지스터 값이 EA
Pseude Absolute : 명령어에서 지정한 상수 값이 EA
명령어포멧
R-Format
opcode(3) | DR(3) | SA(3) | SB/SHT(3) | f1(4)
I7-Format
opcode(3) | DR(3) | SA(3) | imm7(7)
I8-Format
opcode(3) | DR(3) | f2(2) | imm8(8)
J-Format
opcode(3) | addr(13)
R -format는 2개의 피 연산자와 목적지가 모두 레지스터인 경우와 쉬프트 명령어를 위한 포멧이다. R-format 에서 opcode와 f1 field 부분이 연산의 종류를 나타내며, SA 필드는 피연산자로서 레지스터를 나타내는 필드이다. SB/SHT는 일반 산술/논리 연산의 경우에는 피연산자로 사용될 레지스터를 가리키며, 쉬프트 명령어의 경우는 한번에 쉬프트 시킬 비트의 수를 나타낸다.
I7-format는 2개의 피연산자중 하나가 7비트 즉치값인 경우를 위한 포멧이다. 16비트 프로세서임으로 7비트의 값을 16비로 확장하여 사용한다.
I8-format는 8비트 상수 값을 즉치값으로 지정할 필요가 있을 경우에 사용하는 포멧이다. 이 8비트값을 16비트로 확장하여 사용한다. 이때 f2필드는 연산의 종류를 지정하는데 추가로 사용한다.
J-format는 분기명령어 JAL에 사용되는 포멧이다. Pseude Absolute 주소모드로 EA를 계산해서 분기하게 되는데 이때 현제 PC+2의 값은 무조건 R7에 저장된다. 점프할 주소의 계산은 addr필드의 13비트를 2배하여 얻어진 14비트에 현제 PC값의 MSB 2비트를 앞에 덧붙여서 16비트를 만든다. 이렇게 함으로 전체 64K바이트의 주소공간을 4개의 세그먼트로 분할 했을때 각 세그먼트 내에서는 절대 주소로 분기할 수 있다.
산술/논리 연산 명령어
Pseudo code |
RTL 수준의 기술 |
format |
예 |
ADD DR, SA, SB |
Reg[DR] <- Reg[SA] + Reg[SB] |
R-format |
ADD R1, R2, R3 |
SUB DR, SA, SB |
Reg[DR] <- Reg[SA] - Reg[SB] |
R-format |
SUB R1, R2, R3 |
ADI DR, SA, imm7 |
Reg[DR] <- Reg[SA] + se(imm7) |
I7-format |
ADI R1, R2, -63 |
ADIU DR, SA, imm7 |
Reg[DR] <- Reg[SA] + ze(imm7) |
I7-format |
ADIU R1, R2, 64 |
XOR DR, SA, SB |
Reg[DR] <- Reg[SA] xor Reg[SB] |
R-format |
XOR R1, R2, R3 |
AND DR, SA, SB |
Reg[DR] <- Reg[SA] and Reg[SB] |
R-format |
AND R1, R2, R3 |
OR DR, SA, SB |
Reg[DR] <- Reg[SA] and Reg[SB] |
R-format |
OR R1, R2, R3 |
NOT DR, SA |
Reg[DR] <- not Reg[SA] |
R-format |
NOT R1, R2 |
ORI DR, imm8 |
Reg[DR] <- Reg[DR] or ze(imm8) |
I8-format |
ORI R1, 255 |
ANI DR, imm8 |
Reg[DR] <- Reg[DR] and ze(imm8) |
I8-format |
ANI R1, 255 |
LSL DR, SA, SHT |
Reg[DR] <- Reg[SA] << SHT |
R-format |
LSL R1, R2, 5 |
LSR DR, SA, SHT |
Reg[DR] <- 0 || (Reg[SA] >> SHT) |
R-format |
LSR R1, R2, 5 |
ASR DR, SA, SHT |
Reg[DR]<-MSB || (Reg[SA] >> SHT) |
R-format |
ASR R1, R2, 5 |
ze = Zero extension, se = Sign extension
분기 명령어
Pseudo code |
RTL 수준의 기술 |
format |
분기조건 |
JAL addr |
PC <- PC[15:13] || (addr << 1); R[7] <- PC + 2 |
J-format |
- |
JR DR, SA |
PC <- Reg[SA], Reg[DR] <- PC + 2 |
R-format |
- |
BZ DR, imm8 |
PC <- PC + 2 + se(imm8) |
I8-format |
IF Reg[DR] == 0 |
BNZ DR, imm8 |
PC <- PC + 2 + se(imm8) |
I8-format |
IF Reg[DR] != 0 |
BPOS DR, imm8 |
PC <- PC + 2 + se(imm8) |
I8-format |
IF Reg[DR] > 0 |
BNEG DR, imm8 |
PC <- PC + 2 + se(imm8) |
I8-format |
IF Reg[DR] < 0 |
무조건 분기 명령어는 JR이 있다. JR은 분기할 절대 주소 16비트를 레지스터에서 읽어도록 되어있다. DR은 현제 PC + 2를 저장할 레지스터이고 SA는 점프할 주소를 담은 레지스터이다. DR을 R0으로 하면 현제 PC+2는 저장되지 않는다. JAL 명령어가 현제 PC +2를 항상 R7에 저장함으로 JAL명령어와 JR명령어의 조합으로 function이나 procedure call을 구현 할 수 있다.
JAL func |
func : |
적절한 연산들... |
JR R0, R7 |
조건부 분기 명령어 BZ, BNZ, BPOS, BNEG는 두개의 레지스터의 대소를 비교하여 분기할 수 없다. 이를 보안하기 위해서 SLT(Set Less Than), SLE(Set Less then or Equal to)명령어가 제공된다.
비교 명령어
Pseudo code |
RTL 수준의 기술 |
format |
예 |
SLT DR, SA, SB |
if(Reg[SA] < Reg[SB]) then Reg[DR] <- 1 else Reg[DR] <- 0 |
R-format |
SLT R1, R2, R3 |
SLE DR, SA, SB |
if(Reg[SA] <= Reg[SB]) then Reg[DR] <- 1 else Reg[DR] <- 0 |
R-format |
SLE R1, R2, R3 |
이를 이용해서 R1 > R2 인 경우 L2로 분기하는 프로그램은 다음과 같이 2개의 명령어로 작성할 수 있다.
If(R1 > R2) goto L2; |
SLT R3, R2, R1 |
BNZ R2, L2 |
메모리 접근 명령어
Pseudo code |
RTL 수준의 기술 |
format |
비고 |
LD DR, SA |
Reg[DR] <= Mem[Reg[SA]] |
R-format |
word 데이터 |
ST SA, SB |
Mem[Reg[SA]] <- Reg[SB] |
R-format |
word 데이터 |
STB SA, SB |
Mem[Reg[Sa]] <- Reg[SB] |
R-format |
byte 데이터 |
상수값 저장 명령어
Pseudo code |
RTL 수준의 기술 |
format |
비고 |
LDI RD, imm8 |
Reg[DR] <- ze(imm8) |
I8-format |
16비트 하위값 |
LUI RD, imm8 |
Reg[DR] <- imm8 << 8 |
I8-format |
16비트 상위값 |
ORI RD, imm8 |
Reg[DR] <- Reg[DR] | ze(imm8) |
I8-format |
LUI 함께 사용 |
LUI와 ORI 명령어를 사용해서 16비트 즉치값을 레지스터에 메모리 접근없이 저장할 수 있다.
인터럽트 처리
Pseudo code |
RTL 수준의 기술 |
format |
비고 |
EIF |
Enable interrupt |
R-format |
|
CIF |
Disable interrupt |
R-format |
|
SISR SA |
ISR <- Reg[SA] |
R-format |
ISR을 세팅 |
RTI |
PC <- EPC; enable interrupt |
R-format |
기존의 루틴으로 복귀 |
인터럽트가 활성화 되어 있다면 현제 PC+2를 EPC로 백업하고 ISR 레지스터에 지정된 주소로 분기한다. 인터럽트 서비스가 끝나고 RTI 명령어를 만나면 EPC에 백업된 주소로 복귀하면서 다시 프로그램이 수행된다. 인터럽트 루틴으로 분기하면서 인터럽트는 비활성화 되고 복귀하면서 활성화 된다. XX 프로세서는 중첩되는 인터럽트를 허용하지 않는다.



