
노르딕 세미컨덕터(Nordic Semiconductor)의 nRF54L 시리즈 SoC(System-on-Chip)는 효율적인 MCU와 초저전력 무선 연결 기능이 결합된 제품이다. 이 SoC는 128MHz의 Arm® Cortex®-M33 프로세서와 함께 128MHz의 RISC-V 코프로세서를 탑재하고 있어 설계 및 제품의 성능을 향상시키거나 간소화하는 데 효과적으로 활용할 수 있다.
이 글에서는 RISC-V 아키텍처의 일반적인 특징과 구현 방식을 살펴보고, 이를 통해 RISC-V 코프로세서의 가능성과 실제로 이를 효과적으로 활용할 수 있는 방법에 대해 알아보고자 한다.
(참조: 이 글은 nRF54L15 SoC를 중심으로 RISC-V 코프로세서에 대해 설명하고 있지만, 여기에서 다루는 모든 개념은 nRF54LM20A SoC와 같이 RISC-V 코프로세서를 탑재한 nRF54L 시리즈의 다른 제품에도 동일하게 적용된다.)
RISC-V 개요
RISC-V는 개방형 표준 ISA(Instruction Set Architecture, 명령어 집합 아키텍처)이다. 이 아키텍처는 2011년 5월 처음 등장한 이후, 모듈식 구조와 라이선스 비용이 없는 장점 덕분에 빠르게 성장하며, 하드웨어 벤더와 개발자 모두에게 매력적인 선택지로 주목받고 있다.
RISC-V는 미국 캘리포니아대학교 버클리 캠퍼스(University of California, Berkeley)에서 처음 개발되었지만, 현재 이 명령어 집합 사양은 RISC-V 재단(RISC-V Foundation) 웹사이트에서 누구나 확인할 수 있다. 노르딕 세미컨덕터는 RISC-V ISA의 확산을 주도하는 글로벌 비영리 단체인 RISC-V 재단의 전략 회원사(Strategic Member)로 참여하고 있다.
명칭에서도 알 수 있듯이, RISC-V는 RISC(Reduced Instruction Set Computer) 원리를 따른다. 즉, 로드/스토어(load/store) 모델을 기반으로 한 번에 하나의 작업만 수행하는 단순한 개별 명령어들로 설계되었다. 이는 실행 파이프라인에서 단순하고 빠른 명령어를 효율적으로 처리함으로써 더 높은 성능을 달성하는 데 목표를 두고 있기 때문이다.
‘V(five)’라는 명칭은 5세대를 의미하는 것이기도 하지만, 1980년대에 버클리에서 개발된 이전의 4개 세대 아키텍처와 직접적인 연관이 있는 것은 아니다.
RISC-V의 명령어 집합은 기본 아키텍처(Base)와 확장 명령어 집합(Extension)으로 구성된다. 벤더들은 이러한 명령어를 다양한 방식으로 조합하여 구현할 수 있으며, 이 또한 동일하게 RISC-V 프로세서로 분류된다. 따라서 각 벤더들의 RISC-V 프로세서 내부에 어떤 요소가 포함되어 있는지 파악하는 것이 중요하다.
(참조: 명령어 집합이 축소되었다 하더라도, RISC-V의 명령어 집합은 여전히 상당히 방대한 규모를 가지고 있다. 이 글에서는 실제 활용 측면을 고려해 nRF54L 시리즈 코프로세서에 적용된 기본 아키텍처(Base)와 확장 명령어 집합(Extension)에 초점을 맞추고 있지만, 이외에도 선택 가능한 옵션은 다양하다.)
기본 아키텍처
기본 아키텍처는 최신 운영체제 환경을 지원하는 컴파일러 타깃을 구성하기에 충분한 최소 수준의 명령어 집합을 정의하고 있다. 또한, 명령어뿐만 아니라 레지스터의 개수와 크기도 함께 규정하고 있다. nRF54L15의 코프로세서는 RV32E를 기본 아키텍처로 사용하며, 이는 x0에서 x15까지 총 16개의 32bit 레지스터와 프로그램 카운터(Program Counter), 즉 pc라고 불리는 추가 레지스터로 정의되어 있다.
x0 레지스터는 값이 0으로 고정되어 있으며, x1부터 x15까지는 범용 레지스터로 사용된다. 별도의 전용 스택 포인터나 서브루틴 반환 주소를 위한 링크 레지스터는 존재하지 않지만, 명령어 인코딩 방식을 통해 어떤 x 레지스터든 이러한 용도로 사용할 수 있다. RV32E는 총 40개의 고유 명령어를 포함하고 있다.
RV32E는 임베디드 제품에 맞게 조정된 RV32I의 축소 버전이다. 명칭 규칙은 RISC-V를 의미하는 ‘RV’ 뒤에 레지스터 폭을 나타내는 숫자를 붙이는 방식으로 구성된다. 이와 같은 방식으로 RV64I나 RV64E와 같은 아키텍처도 존재한다.
확장 명령어 집합
RISC-V의 확장 명령어 집합은 기본 아키텍처의 기능을 확장하는 명령어 그룹이다. nRF54L15의 코프로세서는 RV32E 기본 아키텍처 위에 C와 M 확장 명령어 집합을 구현하고 있다.
• C는 압축 명령어 집합을 의미하며, 16bit 길이로 인코딩된 짧은 명령어를 지원하여 코드 크기를 줄이고, 실행 속도를 향상시킨다.
• M은 곱셈 및 나눗셈 명령어 집합으로, 레지스터 간 이러한 연산을 수행할 수 있도록 지원한다.
비트 조작(bit-manipulation, bitmanip)을 위한 B 확장 명령어 집합은 코드 크기 축소, 성능 향상, 에너지 절감을 목표로 하는 여러 하위 확장 기능을 포함하고 있다. 이러한 하위 확장 기능들은 공통의 기능과 적용 사례에 따라 그룹화되어 있으며, 각각 Zb*로 시작하는 고유한 확장 기능 이름으로 정의되어 있다. nRF54L15에 구현된 RISC-V에는 기본적인 비트 조작 작업을 처리할 수 있도록 이들 중 일부가 포함되어 있다.
부동소수점 명령어를 지원하는 확장 명령어 집합에는 F, D, Q 세 가지가 있으며, nRF54L15의 RISC-V 코프로세서에는 이러한 확장 명령어 집합이 구현되어 있지 않다. 이는 부동소수점 연산을 위한 네이티브 하드웨어가 지원되지 않음을 의미한다.
FLPR(Fast Lightweight Processor)
nRF54L15 내부에 탑재된 RISC-V 코프로세서(RV32E 기본 아키텍처와 M 및 C 확장 명령어 집합 포함)는 FLPR(Fast Lightweight Processor) 또는 일명 플리퍼(Flipper)라고 불린다. 이러한 명칭은 해당 코프로세서가 고속의 가상 IO를 활용해 네이티브 하드웨어 주변장치에 준하는 성능을 구현할 수 있다는 점에서 비롯되었다. 가상 IO를 통해 처리된 신호는 이후 물리적 IO로 라우팅된다.
FLPR은 애플리케이션 CPU와 병렬로 동작하며, 주변장치와 메모리에 접근하여 스레드를 실행할 수 있다. 이러한 동시 실행은 일부 리소스 경합을 유발할 수 있기 때문에 설계 단계에서 이를 반드시 고려해야 한다. 애플리케이션 CPU는 FLPR의 구성과 시작을 담당한다.
(참조: 여기에서 유념할 점은, nRF54L15에는 애플리케이션 CPU(Arm Cortex-M33)와 FLPR(RISC-V 코프로세서)가 탑재되어 있으며, 메인 RISC-V CPU는 포함되어 있지 않다는 것이다.)
FLPR을 사용하는 프로젝트는 일반적으로 sysbuild를 활용한 멀티 이미지 구조로 구성되는 경우가 많으며, cpuapp 타깃용 이미지와 cpuflpr 타깃용 이미지를 각각 포함하게 된다. 이러한 동작 방식은 노르딕 개발자 아카데미(Nordic Developer Academy)에서 제공하는 nRF 커넥트 SDK(nRF Connect SDK) 중급 과정, 특히 레슨 8을 통해 보다 자세한 내용을 확인할 수 있다.
FLPR은 비휘발성 메모리(NVM)에서 코드를 직접 실행할 수도 있지만, 권장되는 방식은 SRAM에서 코드를 실행하는 것이다. 이는 멀티 이미지 빌드의 결과물로 NVM에 함께 저장된 FLPR용 코드를 시스템 부트스트랩 과정 중 SRAM으로 복사해야 함을 의미하며, 복사가 완료된 이후에는 FLPR의 프로그램 카운터가 해당 코드의 엔트리 포인트를 가리키도록 설정해야 한다. 다소 복잡하게 들릴 수 있지만, 이러한 과정은 멀티 이미지 빌드에서 자동으로 처리되기 때문에 현재로서는 별도로 신경 쓸 필요는 없다.
FLPR의 활용 가능성은?
FLPR은 nRF54L 시리즈 사용자들에게 크게 두 가지 시나리오에서 새로운 설계 옵션과 활용 가능성을 제공한다.
독립적 시스템으로 활용
FLPR은 SoC 내부에서 별도의 독립적인 시스템처럼 동작하여 특히, 시간에 민감한 작업 등을 단독으로 처리할 수 있다. 시스템이 매우 강력한 실시간 성능을 갖추고 있거나 매우 짧은 하드웨어 인터럽트 지연 시간을 지원한다 하더라도, 일부 제품에서는 아주 미세한 간섭조차도 치명적일 수 있기 때문이다. 블루투스 LE(Bluetooth LE) 스택은 애플리케이션 CPU에서 실행되는데, SoC의 무선 특성상 이러한 인터럽트가 중요한 순간에 전혀 발생하지 않는다고 보장할 수는 없다. 물론 일시적으로 인터럽트를 비활성화할 수도 있지만, 이는 또 다른 부작용을 야기할 수 있다.
이러한 인터럽트를 완벽하게 차단할 수 있는 유일한 방법은 동일한 PCB 상에 별도의 IC나 MCU를 추가해 시간에 민감한 작업을 처리하도록 하는 것이다. 그러나 이는 설계와 제조 비용 증가로 이어진다.
FLPR은 독립된 코어로 동작이 가능하기 때문에 이러한 작업을 동일한 SoC 내부에 통합하고, 보호하는 데 사용할 수 있다. 이를 통해 주요한 설계 변경 없이 부품 수를 줄이고, PCB를 소형화할 수 있다.
소프트 주변장치(SoftPeripheral)로 활용
또한, FLPR은 사전 컴파일된 바이너리 이미지를 실행하여 현재 nRF54L15 SoC에 포함되어 있지 않은 주변장치 기능을 소프트웨어 방식으로 추가하는 데에도 활용될 수 있다. 이를 통해 추가 비용 없이 SoC의 적용 범위를 확장할 수 있다.
애플리케이션 CPU는 이러한 사전 컴파일된 바이너리에 대해서도 동일한 방식으로 동작한다. 즉, 제어 대상이 실제 하드웨어 주변장치인지, 아니면 FLPR을 통해 구현된 것인지 인식할 필요 없이 드라이버 API를 호출하게 된다. 또한, 사용자가 필요에 따라 직접 액세스해야 하거나 또는 이를 더 선호하는 경우에는 소프트 주변장치(SoftPeripheral) API를 직접 호출할 수도 있다.

