Add instructions for adding opcode to toolchain. Before the instructions had how to add a new opcode to Renode. This modification now adds instructions and an example for how to add a new opcode to the riscv-toolchain itself for testing with Renode. Change-Id: Ifed836981ce36c6e724276a4af7af314ee558166
diff --git a/RunningOpenTitanVectorSimulation.md b/RunningOpenTitanVectorSimulation.md index a6ba497..80df3f8 100644 --- a/RunningOpenTitanVectorSimulation.md +++ b/RunningOpenTitanVectorSimulation.md
@@ -3,7 +3,7 @@ Follow setups in this document to build and run the following examples: 1. [OpenTitan Hello World Basic Example](#opentitan-hello-world-basic-example) -2. [OpenTitan Hello World Vector Sim Example](#opentitan-hello-world-vector-sim-example) +2. [OpenTitan Hello World Vector Sim Examples](#opentitan-hello-world-vector-sim-example) Keep an eye on the file below for new build targets as they become available: @@ -11,12 +11,6 @@ $ROOTDIR/build/opentitan_sw.mk ``` -``` -Note: Renode runs in multiple x-windows. -Renode does not presently have a terminal only mode. -Run within a graphical session or set up X-Forwarding to run these examples. -``` - ## OpenTitan Hello World Basic Example These instructions guide through setting up and running a test of OpenTitan with a bare-bones Renode @@ -83,7 +77,8 @@ How to run the HelloVector example and how to modify or add a new vector OpCode for Renode simulation. 1. [Run OpenTitan HelloVector Renode Demo](#run-opentitan-hellovector-renode-demo) -2. [Add or Modify Vector OpCodes and Simulate](#add-or-modify-vector-opcodes-and-simulate) +2. [Modify Vector OpCode Behavior and Simulate](#modify-vector-opcode-behavior-and-simulate) +3. [Add New Vector OpCode and Simulate](#add-new-vector-opcode-and-simulate) ### Run OpenTitan HelloVector Renode Demo @@ -113,9 +108,9 @@ renode -e "i @sim/config/shodan_hellovector.resc; start" ``` -### Add or Modify Vector OpCodes and Simulate +### Modify Vector OpCode Behavior and Simulate -To add or modify the functionality of an opcode, we will be modifying the following files: +To modify the functionality of an opcode, we will be modifying the following files: `$ROOTDIR/sim/renode/src/Infrastructure/src/Emulator/Cores/tlib/arch/riscv/translate.c` `$ROOTDIR/sim/renode/src/Infrastructure/src/Emulator/Cores/tlib/arch/riscv/instmap.h` @@ -139,7 +134,6 @@ ``` static void gen_v_arith_ivv(DisasContext *dc, uint32_t opc, int vd, int vs1, int vs2) { tlib_printf(LOG_LEVEL_ERROR, "V_ARITH_IVV"); - ``` In this function there will be a `switch case`. Add an entry here for your new opcode, and fill out the behavior with tcg-lang. @@ -190,3 +184,152 @@ - `$ROOTDIR/sim/renode/src/Infrastructure/src/Emulator/Cores/tlib/arch/riscv/translate.c` -- where to add or modify opcode behavior - `$ROOTDIR/sim/renode/src/Infrastructure/src/Emulator/Cores/tlib/arch/riscv/instmap.h` -- where to add numerical opcode definitions + +### Add New Vector OpCode and Simulate + +To add a new vector opcode, we will be modifying the following toolchain files: +- `$ROOTDIR/toolchain/riscv-binutils/include/opcode/riscv-opc.h` +- `$ROOTDIR/toolchain/riscv-binutils/opcodes/riscv-opc.c` + +And also these files for defining the behavior in simulation: +- `$ROOTDIR/sim/renode/src/Infrastructure/src/Emulator/Cores/tlib/arch/riscv/translate.c` +- `$ROOTDIR/sim/renode/src/Infrastructure/src/Emulator/Cores/tlib/arch/riscv/instmap.h` + +#### Step 1: Obtain the RiscV OpCode Repo + +Clone the [RiscV OpCode Support Repo](https://github.com/riscv/riscv-opcodes) + + +#### Step 2: Add Vector Opcode definition to `opcodes-rvv` file: + +`cd` into the `riscv-opcodes` folder, add the instruction to the `opcodes-rvv` file: + +Example for `vrgatherei16.vv`, add the following line to `opcodes-rvv`: +``` +vrgatherei16.vv 31..26=0x0e vm vs2 vs1 14..12=0x0 vd 6..0=0x57 +``` + +(Note the function6 opcode `0x0e` was determined in this case with the [RiscV Vector OpCode Table](https://github.com/riscv/riscv-v-spec/blob/master/inst-table.adoc)); + +#### Step 3: Utilize the contained python script `parse_opcodes` to generate `MASK` and `MATCH` codes for the new instruction + +Use the `parse_opcodes` script within the `riscv-opcodes` repo to create `MATCH` +and `MASK` macros for the new operation. + +Example: +``` +python3 parse_opcodes opcodes-rvv > temp_opc.h +``` + +This will yield these lines within the output `temp_opc.h` file: +``` +#define MATCH_VRGATHEREI16VV 0x38000057 +#define MASK_VRGATHEREI16VV 0xfc00707f +``` + +#### Step 4: Add these two lines to the `riscv-opc.h` file located at: + +Place the above two macros in a reasonable location within the `riscv-opc.h` +file. + +This file is located: +- `$ROOTDIR/toolchain/riscv-binutils/include/opcode/riscv-opc.h` + +#### Step 5: Add an entry to the RVV Opcode Struct in the `riscv-opc.c` file: + +Take care in spelling in the assembly instruction name (in this example `vrgatherei16.vv`) +as well as spelling in the mask and match names (in this example `MATCH_VRGATHEREI16VV` and `MASKMASK_VRGATHEREI16VV`): + +``` +{"vrgatherei16.vv",0, INSN_CLASS_V, "Vd,Vt,VsVm", MATCH_VRGATHEREI16VV, MASK_VRGATHEREI16VV, match_vd_neq_vs1_neq_vs2_neq_vm, 0}, + +``` + +#### Step 6: Rebuild Relevant RiscV Toolchain + +Will need to rebuild the gnu-toolchain to implement the changes: + +``` +m clean +m tools +``` + +#### Step 7: Add new opcode in `instmap.h`'s enum + +Now we need to define the behavior in the Renode simulator. + +For Renode to interpret this new opcode, create a new entry in `instmap.h`: + +Note to use the `function6` opc in hex: +``` + OPC_RISC_VXOR_IVV = OPC_RISC_V_ARITH_IVV | (0xB << 26), + OPC_RISC_VRGATHER_IVV = OPC_RISC_V_ARITH_IVV | (0xC << 26), + OPC_RISC_VRGATHEREI16_IVV = OPC_RISC_V_ARITH_IVV | (0xE << 26), +``` +See the [RiscV Vector OpCode Table](https://github.com/riscv/riscv-v-spec/blob/master/inst-table.adoc) for guidance. + + +#### Step 8: Define behavior within the `switch...case` within the `translate.c` file + +For example, we can provide means for testing this function with 8 bit elements +of a 512 bit register length (i.e. SEW=8, VLEN=512, LMUL=1) + +``` + case OPC_RISC_VRGATHEREI16_IVV: + tlib_printf(LOG_LEVEL_ERROR, "VRGATHEREI16_IVV"); + for (int i = 0; i < 64; ++i) { + vreg.e8[vd][i] = (vreg.e8[vs1][i] > VLMAX)? 0 : vreg.e8[vs2][vreg.e8[vs1][i]]; + } + break; +``` + +`translate.c` file is located: +- `$ROOTDIR/sim/renode/src/Infrastructure/src/Emulator/Cores/tlib/arch/riscv/translate.c` + +#### Step 9: Rebuild Renode + +``` +m renode_clean +m renode +``` + +Note: Care to look out for errors or warnings which may halt compilation (our make +will halt compilation if there are any unused values for example). + + +#### Step 10: Add opcode test to `hello_vector.c` + +``` +LOG_INFO("trying vrgatherei16"); +__asm__ volatile("vrgatherei16.vv v0, v1, v2"); +``` + +#### Step 11: Build OpenTitan HelloVector Demo + +``` +m shodan_test_sw_bootrom +m shodan_test_sw_hellovector +``` + +#### Step 12: Run Renode Script + +``` +renode -e "i @sim/config/shodan_hellovector.resc; start" +``` + +#### Quicklinks Specific for Creating/Defining new OpCodes: + +- [RiscV OpCode Support Repo](https://github.com/riscv/riscv-opcodes) -- tools for adding new instructions and creating new opcodes + +Toolchain Side: +- `$ROOTDIR/toolchain/riscv-binutils/include/opcode/riscv-opc.h` -- where to add new opcode definitions +- `$ROOTDIR/toolchain/riscv-binutils/opcodes/riscv-opc.c`-- gnu riscv-opcode struct definitions (also needs modification) + +Renode Simulation Side: +- `$ROOTDIR/sim/renode/src/Infrastructure/src/Emulator/Cores/tlib/arch/riscv/translate.c` -- where to add or modify renode opcode sim behavior +- `$ROOTDIR/sim/renode/src/Infrastructure/src/Emulator/Cores/tlib/arch/riscv/instmap.h` -- where to add new opcodes for renode to simulate + +## General References + +- [RiscV v0.9 Vector Extension Draft](https://github.com/riscv/riscv-v-spec/releases/tag/0.9) +- [RiscV Vector OpCode Table](https://github.com/riscv/riscv-v-spec/blob/master/inst-table.adoc)