Follow setups in this document to build and run the following examples:
Keep an eye on the file below for new build targets as they become available:
$ROOTDIR/build/opentitan_sw.mk
These instructions guide through setting up and running a test of OpenTitan with a bare-bones Renode robot-test-script.
repo sync source ./build/setup.sh
m tools
m opentitan_sw_bootrom
m opentitan_sw_helloworld
renode -e "i @sim/config/shodan_secure.resc; start"
shodan_bootrom.robot
Robot-Test-Scriptcd "${ROOTDIR}/sim/tests" ./test.sh shodan_bootrom.robot
Note: since we build Renode from source, we are to use Renode's provided test.sh
instead of renode-test
for running robot test scripts.
More details in Renode's documentation
Results of the robot-test-script will be found in the following files:
$ROOTDIR/out/host/renode/tests/report.html $ROOTDIR/out/host/renode/tests/robot_output.xml $ROOTDIR/out/host/renode/tests/log.html
The report.html
will share the results of each test.
One can utilize robot_output.xml
for scripts/programs which may want to parse and act on results.
How to run the HelloVector example and how to modify or add a new vector OpCode for Renode simulation.
repo sync source ./build/setup.sh
m tools
m shodan_test_sw_bootrom m shodan_test_sw_hellovector
renode -e "i @sim/config/shodan_hellovector.resc; start"
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
instmap.h
's enumTo add a new opcode, create a new entry in instmap.h
:
enum { OPC_RISC_VADD_IVV = OPC_RISC_V_ARITH_IVV | (0x0 << 26), OPC_RISC_VSUB_IVV = OPC_RISC_V_ARITH_IVV | (0x2 << 26), OPC_RISC_VMINU_IVV = OPC_RISC_V_ARITH_IVV | (0x4 << 26), YOUR_OPC_HERE = OPC_RISC_V_ARITH_IVV | (0x8 << 26),
switch...case
entry and definition into translate.c
Open translate.c
and look for the following function (which will be around line 1450):
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.
switch (opc) { case YOUR_OPC_HERE: tlib_printf(LOG_LEVEL_ERROR, "OpCode Not Yet Defined"); break;
Link to TCG Documentation for Reference
m renode_clean m renode
hello_vector.c
Wrap the assembly within an __asm__
block and add to hello_vector.c
:
$ROOTDIR/hw/opentitan/sw_shodan/device/examples/hello_vector/hello_vector.c
shodan_test_sw_hellovector
targetIf hello_vector.c
was modified, run the following to rebuild the shodan_test_sw_hellovector
target:
m shodan_test_sw_hellovector
renode -e "i @sim/config/shodan_hellovector.resc; start"
$ROOTDIR/build/shodan_test_sw.mk
-- build file for hellovector
example$ROOTDIR/sim/config/shodan_hellovector.resc
-- renode script which loads ELFs into memory$ROOTDIR/hw/opentitan/sw_shodan/device/examples/hello_vector/hello_vector.c
-- add assembly here (in __asm__
blocks) for simulation$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 definitionsTo 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
Clone the RiscV OpCode Support Repo
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);
parse_opcodes
to generate MASK
and MATCH
codes for the new instructionUse 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
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
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 MASK_VRGATHEREI16VV
):
{"vrgatherei16.vv",0, INSN_CLASS_V, "Vd,Vt,VsVm", MATCH_VRGATHEREI16VV, MASK_VRGATHEREI16VV, match_vd_neq_vs1_neq_vs2_neq_vm, 0},
Will need to rebuild the gnu-toolchain to implement the changes:
m clean m tools
instmap.h
's enumNow 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 for guidance.
switch...case
within the translate.c
fileFor 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
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).
hello_vector.c
LOG_INFO("trying vrgatherei16"); __asm__ volatile("vrgatherei16.vv v0, v1, v2");
m shodan_test_sw_bootrom m shodan_test_sw_hellovector
renode -e "i @sim/config/shodan_hellovector.resc; start"
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