Skip to content
Merged
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
10 changes: 9 additions & 1 deletion hw/dv/tools/dvsim/bazel.hjson
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
{
sw_build_cmd: "bazel"
sw_build_cmd: [
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor nit: maybe this should be called sw_build.hjson, or even bazel_sw.hjson instead? At the moment it's slightly confusing to just have it named bazel.hjson when its purpose is actually just to build the sw collateral (via Bazel) - "Bazel" should not be synonymous with "SW collateral". I think the naming issue here just becomes more pronounced with the change to a python script that uses Bazel.

"python",
"{proj_root}/util/py/scripts/build_sw_collateral_for_sim.py",
"--sw-images='{sw_images}'",
"--sw-build-opts='{sw_build_opts}'",
"--sw-build-device={sw_build_device}",
"--seed={seed}",
"--run-dir={run_dir}",
]
sw_build_opts: []
}
157 changes: 18 additions & 139 deletions hw/dv/tools/dvsim/sim.mk
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ all: build run
build: build_result

pre_build:
@echo "[make]: pre_build"
@echo -e "\n[make]: pre_build"
mkdir -p ${build_dir}
ifneq (${pre_build_cmds},)
# pre_build_cmds are likely changing the in-tree sources. We hence use FLOCK
Expand All @@ -26,173 +26,51 @@ ifneq (${pre_build_cmds},)
endif

gen_sv_flist: pre_build
@echo "[make]: gen_sv_flist"
@echo -e "\n[make]: gen_sv_flist"
ifneq (${sv_flist_gen_cmd},)
cd ${build_dir} && ${sv_flist_gen_cmd} ${sv_flist_gen_opts}
endif

do_build: gen_sv_flist
@echo "[make]: build"
@echo -e "\n[make]: build"
cd ${sv_flist_gen_dir} && ${build_cmd} ${build_opts}

post_build: do_build
@echo "[make]: post_build"
@echo -e "\n[make]: post_build"
ifneq (${post_build_cmds},)
cd ${build_dir} && ${post_build_cmds}
endif

build_result: post_build
@echo "[make]: build_result"
@echo -e "\n[make]: build_result"

run: run_result

pre_run:
@echo "[make]: pre_run"
@echo -e "\n[make]: pre_run"
mkdir -p ${run_dir}
ifneq (${pre_run_cmds},)
cd ${run_dir} && ${pre_run_cmds}
endif

