Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions dv/uvm/core_ibex/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
cmake_minimum_required(VERSION 3.20)

project(IbexSnippyFlow LANGUAGES NONE)

include(${CMAKE_CURRENT_SOURCE_DIR}/snippy_cmake/Helpers.cmake)
include(${CMAKE_CURRENT_SOURCE_DIR}/snippy_cmake/IbexMake.cmake)
include(${CMAKE_CURRENT_SOURCE_DIR}/snippy_cmake/Options.cmake)
include(${CMAKE_CURRENT_SOURCE_DIR}/snippy_cmake/Paths.cmake)
include(${CMAKE_CURRENT_SOURCE_DIR}/snippy_cmake/Inputs.cmake)
include(${CMAKE_CURRENT_SOURCE_DIR}/snippy_cmake/RiscvDv.cmake)
include(${CMAKE_CURRENT_SOURCE_DIR}/snippy_cmake/RtlCompile.cmake)
include(${CMAKE_CURRENT_SOURCE_DIR}/snippy_cmake/Cosimulation.cmake)
include(${CMAKE_CURRENT_SOURCE_DIR}/snippy_cmake/SnippyCommands.cmake)
include(${CMAKE_CURRENT_SOURCE_DIR}/snippy_cmake/Snippy.cmake)
include(${CMAKE_CURRENT_SOURCE_DIR}/snippy_cmake/Coverage.cmake)
include(${CMAKE_CURRENT_SOURCE_DIR}/snippy_cmake/FlowTargets.cmake)
111 changes: 111 additions & 0 deletions dv/uvm/core_ibex/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,15 @@ IBEX_CONFIG := opentitan
# Path to DUT used for coverage reports
DUT_COV_RTL_PATH := "ibex_top"

# Optional override for compressed extension subset.
# Empty means: use RV32ZC from IBEX_CONFIG in ibex_configs.yaml.
# Allowed values:
# ibex_pkg::RV32Zca
# ibex_pkg::RV32ZcaZcb
# ibex_pkg::RV32ZcaZcmp
# ibex_pkg::RV32ZcaZcbZcmp
RV32ZC :=

export EXTRA_COSIM_CFLAGS ?=

ifeq ($(COSIM_SIGSEGV_WORKAROUND), 1)
Expand All @@ -76,9 +85,23 @@ run:
SEED=$(SEED) WAVES=$(WAVES) COV=$(COV) SIMULATOR=$(SIMULATOR) \
ISS=$(ISS) TEST=$(TEST) VERBOSE=$(VERBOSE) ITERATIONS=$(ITERATIONS) \
SIGNATURE_ADDR=$(SIGNATURE_ADDR) IBEX_CONFIG=$(IBEX_CONFIG) \
RV32ZC=$(RV32ZC) \
DUT_COV_RTL_PATH=$(DUT_COV_RTL_PATH)"
@$(MAKE) --file wrapper.mk --environment-overrides --no-print-directory $(GOAL)

# Run a wrapper.mk goal using already-created metadata.
#
# This is intended for external flows, such as the Snippy CMake flow, where
# metadata is created once by an earlier Ibex Make invocation and many simulator
# runs are launched afterwards. It preserves the top-level Makefile derived
# variables such as OUT-DIR, METADATA-DIR and PYTHONPATH, but avoids calling
# metadata.py --op create_metadata for every individual run.
.PHONY: run_existing_metadata
run_existing_metadata:
@test -f $(METADATA-DIR)/metadata.pickle || \
(echo "Metadata not found: $(METADATA-DIR)/metadata.pickle. Run make run GOAL=rtl_tb_compile first."; false)
@$(MAKE) --file wrapper.mk --environment-overrides --no-print-directory $(GOAL)

###############################################################################

# This is the top-level output directory. Everything we generate goes in
Expand All @@ -94,6 +117,94 @@ export METADATA-DIR := $(OUT-DIR)metadata
# riscv-dv extension directory
export EXT_DIR := riscv_dv_extension

