ARTY 튜토리얼

이 튜토리얼에서는 FPGA 개발 도구를 설치하고, RISC-V 코어를 합성하고, 프로그램을 컴파일 및 설치하여 ARTY에서 실행하는 방법을 보여 드립니다. UART, OLED 디스플레이, LED 매트릭스는 정상적으로 동작합니다. 프레임버퍼(FGA: Femto Graphic Adapter)와 VGA 출력은 곧 추가될 예정입니다.
오픈 소스 FPGA 개발 툴체인 설치
시작하기 전에 오픈 소스 FPGA 개발 툴체인(Yosys, NextPNR 등)을 설치해야 합니다. 설치 방법은 여기에 나와 있습니다.
(선택 사항) femtosoc 및 femtorv32 설정
learn-fpga/FemtoRV/RTL/CONFIGS/arty_config.v 파일을
편집하십시오.
이 파일에서 만들 RISC-V 프로세서의 종류를 정의할 수 있습니다.
learn-fpga/FemtoRV/RTL/CONFIGS/arty_config.v 파일에서는
함께 구성되는 시스템 온 칩(SoC)에 포함할 장치 드라이버도 선택할 수
있습니다.
| 장치 | 설명 | 비고 |
|---|---|---|
NRV_IO_LEDS |
LED 5개 | 그대로 두십시오 |
NRV_IO_UART |
USB를 통한 시리얼 연결 | 그대로 두십시오 |
NRV_IO_SSD1351 |
소형 OLED 화면(128x128) | 없으면 주석 처리하십시오 |
NRV_IO_SSD1331 |
소형 OLED 화면(96x64) | 없으면 주석 처리하십시오 |
NRV_IO_MAX7219 |
LED 매트릭스(10x10) | 없으면 주석 처리하십시오 |
NRV_MAPPED_SPI_FLASH |
메모리 공간에 매핑된 플래시 | 그대로 두십시오 |
시각적 디버깅을 위해 LED를, USB 기반 터미널 연결로 시스템과 통신하기 위해 UART를 활성화합니다. RAM은 64KB를 사용합니다. OLED 화면이나 LED 매트릭스 화면이 없다면 파일에서 해당 줄을 주석 처리하면 됩니다.
파일에는 다른 옵션도 있습니다. 보통은 이 옵션들을 바꿀 필요가 없습니다. 궁금하다면 아래 목록을 참고하십시오:
| 옵션 | 설명 |
|---|---|
NRV_FREQ |
프로세서 주파수(MHz 단위, ARTY에서는 100MHz이며 변경할 수 없음) |
NRV_RAM |
RAM 용량 |
NRV_RESET_ADDR |
시작 시와 리셋 시 점프할 주소 |
NRV_IO_HARDWARE_CONFIG |
코드에서 조회하여 구성된 장치를 확인할 수 있는 하드웨어 레지스터 |
NRV_RUN_FROM_SPI_FLASH |
현재 ARTY에서는 지원하지 않음 |
참고: BOARDS/arty.xdc도 편집하여 사용하지 않는 핀을 모두
주석 처리해야 합니다.
펌웨어 컴파일
$ cd learn-fpga/FemtoRV
$ make ARTY.firmware_config
$ cd FIRMWARE/EXAMPLES
$ make hello.hex
처음 실행하면 RISC-V 개발 도구를 내려받습니다(시간이 좀 걸립니다).
합성 및 프로그래밍
이제 설계를 합성하여 장치로 보낼 수 있습니다. 장치를 USB 포트에 꽂은 다음, 아래를 실행하십시오:
$make ARTY
OLED 화면이나 LED 매트릭스를 연결했다면 메시지가 표시됩니다. 연결하지 않았다면 메시지는 UART로 전송되지만, 현재 UART 지원에 문제가 있습니다(알아볼 수 없는 문자가 출력됩니다). 다음은 UART에 연결하는 방법에 대한 설명입니다(다시 말하지만, 알아볼 수 없는 문자가 출력됩니다).
이제 터미널 에뮬레이터를 설치하십시오:
$sudo apt-get install python3-serial
(또는 sudo apt-get install screen을 사용해도 되며, 둘 다
작동합니다.) 출력을 보려면 터미널 에뮬레이터를 사용하여 장치에 연결해야
합니다:
$make terminal
(python3-serial 대신 screen을 설치했다면
먼저 Makefile을 그에 맞게 편집하십시오. 그 파일에서
ttyUSBnnn도 바꿔야 할 수 있습니다.)
모든 것이 잘 되면 arty 위의 RISC-V 코어가 환영 메시지를 표시합니다!
종료하려면 <ctrl> ](python-3-serial/miniterm)를
누르거나, <ctrl> a를 누른 다음 '\'(screen)를
누르십시오.
시리얼 터미널(UART)을 사용하는 예제
FIRMWARE/EXAMPLES 디렉터리와
FIRMWARE/ASM_EXAMPLES 디렉터리에는 장치에서 실행할 수 있는
C 및 어셈블리 프로그램이 들어 있습니다.
프로그램을 컴파일하려면 다음을 실행하십시오:
$cd FIRMWARE/EXAMPLES
$make hello.prog
.prog 타깃은 프로그램을 생성한 뒤 iceprog를
사용해 장치의 SPI 플래시로 전송합니다. 결과를 보려면 다음을
사용하십시오
$cd ../..
$make terminal
직접 실행해 볼 수 있는 C 및 어셈블리 프로그램이 여러 개 있습니다(아래 목록 참고). RISC-V 어셈블리에 대해 더 알아보려면 RISC-V 명세를 참고하십시오. 특히 명령어 집합과 프로그래머 매뉴얼을 참고하십시오.
어셈블리
프로그램(ASM_EXAMPLES/mandelbrot_terminal.S)으로 계산한
망델브로 집합의 ASCII 아트 버전 
| 프로그램 | 설명 |
|---|---|
ASM_EXAMPLES/blinker_shift.S |
시프트를 사용하는 blinker 프로그램 |
ASM_EXAMPLES/blinker_wait.S |
지연 루프를 사용하는 blinker 프로그램 |
ASM_EXAMPLES/test_serial.S |
USB 시리얼에서 문자를 읽어 다시 돌려보냅니다 |
ASM_EXAMPLES/mandelbrot_terminal.S |
망델브로 집합을 계산해 ASCII 아트로 표시합니다 |
EXAMPLES/hello.c |
환영 메시지를 표시합니다 |
EXAMPLES/sieve.c |
소수를 계산합니다 |
LED 매트릭스를 사용하는 예제
더 재미있게 즐기려면
8x8 LED 매트릭스를 추가할 수 있습니다. 가격이 저렴하고(1달러 미만)
구하기도 쉽습니다(구글에서 max7219 8x8 led matrix로
검색하면 됩니다). 핀 라벨(CLK,CS,DIN,GND,VCC)이 그림과 일치하는지 확인한
다음, 그림에 나온 것처럼 IceStik의 J2 커넥터에 꽂으십시오. OysterPMOD를 만들 수도 있습니다(PMOD 커넥터
하나로 LED 매트릭스와 OLED 화면을 모두 사용합니다).
FemtoSOC 구성
이제 LED 매트릭스에 대한 하드웨어 지원을 활성화해야 합니다(그리고
UART는 비활성화해야 합니다). 이를 위해
FemtoRV/RTL/CONFIGS/arty_config.v에서 장치를 다음과 같이
설정하십시오:
...
`define NRV_IO_MAX7219 // Mapped IO, 8x8 led matrix
...
참고: BOARDS/arty.xdc 파일도 편집하여 LED 매트릭스가
사용하는 핀의 주석을 해제해야 합니다.
그런 다음 다시 합성하여 비트스트림을 ARTY로 전송해야 합니다:
$make ARTY

이제 hello world
프로그램(FIRMWARE/EXAMPLES/hello.c)을 컴파일할 수 있습니다.
이 파일을 편집하여 다음 줄의 주석을 해제하십시오:
femtosoc_tty_init();
이 줄은 printf()의 출력을 설정된 장치(여기서는 LED
매트릭스)로 자동으로 리다이렉트합니다. 이제 프로그램을 컴파일하여 장치로
전송하십시오:
$cd FIRMWARE/EXAMPLES
$make hello.prog
LED 매트릭스가 설정되어 있으면 printf()의 출력은 스크롤
표시 루틴으로 자동으로 리다이렉트됩니다. sieve.c 프로그램도
마찬가지로 동작합니다.
직접 실행해 볼 수 있는 다른 예제도 있습니다:
| 프로그램 | 설명 |
|---|---|
ASM_EXAMPLES/test_led_matrix.S |
어셈블리로 LED 매트릭스에 두 이미지를 표시합니다 |
EXAMPLES/life_led_matrix.c |
8x8 토러스 세계에서 실행하는 생명 게임 |
직접 프로그램을 작성하려면: C에서는 먼저
MAX7219_init()을 사용하여 디스플레이를 켜야 합니다. 그런
다음 MAX7219(col,data) 함수를 사용할 수 있습니다. 여기서
col은 1..8 범위의 열 인덱스이며(0..7이 아닙니다!!!),
데이터는 어떤 LED를 켤지 나타내는 8비트 정수입니다.
FIRMWARE/EXAMPLES/life_led_matrix.c를 참고하십시오.
OLED 화면을 사용하는 예제

픽셀이 64개뿐인 LED 매트릭스는 다소 제한적이고 색상도 없습니다... 좀 더 멋진 그래픽을 만들어 봅시다. 이를 위해서는 SSD1351 128x128 OLED 디스플레이가 필요합니다. 가격은 약 15달러입니다(ST7789로 구동하는 240x240 IPS 화면처럼 더 저렴한 화면도 있지만 보기에 그만큼 좋지 않고 호환되지도 않습니다. 제 말을 믿으십시오. SSD1351은 충분히 그만한 값어치를 합니다). 반드시 품질이 좋은 제품을 구하십시오(5달러 미만이라면 저라면 의심하겠습니다. 이런 저가형 제품에서 고장을 겪었다고 보고한 사용자들이 있습니다). 저는 Waveshare에서 구입했습니다. Adafruit 제품도 잘 동작한다는 보고가 있습니다.
이 작은 화면에는 전선 7개가 필요합니다. 다행히 납땜은 필요 없습니다. 그림에 있는 것과 같은 2x6 핀 커넥터를 구해서 그림처럼 전선을 커넥터에 연결한 다음 커넥터를 ARTY에 연결하면 됩니다. 전선 색상이 다르면 오른쪽 회로도를 보고 어느 전선을 어디에 연결할지 확인하십시오.
OysterPMOD를 만들 수도 있습니다(PMOD 커넥터 하나로 LED 매트릭스와 OLED 화면을 모두 사용합니다).
이제 arty_config.v를 다음과 같이 다시 설정해야
합니다:
...
`define NRV_IO_SSD1351 // Mapped IO, 128x128x64K OLed screen
...
참고: BOARDS/arty.xdc도 편집하여 OLED 화면이 사용하는
핀의 주석을 해제해야 합니다.
그런 다음 다시 합성하고 비트스트림을 ARTY로 전송해야 합니다:
$make ARTY
테스트 프로그램을 컴파일해 봅시다:
$ cd FIRMWARE/EXAMPLES
$ make gfx_test.prog
모든 것이 잘 진행되면 화면에 움직이는 컬러 패턴이 나타납니다. 텍스트
모드 데모(hello.c와 sieve.c)도 여전히
동작하며, 이제 화면에 텍스트를 표시합니다. 이 밖에도 가지고 놀 수 있는
프로그램이 있습니다:
(검은 대각선 줄무늬는
디스플레이 갱신 때문에 생긴 것으로, 평소에는 보이지 않습니다).
| 프로그램 | 설명 |
|---|---|
ASM_EXAMPLES/test_OLED.S |
움직이는 패턴을 표시합니다. |
ASM_EXAMPLES/mandelbrot_OLED.S |
망델브로 집합을 표시합니다. |
EXAMPLES/cube.c |
회전하는 3D 정육면체를 표시합니다. |
EXAMPLES/mandelbrot.c |
망델브로 집합을 표시합니다(C 버전). |
EXAMPLES/riscv_logo.c |
RISCV 로고를 사용한 로토줌입니다(90년대로 돌아가 봅시다). |
EXAMPLES/spirograph.c |
회전하는 사각형들입니다. |
EXAMPLES/gfx_test.c |
움직이는 패턴을 표시합니다(C 버전). |
EXAMPLES/gfx_demo.c |
그래픽 함수 데모입니다(옛 친구 여러분, EGAVGA.bgi를 기억하십니까?). |
EXAMPLES/test_font_OLED.c |
폰트 렌더링을 테스트합니다. |
EXAMPLES/sysconfig.c |
femtosoc 및 femtorv 구성을 표시합니다. |
LIBFEMTORV32 라이브러리에는 기본적인 폰트 렌더링, 2D 다각형 클리핑, 2D 다각형 채우기 루틴이 들어 있습니다. 이 모든 것이 사용 가능한 6KB 메모리 안에 들어갑니다!
이 작은 시스템으로 더 많은 것을 할 수 있을까요? 네, 레이트레이싱도 할 수 있습니다!
$ cd FIRMWARE/EXAMPLES
$ make tinyraytracer.hex
$ cd ../..
$ make ARTY