FLPR 활용 예시
이러한 활용 사례를 실제 예시를 통해 알아보도록 하자. 먼저 소프트 주변장치에 대해 살펴보도록 하겠다.
(참조: 사용되는 GPIO는 FLPR의 소스 코드에서 vIO라는 형태로 정의되어 있다. 또한, 메인 애플리케이션의 DTS 오버레이에서 해당 GPIO를 FLPR에 할당하는 것을 잊지 말아야 한다.)
소프트 주변장치용 바이너리는 노르딕 세미컨덕터에서 제공하며, 최신 nRF 커넥트 SDK 릴리스(이 글을 작성하는 시점 기준)에서는 sQSPI와 sEMMC 두 가지 옵션을 지원한다. 두 옵션 모두 nrf_s라는 별도의 명명 규칙을 따르는 nrfx 드라이버 API 인터페이스를 지원한다. sQSPI의 경우 별도의 설정 없이 제퍼(Zephyr)와 즉시 통합하여 사용할 수 있다.
소프트 주변장치가 적용되는 사례는 nRF54L15의 기능을 내부적으로 확장해야 하는 상황과 관련되는 경우가 많으며, 제품의 최종 기능과 직접적으로 연결되지 않을 수도 있다.
그렇다면 FLPR이 별도의 독립적인 시스템으로 활용되는 사례를 살펴보자. 이 경우에는 개발자들의 아이디어와 요구사항에 따라 자유롭게 구현할 수 있다. 데모 프로젝트에서 LED 패널을 제어하는데 활용하거나 BLDC 모터 구동 알고리즘을 구현하는 경우에도 유사한 시나리오를 적용할 수 있다. 또한, 출력을 제어하는 대신 입력 신호를 판독해야 하는 경우도 있을 수 있다. 예를 들어, 신호 측정 타이밍 오류가 허용되지 않는 고속 생산 라인에 설치된 스마트 산업용 센서를 생각해 볼 수 있다. 또한, 노르딕 고객사인 리콘(Reekon)이 개발한 정밀 휴대용 기기에도 이러한 독립적인 처리 방식이 적용되었다.
맺음말
22nm 공정 기술에 기반한 nRF54L15는 매우 비용 효율적이면서도 강력한 성능과 뛰어난 에너지 효율성을 갖춘 아키텍처로 구현되었다. 물론, ‘큰 힘에는 큰 책임이 따른다’는 말처럼, 두 번째 실행 유닛을 활용하기 위해서는 몇 가지 세부 사항에 대한 고려가 필요하며, 이전에는 존재하지 않았던 동시성 문제를 발생시킬 수도 있다. 그러나 분명한 점은, nRF54L15의 RISC-V 코프로세서는 기존 설계는 물론, 새로운 설계에서 모두 수많은 선택지와 가능성을 제공한다는 것이다.
세바스티안 비비아니(Sebastian Viviani), 노르딕 세미컨덕터(Nordic Semiconductor) |





