본문 바로가기

RISC-V/RISC-V 개념

[RISC-V] RV32I ISA

 RV32I ISA(Instruction Set Architecture)는 최소한의 명령어로 모든 계산을 수행한다는 RISC-V의 철학을 보여줍니다. 전체 명령어는 총 47개 뿐이며, 모든 명령어 길이는 32비트로 고정되어 있습니다.

 

1. 하드웨어 관점: 명령어 포맷

RISC-V 디코더는 며령어의 비트 배열을 보고 어떤 작업을 할지 결정합니다. RV32I는 모든 명령어가 32비트 고정 길이이며, 아래 6가지 형식을 따릅니다.

 

 

 

 

2. 소프트웨어적 관점: 기능별 분류

아래는 RV32I의 명령어를 기능적으로  분류 한 것입니다.  

2.1. Integer Computation (산술, 논리연산, shift 연산)

 레지스터 간의 계산이나 상수를 이용한 계산을 수행합니다.

 ✔  R-type  (Register - Register): 두 레지스터 값을 연산하여 결과를 레지스터에 저장합니다.

     - add

     - sub

     - and

     - or

     - xor

     - sll(shift left logical)

     - srl(shift right logical)

     - sra(shift right arithmetic)

     - slt(set less than)

     - sltu(set less than unsigned)

 

 ✔ I-type(Register - Immediate) 레지스터와 명령어에 포함된 상수를 연산합니다.

     - addi

     - andi

     - ori

     - xori

     - slli(shift left logical immediate)

     - srli(shift right logical immediate)

     - srai(shift right arithmetic immediate)

     - slti(set less than immediate)

     - sltiu(set less than immediate unsigned)

 

 ✔  U-type:  RV32의 명령어는 32비트 고정 길이라서, 32비트 크기의 큰 숫자를 한 번에 레지스터에 담을 수 없습니다. 이를 해결하기 위해 상위 20비트를 다루는 전용 명령어가 존재합니다.

     - lui(load upper immediate): 20비트의 큰 상수를 레지스터 상위 비트에 넣고, 하위 12비트는 0으로 채움

     - auipc(add upper immediate to pc): 상위 20비트 값을 현재 PC값에 더한 결과를 레지스터에 저장

 

 

2.2. Loads & Stores (메모리 접근)

 프로세스 외부의 메모리와 레지스터 사이에서 데이터를 주고받습니다.

 ✔ I-type(Load): 메모리에서 데이터를 읽어 레지스터에 씁니다.

     - lw(load word)

     - lh(load halfword)

     - lb(load byte)

     - lhu(load halfword unsigned)

     - lbu(load byte unsigned)

 

 ✔ S-type(Store): 레지스터의 값을 메모리에 저장합니다.

     - sw(store word)

     - sh(store halfword)

     - sb(store byte)

 

 

2.3. Control transfer (흐름 제어)

 프로그램의 실행 순서를 바꾸는 명령어 입니다. PC 값을 변경하는 유일한 수단입니다.

 ✔  B-type(Conditional Branch): 조건이 맞으면 특정 주소로 점프합니다. (if문 역할)

     - beq(branch equal)

     - bne(branch not equal)

     - blt(branch less than)

     - bge(branch greater than or eqaul)

     - bltu(branch less than unsigned)

     - bgeu(branch greater than or eqaul unsigned)

 

 ✔  J-type(Unconditional Jump): 무조건 점프합니다.

     - jal(jump and link): 함수를 호출할 때 사용(돌아올 주소를 rd에 저장)

 

 ✔  I-type(Unconditional Jump): 무조건 점프합니다.

     - jalr(jump and link register): 레지스터에 저장된 주소로 점프    

 

 

2.4. Miscellaneous instructions (시스템 및 특수 명령어)

CPU 자체를 제어하거나 운영체제와 통신할 때 사용됩니다.

 

2.4.1. 메모리 배리어(Memory Ordering)

 멀티코어나 입출력 장치와의 동기화를 위해 필요한 명령어

 ✔  I-type

     - fence(load & store): 이 명령어 이전의 메모리 접근이 이후의 메모리 접근보다 먼저 완료되도록 보장

     - fence.i(instruction & data): 명령어 캐시와 데이터 메모리 사이의 일관성을 맞춤

 

2.4.2. 환경 및 시스템 제어(Environment Call & Break)

 운영체제나 디버거와 대화하기 위한 통로

 ✔  I-type

     - ecall(Environment Call): 사용자 모드에서 실행중인 프로그램이 OS에게 서비스를 요청할 때 사용

     - ebreak(Environment Break): 디버거에게 제어권을 넘깁니다. 프로그램 실행중에 중단점을 만났을 때 사용 

 

2.4.3. 제어 및 상태 레지스터(Control and Status Register)

 CPU의 내부 상태를 읽고 설정하거나, 성능을 측정하고, 시스템 예외를 처리하는데 사용됩니다. 이 명령어들은 범용 레지스터가 아니라, 별도의 주소공간에 존재하는 제어 및 상태 레지스터를 대상으로 합니다.

 ✔  I-type

     - csrrw(csr read write)

     - csrrs(csr read set)

     - csrrc(csr read clear)

     - csrrwi(csr read write immediate) 

     - csrrsi(csr read set immediate)

     - csrrci(csr read clear immediate)

 

 

3.  요약

 RV32I 명령어 세트는 분석 관점에 따라 두 가지로 분류할 수 있습니다. 하드웨어적 관점에서는 비트 배열 구조에 따라 6가지 명령어 포맷으로 나뉘며, 소프트웨어적 관점에서는 실행 목적과 기능에 따라 4가지 기능적 범주로 구분됩니다.