###############################################################################
# Snippy CMake flow
#
# The Snippy flow is implemented in CMake under snippy_cmake/. This Makefile
# block is intentionally a thin bridge:
#
# Ibex Make knobs -> CMake cache variables -> Snippy CMake flow
#
# Toolchain and Spike variables are shared with the normal Ibex flow:
#
# RISCV_GCC
# RISCV_OBJCOPY
# SPIKE_PATH
# PKG_CONFIG_PATH
#
# Snippy runs write their standard Ibex-compatible runtime artifacts into
# $(OUT-DIR), so later Ibex coverage goals can consume them together with
# normal riscv-dv results.

# Comma-separated list of Snippy YAML layouts to run, for example:
#
# SNIPPY_TEST="layout_arith, jalr, rem_div"
#
# Empty means: use the CMake flow default selection.
SNIPPY_TEST ?=

# Number of Snippy runs for each selected YAML layout.
SNIPPY_ITERATIONS ?= 1

# Directory with Snippy YAML layout files.
# Relative paths are resolved by CMake from dv/uvm/core_ibex.
SNIPPY_YAML_DIR ?= snippy/yaml_tests

# Placeholder metadata test name used by the Snippy CMake flow when creating
# Ibex metadata. Keep this separate from TEST so normal riscv-dv Make runs can
# keep using TEST=all or any user-selected riscv-dv test.
SNIPPY_METADATA_TEST ?= snippy_func_test

# Use snippy/urg_exclude/urg_exclude_all.txt during VCS/URG coverage merge.
USE_URG_EXCLUDE ?= ON

# CMake source and build directories for the Snippy flow.
#
# CMakeLists.txt is expected to live in this core_ibex directory and include the
# implementation files from snippy_cmake/.
SNIPPY_CMAKE_SOURCE_DIR ?= $(CURDIR)
SNIPPY_CMAKE_BUILD_DIR ?= $(OUT-DIR)snippy_cmake_build

# Do not let the top-level Ibex VERBOSE=0 leak into CMake-generated Makefiles:
# for them, any non-empty VERBOSE value enables command echoing. Pass VERBOSE=1
# to the native build tool only when the user explicitly requested it.
SNIPPY_CMAKE_BUILD_NATIVE_ARGS := --no-print-directory
ifeq ($(VERBOSE),1)
SNIPPY_CMAKE_BUILD_NATIVE_ARGS += VERBOSE=1
endif

.PHONY: configure_snippy
configure_snippy:
cmake -S $(SNIPPY_CMAKE_SOURCE_DIR) -B $(SNIPPY_CMAKE_BUILD_DIR) \
-DOUT=$(abspath $(OUT-DIR)) \
-DSEED=$(SEED) \
-DWAVES=$(WAVES) \
-DCOV=$(COV) \
-DSIMULATOR=$(SIMULATOR) \
-DISS=$(ISS) \
-DTEST=$(SNIPPY_METADATA_TEST) \
-DIBEX_CONFIG=$(IBEX_CONFIG) \
-DRV32ZC=$(RV32ZC) \
-DSIGNATURE_ADDR=$(SIGNATURE_ADDR) \
-DRISCV_GCC="$(RISCV_GCC)" \
-DRISCV_OBJCOPY="$(RISCV_OBJCOPY)" \
-DSPIKE_PATH="$(SPIKE_PATH)" \
-DPKG_CONFIG_PATH="$(PKG_CONFIG_PATH)" \
-DSNIPPY_ITERATIONS=$(SNIPPY_ITERATIONS) \
-DSNIPPY_TEST="$(SNIPPY_TEST)" \
-DYAML_DIR="$(SNIPPY_YAML_DIR)" \
-DUSE_URG_EXCLUDE=$(USE_URG_EXCLUDE)

.PHONY: run_snippy
run_snippy: configure_snippy
env -u VERBOSE cmake --build $(SNIPPY_CMAKE_BUILD_DIR) --target run_all -j 60 -- $(SNIPPY_CMAKE_BUILD_NATIVE_ARGS)

