# Lab2: RISC-V Instruction Set Simulator and System Emulator
{%preview https://hackmd.io/@sysprog/Sko2Ja5pel %}
## Following the Lab2
> https://hackmd.io/@sysprog/Sko2Ja5pel#Building-from-Source
``` bash
cd rv32emu
pushd tests/system/alignment
make
popd
make ENABLE_ELF_LOADER=1 ENABLE_EXT_C=0 ENABLE_SYSTEM=1 misalign-in-blk-emu
```
## Playground Test Suite in RV32EMU
```bash
pushd tests/system/playground
make
popd
make distclean && make ENABLE_SYSTEM=1 ENABLE_ELF_LOADER=1
pushd tests/system/playground
make run
popd
```
## Build Playground Test Suite to Litex FPGA Bare-metal Run
https://hackmd.io/w38bfeaCQBesfsYXUTd_OA
### Access RISC-V CSRs for cycle-accurate profiling
🧠3. Companion Spec (for User-Level CSRs)
For user-level CSRs like cycle, time, instret, refer to:
📗 RISC-V Unprivileged ISA Specification (Volume I)
→ [riscv-isa-manual/src/machine.adoc](https://github.com/riscv/riscv-isa-manual/blob/main/src/machine.adoc)
This defines the CSRs that user programs can access without privilege (especially the performance counters).
Custom linker script (linker.ld) defines bare-metal memory map:
## How to Debug Use VSCode
Debug Build need add the `-g`
```bash
cd rv32emu
riscv-none-elf-gcc -g -Wall -O0 -std=c99 -march=rv32if -mabi=ilp32 -o tests/ieee754 tests/ieee754.c -lm
```
Debug Run
```bash
cd rv32emu
build/rv32emu -g tests/ieee754.c
```
vscode change arch
```shell
-exec set arch riscv:rv32
```
```javascript
{
"version": "0.2.0",
"configurations": [
{
"name": "Debug RV32EMU",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/tests/ieee754", // ELF 檔案
"miDebuggerPath": "riscv-none-elf-gdb", // GDB path
"miDebuggerServerAddress": ":1234",
"cwd": "${workspaceFolder}",
"stopAtEntry": true,
"externalConsole": false,
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
},
]
}
]
}
```
## Find ToDoList from the RV32EMU
* https://hackmd.io/@eastWillow/RV32I_Long_Double_Support
## rv32_template.c has a lot of FIXME: Implement
read the `addi` command Implement Example
```cpp
/* ADDI adds the sign-extended 12-bit immediate to register rs1. Arithmetic
* overflow is ignored and the result is simply the low XLEN bits of the
* result. ADDI rd, rs1, 0 is used to implement the MV rd, rs1 assembler
* pseudo-instruction.
*/
RVOP(
addi,
{ rv->X[ir->rd] = rv->X[ir->rs1] + ir->imm; },
GEN({
rald, VR0, rs1;
map, VR1, rd;
cond, regneq;
mov, VR0, VR1;
end;
alu32imm, 32, 0x81, 0, VR1, imm;
}))
```