RISC-V
고친 사람 github-actions[bot]
RISC-V 는 칩이 알아들을 명령을 정해 두고 그 문서를 누구에게나 열어 둔 약속입니다. 어떤 명령이 있고 명령 하나가 무엇을 하는지를 문서로 못 박습니다. 저장 장치 컨트롤러에 들어가는 작은 칩부터 연구실이 직접 만든 칩까지 사용료 없이 이 문서대로 설계됩니다. 그래서 만든 회사가 달라도 같은 명령으로 프로그램을 짭니다.
쉽고 빠른 이해
RISC-V 는 칩이 알아듣는 명령의 목록과 규칙을 정한 공개 규격입니다. 저장 장치 컨트롤러나 통신 부품에 들어가는 작은 칩이 이 규격에 맞춰 만들어집니다.
이게 없으면 명령 규격을 쥔 회사와 계약을 맺고 사용료를 내야 칩을 만들 수 있습니다. 쓰지도 않을 명령까지 한 덩어리로 떠안기도 합니다.
어떻게 도나:
- 모든 칩이 갖춰야 하는 기본 명령을 정해 둡니다. 정수 계산, 메모리 읽고 쓰기, 조건을 보고 다른 곳으로 건너뛰기가 여기 들어갑니다
- 곱셈이나 소수점 계산처럼 분야를 타는 명령은 확장으로 갈라 둡니다. 칩마다 필요한 것만 고릅니다
- 프로그램을 번역할 때 어떤 확장을 갖춘 칩에서 돌릴지 함께 정해 줍니다
대가도 있습니다. 칩마다 고른 확장이 달라서, 한 번 번역한 프로그램이 모든 RISC-V 칩에서 돌지는 않습니다. 오래 쌓인 프로그램과 개발 도구는 아직 다른 명령 규격 쪽이 두텁습니다.
상세
RISC-V 는 CPU(Central Processing Unit, 중앙 처리 장치)가 실행할 명령을 정한 규격입니다. CPU 는 프로그램을 한 줄씩 읽어 계산하는 칩입니다. 프로세서라고도 부릅니다. 덧셈 명령 하나가 어떤 비트 조합으로 적히고, 어느 값을 읽어 어디에 결과를 남기는지까지 문서에 적혀 있습니다.
값을 읽고 쓰는 곳은 레지스터입니다. 레지스터는 CPU 안에 있는 아주 작은 저장 칸입니다. 계산은 이 칸에 올려 둔 값으로 합니다. 칸마다 이름이 붙어 있어서 명령이 그 이름으로 가리킵니다.
이런 명령 목록과 규칙을 통틀어 명령어 집합이라고 부릅니다. 영어로는 ISA(Instruction Set Architecture, 명령어 집합 구조)라고 씁니다.
이름의 뜻
앞 토막은 RISC(Reduced Instruction Set Computer, 축소 명령어 집합 컴퓨터)에서 왔습니다. 명령 하나가 맡는 일을 작게 자르는 설계 방향입니다. 그 대신 프로그램은 명령 수를 늘려 짭니다. 명령이 단순하면 그 명령을 해석하는 회로도 단순해집니다.
뒤의 V 는 로마 숫자 5 입니다. 같은 계열에서 이어진 다섯 번째 설계라는 뜻으로 붙은 이름입니다.
소프트웨어와 하드웨어 사이의 약속
프로그램을 컴파일러로 번역하면, 나온 실행 파일에는 명령어 집합이 정한 명령만 담깁니다. 컴파일러는 사람이 쓴 코드를 칩이 읽는 기계어로 옮기는 프로그램입니다. 그래서 번역할 때 어느 명령어 집합을 쓸지부터 정해야 합니다.
명령어 집합이 다르면 번역 결과도 다릅니다. x86 용으로 번역한 실행 파일은 ARM(Advanced RISC Machine) 칩에서 돌지 않습니다. 같은 덧셈이라도 명령을 적는 비트 배치가 서로 다르기 때문입니다.
RISC-V 는 그런 명령어 집합 중 하나입니다. 설치하는 프로그램도 사서 꽂는 칩도 아니고 문서입니다. 문서는 RISC-V International 이라는 비영리 단체가 관리합니다.
flowchart TD
P["프로그램 · 컴파일러가 낸 기계어"] --> I["RISC-V 규격 · 명령과 그 뜻의 약속"]
I --> A["회사 A 가 만든 칩"]
I --> B["회사 B 가 만든 칩"]
I --> C["연구실이 설계한 칩"]
같은 규격을 여러 회사와 연구실이 각자 구현합니다. 그래서 프로그램은 어느 칩이 받든 같은 명령을 씁니다. 다만 칩마다 갖춘 명령이 조금씩 다를 수 있습니다. 무엇을 갖춘 칩에 올릴지는 번역할 때 정해 줘야 합니다.
사용료 없는 규격
x86 과 ARM 은 명령어 집합을 만든 회사가 권리를 쥐고 있습니다. 다른 회사가 그 명령을 실행하는 칩을 만들려면 계약을 맺고 값을 치러야 합니다. 계약을 못 맺으면 그 명령어 집합으로는 칩을 못 만듭니다.
RISC-V 규격은 누구나 내려받아 구현할 수 있습니다. 칩을 만들어 팔아도 규격 사용료를 따로 내지 않습니다. 수업에서 학생이 작은 RISC-V 칩을 직접 설계해 보는 것도 이래서 됩니다.
기본 집합과 확장
RISC-V 는 명령을 한 덩어리로 주지 않습니다. 모든 칩이 갖춰야 하는 기본이 있습니다. 나머지는 확장으로 갈라 두었습니다. 칩을 만드는 쪽이 쓸 확장만 골라 담습니다.
기본에는 정수 덧셈과 뺄셈, 값 비교, 메모리 읽고 쓰기, 조건을 보고 건너뛰기처럼 프로그램을
굴리는 데 없으면 안 되는 명령만 담깁니다. 주소와 레지스터의 폭이 32비트인 기본을 RV32I,
64비트인 기본을 RV64I 라고 부릅니다.
확장에는 문자 하나씩이 붙어 있습니다. 자주 보는 것만 추리면 아래와 같습니다.
| 문자 | 붙는 명령 |
|---|---|
M |
곱셈과 나눗셈 |
A |
여러 프로그램이 같은 메모리 칸을 동시에 건드릴 때, 중간에 끼어들 수 없게 읽고 쓰기 |
F · D |
소수점이 있는 수의 계산. F 는 32비트 수, D 는 64비트 수 |
C |
자주 쓰는 명령을 16비트로 짧게 적는 꼴 |
칩이 무엇을 갖췄는지는 이름에 이 문자를 이어 붙여 적습니다. RV64IMAC 는 64비트 기본에 곱셈과
나눗셈, 끼어들 수 없는 읽고 쓰기, 짧게 적는 명령을 갖춘 칩이라는 뜻입니다.
block-beta columns 6 a["RV"] b["64"] c["I"] d["M"] e["A"] f["C"] g["모든 칩에 있다 · 기본"]:3 h["골라 담았다 · 확장"]:3
이름의 앞 세 토막까지가 모든 칩에 있는 기본입니다. 그 뒤에 이어 붙은 문자는 이 칩이 골라 담은 확장이라 칩마다 달라집니다.
확장을 고르게 한 대가도 있습니다. 곱셈 확장이 없는 칩에 곱셈 명령을 쓴 프로그램을 올리면 그 명령에서 멈춥니다. 그래서 번역할 때 어떤 확장을 전제할지 미리 일러 줘야 합니다. 같은 프로그램이라도 확장 조합이 다르면 다시 번역해야 합니다.
명령 한 줄이 하는 일
RISC-V 의 계산 명령은 레지스터만 건드립니다. 메모리에 있는 값을 더하려면 그 값을 먼저 레지스터로 읽어 와야 합니다.
메모리를 건드리는 명령은 읽어 오는 것과 내려 쓰는 것 둘뿐입니다. 이렇게 메모리 접근을 두 갈래로 몰아 둔 구조를 로드-스토어 구조라고 부릅니다. 계산 명령은 메모리를 몰라도 되니 명령의 생김새가 단순해집니다.
flowchart TD
M["메모리"] -->|"읽어 온다"| R1["레지스터 · 계산할 값"]
R1 -->|"계산 명령은 여기서만 돈다"| R2["레지스터 · 결과"]
R2 -->|"내려 쓴다"| M
정수 레지스터는 서른두 개입니다. 이름은 x0 부터 x31 까지입니다. 그중 x0 은 언제나 0 입니다.
값을 써넣어도 0 으로 남습니다. 0 을 쓸 데가 워낙 많아서 한 칸을 아예 0 으로 못 박아 둔 것입니다.
아래는 7 과 5 를 더해 메모리에 내려 쓰는 명령 다섯입니다. add 는 레지스터 둘을 더하는
명령입니다. addi 는 레지스터 값에 숫자를 더하는 명령입니다. 뒤에 붙은 i 가 「숫자를 직접
적는다」는 뜻입니다.
sw 는 레지스터 값을 메모리에 내려 쓰는 명령입니다. 0(x8) 은 x8 이 가리키는 주소에서 0 만큼
떨어진 곳을 뜻합니다. x8 에는 값을 내려놓을 메모리 주소가 이미 들어 있다고 봅니다.
addi x5, x0, 7 // x5 = 7
addi x6, x5, 5 // x6 = 12
add x7, x5, x6 // x7 = 19
sw x7, 0(x8) // x8 이 가리키는 곳에 19
addi x0, x0, 1 // x0 = 0 · 안 바뀐다
첫 줄은 0 에 7 을 더해 x5 를 7 로 만듭니다. x0 이 0 이라서 이 한 줄이 곧 "x5 에 7 을
넣어라"가 됩니다. 마지막 줄처럼 x0 에 써도 값은 0 그대로입니다.
기본 명령은 모두 32비트 고정 길이입니다. 길이가 고정이면 다음 명령이 어디서 시작하는지 바로 알 수 있습니다. 짧게 적는 확장을 갖춘 칩은 자주 쓰는 명령을 16비트로도 적어서 프로그램이 차지하는 메모리를 줄입니다.
명령을 적는 순서를 봤으니 값을 담는 순서도 정해야 합니다. 여러 바이트짜리 값을 메모리에 담을 때 어느 바이트를 앞에 두는지는 엔디언이 정합니다. RISC-V 는 작은 쪽 바이트를 앞에 두는 리틀엔디언으로 읽고 씁니다.
네트워크로 오가는 값은 큰 쪽 바이트를 앞에 두기로 오래전에 정해져 있습니다. 그런 데이터를 RISC-V 칩에서 정수로 읽을 때는 바이트 순서를 뒤집어 줍니다.
실행 권한의 세 층
한 칩 위에서 운영체제와 응용 프로그램이 같은 권한을 가지면 곤란합니다. 응용 프로그램이 다른 프로그램의 메모리를 읽거나 장치를 마음대로 건드릴 수 있기 때문입니다.
그래서 RISC-V 는 실행 권한을 층으로 나눕니다. 이 층을 특권 모드라고 부릅니다. 층은 셋입니다. 위에 있는 층일수록 할 수 있는 일이 많습니다.
아래에서부터 사용자 모드 · 감독자 모드 · 머신 모드입니다. 사용자 모드에서는 응용 프로그램이 돕니다. 감독자 모드에서는 운영체제의 핵심부인 커널이 돕니다. 머신 모드에서는 전원이 들어온 뒤 하드웨어를 깨우는 펌웨어가 돕니다.
flowchart TD
M["머신 모드 · 펌웨어"]
S["감독자 모드 · 운영체제 커널"]
U["사용자 모드 · 응용 프로그램"]
M -->|"쓸 수 있는 범위를 내준다"| S
S -->|"쓸 수 있는 범위를 내준다"| U
U -->|"부탁 · 트랩"| S
아래 층은 위층이 내준 범위 안에서만 돕니다. 사용자 모드에서 도는 프로그램은 디스크를 직접 건드리지 못합니다. 파일을 읽으려면 커널에게 부탁해야 합니다. 커널은 감독자 모드에서 그 일을 대신해 줍니다.
부탁은 아래에서 위로 갑니다. 부탁하는 순간 실행 흐름이 커널이 정해 둔 곳으로 옮겨 갑니다. 이 동작을 트랩이라고 부릅니다. 장치가 보낸 신호나 잘못된 명령도 같은 길로 커널에 전해집니다.
명령을 덧붙이라고 비워 둔 공간
규격은 명령을 적는 비트 조합 가운데 일부를 정하지 않고 비워 둡니다. 칩을 만드는 쪽이 자기 분야에 필요한 명령을 거기 넣으라는 뜻입니다.
영상 처리나 암호 계산처럼 같은 연산이 되풀이되는 분야에서는 전용 명령 하나가 여러 줄을 대신합니다. 같은 일을 기본 명령만으로 하면 명령 수가 늘고 그만큼 시간이 더 걸립니다.
대가는 도구 쪽에서 치릅니다. 직접 만든 명령은 표준 컴파일러가 모르니 번역 도구를 손봐야 합니다. 그 명령을 쓴 프로그램은 다른 RISC-V 칩에서 돌지 않습니다.
쓰이는 분야와 안 쓰이는 분야
지금 RISC-V 가 많이 들어가는 곳은 임베디드 기기와 큰 칩 안에 딸려 들어가는 작은 프로세서입니다. 저장 장치 컨트롤러, 통신 부품, 센서를 다루는 프로세서가 그렇습니다. 규격 사용료가 없어서입니다. 필요한 확장만 골라 담아 회로를 작게 만들 수 있다는 점도 있습니다.
교육과 연구에서도 자주 쓰입니다. 규격이 공개돼 있어 수업에서 칩 설계를 처음부터 따라 해 볼 수 있습니다. 새 명령을 넣어 실험하기도 쉽습니다.
서버와 개인용 컴퓨터에서는 아직 x86 과 ARM 이 주로 쓰입니다. 오래 쌓인 실행 파일과 장치 드라이버가 그 명령어 집합에 맞춰져 있어서, 옮기려면 전부 다시 번역하고 다시 검증해야 하기 때문입니다.
관련 항목
RISC-V 가 속하는 상위 분류
명령어 집합 · 컴퓨터 구조 · CPU · RISC · CISC · 마이크로아키텍처
RISC-V 와 같은 역할을 두고 겨루는 명령어 집합
x86 · x86-64 · ARM · MIPS · SPARC · PowerPC · OpenRISC
RISC-V 가 정하는 기본 집합과 확장
RV32I · RV64I · 압축 명령 · 원자적 연산 · 부동소수점 · 벡터 연산
RISC-V 명령이 다루는 하드웨어 요소
레지스터 · 프로그램 카운터 · 메모리 · 워드 · 엔디언 · 메모리 정렬 · hart
RISC-V 가 나누는 실행 권한과 예외 처리
특권 모드 · 커널 모드 · 사용자 모드 · 트랩 · 인터럽트 · 예외 · 시스템 콜 · 트랩 벡터
RISC-V 기계어를 만들어 내는 도구
컴파일러 · 어셈블러 · 링커 · 툴체인 · GCC · LLVM · ABI · 크로스 컴파일
RISC-V 칩 위에서 도는 소프트웨어
운영체제 · Linux · Zephyr · 펌웨어 · 부트로더 · QEMU
RISC-V 가 주로 들어가는 분야
임베디드 · 마이크로컨트롤러 · SoC · FPGA · 하드웨어 가속기
다른 이름: 리스크 파이브 · RISC-V ISA