sw_build: pre_run
@echo "[make]: sw_build"
@echo -e "\n[make]: sw_build"
ifneq (${sw_images},)
# Loop through the list of sw_images and invoke Bazel on each.
# `sw_images` is a space-separated list of tests to be built into an image.
# Optionally, each item in the list can have additional metadata / flags using
# the delimiter ':'. The format is as follows:
# <Bazel label>:<index>:<flag1>:<flag2>
#
# If one delimiter is detected, then the full string is considered to be the
# <Bazel label>. If two delimiters are detected, then it must be <Bazel label>
# followed by <index>. The <flag> is considered optional.
#
# After the images are built, we use `bazel cquery ...` to locate the built
# software artifacts so they can be copied to the test bench run directory.
# We only copy device SW images, and do not copy host-side artifacts (like
# opentitantool) that are also dependencies of the Bazel test target that
# encode the software image targets.
set -e; \
for sw_image in ${sw_images}; do \
if [[ -z $$sw_image ]]; then \
echo "ERROR: SW image \"$$sw_image\" is malformed."; \
echo "Expected format: <Bazel label>:<index>:<optional-flags>."; \
exit 1; \
fi; \
prebuilt_path=`echo $$sw_image | cut -d: -f 1`; \
bazel_target=`echo $$sw_image | cut -d: -f 2`; \
index=`echo $$sw_image | cut -d: -f 3`; \
flags=(`echo $$sw_image | cut -d: -f 4- --output-delimiter " "`); \
bazel_label="`echo $$sw_image | cut -d: -f 1-2`"; \
if [[ $${index} != 4 && $${index} != 5 ]]; then \
if [[ $${flags[@]} =~ "silicon_creator" ]]; then \
bazel_label="$${bazel_label}_silicon_creator"; \
else \
bazel_label="$${bazel_label}_$${sw_build_device}"; \
fi; \
bazel_cquery="labels(data, $${bazel_label}) union labels(srcs, $${bazel_label})"; \
else \
bazel_cquery="$${bazel_label}"; \
fi; \
cd ${proj_root}; \
if [[ $${flags[@]} =~ "prebuilt" ]]; then \
echo "SW image \"$$bazel_label\" is prebuilt - copying sources."; \
cp ${proj_root}/$${prebuilt_path} $${run_dir}/`basename $${prebuilt_path}`; \
else \
echo "Building SW image \"$${bazel_label}\"."; \
bazel_airgapped_opts=""; \
bazel_opts="${sw_build_opts} --define DISABLE_VERILATOR_BUILD=true"; \
if [[ -n $${BAZEL_OTP_DATA_PERM_FLAG} ]]; then \
bazel_opts+=" --//util/design/data:data_perm=$${BAZEL_OTP_DATA_PERM_FLAG}"; \
fi; \
if [[ $${OT_AIRGAPPED} != true ]]; then \
echo "Building \"$${bazel_label}\" on network connected machine."; \
bazel_cmd="./bazelisk.sh"; \
else \
echo "Building \"$${bazel_label}\" on air-gapped machine."; \
bazel_airgapped_opts+=" --define SPECIFY_BINDGEN_LIBSTDCXX=true"; \
bazel_airgapped_opts+=" --distdir=$${BAZEL_DISTDIR}"; \
bazel_airgapped_opts+=" --repository_cache=$${BAZEL_CACHE}"; \
bazel_cmd="bazel"; \
fi; \
echo "Building with command: $${bazel_cmd} build $${bazel_opts} $${bazel_label}"; \
$${bazel_cmd} build $${bazel_airgapped_opts} $${bazel_opts} $${bazel_label}; \
kind=$$($${bazel_cmd} cquery $${bazel_airgapped_opts} \
$${bazel_label} \
--ui_event_filters=-info \
--noshow_progress \
--output=label_kind | cut -f1 -d' '); \
if [[ $${kind} == "opentitan_test" ]]; then \
for artifact in $$($${bazel_cmd} cquery $${bazel_airgapped_opts} $${bazel_opts} \
$${bazel_label} \
--ui_event_filters=-info \
--noshow_progress \
--output=starlark \
`# An opentitan_test rule has all of its needed files in its runfiles.` \
--starlark:expr='"\n".join([f.path for f in target.data_runfiles.files.to_list()])'); do \
cp -f $${artifact} $${run_dir}/$$(basename $${artifact}); \
if [[ $$artifact == *.bin && \
-f "$$(echo $${artifact} | cut -d. -f 1).elf" ]]; then \
cp -f "$$(echo $${artifact} | cut -d. -f 1).elf" \
$${run_dir}/$$(basename -s .bin $${artifact}).elf; \
fi; \
done; \
elif [[ $${kind} == "alias" || $${kind} == "opentitan_binary" ]]; then \
for artifact in $$($${bazel_cmd} cquery $${bazel_airgapped_opts} $${bazel_opts} \
$${bazel_label} \
--ui_event_filters=-info \
--noshow_progress \
--output=starlark \
`# An opentitan_binary rule has all of its needed files in its runfiles.` \
--starlark:expr='"\n".join([f.path for f in target.files.to_list()])'); do \
cp -f $${artifact} $${run_dir}/$$(basename $${artifact}); \
if [[ $$artifact == *.bin && \
-f "$$(echo $${artifact} | cut -d. -f 1).elf" ]]; then \
cp -f "$$(echo $${artifact} | cut -d. -f 1).elf" \
$${run_dir}/$$(basename -s .bin $${artifact}).elf; \
fi; \
done; \
else \
for dep in $$($${bazel_cmd} cquery $${bazel_airgapped_opts} $${bazel_opts} \
$${bazel_cquery} \
--ui_event_filters=-info \
--noshow_progress \
--output=starlark \
`# Bazel 6 cquery outputs repository targets in canonical format (@//blabla) whereas bazel 5 does not, ` \
`# so we use a custom starlark printer to remove in leading @ when needed.` \
--starlark:expr='str(target.label)[1:] if str(target.label).startswith("@//") else target.label'); do \
if [[ $$dep == //hw/top_*/ip_autogen/otp_ctrl/data* ]] || \
([[ $$dep != //hw* ]] && [[ $$dep != //util* ]] && [[ $$dep != //sw/host* ]]); then \
for artifact in $$($${bazel_cmd} cquery $${bazel_airgapped_opts} $${bazel_opts} $${dep} \
--ui_event_filters=-info \
--noshow_progress \
--output=starlark \
--starlark:expr="\"\\n\".join([f.path for f in target.files.to_list()])"); do \
cp -f $${artifact} $${run_dir}/$$(basename $${artifact}); \
if [[ $$artifact == *.bin && \
-f "$$(echo $${artifact} | cut -d. -f 1).elf" ]]; then \
cp -f "$$(echo $${artifact} | cut -d. -f 1).elf" \
$${run_dir}/$$(basename -s .bin $${artifact}).elf; \
fi; \
done; \
fi; \
done; \
fi; \
fi; \
done;
cd ${proj_root} && ${sw_build_cmd} --build-seed=${build_seed}
endif

simulate: sw_build
@echo "[make]: simulate"
@echo -e "\n[make]: simulate"
cd ${run_dir} && ${run_cmd} ${run_opts}

post_run: simulate
@echo "[make]: post_run"
@echo -e "\n[make]: post_run"
ifneq (${post_run_cmds},)
cd ${run_dir} && ${post_run_cmds}
endif

run_result: post_run
@echo "[make]: run_result"
@echo -e "\n[make]: run_result"

#######################
## Load waves target ##
Expand All @@ -204,19 +82,20 @@ debug_waves:
## coverage rated targets ##
############################
cov_unr_build: gen_sv_flist
@echo "[make]: cov_unr_build"
@echo -e "\n[make]: cov_unr_build"
cd ${sv_flist_gen_dir} && ${cov_unr_build_cmd} ${cov_unr_build_opts}

cov_unr_vcs: cov_unr_build
@echo "[make]: cov_unr"
@echo -e "\n[make]: cov_unr"
cd ${sv_flist_gen_dir} && ${cov_unr_run_cmd} ${cov_unr_run_opts}

cov_unr_xcelium:
@echo "[make]: cov_unr"
@echo -e "\n[make]: cov_unr"
mkdir -p ${cov_unr_dir}
cd ${cov_unr_dir} && ${cov_unr_run_cmd} ${cov_unr_run_opts}

cov_unr_merge:
@echo -e "\n[make]: cov_unr_merge"
cd ${cov_unr_dir} && ${job_prefix} ${cov_merge_cmd} -init ${cov_unr_dir}/jgproject/sessionLogs/session_0/unr_imc_coverage_merge.cmd

ifeq (${SIMULATOR}, xcelium)
Expand All @@ -227,17 +106,17 @@ endif

# Merge coverage if there are multiple builds.
cov_merge:
@echo "[make]: cov_merge"
@echo -e "\n[make]: cov_merge"
${job_prefix} ${cov_merge_cmd} ${cov_merge_opts}

# Generate coverage reports.
cov_report:
@echo "[make]: cov_report"
@echo -e "\n[make]: cov_report"
${cov_report_cmd} ${cov_report_opts}

# Open coverage tool to review and create report or exclusion file.
cov_analyze:
@echo "[make]: cov_analyze"
@echo -e "\n[make]: cov_analyze"
${cov_analyze_cmd} ${cov_analyze_opts}

.PHONY: build \
Expand Down
4 changes: 3 additions & 1 deletion hw/top_darjeeling/dv/env/chip_env_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,10 @@ package chip_env_pkg;
SpiDeviceIngressMem
} chip_mem_e;

// On OpenTitan, we deal with 4 types of SW - ROM, the main test, the OTBN test and the OTP image.
// On Darjeeling, we deal with 8 types of SW.
// This basically puts these SW types into 'slots' that the external regression tool can set.
// Note: This enum must be consistent across tops.
// Note: If this enum is updated, then also update the file `build_sw_collateral_for_sim.py`.
typedef enum {
SwTypeRom = 0, // Ibex SW - first stage boot ROM.
SwTypeTestSlotA = 1, // Ibex SW - test SW in (flash) slot A.
Expand Down
49 changes: 35 additions & 14 deletions hw/top_earlgrey/dv/chip_sim_cfg.hjson
Original file line number Diff line number Diff line change
Expand Up @@ -325,22 +325,43 @@
run_opts: ["+accelerate_cold_power_up_time=3",
"+accelerate_regulators_power_up_time=2"]
}
{
// Format SW image names into output file names separated by commas to feed into
// +sw_images plusarg. Image names are just Bazel labels concatenated with an index
// and/or flags.
// The input is a space-seperated list in the variable 'sw_images'.
// The result is saved to the same variable 'sw_images'.
//
// For example, for an input of:
// [
// "//sw/device/tests:uart_tx_rx_test:1",
// "//sw/device/lib/testing/test_rom:test_rom:0"
// ]
//
// ..then the result will be:
//
// "uart_tx_rx_test:1,test_rom:0".
//
name: format_sw_images
run_opts: [
"+sw_build_device={sw_build_device}",
'''
+sw_images={eval_cmd} \
reformatted_sw_images=; \
for image in {sw_images}; do \
reformatted_sw_images="$reformatted_sw_images `echo $image | cut -d: -f2-`"; \
done; \
echo $reformatted_sw_images | sed -E 's/\s+/,/g'
'''
]
}
{
name: sw_test_mode_base
en_run_modes: ["format_sw_images"]
}
{
name: sw_test_mode_common
run_opts: ["+sw_build_device={sw_build_device}",
// Format SW image names (which are Bazel labels concatenated with an index
// and/or flags, see below) into output file names separated by commas to feed into
// +sw_images plusarg. For example, if the input list of SW images is
// ["//sw/device/tests:uart_tx_rx_test:1",
// "//sw/device/lib/testing/test_rom:test_rom:0"], then the output of this eval_cmd
// will be: "uart_tx_rx_test:1,test_rom:0".
'''+sw_images={eval_cmd} \
reformatted_sw_images=; \
for image in {sw_images}; do \
reformatted_sw_images="$reformatted_sw_images `echo $image | cut -d: -f2-`"; \
done; \
echo $reformatted_sw_images | sed -E 's/\s+/,/g' ''']
en_run_modes: ["gen_otp_images_mode"]
en_run_modes: ["sw_test_mode_base", "gen_otp_images_mode"]
}
{
name: sw_test_mode_test_rom
Expand Down
4 changes: 3 additions & 1 deletion hw/top_earlgrey/dv/env/chip_env_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,10 @@ package chip_env_pkg;
Rom
} chip_mem_e;

// On OpenTitan, we deal with 4 types of SW - ROM, the main test, the OTBN test and the OTP image.
// On Earlgrey, we deal with 6 types of SW.
// This basically puts these SW types into 'slots' that the external regression tool can set.
// Note: This enum must be consistent across tops.
// Note: If this enum is updated, then also update the file `build_sw_collateral_for_sim.py`.
typedef enum {
SwTypeRom = 0, // Ibex SW - first stage boot ROM.
SwTypeTestSlotA = 1, // Ibex SW - test SW in (flash) slot A.
Expand Down
Loading