본문으로 바로가기

[RISC-V] spike 다루기

category SoC/RISC-V 2018.08.28 18:14

1. 본 글은 개인적으로 RISC-V 프로세서를 스터디 하면서 습득한 내용을 정리한 것입니다.  

2. 정확히 이해를 하고 기술하는 글이 아니기 때문에 잘못된 내용이 전달 될 수도 있습니다. 

3. 수정 사항 및 질문은 언제든지 환영입니다.



1. RISC-V ISS (Instruction Set Simulator) - spike

직접 작성한 RISC-V 프로그램을 확인해 보는 방법으로는 명령어셋 시뮬레이터(ISS)를 이용하는 것이 가장 쉬운 방법입니다. RISC-V 에서는 spike 라는 ISS를 지원하고 있으며 spike 개발 페이지에는 간단히 명령에 레벨 디버깅부터 GDB 연동까지 지원이 된다고 합니다. 이번 글에서는 직접 spike를 실행해 보면서 몇 가지 tip 을 공유하고자 합니다. 


우선 간단히 spike 의 명령어 살펴보면 아래와 같습니다. 


myskan@ubuntu:$ spike --help 
spike: unrecognized option --help
usage: spike [host options] <target program> [target options]
Host Options:
  -p<n>                 Simulate <n> processors [default 1]
  -m<n>                 Provide <n> MiB of target memory [default 2048]
  -m<a:m,b:n,...>       Provide memory regions of size m and n bytes
                          at base addresses a and b (with 4 KiB alignment)
  -d                    Interactive debug mode
  -g                    Track histogram of PCs
  -l                    Generate a log of execution
  -h                    Print this help message
  -H                    Start halted, allowing a debugger to connect
  --isa=<name>          RISC-V ISA string [default rv32ima]
  --pc=<address>        Override ELF entry point
  --hartids=<a,b,...>   Explicitly specify hartids, default is 0,1,...
  --ic=<S>:<W>:<B>      Instantiate a cache model with S sets,
  --dc=<S>:<W>:<B>        W ways, and B-byte blocks (with S and
  --l2=<S>:<W>:<B>        B both powers of 2).
  --extension=<name>    Specify RoCC Extension
  --extlib=<name>       Shared library to load
  --rbb-port=<port>     Listen on <port> for remote bitbang connection
  --dump-dts            Print device tree string and exit
  --progsize=<words>    Progsize for the debug module [default 2]
  --debug-sba=<bits>    Debug bus master supports up to <bits> wide accesses [default 0]
  --debug-auth          Debug module requires debugger to authenticate




2. spike 명령어 레벨 디버깅 

이전 글에서 작성 하였던 hello 프로그램을 이용하여 명령어 레벨 디버깅을 실행해 보겠습니다. 위에서 살펴 보았듯이 -d 옵션과 함께 spike 를 수행합니다. 


myskan@ubuntu:$ spike -d pk hello.o :


디버깅 옵션과 함께 spike를 실행하면 위에서처럼 디버깅 명령어를 기다리는 것을 확인 할 수 있습니다. 디버깅 명령어는 spike 개발 페이지 살펴 보시길 바랍니다. 여기서는 reg 0 (모든 레지스터를 보기) 와 r 1 (명령어 한개 실행) 만 간단히 보여드리고 있습니다.   


myskan@ubuntu:$ spike -d pk hello.o : reg 0 zero: 0x0000000000000000 ra : 0x0000000000000000 sp : 0x0000000000000000 gp : 0x0000000000000000 tp : 0x0000000000000000 t0 : 0x0000000000000000 t1 : 0x0000000000000000 t2 : 0x0000000000000000 s0 : 0x0000000000000000 s1 : 0x0000000000000000 a0 : 0x0000000000000000 a1 : 0x0000000000000000 a2 : 0x0000000000000000 a3 : 0x0000000000000000 a4 : 0x0000000000000000 a5 : 0x0000000000000000 a6 : 0x0000000000000000 a7 : 0x0000000000000000 s2 : 0x0000000000000000 s3 : 0x0000000000000000 s4 : 0x0000000000000000 s5 : 0x0000000000000000 s6 : 0x0000000000000000 s7 : 0x0000000000000000 s8 : 0x0000000000000000 s9 : 0x0000000000000000 s10 : 0x0000000000000000 s11 : 0x0000000000000000 t3 : 0x0000000000000000 t4 : 0x0000000000000000 t5 : 0x0000000000000000 t6 : 0x0000000000000000 : r 1 core 0: 0x0000000000001000 (0x00000297) auipc t0, 0x0 : r 1 core 0: 0x0000000000001004 (0x02028593) addi a1, t0, 32 : r 1 core 0: 0x0000000000001008 (0xf1402573) csrr a0, mhartid : r 1 core 0: 0x000000000000100c (0x0182a283) lw t0, 24(t0) : r 1 core 0: 0x0000000000001010 (0x00028067) jr t0 : r 1 core 0: 0xffffffff80000000 (0x1f00006f) j pc + 0x1f0 : r 1 core 0: 0xffffffff800001f0 (0x00000093) li ra, 0 : r 1 core 0: 0xffffffff800001f4 (0x00000113) li sp, 0 : q myskan@ubuntu:$


위의 결과를 눈여겨 보시면 (혹은 몇 가지 테스트를 하다보면) 약간 흥미로운 점을 발견 할 수 있습니다. 우선 첫번째 PC의 값이 0x0000_1000 이라는 것입니다. 두번 째로는 처음 5개의 명령어가 항상 실행이 되며, 0x8000_0000 으로 점프한다는 것입니다. 마치 5개의 명령어가 부트 ROM에 존재하는 것처럼 느끼어 졌습니다. (간단한 임베디드 프로그램을 작성하여 수행해본 결과 pk (Proxy Kernel) 여부와 상관 없으며, 링커 스크립트(linker script)의 영역을 0x8000_000 으로 지정해야만 원하는 동작이 수행되는 것을 확인 하였습니다.)


여러가지 검색 및 확인 결과 위의 내용을 다음과 같이 확인 할 수 있었습니다. 


~/RISCV/rocket-chip/riscv-tools/riscv-isa-sim/riscv/encoding.h 

#define DEFAULT_RSTVEC     0x00001000
#define CLINT_BASE         0x02000000
#define CLINT_SIZE         0x000c0000
#define EXT_IO_BASE        0x40000000
#define DRAM_BASE          0x80000000


추가 1.  https://github.com/slavaim/riscv-notes/blob/master/bbl/boot.md



3. spike와 GDB 연동 

GDB의 연동은 spike 개발 페이지에 이미 순서가 설명이 되어 있으며 제가 잘 알고 있는 분야가 아니기 때문에 실습한 화면으로 대신 할까 합니다. 다만 실습 과정 중 오류 사항을 발견하여 공유해 드리면, 예제코드를 64bit 으로 컴파일 하였기 때문에 spike 를 실행 할 때 --isa=rv64 옵션을 주어야 합니다.





지금까지 간단히 spike에 살펴 보았는데 좀 더 자세한 사항은 spike 개발페이지문서 작성 페이지를 참고하시기 바랍니다. 



'SoC > RISC-V' 카테고리의 다른 글

[RISC-V] Chisel Tutorial  (0) 2018.09.16
[RISC-V] C Emulator 수행 및 Waveform 생성  (0) 2018.09.07
[RISC-V] spike 다루기  (0) 2018.08.28
[RISC-V] RISC-V 설치 및 Hello RISC-V 실행  (0) 2018.08.19

댓글을 달아 주세요

티스토리 툴바