mirror of
https://github.com/lowRISC/ibex.git
synced 2025-04-22 04:47:25 -04:00
Rationalize paths in core_ibex Makefile and scripts
Now we have the following structure (for an example where we've just run seed 123 of riscv_arithmetic_basic_test): out/ +- build/ | +- tb/ | | (built testbench) | +- instr-gen/ | | (built instruction generator) +- run/ +- riscv_arithmetic_basic_test.123/ | +- test.S | +- test.o | +- test.bin | +- rtl.log | +- trace_core_00000000.log | +- spike.log | ... (some more log files etc. here) +- fcov/ | (architectural fcov from riscv-dv) +- coverage/ | (merged coverage data) +- regr.log +- regr_junit.xml +- regr_junit_merged.xml
This commit is contained in:
parent
ca4b655564
commit
f082cf2351
7 changed files with 132 additions and 159 deletions
|
@ -31,10 +31,8 @@ SHELL := bash
|
|||
SEED := $(shell echo $$RANDOM)
|
||||
|
||||
# This is the top-level output directory. Everything we generate goes in
|
||||
# here. Most generated stuff actually goes in $(OUT)/seed-$(SEED), which allows
|
||||
# us to run multiple times without deleting existing results.
|
||||
OUT := out
|
||||
OUT-SEED := $(OUT)/seed-$(SEED)
|
||||
# here.
|
||||
OUT := out
|
||||
|
||||
# Needed for tcl files that are used with Cadence tools.
|
||||
export dv_root := $(realpath ../../../vendor/lowrisc_ip/dv)
|
||||
|
@ -75,20 +73,23 @@ PMP_GRANULARITY := 0
|
|||
|
||||
IBEX_CONFIG := opentitan
|
||||
|
||||
# A version of $(OUT) with a trailing '/'. The point is that this will
|
||||
# never match the name of a phony targets like "sim" (which causes
|
||||
# strange rebuilds otherwise). The call to $(dir ) avoids adding
|
||||
# another trailing slash if $(OUT) had one already.
|
||||
OUT-DIR := $(dir $(OUT)/)
|
||||
# Derived directories from $(OUT), used for stuff that's built once or
|
||||
# stuff that gets run for each seed, respectively. Using OUT-DIR on
|
||||
# the way avoids ugly double slashes if $(OUT) happens to end in a /.
|
||||
OUT-DIR := $(dir $(OUT)/)
|
||||
BUILD-DIR := $(OUT-DIR)build
|
||||
RUN-DIR := $(OUT-DIR)run
|
||||
|
||||
# This expands to '@' if VERBOSE is 0 or not set, and to the empty
|
||||
# string otherwise. Prefix commands with it in order that they only
|
||||
# get printed when VERBOSE.
|
||||
verb = $(if $(filter-out 0,$(VERBOSE)),,@)
|
||||
|
||||
# Like verb, but expands to --verbose if we're in verbose mode (used
|
||||
# for running sub-commands)
|
||||
verb-arg = $(if $(filter-out 0,$(VERBOSE)),--verbose,)
|
||||
# Convert VERBOSE, COV, WAVE and COSIM to "store_true" arguments
|
||||
verb-arg := $(if $(filter-out 0,$(VERBOSE)),--verbose,)
|
||||
cov-arg := $(if $(call equal,$(COV),1),--en_cov,)
|
||||
wave-arg := $(if $(call equal,$(WAVES),1),--en_wave,)
|
||||
cosim-arg := $(if $(call equal,$(COSIM),1),--en_cosim,)
|
||||
|
||||
SHELL=/bin/bash
|
||||
|
||||
|
@ -110,18 +111,11 @@ CSR_OPTS=--csr_yaml=${CSR_FILE} \
|
|||
--isa="${ISA}" \
|
||||
--end_signature_addr=${SIGNATURE_ADDR}
|
||||
|
||||
# To avoid cluttering the output directory with stamp files, we place them in
|
||||
# $(metadata).
|
||||
metadata := $(OUT-SEED)/.metadata
|
||||
|
||||
# This is a list of directories that are automatically generated by some
|
||||
# targets. To ensure the directory has been built, add a order-only dependency
|
||||
# (with the pipe symbol before it) on the directory name and add the directory
|
||||
# to this list.
|
||||
gen-dirs := \
|
||||
$(OUT-DIR) $(OUT-SEED) \
|
||||
$(metadata) $(OUT-DIR)rtl_sim $(OUT-DIR)instr_gen \
|
||||
$(OUT-SEED)/$(ISS)
|
||||
gen-dirs := $(BUILD-DIR)
|
||||
|
||||
$(gen-dirs): %:
|
||||
mkdir -p $@
|
||||
|
@ -193,6 +187,10 @@ tests-and-seeds := \
|
|||
--iterations $(ITERATIONS) \
|
||||
--ibex-config $(IBEX_CONFIG))
|
||||
|
||||
# Define a variable that contains the output directories for all the
|
||||
# test/seed combinations
|
||||
ts-dirs := $(foreach ts,$(tests-and-seeds),$(RUN-DIR)/$(ts)/)
|
||||
|
||||
###############################################################################
|
||||
###############################################################################
|
||||
# Build the Random Instruction Generator
|
||||
|
@ -212,7 +210,7 @@ instr-gen-build-var-deps := SIMULATOR ISA CSR_OPTS \
|
|||
# First, load up the saved variable values from the last time around. If this
|
||||
# fails, it's no problem: we'll assume that the previous run either doesn't
|
||||
# exist or something went wrong.
|
||||
ig-build-vars-path := $(OUT-DIR).instr-gen-build.vars.mk
|
||||
ig-build-vars-path := $(BUILD-DIR)/.instr-gen.vars.mk
|
||||
-include $(ig-build-vars-path)
|
||||
|
||||
# Next, compare the current variables to those we just loaded. This uses the
|
||||
|
@ -237,37 +235,37 @@ riscv-dv-files := $(shell find $(GEN_DIR) -type f)
|
|||
# command exactly once. Wasteful if we're trying to make clean, but much better
|
||||
# than running it for every target otherwise.
|
||||
|
||||
$(OUT-DIR)instr_gen/.compile.stamp: \
|
||||
$(BUILD-DIR)/instr-gen/.compile.stamp: \
|
||||
$(instr-gen-build-vars-prereq) \
|
||||
$(riscv-dv-files) scripts/build-instr-gen.py | $(OUT-DIR)instr_gen
|
||||
$(riscv-dv-files) scripts/build-instr-gen.py | $(BUILD-DIR)
|
||||
$(verb)scripts/build-instr-gen.py \
|
||||
$(verb-arg) \
|
||||
--simulator $(SIMULATOR) \
|
||||
--end-signature-addr $(SIGNATURE_ADDR) \
|
||||
--output $(OUT-DIR)instr_gen \
|
||||
--output $(BUILD-DIR)/instr-gen \
|
||||
--isa $(ISA)
|
||||
$(call dump-vars,$(ig-build-vars-path),gen,$(instr-gen-build-var-deps))
|
||||
@touch $@
|
||||
|
||||
.PHONY: instr_gen_build
|
||||
instr_gen_build: $(OUT-DIR)instr_gen/.compile.stamp
|
||||
instr_gen_build: $(BUILD-DIR)/instr-gen/.compile.stamp
|
||||
|
||||
###############################################################################
|
||||
# Run the random instruction generator
|
||||
#
|
||||
test-asms := $(foreach ts,$(tests-and-seeds),$(OUT-SEED)/instr_gen/$(ts).S)
|
||||
test-asms := $(addsuffix test.S,$(ts-dirs))
|
||||
|
||||
$(test-asms): \
|
||||
$(OUT-SEED)/instr_gen/%.S: \
|
||||
$(OUT-DIR)instr_gen/.compile.stamp \
|
||||
$(RUN-DIR)/%/test.S: \
|
||||
$(BUILD-DIR)/instr-gen/.compile.stamp \
|
||||
$(TESTLIST) \
|
||||
scripts/run-instr-gen.py | $(metadata)
|
||||
scripts/run-instr-gen.py
|
||||
$(verb)scripts/run-instr-gen.py \
|
||||
$(verb-arg) \
|
||||
--simulator $(SIMULATOR) \
|
||||
--end-signature-addr $(SIGNATURE_ADDR) \
|
||||
--output-dir $(@D) \
|
||||
--gen-build-dir $(OUT-DIR)instr_gen \
|
||||
--gen-build-dir $(BUILD-DIR)/instr-gen \
|
||||
--isa $(ISA) \
|
||||
--test-dot-seed $* \
|
||||
--pmp-num-regions $(PMP_REGIONS) \
|
||||
|
@ -287,17 +285,16 @@ instr_gen_run: $(test-asms)
|
|||
# uses the .bin. In the Makefile, we just track the .bin to represent
|
||||
# both.
|
||||
|
||||
test-bins := $(foreach ts,$(tests-and-seeds),$(OUT-SEED)/instr_gen/$(ts).bin)
|
||||
test-bins := $(addsuffix test.bin,$(ts-dirs))
|
||||
|
||||
$(test-bins): \
|
||||
$(OUT-SEED)/instr_gen/%.bin: \
|
||||
$(OUT-SEED)/instr_gen/%.S \
|
||||
scripts/compile-generated-test.py
|
||||
$(RUN-DIR)/%/test.bin: \
|
||||
$(RUN-DIR)/%/test.S scripts/compile-generated-test.py
|
||||
$(verb)scripts/compile-generated-test.py \
|
||||
$(verb-arg) \
|
||||
--input $(RUN-DIR)/$*/test.S \
|
||||
--output $@ \
|
||||
--isa $(ISA) \
|
||||
--input-dir $(OUT-SEED)/instr_gen \
|
||||
--test-dot-seed $*
|
||||
|
||||
.PHONY: instr_gen_compile
|
||||
|
@ -311,16 +308,15 @@ instr_gen_compile: $(test-bins)
|
|||
# other variable that's going to affect things is the actual choice of ISS. We
|
||||
# cheat and include it in the path.
|
||||
|
||||
iss-sim-logs := $(foreach ts,$(tests-and-seeds),$(OUT-SEED)/$(ISS)/$(ts).log)
|
||||
iss-sim-logs := $(addsuffix $(ISS).log,$(ts-dirs))
|
||||
|
||||
$(iss-sim-logs): \
|
||||
$(OUT-SEED)/$(ISS)/%.log: \
|
||||
$(OUT-SEED)/instr_gen/%.bin \
|
||||
$(TESTLIST) scripts/run-iss.py | $(OUT-SEED)/$(ISS)
|
||||
$(RUN-DIR)/%/$(ISS).log: \
|
||||
$(RUN-DIR)/%/test.bin scripts/run-iss.py
|
||||
$(verb)scripts/run-iss.py \
|
||||
$(verb-arg) \
|
||||
--iss=$(ISS) \
|
||||
--input=$(OUT-SEED)/instr_gen/$*.o \
|
||||
--input=$(RUN-DIR)/$*/test.o \
|
||||
--output=$@ \
|
||||
--isa=$(ISA_ISS)
|
||||
|
||||
|
@ -351,53 +347,44 @@ all-verilog = \
|
|||
$(shell find ../.. -name '*.v' -o -name '*.sv' -o -name '*.svh')
|
||||
|
||||
tb-compile-var-deps := SIMULATOR COV WAVES COSIM
|
||||
-include $(OUT-DIR)rtl_sim/.rtl.tb_compile.vars.mk
|
||||
tb-compile-vars-path := $(BUILD-DIR)/.tb.vars.mk
|
||||
-include $(tb-compile-vars-path)
|
||||
tb-compile-vars-prereq = $(call vars-prereq,comp,compiling TB,$(tb-compile-var-deps))
|
||||
|
||||
$(call dump-vars-match,$(tb-compile-var-deps),comp)
|
||||
|
||||
cov-arg := $(if $(call equal,$(COV),1),--en_cov,)
|
||||
wave-arg := $(if $(call equal,$(WAVES),1),--en_wave,)
|
||||
cosim-arg := $(if $(call equal,$(COSIM),1),--en_cosim,)
|
||||
|
||||
$(OUT-DIR)rtl_sim/.rtl.tb_compile.stamp: \
|
||||
$(BUILD-DIR)/tb/.compile.stamp: \
|
||||
$(tb-compile-vars-prereq) $(all-verilog) $(risc-dv-files) \
|
||||
scripts/compile-tb.py yaml/rtl_simulation.yaml \
|
||||
| $(OUT-DIR)rtl_sim
|
||||
| $(BUILD-DIR)
|
||||
$(verb)scripts/compile-tb.py \
|
||||
$(verb-arg) \
|
||||
--ibex-config $(IBEX_CONFIG) \
|
||||
--output=$(OUT-DIR) \
|
||||
--output=$(BUILD-DIR)/tb \
|
||||
--simulator=$(SIMULATOR) \
|
||||
$(cov-arg) $(wave-arg) $(cosim-arg)
|
||||
$(call dump-vars,$(OUT-DIR)rtl_sim/.rtl.tb_compile.vars.mk,comp,$(tb-compile-var-deps))
|
||||
$(call dump-vars,$(tb-compile-vars-path),comp,$(tb-compile-var-deps))
|
||||
@touch $@
|
||||
|
||||
.PHONY: rtl_tb_compile
|
||||
rtl_tb_compile: $(OUT-DIR)rtl_sim/.rtl.tb_compile.stamp
|
||||
rtl_tb_compile: $(BUILD-DIR)/tb/.compile.stamp
|
||||
|
||||
###############################################################################
|
||||
# Run ibex RTL simulation with generated programs
|
||||
|
||||
rtl-sim-dirs := $(addprefix $(OUT-SEED)/rtl_sim/,$(tests-and-seeds))
|
||||
rtl-sim-logs := $(addsuffix /sim.log,$(rtl-sim-dirs))
|
||||
rtl-sim-logs := $(addsuffix rtl.log,$(ts-dirs))
|
||||
|
||||
$(rtl-sim-logs): \
|
||||
$(OUT-SEED)/rtl_sim/%/sim.log: \
|
||||
$(OUT-DIR)rtl_sim/.rtl.tb_compile.stamp \
|
||||
$(OUT-SEED)/instr_gen/%.bin \
|
||||
scripts/run-rtl.py
|
||||
$(RUN-DIR)/%/rtl.log: \
|
||||
$(BUILD-DIR)/tb/.compile.stamp $(RUN-DIR)/%/test.bin scripts/run-rtl.py
|
||||
@echo Running RTL simulation at $@
|
||||
$(verb)mkdir -p $(@D)
|
||||
$(verb)scripts/run-rtl.py \
|
||||
--ibex-config $(IBEX_CONFIG) \
|
||||
--simulator $(SIMULATOR) \
|
||||
$(cov-arg) $(wave-arg) \
|
||||
--signature-addr $(SIGNATURE_ADDR) \
|
||||
--test-dot-seed $* \
|
||||
--binary $(OUT-SEED)/instr_gen/$*.bin \
|
||||
--rtl-sim-dir $(OUT-DIR)rtl_sim \
|
||||
--out-dir $(OUT-SEED)/rtl_sim/$*
|
||||
--binary $(RUN-DIR)/$*/test.bin \
|
||||
--rtl-sim-dir $(BUILD-DIR)/tb \
|
||||
--out-dir $(@D)
|
||||
|
||||
.PHONY: rtl_sim_run
|
||||
rtl_sim_run: $(rtl-sim-logs)
|
||||
|
@ -407,70 +394,68 @@ rtl_sim_run: $(rtl-sim-logs)
|
|||
#
|
||||
# For a given TEST/SEED pair, the ISS and RTL logs appear at:
|
||||
#
|
||||
# $(OUT-SEED)/$(ISS)/$(TEST).$(SEED).log
|
||||
# $(OUT-SEED)/rtl_sim/$(TEST).$(SEED)/trace_core_00000000.log
|
||||
# $(RUN-DIR)/$(TEST).$(SEED)/$(ISS).log
|
||||
# $(RUN-DIR)/$(TEST).$(SEED)/trace_core_00000000.log
|
||||
#
|
||||
# The comparison script compares these and writes to a result file at
|
||||
#
|
||||
# $(OUT-SEED)/rtl_sim/$(TEST).$(SEED)/test-result.yml
|
||||
#
|
||||
# with PASSED or FAILED, depending.
|
||||
# $(RUN-DIR)/$(TEST).$(SEED)/test-result.yml
|
||||
|
||||
comp-results := $(addsuffix /test-result.yml,$(rtl-sim-dirs))
|
||||
comp-results := $(addsuffix test-result.yml,$(ts-dirs))
|
||||
|
||||
$(comp-results): \
|
||||
%/test-result.yml: \
|
||||
$(iss-sim-logs) \
|
||||
$(rtl-sim-logs) compare.py
|
||||
$(RUN-DIR)/%/test-result.yml: \
|
||||
$(RUN-DIR)/%/$(ISS).log $(RUN-DIR)/%/rtl.log compare.py
|
||||
@echo Comparing traces for $*
|
||||
$(verb)./compare.py \
|
||||
--instr-gen-bin-dir $(OUT-SEED)/instr_gen/asm_test \
|
||||
--iss $(ISS) \
|
||||
--iss-log-dir $(OUT-SEED)/$(ISS) \
|
||||
--start-seed $(SEED) \
|
||||
--test-dot-seed "$(notdir $*)" \
|
||||
--output $@ \
|
||||
--rtl-log-dir $(OUT-SEED)/rtl_sim/$(notdir $*)
|
||||
$(verb)./compare.py \
|
||||
--test-dot-seed $* \
|
||||
--iss $(ISS) \
|
||||
--iss-trace $(@D)/$(ISS).log \
|
||||
--rtl-log $(@D)/rtl.log \
|
||||
--rtl-trace $(@D)/trace_core_00000000.log \
|
||||
--binary $(@D)/test.o \
|
||||
--compare-log $(@D)/compare.log \
|
||||
--output $@
|
||||
|
||||
$(OUT-SEED)/regr.log: collect_results.py $(comp-results)
|
||||
$(RUN-DIR)/regr.log: collect_results.py $(comp-results)
|
||||
@echo "Collecting up results (report at $@)"
|
||||
$(verb)./collect_results.py -o $(@D) $(comp-results)
|
||||
|
||||
.PHONY: post_compare
|
||||
post_compare: $(OUT-SEED)/regr.log
|
||||
post_compare: $(RUN-DIR)/regr.log
|
||||
|
||||
###############################################################################
|
||||
# Generate RISCV-DV functional coverage
|
||||
# TODO(udi) - add B extension
|
||||
$(metadata)/.cov.gen_fcov.stamp: $(rtl-sim-logs)
|
||||
$(RUN-DIR)/fcov/.fcov.stamp: $(comp-results)
|
||||
$(verb)python3 ${GEN_DIR}/cov.py \
|
||||
--core ibex \
|
||||
--dir ${OUT-SEED}/rtl_sim \
|
||||
-o ${OUT-SEED}/fcov \
|
||||
--simulator "${SIMULATOR}" \
|
||||
--opts "--gen_timeout 1000" \
|
||||
--isa rv32imcb \
|
||||
--custom_target riscv_dv_extension
|
||||
--core ibex \
|
||||
--dir $(RUN-DIR) \
|
||||
-o $(RUN-DIR)/fcov \
|
||||
--simulator $(SIMULATOR) \
|
||||
--opts "--gen_timeout 1000" \
|
||||
--isa rv32imcb \
|
||||
--custom_target riscv_dv_extension
|
||||
@ # Bookkeeping
|
||||
@touch $@
|
||||
|
||||
.PHONY: riscv_dv_fcov
|
||||
riscv_dv_fcov: $(metadata)/.cov.gen_fcov.stamp
|
||||
riscv_dv_fcov: $(RUN-DIR)/fcov/.fcov.stamp
|
||||
|
||||
###############################################################################
|
||||
# Merge all output coverage directories into the <out>/rtl_sim directory
|
||||
#
|
||||
# Any coverage databases generated from the riscv_dv_fcov target will be merged
|
||||
# as well.
|
||||
$(metadata)/.cov.merge.stamp: \
|
||||
$(metadata)/.cov.gen_fcov.stamp \
|
||||
$(RUN-DIR)/coverage/.merge.stamp: \
|
||||
$(RUN-DIR)/fcov/.fcov.stamp \
|
||||
scripts/merge-cov.py
|
||||
$(verb)scripts/merge-cov.py \
|
||||
$(verb-arg) \
|
||||
--working-dir=$(OUT-SEED) \
|
||||
--working-dir=$(RUN-DIR) \
|
||||
--simulator=$(SIMULATOR)
|
||||
@ # Bookkeeping
|
||||
@touch $@
|
||||
|
||||
.PHONY: merge_cov
|
||||
merge_cov: $(metadata)/.cov.merge.stamp
|
||||
merge_cov: $(RUN-DIR)/coverage/.merge.stamp
|
||||
|
|
|
@ -42,21 +42,28 @@ _CompareResult = Tuple[bool, Optional[str], Dict[str, str]]
|
|||
|
||||
|
||||
def compare_test_run(test: TestEntry,
|
||||
idx: int,
|
||||
seed: int,
|
||||
rtl_log_dir: str,
|
||||
iss: str,
|
||||
iss_log_dir: str,
|
||||
instr_gen_bin_dir: str) -> TestRunResult:
|
||||
rtl_log: str,
|
||||
rtl_trace: str,
|
||||
iss_trace: str,
|
||||
binary: str,
|
||||
compare_log: str) -> TestRunResult:
|
||||
'''Compare results for a single run of a single test
|
||||
|
||||
Here, test is a dictionary describing the test (read from the testlist YAML
|
||||
file). idx is the iteration index and seed is the corresponding seed. iss
|
||||
is the chosen instruction set simulator (currently supported: spike and
|
||||
ovpsim).
|
||||
file). seed is the seed that was run. iss is the chosen instruction set
|
||||
simulator (currently supported: spike and ovpsim).
|
||||
|
||||
rtl_log_dir is the directory containing log output from the RTL simulation.
|
||||
iss_log_dir is the directory that contains logs for ISS runs.
|
||||
rtl_log is the log file generated by the RTL simulation. rtl_trace and
|
||||
iss_trace are the traces of instructions executed generated by the RTL
|
||||
simulation and ISS, respectively. This function generates CSV files at
|
||||
rtl_trace + '.csv' and iss_trace + '.csv'.
|
||||
|
||||
binary is the path to an ELF file with the code that was executed.
|
||||
|
||||
compare_log is the path where we should write a log describing the
|
||||
comparison operation.
|
||||
|
||||
Returns a _CompareResult with a pass/fail flag, together with some
|
||||
information about the run (to be written to the log file).
|
||||
|
@ -64,20 +71,15 @@ def compare_test_run(test: TestEntry,
|
|||
'''
|
||||
test_name = test['test']
|
||||
assert isinstance(test_name, str)
|
||||
uvm_log = os.path.join(rtl_log_dir, 'sim.log')
|
||||
elf = os.path.join(instr_gen_bin_dir, '{}_{}.o'.format(test_name, idx))
|
||||
|
||||
rtl_trace = os.path.join(rtl_log_dir, 'trace_core_00000000.log')
|
||||
|
||||
kv_data = {
|
||||
'name': test_name,
|
||||
'idx': idx,
|
||||
'seed': seed,
|
||||
'binary': elf,
|
||||
'uvm_log': uvm_log,
|
||||
'binary': binary,
|
||||
'uvm_log': rtl_log,
|
||||
'rtl_trace': rtl_trace,
|
||||
'rtl_trace_csv': None,
|
||||
'iss_trace': None,
|
||||
'iss_trace': iss_trace,
|
||||
'iss_trace_csv': None,
|
||||
'comparison_log': None,
|
||||
'passed': False,
|
||||
|
@ -87,7 +89,7 @@ def compare_test_run(test: TestEntry,
|
|||
# Have a look at the UVM log. Report a failure if an issue is seen in the
|
||||
# log.
|
||||
try:
|
||||
uvm_pass, uvm_log_lines = check_ibex_uvm_log(uvm_log)
|
||||
uvm_pass, uvm_log_lines = check_ibex_uvm_log(rtl_log)
|
||||
except IOError as e:
|
||||
kv_data['failure_message'] = str(e)
|
||||
kv_data['failure_message'] += \
|
||||
|
@ -99,7 +101,7 @@ def compare_test_run(test: TestEntry,
|
|||
kv_data['failure_message'] += '\n[FAILED]: sim error seen'
|
||||
return TestRunResult(**kv_data)
|
||||
|
||||
rtl_trace_csv = os.path.join(rtl_log_dir, 'trace_core_00000000.csv')
|
||||
rtl_trace_csv = rtl_trace + '.csv'
|
||||
|
||||
kv_data['rtl_trace_csv'] = rtl_trace_csv
|
||||
try:
|
||||
|
@ -119,24 +121,22 @@ def compare_test_run(test: TestEntry,
|
|||
kv_data['passed'] = True
|
||||
return TestRunResult(**kv_data)
|
||||
|
||||
# There were no UVM errors. Process the log file from the ISS.
|
||||
iss_log = os.path.join(iss_log_dir, '{}.{}.log'.format(test_name, seed))
|
||||
iss_csv = os.path.join(iss_log_dir, '{}.{}.csv'.format(test_name, seed))
|
||||
|
||||
kv_data['iss_trace'] = iss_log
|
||||
kv_data['iss_trace_csv'] = iss_csv
|
||||
# There were no UVM errors. Process the log file from the ISS. Note that
|
||||
# the filename is a bit odd-looking. This is silly, but it ensures that
|
||||
# riscv-dv's cov.py script won't pick it up for architectural coverage.
|
||||
iss_trace_csv = iss_trace + '-csv'
|
||||
kv_data['iss_trace_csv'] = iss_trace_csv
|
||||
try:
|
||||
if iss == "spike":
|
||||
process_spike_sim_log(iss_log, iss_csv)
|
||||
process_spike_sim_log(iss_trace, iss_trace_csv)
|
||||
else:
|
||||
assert iss == 'ovpsim' # (should be checked by argparse)
|
||||
process_ovpsim_sim_log(iss_log, iss_csv)
|
||||
process_ovpsim_sim_log(iss_trace, iss_trace_csv)
|
||||
except (OSError, RuntimeError) as e:
|
||||
kv_data['failure_message'] = \
|
||||
'[FAILED]: Log processing failed: {}'.format(e)
|
||||
return TestRunResult(**kv_data)
|
||||
|
||||
compare_log = os.path.join(rtl_log_dir, 'compare.log')
|
||||
kv_data['comparison_log'] = compare_log
|
||||
|
||||
# Delete any existing file at compare_log (the compare_trace_csv function
|
||||
|
@ -147,7 +147,8 @@ def compare_test_run(test: TestEntry,
|
|||
pass
|
||||
|
||||
compare_result = \
|
||||
compare_trace_csv(rtl_trace_csv, iss_csv, "ibex", iss, compare_log,
|
||||
compare_trace_csv(rtl_trace_csv, iss_trace_csv, "ibex",
|
||||
iss, compare_log,
|
||||
**test.get('compare_opts', {}))
|
||||
|
||||
try:
|
||||
|
@ -160,15 +161,15 @@ def compare_test_run(test: TestEntry,
|
|||
return TestRunResult(**kv_data)
|
||||
|
||||
# Rather oddly, compare_result is a string. The comparison passed if it
|
||||
# starts with '[PASSED]' and failed otherwise.
|
||||
# starts with '[PASSED]: ' and failed otherwise.
|
||||
compare_passed = compare_result.startswith('[PASSED]: ')
|
||||
kv_data['passed'] = compare_passed
|
||||
if not compare_passed:
|
||||
assert compare_result.startswith('[FAILED]: ')
|
||||
kv_data['failure_message'] = ('RTL / ISS trace comparison failed\n' +
|
||||
compare_log_contents)
|
||||
return TestRunResult(**kv_data)
|
||||
|
||||
kv_data['passed'] = True
|
||||
return TestRunResult(**kv_data)
|
||||
|
||||
|
||||
|
@ -212,32 +213,27 @@ def on_result(result: TestRunResult, output: TextIO) -> None:
|
|||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('--instr-gen-bin-dir', required=True)
|
||||
parser.add_argument('--iss', required=True, choices=['spike', 'ovpsim'])
|
||||
parser.add_argument('--iss-log-dir', required=True)
|
||||
parser.add_argument('--start-seed', type=int, required=True)
|
||||
parser.add_argument('--test-dot-seed',
|
||||
type=read_test_dot_seed,
|
||||
required=True)
|
||||
parser.add_argument('--rtl-log-dir', required=True)
|
||||
parser.add_argument('--iss', required=True, choices=['spike', 'ovpsim'])
|
||||
parser.add_argument('--iss-trace', required=True)
|
||||
parser.add_argument('--rtl-log', required=True)
|
||||
parser.add_argument('--rtl-trace', required=True)
|
||||
parser.add_argument('--binary', required=True)
|
||||
parser.add_argument('--compare-log', required=True)
|
||||
parser.add_argument('--output', required=True)
|
||||
|
||||
args = parser.parse_args()
|
||||
if args.start_seed < 0:
|
||||
raise RuntimeError('Invalid start seed: {}'.format(args.start_seed))
|
||||
|
||||
testname, seed = args.test_dot_seed
|
||||
if seed < args.start_seed:
|
||||
raise RuntimeError('Start seed is greater than test seed '
|
||||
f'({args.start_seed} > {seed}).')
|
||||
|
||||
iteration = seed - args.start_seed
|
||||
|
||||
entry = get_test_entry(testname)
|
||||
|
||||
result = compare_test_run(entry, iteration, seed,
|
||||
args.rtl_log_dir, args.iss, args.iss_log_dir,
|
||||
args.instr_gen_bin_dir)
|
||||
result = compare_test_run(entry, seed, args.iss,
|
||||
args.rtl_log, args.rtl_trace, args.iss_trace,
|
||||
args.binary, args.compare_log)
|
||||
|
||||
with open(args.output, 'w', encoding='UTF-8') as outfile:
|
||||
on_result(result, outfile)
|
||||
|
||||
|
|
|
@ -16,10 +16,10 @@ from scripts_lib import read_test_dot_seed, start_riscv_dv_run_cmd, run_one
|
|||
def main() -> int:
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('--verbose', action='store_true')
|
||||
parser.add_argument('--input', required=True)
|
||||
parser.add_argument('--output', required=True)
|
||||
parser.add_argument('--isa', required=True)
|
||||
|
||||
parser.add_argument('--input-dir', required=True)
|
||||
parser.add_argument('--test-dot-seed',
|
||||
type=read_test_dot_seed, required=True)
|
||||
|
||||
|
@ -31,13 +31,10 @@ def main() -> int:
|
|||
raise RuntimeError("Output argument must end with .bin: "
|
||||
f"got {args.output!r}")
|
||||
out_base = args.output[:-4]
|
||||
out_riscv_dv_path = out_base + '.riscv-dv.log'
|
||||
out_riscv_dv_path = os.path.join(os.path.dirname(args.output),
|
||||
'compile.riscv-dv.log')
|
||||
out_obj_path = out_base + '.o'
|
||||
|
||||
src_file = os.path.join(args.input_dir, f'{testname}.{seed}.S')
|
||||
if not os.path.exists(src_file):
|
||||
raise RuntimeError(f'No such input file: {src_file!r}.')
|
||||
|
||||
# Run riscv-dv to get a list of commands that it would run to try to
|
||||
# compile and convert the files in question. These will need some massaging
|
||||
# to match our paths, but we can't generate the commands by hand because
|
||||
|
@ -72,7 +69,7 @@ def main() -> int:
|
|||
# our call to riscv-dv, which should let us find all the things that matter
|
||||
# easily.
|
||||
rewrites = [
|
||||
(f"{placeholder}/asm_test/{testname}_0.S", src_file),
|
||||
(f"{placeholder}/asm_test/{testname}_0.S", args.input),
|
||||
(f"{placeholder}/asm_test/{testname}_0.o", out_obj_path),
|
||||
(f"{placeholder}/asm_test/{testname}_0.bin", args.output)
|
||||
]
|
||||
|
|
|
@ -33,8 +33,7 @@ def main() -> int:
|
|||
|
||||
core_ibex = os.path.normpath(os.path.join(THIS_DIR, '..'))
|
||||
|
||||
output_dir = os.path.join(args.output, 'rtl_sim')
|
||||
os.makedirs(output_dir, exist_ok=True)
|
||||
os.makedirs(args.output, exist_ok=True)
|
||||
|
||||
enables = {
|
||||
'cov_opts': args.en_cov,
|
||||
|
@ -47,7 +46,7 @@ def main() -> int:
|
|||
cmd = subst_vars(pre_cmd,
|
||||
{
|
||||
'core_ibex': core_ibex,
|
||||
'out': output_dir,
|
||||
'out': args.output,
|
||||
'cmp_opts': get_compile_opts(args.ibex_config,
|
||||
args.simulator)
|
||||
})
|
||||
|
|
|
@ -50,15 +50,13 @@ def main() -> int:
|
|||
sim_opts_str = ' '.join('+{}={}'.format(k, v)
|
||||
for k, v in sim_opts_dict.items())
|
||||
|
||||
output_pfx = os.path.join(args.output_dir, f'{testname}.{seed}')
|
||||
|
||||
riscv_dv_log = output_pfx + '.riscv-dv.log'
|
||||
gen_log = output_pfx + '.gen.log'
|
||||
gen_asm = output_pfx + '.S'
|
||||
|
||||
# Ensure that the output directory actually exists
|
||||
os.makedirs(args.output_dir, exist_ok=True)
|
||||
|
||||
riscv_dv_log = os.path.join(args.output_dir, 'gen.riscv-dv.log')
|
||||
gen_log = os.path.join(args.output_dir, 'gen.log')
|
||||
gen_asm = os.path.join(args.output_dir, 'test.S')
|
||||
|
||||
with tempfile.TemporaryDirectory() as td:
|
||||
orig_list = os.path.join(td, 'cmds.list')
|
||||
|
||||
|
|
|
@ -97,7 +97,7 @@ def main() -> int:
|
|||
# so). Note that we don't capture the success or failure of the subprocess:
|
||||
# if something goes horribly wrong, we assume we won't have a matching
|
||||
# trace.
|
||||
sim_log = os.path.join(args.out_dir, 'sim.log')
|
||||
sim_log = os.path.join(args.out_dir, 'rtl.log')
|
||||
os.makedirs(args.out_dir, exist_ok=True)
|
||||
with open(sim_log, 'wb') as sim_fd:
|
||||
subprocess.run(test_cmd, shell=True, stdout=sim_fd, stderr=sim_fd)
|
||||
|
|
|
@ -8,7 +8,6 @@ import collections
|
|||
# None.
|
||||
test_run_result_fields = [
|
||||
'name', # Name of test
|
||||
'idx', # Index of test
|
||||
'seed', # Seed of test
|
||||
'binary', # Path to test binary
|
||||
'uvm_log', # Path to UVM DV simulation log
|
||||
|
@ -28,7 +27,6 @@ TestRunResult = collections.namedtuple('TestRunResult', test_run_result_fields)
|
|||
|
||||
def check_test_run_result(trr: TestRunResult):
|
||||
assert (trr.name is not None and isinstance(trr.name, str))
|
||||
assert (trr.idx is not None and isinstance(trr.idx, int))
|
||||
assert (trr.seed is not None and isinstance(trr.seed, int))
|
||||
assert (trr.binary is None or isinstance(trr.binary, str))
|
||||
assert (trr.uvm_log is None or isinstance(trr.uvm_log, str))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue