Implementation of RISC-V Processor in System Verilog.
- Unprivileged
- RV32I (jump, branch, load/store, arithmetic/logical operations, ecall, ebreak)
- RV32 Zicsr (CSR operations)
- RV32M (mul, div, rem)
- Privileged
- Trap-Return Instructions (mret)
ISA is published in RISC-V official page.
Unprivileged Instructions are based on "Volume 1, Unprivileged Spec v. 20191213."
Privileged Instructions are based on "Volume 2, Privileged Spec v. 20190608."
- 4-stage pipeline (
Fetch,Decode,Execute,Write) - Forwarding (
E → D,W → D) - Branch prediction (
Two-level adaptive predictor) - Register (32 entries, 32 bit)
- Memory (1024 entries, 32 bit)
- Use just registers for ease of implementation
- CSR (Control and Status Register)
- Exception/Interrupt handling (only
UserandMachinemode withoutSupervisormode)- Exception
- 2: Illegal instruction exception
- 3: Breakpoint exception
- 8: System call exception (from User mode)
- 11: System call exception (from Machine mode)
- Interrupt
- 7: Machine timer interrupt
- 11: Machine external interrupt
- Exception
| Register | ABI Name | Description |
|---|---|---|
| r0 | zero | hardwired zero |
| r1 | ra | return address |
| r2 | sp | stack pointer |
| r8 | s0 / fp | saved register / frame pointer |
| r9 | s1 | saved register |
| r10-11 | a0-1 | function arguments / return values |
| r12-17 | a2-7 | function arguments |
-
fib-csr- fib function with all exceptions, all interrupts, and CSR operations
r15 = fib(10)
clocks : 18613 pc : 43 instructions : total 14587, normal 3809, exception 709, others 10069 prediction : total 1344, succeed 1130, fail 214 register : r00: 0, r01: 43, r02: 2032, r03: 0, r04: 0, r05: 0, r06: 0, r07: 0, r08: 2048, r09: 0, r10: 89, r11: 0, r12: 0, r13: 0, r14: 0, r15: 89 -
fib-ebreak- fib function with exceptions and interrupts
r15 = fib(10)
clocks : 9385 pc : 43 instructions : total 5267, normal 3809, exception 709, others 749 prediction : total 622, succeed 416, fail 206 register : r00: 0, r01: 43, r02: 2032, r03: 0, r04: 0, r05: 0, r06: 0, r07: 0, r08: 2048, r09: 0, r10: 89, r11: 0, r12: 0, r13: 0, r14: 0, r15: 89 -
fib- fib function
r15 = fib(10)- 4222 [clocks] = 3809 [instructions] + (206-1) * 2 [stalls] + (4-1) [stages]
206-1is performed to ignore the prediction miss of the final instruction.
clocks : 4222 pc : 35 instructions : total 3809, normal 3809, exception 0, others 0 prediction : total 622, succeed 416, fail 206 register : r00: 0, r01: 35, r02: 2032, r03: 0, r04: 0, r05: 0, r06: 0, r07: 0, r08: 2048, r09: 0, r10: 89, r11: 0, r12: 0, r13: 0, r14: 0, r15: 89 -
memory- memory operations
r15 = a[0](=1) + a[1](=2)
clocks : 16 pc : 12 instructions : total 13, normal 13, exception 0, others 0 prediction : total 2, succeed 1, fail 1 register : r00: 0, r01: 1, r02: 2016, r03: 0, r04: 0, r05: 0, r06: 0, r07: 0, r08: 2048, r09: 0, r10: 0, r11: 0, r12: 0, r13: 0, r14: 1, r15: 3
-
This repository
$ git clone https://github.com/hashi0203/riscv-processor.git
-
RISC-V Cross Compiler
If you just want to run the processor, you can skip this process.
If you want to run youroriginal test program, you should follow this process.We use riscv-gnu-toolchain as a cross compiler.
Basically, you can follow the instructions on the GitHub page.$ git clone https://github.com/riscv/riscv-gnu-toolchain $ ./configure --prefix=/opt/riscv32 --with-arch=rv32ima --with-abi=ilp32d $ make linux
You can change
--prefix=/opt/riscv32to the path you want to install this compiler.You also have to update
PATH.export PATH=/opt/riscv32/bin:$PATH
If you just want to run the processor, you can skip 1 and 2.
If you want to run your original test program, you should follow 1 to 3.
-
Make a test program for processor in test-programs.
- Make a test program in C (e.g., fib.c, memory.c).
- Compile the program by the following command (change "fib" to the file name (without extension) you have made).
$ cd /path/to/test-programs $ make ARG=fib- Output files are explained later in Files in test-programs chapter.
-
Change the test program for the processor.
- Update instruction memory (
instr_mem) in fetch.sv.- Make sure to change
63in line 14 tothe number of lines - 1.
- Make sure to change
- Update
MEM_SIZE,final_pc,privilege_jump_addr,exception_enabled, andinterrupt_enabledin core.sv.- If you don't expect exception or interruption, you don't have to set
privilege_jump_addr, and you have to setexception_enabled, andinterrupt_enabledto zero.
- If you don't expect exception or interruption, you don't have to set
- Set
max_clocks,max_reg_show,ext_intrandtimer_intrin test_core.sv.- If
max_clocksis small, the program may not finish. - If you don't expect external or timer interruption, you don't have to set
ext_intrandtimer_intr.
- If
- Update instruction memory (
-
Run the processor.
- We use Vivado simulator commands (
xvlog,xelab, andxsim). - You just have to run the following command.
- All the
.svfiles in src will be compiled.
- All the
$ cd /path/to/src $ make - We use Vivado simulator commands (
-
Compile from Assembly
When you make test programs, you can also write or edit RISC-V assembly code.
For example, fib-ebreak.S and fib-csr.S are obtained by editing fib.S.
When editing assemblies, you have to make sure that the edited part should beabovethe following three lines..size main, .-main .ident "GCC: (GNU) 10.2.0" .section .note.GNU-stack,"",@progbitsAfter creating test programs in assembly, edit the Makefile by commenting out line 25 and 26.
# $(ARG).S: $(ARG).c # $(CC) $(CFLAGS) -S -o $(ARG).S $(ARG).cThen, compile it by using
makecommand.$ cd /path/to/test-programs $ make ARG=fib-ebreakFiles in test-programs
- start.S
- disable default initial routine
- no need to edit
- link.ld
- set start pc (program counter) to 0
- no need to edit
Explanation when using fib.c
- fib.c
- test program in C
- fib.S
- test program in assembly
- automatically generated by
makecommand
- fib.bin
- binary file of test program
- automatically generated by
makecommand
- fib.hex
- test program in hexadecimal
- automatically generated by
makecommand
- fib.b
- test program in binary for Verilog
- used to test processor by editing fetch.sv
- automatically generated by
makecommand
- fib.dump
- disassembled test program (almost same as fib.S)
- automatically generated by
makecommand
.hexand.dumpare used for debugging. - start.S
-
Simulation in Vivado
- Start Vivado
- Create Project
Create a New Vivado Project→Next >Project Name→ Set anyProject NameandProject location→Next >Project Type→RTL Project(Default) →Next >Add Sources→ Add all.svfiles in src (including test_core.sv) →Next >Add Constraints (optional)→Next >Default Part→Next >New Project Summary→Finish
- Run Simulation
Flow Navigator>PROJECT MANAGER>SIMULATION>Run Simulation>Run Behavioral Simulation- Click
YesorSave, if there are any pop-ups - Add
wireorregyou want to check- Choose modules (e.g.,
_core) inScopetab wireandregin the module appear inObjectstab- Choose
wireorreginObjectstab - Drag and drop it on
Namein the wave orm area
- Choose modules (e.g.,
- Top bar >
Run All▶ - Check the waveform
After updating source codes, you have to follow
Run Simulationagain.
- riscv-gnu-toolchain (Cross Compiler)
- to cross-compile the C programs to binary.
- RISC-Vを使用したアセンブリ言語入門 〜2. アセンブリ言語を見てみよう〜
- to see how to compile programs by using
riscv-gnu-toolchain.
- to see how to compile programs by using
- RISC-Vクロスコンパイラで生成したバイナリを自作RISC-V上で実行する
- to see how to compile C programs to binary.
- to validate the compile result.
- RV32I, RV64I Instructions
- to see the detailed explanation of RISC-V ISA.
- RISC-Vについて(CPU実験その2)
- to see the detailed explanation of RISC-V ISA.
- RV32I インストラクション・セット
- to see the detailed explanation of RISC-V ISA.
- 分岐先アドレスを予測する
- to see how to implement branch prediction.
- cpuex2019-7th/core
- to see how to implement a processor.
- RISC-Vの特権命令まとめ
- to see how the CSR instructions work.
- RISC-VでLinuxを動かすためのレジスタ制御
- to see how the CSR instructions work.
- RISC-Vにおけるprivilege modeの遷移(xv6-riscvを例にして)
- to see how to handle exceptions and interrupts.
- RISC-Vとx86のsystem callの内部実装の違い(xv6を例に)
- to see the behavior of system call instructions.
- xv6-riscv (simple OS)
- to check exception/interrupt behavior.
- cpuex2019-yokyo/core
- to see how to implement privileged instructions.
