blob: 3b3f4da9be0aeca2867bd94d523dcc853f951eca [file] [log] [blame] [view]
# Create Springbok Vector Unit Test
* [Step 0: Repo Sync and Build Prequisites](#step-0:-repo-sync-and-build-prequisites)
* [Step 1: Select Instruction and Update Tracker](#step-1:-select-instruction-and-update-tracker)
* [Step 2: Create operation definition in `${ROOTDIR}/sw/vec/softrvv/include`](#step-2:-create-operation-definition-in-`${rootdir}/sw/vec/softrvv/include`)
* [Step 3: Add the header to softrvv.h](#step-3:-add-the-header-to-softrvv.h)
* [Step 4: Add main test entry within the CMakeLists.txt](#step-4:-add-main-test-entry-within-the-cmakelists.txt)
* [Step 5: Create subtest](#step-5:-create-subtest)
* [Add brief softrvv test](#add-brief-softrvv-test)
* [Add this smaller test to a 2nd Cmake file](#add-this-smaller-test-to-a-2nd-cmake-file)
* [Step 6.1: Build and Run Elf with Renode/Qemu](#step-6.1:-build-and-run-elf-with-renode/qemu)
* [Run Elf with Renode](#run-elf-with-renode)
* [Run Elf with Qemu](#run-elf-with-qemu)
* [Step 6.2 (Optional): Debug Elf with Renode/Qemu and gdb](#step-6.2-(optional):-debug-elf-with-renode/qemu-and-gdb)
* [Step 6.3 (Optional): Object dump with binutils](#step-6.3-(optional):-object-dump-with-binutils)
* [Step 7: Build and Run CTests](#step-7:-build-and-run-ctests)
* [Step 8 (optional): view generated code](#step-8-(optional):-view-generated-code)
* [Step 9: Mark Tests as Passing](#step-9:-mark-tests-as-passing)
* [Step 10: Git Commit](#step-10:-git-commit)
## Step 0: Repo Sync and Build Prequisites
```sh
repo sync
m renode_clean renode
m qemu_clean qemu
```
## Step 1: Select Instruction and Update Tracker
Go to the following spreadsheet and write or select one's name under the `DRI - Unit Test`.
[Select Instructions Here](https://docs.google.com/spreadsheets/d/1MVh0eQjdKkPiBOCXysfuLWWkFiL3gWzqvk-xA8-1rNg/edit#gid=1311575874)
Now you've signed up to develop a unit test for this vector instruction :)
Side Note: The following pivot table is very useful for quickly scanning through the instructions available:
[DRI Pivot Table](https://docs.google.com/spreadsheets/d/1MVh0eQjdKkPiBOCXysfuLWWkFiL3gWzqvk-xA8-1rNg/edit#gid=1165644093)
## Step 2: Create operation definition in `${ROOTDIR}/sw/vec/softrvv/include`
Add definition of the operation as a file `softrvv_<op>h.h` in the following folder, where `<op>` is your operation (e.g. `vadd`, `vor`, `vmerge`, etc...):
```sh
${ROOTDIR}/sw/vec/softrvv/include
```
This test will contain the definition of the operation (e.g. `vadd` operation below):
```cpp
template <typename T>
void vadd_vi(T *dest, T *src1, T src2, int32_t avl) {
for (int32_t idx = 0; idx < avl; idx++) {
dest[idx] = src1[idx] + src2;
}
}
```
See [softrvv_vadd.h](https://spacebeaker.googlesource.com/shodan/sw/vec/+/refs/heads/master/softrvv/include/softrvv_vadd.h) for a reference.
## Step 3: Add the header to softrvv.h
Add the header file as an includes in the `softrvv.h`:
```cpp
#include "softrvv_vadd.h"
```
` softrvv.h ` is in the `${ROOTDIR}/sw/vec/softrvv/include` directory.
## Step 4: Add main test entry within the CMakeLists.txt
`cd` into the following folder, and edit the `CMakeLists.txt` file there
```sh
${ROOTDIR}/sw/vec/tests/CMakeLists.txt
```
Add an entry there with the opcode formats relavant to the operation:
```cmake
vec_cc_generated_test(
NAME
vadd
OPFMT
OPIVV
OPIVX
OPIVI
LINKOPTS
-Xlinker --defsym=__itcm_length__=200K
)
```
Note: this operation uses OPIVV, OPIVX, and OPIVI formats.
A range of tests will be be autogenerated for each one of the OPFMT's added.
The Mako templates for each OPFMT test can be found at `${ROOTDIR}/sw/vec/tests/templates`.
Note on `__itcm_length__`: keeping this number low for each test helps our overall performance, most tests are good with 128K, some might need a little more memory (`ctest` will let you know if you need to add more here).
## Step 5: Create subtest
Please also add a small manual test the new softvv instruction.
Steps delineated as follows:
### Add brief softrvv test
```sh
cd ${ROOTDIR}/sw/vec/softrvv/tests
```
Then add a test-file named `softrvv_<op>_test.cpp`.
See other files in the same folder as references.
In this test-file you'll define a few simple test cases to run on the defined functions:
See for example this VV test from [softrvv_vadd_test.cpp](https://spacebeaker.googlesource.com/shodan/sw/vec/+/refs/heads/master/softrvv/tests/softrvv_vadd_test.cpp):
```cpp
uint32_t src1[] = {1, 2, 3, 4, 5};
uint32_t src2[] = {1, 2, 3, 4, 5};
uint32_t ref_vv[] = {2, 4, 6, 8, 10};
TEST_F(SoftRvvVaddTest, VV) {
softrvv::vadd_vv<uint32_t>(dest, src1, src2, AVL_CONST);
ASSERT_EQ(memcmp(dest, ref_vv, sizeof(dest)), 0);
}
```
### Add this smaller test to a 2nd Cmake file
Edit another CMakeLists.txt file (path below):
```sh
${ROOTDIR}/sw/vec/softrvv/tests/CMakeLists.txt
```
Add the subtest just created:
```cmake
vec_cc_test(
NAME
softrvv_vadd
SRCS
softrvv_vadd_test.cpp
DEPS
softrvv
LINKOPTS
-Xlinker --defsym=__itcm_length__=128K
```
## Step 6.1: Build and Run Elf with Renode/Qemu
`cd` into the root directory (`cd $ROOTDIR`), and build the elf with:
```sh
m springbok
```
### Run Elf with Renode
From the root directory, run `sim_springbok`
```sh
sim_springbok ./out/springbok/tests/vadd_test.elf
```
This will run the single elf, and if there is an error, can give useful
information, such as the PC and MTVAL associated with any illegal instruction.
### Run Elf with Qemu
From the root directory, run `qemu_sim_springbok`
```sh
qemu_sim_springbok ./out/springbok/tests/vadd_test.elf
```
## Step 6.2 (Optional): Debug Elf with Renode/Qemu and gdb
To debug an elf, open two console sessions in the `$ROOTDIR`, in one run start a simulator
(either `sim_springbok` or `qemu_sim_springbok`):
Start Renode simulation:
```sh
sim_springbok ./out/springbok/tests/vadd_test.elf debug
```
Alternatively, start Qemu simulation:
```sh
qemu_sim_springbok ./out/springbok/tests/vadd_test.elf -s -S
```
Now, in the other console session run the following command to start a gdb session:
```sh
cache/toolchain/bin/riscv32-unknown-elf-gdb -ex "target remote :3333" out/springbok/tests/vadd_test.elf
```
Note: To run GDB with the Qemu simulation, use
```sh
cache/toolchain/bin/riscv32-unknown-elf-gdb -ex "target remote :1234" out/springbok/tests/vadd_test.elf
```
First, in the Renode session, type `start`.
Then, in the gdb session, type the following,
```sh
layout split
b main
```
and step through as usual with GDB.
## Step 6.3 (Optional): Object dump with binutils
Sadly, gdb cannot presently decode RVV machine code into assembly instructions.
However, the objdump __is__ able to decode the RVV machine code into assembly.
To do this, obtain the program counter for the RVV machine code in question, then perform an objdump.
Run this on the elf (while in the `$ROOTDIR`):
```sh
cache/toolchain_iree_rv32imf/bin/riscv32-unknown-elf-objdump -d out/springbok/tests/vadd_test.elf | less
```
Then search for the PC for any instruction of interest.
## Step 7: Build and Run CTests
CTests must be run from the `${ROOTDIR}/out/springbok` directory.
`cd ${ROOTDIR}/out/springbok`
Next, using Regex in the quoted section, select Qemu, Renode, and/or other operations
to include in a test run:
```sh
m springbok && ctest --verbose -R ".*vadd.*" --gtest_color=yes
```
## Step 8 (optional): view generated code
Code for the main test was autogenerated, however by `cd`'ing into the following directory, one can inspect the generated code.
```sh
${ROOTDIR}/out/springbok/tests/generated/
```
## Step 9: Mark Tests as Passing
Note: at minimum, one's test should be expected to pass in Qemu. Since Renode vec support is WIP, a unit test failing may indicate problem in the Renode implementation.
On the [unit test tracker](https://docs.google.com/spreadsheets/d/1MVh0eQjdKkPiBOCXysfuLWWkFiL3gWzqvk-xA8-1rNg/edit#gid=1311575874):
1. Mark whether the unit test passes in Qemu
2. Mark whether the unit test passes in Renode
3. Mark the instruction "Springbok Unit Test" as "implemented"
## Step 10: Git Commit
At this point there are two commitable chunks:
1. operation definition, softrvv.h change, and CMakeLists.txt entry.
2. the manual test and its CMakeLists.txt entry
These may be added as either one CL, or two CL's separating these two contributions.