.PHONY: coverage_snippy
coverage_snippy:
@test -d $(SNIPPY_CMAKE_BUILD_DIR) || \
(echo "Snippy CMake build directory not found: $(SNIPPY_CMAKE_BUILD_DIR). Run make run_snippy first."; false)
env -u VERBOSE cmake --build $(SNIPPY_CMAKE_BUILD_DIR) --target coverage -- $(SNIPPY_CMAKE_BUILD_NATIVE_ARGS)

###############################################################################

.PHONY: clean
Expand Down
109 changes: 109 additions & 0 deletions dv/uvm/core_ibex/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,118 @@ export RISCV_GCC=riscv32-unknown-elf-gcc
export RISCV_OBJCOPY=riscv32-unknown-elf-objcopy
```

For the optional llvm-snippy flow, set `SC_SNIPPY_PATH` to the llvm-snippy
installation directory:

```bash
export SC_SNIPPY_PATH=/path/to/llvm-snippy
```

The Snippy flow expects the executable at `$SC_SNIPPY_PATH/llvm-snippy`.
More Snippy-specific setup notes are documented in `snippy_cmake/README.md`.

## Running tests

To run tests you can make variations of the following command, where you replace `$TEST_NAME` with the test (or a series of comma-separated tests) that you would like to run as specified in `dv/uvm/core_ibex/riscv_dv_extension/testlist.yaml`:
```bash
make --keep-going IBEX_CONFIG=opentitan SIMULATOR=xlm ISS=spike ITERATIONS=1 SEED=1 TEST=$TEST_NAME WAVES=0 COV=0
```

## Running Snippy tests

The custom Snippy flow can be launched through the Ibex Makefile with
`run_snippy`.

Example:

```bash
make run_snippy \
OUT=out \
COV=1 \
SIMULATOR=vcs \
IBEX_CONFIG=opentitan \
RV32ZC=ibex_pkg::RV32Zca \
SNIPPY_ITERATIONS=3 \
SNIPPY_TEST="layout_arith, jalr, rem_div" \
SNIPPY_YAML_DIR=snippy/yaml_tests
```

`SNIPPY_TEST` selects YAML files from `SNIPPY_YAML_DIR`.

`SNIPPY_TEST` is a comma-separated list of Snippy YAML layouts. The accepted
forms include `layout_arith`, `arith`, and `layout_arith.yaml`.

`SNIPPY_ITERATIONS` controls the number of Snippy runs for each selected layout.

Snippy runtime results are written into the standard Ibex output tree:

```text
out/run/tests/snippy_<layout>.<seed>/
```

The CMake-side Snippy intermediate files and summary are written under:

```text
out/snippy_cmake_build/
```

## Collecting combined riscv-dv and Snippy coverage

To collect one combined coverage report from both riscv-dv and Snippy runs, use
the same `OUT` directory and enable `COV=1` for both flows.

First, run riscv-dv only up to RTL simulation:

```bash
make run \
GOAL=rtl_sim_run \
OUT=out \
COV=1 \
SIMULATOR=vcs \
IBEX_CONFIG=opentitan \
RV32ZC=ibex_pkg::RV32Zca \
TEST=riscv_arithmetic_basic_test
```

Using `GOAL=rtl_sim_run` avoids collecting an intermediate coverage report
before the Snippy tests have been added.

Then run Snippy into the same `OUT` directory:

```bash
make run_snippy \
OUT=out \
COV=1 \
SIMULATOR=vcs \
IBEX_CONFIG=opentitan \
RV32ZC=ibex_pkg::RV32Zca \
SNIPPY_ITERATIONS=3 \
SNIPPY_TEST="layout_arith, jalr, rem_div"
```

Finally, merge coverage once:

```bash
make coverage_snippy OUT=out
```

The final report is written to:

```text
out/run/coverage/report/
```

## Cleaning generated files

To remove generated outputs:

```bash
make clean OUT=out
```

This also removes the Snippy CMake build directory when it is located under
`OUT`, for example:

```text
out/snippy_cmake_build/
```
Loading