summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlejandro Soto <alejandro@34project.org>2023-09-25 23:46:34 -0600
committerAlejandro Soto <alejandro@34project.org>2023-09-25 23:46:34 -0600
commit1db38c7cccd74af09109a5161edc95233e75fc74 (patch)
tree8c2e776635286974a630fee28eebc2afcbcc1627
parent9fa82e6621df63335199b7abc0b4ca8acd2f3e03 (diff)
tb: implement coverage reports
Diffstat (limited to '')
-rw-r--r--.gitignore1
-rw-r--r--Makefile33
-rw-r--r--nix/flake.nix1
-rwxr-xr-xsim/sim.py18
-rw-r--r--tb/top/conspiracion.cpp28
5 files changed, 59 insertions, 22 deletions
diff --git a/.gitignore b/.gitignore
index 4b52e55..353ae87 100644
--- a/.gitignore
+++ b/.gitignore
@@ -34,6 +34,7 @@ __pycache__
hps_sdram_p0_summary.csv
vcd/
+cov/
obj/
.qsys_edit/
platform/
diff --git a/Makefile b/Makefile
index e84867a..a931d93 100644
--- a/Makefile
+++ b/Makefile
@@ -6,16 +6,24 @@ TB_DIR := tb
SIM_DIR := sim
TB_SIM_DIR := $(TB_DIR)/sim
SIM_OBJ_DIR := $(OBJ_DIR)/$(TOP)/sim
-VERILATOR := verilator
+VERILATOR ?= verilator
+GENHTML ?= genhtml
CROSS_CC := $(CROSS_COMPILE)gcc
CROSS_OBJCOPY := $(CROSS_COMPILE)objcopy
CROSS_CFLAGS := -O3 -Wall -Wextra -Werror
CROSS_LDFLAGS :=
+VFLAGS ?= \
+ --x-assign unique --x-initial unique \
+ --threads $(shell nproc) \
+ $(if $(DISABLE_COV),,--coverage)
+
RTL_FILES = $(shell find $(RTL_DIR)/ ! -path '$(RTL_DIR)/top/*' -type f -name '*.sv')
RTL_FILES += $(shell find $(TB_DIR)/ ! -path '$(TB_DIR)/top/*' -type f -name '*.sv')
TB_FILES = $(shell find $(TB_DIR)/ ! -path '$(TB_DIR)/top/*' -type f -name '*.cpp')
+SIMS := $(patsubst $(TB_SIM_DIR)/%.py,%,$(wildcard $(TB_SIM_DIR)/*.py))
+
all: sim
clean:
@@ -29,14 +37,29 @@ trace/%: exe/% $(VCD_DIR)/%
$(VCD_DIR)/%:
mkdir -p $@
-sim: $(patsubst $(TB_SIM_DIR)/%.py,sim/%,$(wildcard $(TB_SIM_DIR)/*.py))
+sim: $(addprefix sim/,$(SIMS))
sim/%: $(SIM_DIR)/sim.py $(TB_SIM_DIR)/%.py exe/$(TOP) $(SIM_OBJ_DIR)/%.bin
- @$< $(TB_SIM_DIR)/$*.py $(OBJ_DIR)/$(TOP)/V$(TOP) $(SIM_OBJ_DIR)/$*.bin
+ @$< $(TB_SIM_DIR)/$*.py $(OBJ_DIR)/$(TOP)/V$(TOP) \
+ $(SIM_OBJ_DIR)/$*.bin \
+ $(if $(DISABLE_COV),,$(SIM_OBJ_DIR)/$*.cov)
vmlaunch: $(SIM_DIR)/sim.py $(SIM_DIR)/gdbstub.py exe/$(TOP)
@$< $(SIM_DIR)/gdbstub.py $(OBJ_DIR)/$(TOP)/V$(TOP) u-boot/build/taller/u-boot-dtb.bin
+ifndef DISABLE_COV
+cov: $(OBJ_DIR)/$(TOP)/cov.info
+ @rm -rf $@
+ $(GENHTML) $< --output-dir=$@
+
+cov/%: $(SIM_OBJ_DIR)/%.cov
+
+$(SIM_OBJ_DIR)/%.cov: sim/%
+
+$(OBJ_DIR)/$(TOP)/cov.info: $(patsubst %,$(SIM_OBJ_DIR)/%.cov,$(SIMS))
+ $(VERILATOR)_coverage -write-info $@ $(SIM_OBJ_DIR)/*.cov
+endif
+
$(SIM_OBJ_DIR)/%.bin: $(SIM_OBJ_DIR)/%
$(CROSS_OBJCOPY) -O binary --only-section=._img $< $@
@@ -60,7 +83,7 @@ exe: exe/$(TOP)
exe/%: $(OBJ_DIR)/%/V%.mk
$(MAKE) -C $(OBJ_DIR)/$* -f V$*.mk
-.PRECIOUS: $(SIM_OBJ_DIR)/% $(SIM_OBJ_DIR)/%.o $(SIM_OBJ_DIR)/%.bin
+.PRECIOUS: $(SIM_OBJ_DIR)/% $(SIM_OBJ_DIR)/%.o $(SIM_OBJ_DIR)/%.bin $(SIM_OBJ_DIR)/%.cov
.SECONDEXPANSION:
$(OBJ_DIR)/%.mk: \
@@ -74,4 +97,4 @@ $(OBJ_DIR)/%.mk: \
$(VERILATOR) \
-O3 --cc --exe --trace -y $(RTL_DIR) --Mdir $(dir $@) \
--top $(word 1,$(subst /, ,$*)) $(patsubst tb/%,../tb/%,$^) \
- --x-assign unique --x-initial unique --threads $(shell nproc)
+ $(VFLAGS)
diff --git a/nix/flake.nix b/nix/flake.nix
index 5de1f31..d7c7125 100644
--- a/nix/flake.nix
+++ b/nix/flake.nix
@@ -114,6 +114,7 @@
gdb
gnumake
gtkwave
+ lcov
pkg-config
(python3.withPackages (py: [ py.numpy py.pillow py.matplotlib ]))
(quartus-prime-lite.override { supportedDevices = [ "Cyclone V" ]; })
diff --git a/sim/sim.py b/sim/sim.py
index 5f64d43..e1dbd41 100755
--- a/sim/sim.py
+++ b/sim/sim.py
@@ -1,8 +1,19 @@
#!/usr/bin/env python3
-import importlib.util, io, os, pathlib, random, selectors, signal, socket, subprocess, sys
+import argparse, importlib.util, io, os, pathlib, random, selectors, signal, socket, subprocess, sys
+
+parser = argparse.ArgumentParser()
+parser.add_argument('module_path')
+parser.add_argument('verilated')
+parser.add_argument('image')
+parser.add_argument('coverage_out', nargs='?')
+args = parser.parse_args()
+
+module_path = args.module_path
+verilated = args.verilated
+image = args.image
+coverage_out = args.coverage_out
-module_path, verilated, image = sys.argv[1:]
test_name = pathlib.Path(module_path).stem
module = None
@@ -390,6 +401,9 @@ exec_args.extend(['--control-fd', str(target_fd)])
init_regs = None
exec_args.append(image)
+if coverage_out:
+ exec_args.append(coverage_out)
+
exec_args.append(f'+verilator+seed+{seed}')
if not os.getenv('SIM_PULLX', 0):
exec_args.append('+verilator+rand+reset+2')
diff --git a/tb/top/conspiracion.cpp b/tb/top/conspiracion.cpp
index 4f0fb3d..49c05bf 100644
--- a/tb/top/conspiracion.cpp
+++ b/tb/top/conspiracion.cpp
@@ -261,6 +261,11 @@ int main(int argc, char **argv)
parser, "image", "Executable image to run", args::Options::Required
);
+ args::Positional<std::string> coverage_out
+ (
+ parser, "coverage-out", "Coverage output file"
+ );
+
try
{
parser.ParseCLI(argc, argv);
@@ -757,32 +762,25 @@ int main(int argc, char **argv)
core.fetch->explicit_branch__VforceEn = 0;
}
- if(!no_tty)
- {
+ if (!no_tty)
ttyJ0.release();
- }
- if(enable_trace)
- {
+ if (enable_trace)
trace.close();
- }
- if(dump_regs)
- {
+ if (dump_regs)
do_reg_dump();
- }
const auto &dumps = *dump_mem;
- if(!dumps.empty())
- {
+ if (!dumps.empty())
do_mem_dump(dumps.data(), dumps.size());
- }
top.final();
- if(ctrl != stdout)
- {
+ if (ctrl != stdout)
std::fclose(ctrl);
- }
+
+ if (coverage_out)
+ Verilated::threadContextp()->coveragep()->write(coverage_out->c_str());
return failed ? EXIT_FAILURE : EXIT_SUCCESS;
}