Cache the classpath between SBT runs (#1390)

The build system includes 3 targets caching the classpath containing compiled jars to be used by subsequent java invocations, fully bypassing the slow sbt setup on repeated invocations to SBT.
This commit is contained in:
Nandor Licker 2023-01-20 00:12:49 +02:00 committed by GitHub
parent 6652b02f56
commit 43b09980e5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 217 additions and 126 deletions

View File

@ -49,6 +49,7 @@ PLATFORM ?= f1
include $(TARGET_PROJECT_MAKEFRAG)/config.mk
include make/config.mk
include make/scala-build.mk
include $(TARGET_PROJECT_MAKEFRAG)/build.mk
include make/goldengate.mk

View File

@ -63,22 +63,7 @@ include $(base_dir)/common.mk
endif
ifdef FIRESIM_STANDALONE
firesim_sbt_project := firesim
FIRESIM_SBT_PROJECT := firesim
else
firesim_sbt_project := {file:${firesim_base_dir}/}firesim
FIRESIM_SBT_PROJECT := {file:${firesim_base_dir}/}firesim
endif
# Phony targets for launching the sbt shell and running scalatests
SBT_COMMAND ?= shell
SBT_NON_THIN ?= $(subst $(SBT_CLIENT_FLAG),,$(SBT))
.PHONY: sbt
sbt:
cd $(base_dir) && $(SBT_NON_THIN) ";project $(firesim_sbt_project); $(SBT_COMMAND)"
.PHONY: test
test:
cd $(base_dir) && $(SBT_NON_THIN) ";project $(firesim_sbt_project); test"
.PHONY: testOnly
testOnly:
cd $(base_dir) && $(SBT_NON_THIN) ";project $(firesim_sbt_project); testOnly $(SCALA_TEST)"

View File

@ -3,6 +3,7 @@
################################################################################
# Target-Specific Configuration
################################################################################
# Root name for generated binaries
DESIGN ?=
@ -37,10 +38,21 @@ long_name := $(DESIGN_PACKAGE).$(DESIGN).$(TARGET_CONFIG)
# The directory into which generated verilog and headers will be dumped
# RTL simulations will also be built here
GENERATED_DIR ?= $(firesim_base_dir)/generated-src/$(PLATFORM)/$(name_tuple)
BUILD_DIR := $(firesim_base_dir)/generated-src
GENERATED_DIR ?= $(BUILD_DIR)/$(PLATFORM)/$(name_tuple)
# Results from RTL simulations live here
OUTPUT_DIR ?= $(firesim_base_dir)/output/$(PLATFORM)/$(name_tuple)
# The target's FIRRTL and associated anotations; inputs to Golden Gate
FIRRTL_FILE := $(GENERATED_DIR)/$(long_name).fir
ANNO_FILE := $(GENERATED_DIR)/$(long_name).anno.json
################################################################################
# Set up a fully-qualified classpath for the target.
################################################################################
# Rocket Chip stage requires a fully qualified classname for each fragment, whereas Chipyard's does not.
# This retains a consistent TARGET_CONFIG naming convention across the different target projects.
subst_prefix :=,$(TARGET_CONFIG_PACKAGE).
TARGET_CONFIG_QUALIFIED := $(TARGET_CONFIG_PACKAGE).$(subst _,$(subst_prefix),$(TARGET_CONFIG))

View File

@ -26,8 +26,8 @@ $(simulator_verilog) $(header) $(fame_annos): $(simulator_verilog).intermediate
# Disable FIRRTL 1.4 deduplication because it creates multiple failures
# Run the 1.3 version instead (checked-in). If dedup must be completely disabled,
# pass --no-legacy-dedup as well
$(simulator_verilog).intermediate: $(FIRRTL_FILE) $(ANNO_FILE) $(SCALA_BUILDTOOL_DEPS)
$(call run_scala_main,$(firesim_sbt_project),midas.stage.GoldenGateMain,\
$(simulator_verilog).intermediate: $(FIRRTL_FILE) $(ANNO_FILE) $(FIRESIM_MAIN_CP)
java -cp $$(cat $(FIRESIM_MAIN_CP)) midas.stage.GoldenGateMain \
-i $(FIRRTL_FILE) \
-td $(GENERATED_DIR) \
-faf $(ANNO_FILE) \
@ -35,7 +35,7 @@ $(simulator_verilog).intermediate: $(FIRRTL_FILE) $(ANNO_FILE) $(SCALA_BUILDTOOL
-ggcs $(PLATFORM_CONFIG) \
--output-filename-base $(BASE_FILE_NAME) \
--no-dedup \
)
grep -sh ^ $(GENERATED_DIR)/firrtl_black_box_resource_files.f | \
xargs cat >> $(simulator_verilog) # Append blackboxes to FPGA wrapper, if any

141
sim/make/scala-build.mk Normal file
View File

@ -0,0 +1,141 @@
# See LICENSE for license details.
################################################################################
#
# This file defines rules to build the Scala components of FireSim.
#
# The file provides 3 targets caching the classpath containing compiled jars
# to be used by subsequent java invocations, fully bypassing the slow sbt setup
# on repeated invocations to SBT.
#
# The 3 cached classpaths are:
#
# FIRESIM_MAIN_CP: contains the GoldenGate entry point.
#
# FIRESIM_TEST_CP: contains generators and configurations for most tests.
#
# TARGET_CP: contains the entry point of the target Chisel generator.
# It is built out of the TARGET_SBT_PROJECT. TARGET_SOURCE_DIRS
# must enumerate all the directories containing the scala sources
# to compile this target.
#
# Any rule containing a Java invocation must add as a dependency one of these
# classpaths. Corresponding SBT invocations still work (substitute the classpath
# with the correct project).
#
################################################################################
################################################################################
# Helper to run SBT in the project.
################################################################################
SBT_COMMAND ?= shell
SBT_NON_THIN ?= $(subst $(SBT_CLIENT_FLAG),,$(SBT))
.PHONY: sbt
sbt:
cd $(base_dir) && $(SBT_NON_THIN) ";project $(firesim_sbt_project); $(SBT_COMMAND)"
################################################################################
# Target Configuration
################################################################################
# Target project containing the generator of the design.
TARGET_SBT_PROJECT ?= $(firesim_sbt_project)
# If the target project is not the implicit FireSim one, this definition must
# enumerate all directories containing the sources of the generator.
TARGET_SOURCE_DIRS ?=
################################################################################
# Build jars using SBT assembly and cache them.
################################################################################
# Helper to build a classpath for a project. This first builds the project
# while showing error messages, then it runs sbt again with errors disabled to
# capture the classpath from the output (errors are dumped to stdout otherwise).
define build_classpath
$(SBT_NON_THIN) \
--error \
"set showSuccess := false; project $(1); compile; package; export $(2):fullClasspath" \
| head -n 1 | tr -d '\n' > $@
endef
# Helpers to identify all source files of the FireSim project.
find_sources_in_dir = $(shell \
find -L $(1)/ -name target -prune -o -iname "[!.]*.scala" -print \
2> /dev/null \
| grep -E '$(2)' \
)
firesim_source_dirs = \
$(addprefix $(firesim_base_dir)/,\
. \
midas \
midas/targetutils \
firesim-lib \
rocket-chip/src \
rocket-chip/api-config-chipsalliance \
)
firesim_main_srcs = $(foreach dir, $(firesim_source_dirs), \
$(call find_sources_in_dir, $(dir), 'src/main/scala'))
firesim_test_srcs = $(foreach dir, $(firesim_source_dirs), \
$(call find_sources_in_dir, $(dir), 'src/test/scala'))
# Dummy rule building a token file which compiles all scala sources of the main
# FireSim project. This ensures that SBT is invoked once in parallel builds.
$(BUILD_DIR)/firesim.build: $(SCALA_BUILDTOOL_DEPS) $(firesim_main_srcs) $(firesim_test_srcs)
@mkdir -p $(@D)
$(SBT_NON_THIN) "set showSuccess := false; project $(1); compile; package"
@touch $@
FIRESIM_MAIN_CP := $(BUILD_DIR)/firesim-main.classpath
$(FIRESIM_MAIN_CP): $(BUILD_DIR)/firesim.build
@mkdir -p $(@D)
cd $(base_dir) && $(call build_classpath,$(firesim_sbt_project),runtime)
FIRESIM_TEST_CP := $(BUILD_DIR)/firesim-test.classpath
$(FIRESIM_TEST_CP): $(BUILD_DIR)/firesim.build
@mkdir -p $(@D)
cd $(base_dir) && $(call build_classpath,$(firesim_sbt_project),test)
# If the target project is the main FireSim project, provide the test classpath
# as it defines the target configs and parameters for designs to elaborate.
ifneq ($(firesim_sbt_project),$(TARGET_SBT_PROJECT))
target_srcs = $(foreach dir,$(TARGET_SOURCE_DIRS), \
$(call find_sources_in_dir, $(dir), 'src/main/scala'))
$(BUILD_DIR)/target.build: $(BUILD_DIR)/firesim.build $(target_srcs)
@mkdir -p $(@D)
$(SBT_NON_THIN) "set showSuccess := false; project $(TARGET_SBT_PROJECT); compile; package"
@touch $@
TARGET_CP := $(BUILD_DIR)/target.classpath
$(TARGET_CP): $(BUILD_DIR)/target.build
@mkdir -p $(@D)
cd $(base_dir) && $(call build_classpath,$(TARGET_SBT_PROJECT),runtime)
else
TARGET_CP := $(FIRESIM_TEST_CP)
endif
.PHONY: firesim-main-classpath firesim-test-classpath target-classpath
firesim-main-classpath: $(FIRESIM_MAIN_CP)
firesim-test-classpath: $(FIRESIM_TEST_CP)
target-classpath: $(TARGET_CP)
################################################################################
# Runners for tests.
################################################################################
.PHONY: test
test: $(FIRESIM_MAIN_CP) $(FIRESIM_TEST_CP) $(TARGET_CP)
cd $(base_dir) && $(SBT_NON_THIN) ";project $(firesim_sbt_project); test"
.PHONY: testOnly
testOnly: $(FIRESIM_MAIN_CP) $(FIRESIM_TEST_CP) $(TARGET_CP)
cd $(base_dir) && java -cp $$(cat $(FIRESIM_TEST_CP)) org.scalatest.run $(SCALA_TEST)

View File

@ -1,56 +1,14 @@
# See LICENSE for license details.
##########################
# RTL Generation #
##########################
chisel_src_dirs = \
$(addprefix $(firesim_base_dir)/,. midas midas/targetutils firesim-lib) \
$(addprefix $(chipyard_dir)/generators/, rocket-chip/src, rocket-chip/api-config-chipsalliance)
chisel_srcs = $(foreach submodule,$(chisel_src_dirs),\
$(shell find $(submodule)/ -iname "[!.]*.scala" -print 2> /dev/null | grep 'src/main/scala'))
SIM_RUNTIME_CONF ?= $(GENERATED_DIR)/$(CONF_NAME)
mem_model_args = $(shell cat $(SIM_RUNTIME_CONF))
COMMON_SIM_ARGS ?= $(mem_model_args)
vcs_args = +vcs+initreg+0 +vcs+initmem+0
# Rocket Chip stage requires a fully qualified classname for each fragment, whereas Chipyard's does not.
# This retains a consistent TARGET_CONFIG naming convention across the different target projects.
subst_prefix=,$(TARGET_CONFIG_PACKAGE).
$(FIRRTL_FILE) $(ANNO_FILE): $(chisel_srcs) $(FIRRTL_JAR) $(SCALA_BUILDTOOL_DEPS)
mkdir -p $(@D)
$(call run_scala_main,$(firesim_sbt_project),freechips.rocketchip.system.Generator, \
$(FIRRTL_FILE) $(ANNO_FILE): $(TARGET_CP)
@mkdir -p $(@D)
java -cp $$(cat $(TARGET_CP)) freechips.rocketchip.system.Generator \
--target-dir $(GENERATED_DIR) \
--name $(long_name) \
--top-module $(DESIGN_PACKAGE).$(DESIGN) \
--configs $(TARGET_CONFIG_PACKAGE).$(subst _,$(subst_prefix),$(TARGET_CONFIG)))
#######################################
# Setup Extra Verilator Compile Flags #
#######################################
## default flags added for cva6
CVA6_VERILATOR_FLAGS = \
--unroll-count 256 \
-Werror-PINMISSING \
-Werror-IMPLICIT \
-Wno-fatal \
-Wno-PINCONNECTEMPTY \
-Wno-ASSIGNDLY \
-Wno-DECLFILENAME \
-Wno-UNUSED \
-Wno-UNOPTFLAT \
-Wno-BLKANDNBLK \
-Wno-style \
-Wall
# normal flags used for midas builds (that are incompatible with cva6)
DEFAULT_MIDAS_VERILATOR_FLAGS = \
--assert
# AJG: this must be evaluated after verilog generation to work (hence the =)
EXTRA_VERILATOR_FLAGS = \
$(shell if ! grep -iq "module.*cva6" $(simulator_verilog); then echo "$(DEFAULT_MIDAS_VERILATOR_FLAGS)"; else echo "$(CVA6_VERILATOR_FLAGS)"; fi)
--configs $(TARGET_CONFIG_QUALIFIED)

View File

@ -1,23 +1,9 @@
# See LICENSE for license details.
##################
# RTL Generation #
##################
chisel_src_dirs = \
$(addprefix $(firesim_base_dir)/,. midas midas/targetutils firesim-lib) \
$(addprefix $(chipyard_dir)/generators/, rocket-chip/src, rocket-chip/api-config-chipsalliance)
chisel_srcs = $(foreach submodule,$(chisel_src_dirs),\
$(shell find $(submodule)/ -iname "[!.]*.scala" -print 2> /dev/null | grep 'src/main/scala'))
# Rocket Chip stage requires a fully qualified classname for each fragment, whereas Chipyard's does not.
# This retains a consistent TARGET_CONFIG naming convention across the different target projects.
subst_prefix=,$(TARGET_CONFIG_PACKAGE).
$(FIRRTL_FILE) $(ANNO_FILE): $(chisel_srcs) $(FIRRTL_JAR) $(SCALA_BUILDTOOL_DEPS)
mkdir -p $(@D)
$(call run_scala_main,$(firesim_sbt_project),freechips.rocketchip.system.Generator, \
$(FIRRTL_FILE) $(ANNO_FILE): $(TARGET_CP)
@mkdir -p $(@D)
java -cp $$(cat $(TARGET_CP)) freechips.rocketchip.system.Generator \
--target-dir $(GENERATED_DIR) \
--name $(long_name) \
--top-module $(DESIGN_PACKAGE).$(DESIGN) \
--configs $(TARGET_CONFIG_PACKAGE).$(subst _,$(subst_prefix),$(TARGET_CONFIG)))
--configs $(TARGET_CONFIG_QUALIFIED)

View File

@ -8,10 +8,8 @@ DESIGN ?= AXI4Fuzzer
# See src/main/scala/SimConfigs.scala
TARGET_CONFIG_PACKAGE ?= firesim.fasedtests
TARGET_CONFIG ?= DefaultConfig
# TARGET_CONFIG ?= FireSimBoomConfig
# These guide chisel elaboration of simulation components by MIDAS, including models and widgets.
# See src/main/scala/SimConfigs.scala
PLATFORM_CONFIG_PACKAGE ?= firesim.fasedtests
PLATFORM_CONFIG ?= DefaultF1Config

View File

@ -1,22 +1,36 @@
# See LICENSE for license details.
##################
# RTL Generation #
##################
ifdef FIRESIM_STANDALONE
target_sbt_project := {file:${chipyard_dir}}firechip
lookup_scala_srcs = $(shell find -L $(1)/ -name target -prune -o -iname "[!.]*.scala" -print 2> /dev/null)
SOURCE_DIRS = $(chipyard_dir)/generators $(firesim_base_dir)
SCALA_SOURCES = $(call lookup_scala_srcs,$(SOURCE_DIRS))
else
target_sbt_project := firechip
endif
$(FIRRTL_FILE) $(ANNO_FILE): $(SCALA_SOURCES) $(FIRRTL_JAR) $(SCALA_BUILDTOOL_DEPS)
mkdir -p $(@D)
$(call run_scala_main,$(target_sbt_project),chipyard.Generator,\
$(FIRRTL_FILE) $(ANNO_FILE): $(TARGET_CP)
@mkdir -p $(@D)
java -cp $$(cat $(TARGET_CP)) chipyard.Generator \
--target-dir $(GENERATED_DIR) \
--name $(long_name) \
--top-module $(DESIGN_PACKAGE).$(DESIGN) \
--legacy-configs $(TARGET_CONFIG_PACKAGE):$(TARGET_CONFIG))
--legacy-configs $(TARGET_CONFIG_PACKAGE):$(TARGET_CONFIG)
#######################################
# Setup Extra Verilator Compile Flags #
#######################################
## default flags added for cva6
CVA6_VERILATOR_FLAGS = \
--unroll-count 256 \
-Werror-PINMISSING \
-Werror-IMPLICIT \
-Wno-fatal \
-Wno-PINCONNECTEMPTY \
-Wno-ASSIGNDLY \
-Wno-DECLFILENAME \
-Wno-UNUSED \
-Wno-UNOPTFLAT \
-Wno-BLKANDNBLK \
-Wno-style \
-Wall
# normal flags used for midas builds (that are incompatible with cva6)
DEFAULT_MIDAS_VERILATOR_FLAGS = \
--assert
# AJG: this must be evaluated after verilog generation to work (hence the =)
EXTRA_VERILATOR_FLAGS = \
$(shell if ! grep -iq "module.*cva6" $(simulator_verilog); then echo "$(DEFAULT_MIDAS_VERILATOR_FLAGS)"; else echo "$(CVA6_VERILATOR_FLAGS)"; fi)

View File

@ -3,15 +3,27 @@
# These point at the main class of the target's Chisel generator
DESIGN_PACKAGE ?= firesim.firesim
DESIGN ?= FireSim
# DESIGN ?= FireBoom
# These guide chisel elaboration of the target design specified above.
# See src/main/scala/SimConfigs.scala
TARGET_CONFIG_PACKAGE ?= firesim.firesim
TARGET_CONFIG ?= FireSimRocketConfig
# These guide chisel elaboration of simulation components by MIDAS, including models and widgets.
# These guide chisel elaboration of simulation components by MIDAS,
# including models and widgets.
# See src/main/scala/SimConfigs.scala
PLATFORM_CONFIG_PACKAGE ?= firesim.firesim
PLATFORM_CONFIG ?= BaseF1Config
# Directory where target-specific sources are located.
TARGET_SRC_DIRS ?= $(chipyard_dir)/generators/
# Project for the target.
ifdef FIRESIM_STANDALONE
TARGET_SBT_PROJECT := {file:${chipyard_dir}}firechip
else
TARGET_SBT_PROJECT := firechip
endif
# Directory where sources are located.
TARGET_SOURCE_DIRS = $(chipyard_dir)/generators

View File

@ -1,25 +1,9 @@
# See LICENSE for license details.
##########################
# RTL Generation #
##########################
chisel_src_dirs = \
$(addprefix $(firesim_base_dir)/,. midas midas/targetutils firesim-lib) \
$(addprefix $(chipyard_dir)/generators/, rocket-chip/src, rocket-chip/api-config-chipsalliance)
chisel_srcs = $(foreach submodule,$(chisel_src_dirs),\
$(shell find $(submodule)/ -iname "[!.]*.scala" -print 2> /dev/null | grep 'src/main/scala'))
# Rocket Chip stage requires a fully qualified classname for each fragment, whereas Chipyard's does not.
# This retains a consistent TARGET_CONFIG naming convention across the different target projects.
subst_prefix=,$(TARGET_CONFIG_PACKAGE).
$(FIRRTL_FILE) $(ANNO_FILE): $(chisel_srcs) $(FIRRTL_JAR) $(SCALA_BUILDTOOL_DEPS)
mkdir -p $(@D)
$(call run_scala_main,$(firesim_sbt_project),freechips.rocketchip.system.Generator, \
$(FIRRTL_FILE) $(ANNO_FILE): $(TARGET_CP)
@mkdir -p $(@D)
java -cp $$(cat $(TARGET_CP)) freechips.rocketchip.system.Generator \
--target-dir $(GENERATED_DIR) \
--name $(long_name) \
--top-module $(DESIGN_PACKAGE).$(DESIGN) \
--configs $(TARGET_CONFIG_PACKAGE).$(subst _,$(subst_prefix),$(TARGET_CONFIG)))
--configs $(TARGET_CONFIG_QUALIFIED)