312 lines
11 KiB
Makefile
312 lines
11 KiB
Makefile
# See LICENSE for license details.
|
|
|
|
# FireSim Target Agnostic Make Fragment
|
|
#
|
|
# Defines make targets for:
|
|
# - invoking Golden Gate (phony: verilog / compile)
|
|
# - building a simulation driver (phony: f1)
|
|
# - populating an FPGA build directory (phony: replace-rtl)
|
|
# - generating new runtime configurations (phony: conf)
|
|
# - compiling meta-simulators (phony: verilator, vcs, verilator-debug, vcs-debug)
|
|
#
|
|
|
|
# The prefix used for all Golden Gate-generated files
|
|
BASE_FILE_NAME ?=
|
|
|
|
# The directory into which generated verilog and headers will be dumped
|
|
# RTL simulations will also be built here
|
|
GENERATED_DIR ?=
|
|
# Results from RTL simulations live here
|
|
OUTPUT_DIR ?=
|
|
# Root name for generated binaries
|
|
DESIGN ?=
|
|
|
|
# The target's FIRRTL and associated anotations; inputs to Golden Gate
|
|
FIRRTL_FILE ?=
|
|
ANNO_FILE ?=
|
|
|
|
# The host config package and class string
|
|
PLATFORM_CONFIG_PACKAGE ?= firesim.midasexamples
|
|
PLATFORM_CONFIG ?= DefaultF1Config
|
|
|
|
# The name of the generated runtime configuration file
|
|
CONF_NAME ?= $(BASE_FILE_NAME).runtime.conf
|
|
|
|
# The host platform type, currently only f1 is supported
|
|
PLATFORM ?=
|
|
|
|
# Driver source files
|
|
DRIVER_CC ?=
|
|
DRIVER_H ?=
|
|
|
|
# Target-specific CXX and LD flags for compiling the driver and meta-simulators
|
|
TARGET_CXX_FLAGS ?=
|
|
TARGET_LD_FLAGS ?=
|
|
|
|
simif_dir = $(firesim_base_dir)/midas/src/main/cc
|
|
midas_h = $(shell find $(simif_dir) -name "*.h")
|
|
midas_cc = $(shell find $(simif_dir) -name "*.cc")
|
|
|
|
common_cxx_flags := $(TARGET_CXX_FLAGS) -Wno-unused-variable
|
|
common_ld_flags := $(TARGET_LD_FLAGS) -lrt
|
|
|
|
# Simulation memory map emitted by the MIDAS compiler
|
|
header := $(GENERATED_DIR)/$(BASE_FILE_NAME).const.h
|
|
# The midas-generated simulator RTL which will be baked into the FPGA shell project
|
|
simulator_verilog := $(GENERATED_DIR)/$(BASE_FILE_NAME).sv
|
|
|
|
####################################
|
|
# Golden Gate Invocation #
|
|
####################################
|
|
firesim_root_sbt_project := {file:$(firesim_base_dir)}firesim
|
|
# Pre-simulation-mapping annotations which includes all Bridge Annotations
|
|
# extracted used to generate new runtime configurations.
|
|
fame_annos := $(GENERATED_DIR)/post-bridge-extraction.json
|
|
|
|
.PHONY: verilog compile
|
|
verilog: $(simulator_verilog)
|
|
compile: $(simulator_verilog)
|
|
|
|
# empty recipe to help make understand multiple targets come from single recipe invocation
|
|
# without using the new (4.3) '&:' grouped targets see https://stackoverflow.com/a/41710495
|
|
.SECONDARY: $(simulator_verilog).intermediate
|
|
$(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,\
|
|
-i $(FIRRTL_FILE) \
|
|
-td $(GENERATED_DIR) \
|
|
-faf $(ANNO_FILE) \
|
|
-ggcp $(PLATFORM_CONFIG_PACKAGE) \
|
|
-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
|
|
|
|
####################################
|
|
# Runtime-Configuration Generation #
|
|
####################################
|
|
|
|
# This reads in the annotations from a generated target, elaborates a
|
|
# FASEDTimingModel if a BridgeAnnoation for one exists, and asks for user input
|
|
# to generate a runtime configuration that is compatible with the generated
|
|
# hardware (BridgeModule). Useful for modelling a memory system that differs from the default.
|
|
.PHONY: conf
|
|
conf: $(fame_annos)
|
|
mkdir -p $(GENERATED_DIR)
|
|
cd $(base_dir) && $(SBT) "project $(firesim_sbt_project)" "runMain midas.stage.RuntimeConfigGeneratorMain \
|
|
-td $(GENERATED_DIR) \
|
|
-faf $(fame_annos) \
|
|
-ggcp $(PLATFORM_CONFIG_PACKAGE) \
|
|
-ggcs $(PLATFORM_CONFIG) \
|
|
-ggrc $(CONF_NAME)"
|
|
|
|
####################################
|
|
# Verilator MIDAS-Level Simulators #
|
|
####################################
|
|
|
|
VERILATOR_CXXOPTS ?= -O0
|
|
VERILATOR_MAKEFLAGS ?= -j8 VM_PARALLEL_BUILDS=1
|
|
|
|
verilator = $(GENERATED_DIR)/V$(DESIGN)
|
|
verilator_debug = $(GENERATED_DIR)/V$(DESIGN)-debug
|
|
|
|
$(verilator) $(verilator_debug): export CXXFLAGS := $(CXXFLAGS) $(common_cxx_flags) $(VERILATOR_CXXOPTS) -D RTLSIM
|
|
$(verilator) $(verilator_debug): export LDFLAGS := $(LDFLAGS) $(common_ld_flags)
|
|
|
|
$(verilator): $(header) $(DRIVER_CC) $(DRIVER_H) $(midas_cc) $(midas_h) $(simulator_verilog)
|
|
$(MAKE) $(VERILATOR_MAKEFLAGS) -C $(simif_dir) verilator PLATFORM=$(PLATFORM) DRIVER_NAME=$(DESIGN) GEN_FILE_BASENAME=$(BASE_FILE_NAME) \
|
|
GEN_DIR=$(GENERATED_DIR) DRIVER="$(DRIVER_CC)" TOP_DIR=$(chipyard_dir) VERILATOR_FLAGS="$(EXTRA_VERILATOR_FLAGS)"
|
|
|
|
$(verilator_debug): $(header) $(DRIVER_CC) $(DRIVER_H) $(midas_cc) $(midas_h) $(simulator_verilog)
|
|
$(MAKE) $(VERILATOR_MAKEFLAGS) -C $(simif_dir) verilator-debug PLATFORM=$(PLATFORM) DRIVER_NAME=$(DESIGN) GEN_FILE_BASENAME=$(BASE_FILE_NAME) \
|
|
GEN_DIR=$(GENERATED_DIR) DRIVER="$(DRIVER_CC)" TOP_DIR=$(chipyard_dir) VERILATOR_FLAGS="$(EXTRA_VERILATOR_FLAGS)"
|
|
|
|
.PHONY: verilator verilator-debug
|
|
verilator: $(verilator)
|
|
verilator-debug: $(verilator_debug)
|
|
|
|
##############################
|
|
# VCS MIDAS-Level Simulators #
|
|
##############################
|
|
|
|
VCS_CXXOPTS ?= -O2
|
|
|
|
vcs = $(GENERATED_DIR)/$(DESIGN)
|
|
vcs_debug = $(GENERATED_DIR)/$(DESIGN)-debug
|
|
|
|
$(vcs) $(vcs_debug): export CXXFLAGS := $(CXXFLAGS) $(common_cxx_flags) $(VCS_CXXOPTS) -I$(VCS_HOME)/include -D RTLSIM
|
|
$(vcs) $(vcs_debug): export LDFLAGS := $(LDFLAGS) $(common_ld_flags)
|
|
|
|
$(vcs): $(header) $(DRIVER_CC) $(DRIVER_H) $(midas_cc) $(midas_h) $(simulator_verilog)
|
|
$(MAKE) -C $(simif_dir) vcs PLATFORM=$(PLATFORM) DRIVER_NAME=$(DESIGN) GEN_FILE_BASENAME=$(BASE_FILE_NAME) \
|
|
GEN_DIR=$(GENERATED_DIR) DRIVER="$(DRIVER_CC)" TOP_DIR=$(chipyard_dir)
|
|
|
|
$(vcs_debug): $(header) $(DRIVER_CC) $(DRIVER_H) $(midas_cc) $(midas_h) $(simulator_verilog)
|
|
$(MAKE) -C $(simif_dir) vcs-debug PLATFORM=$(PLATFORM) DRIVER_NAME=$(DESIGN) GEN_FILE_BASENAME=$(BASE_FILE_NAME) \
|
|
GEN_DIR=$(GENERATED_DIR) DRIVER="$(DRIVER_CC)" TOP_DIR=$(chipyard_dir)
|
|
|
|
.PHONY: vcs vcs-debug
|
|
vcs: $(vcs)
|
|
vcs-debug: $(vcs_debug)
|
|
|
|
############################
|
|
# Master Simulation Driver #
|
|
############################
|
|
DRIVER_CXXOPTS ?= -O2
|
|
|
|
$(PLATFORM) = $(OUTPUT_DIR)/$(DESIGN)-$(PLATFORM)
|
|
$(PLATFORM): $($(PLATFORM))
|
|
|
|
.PHONY: driver
|
|
driver: $($(PLATFORM))
|
|
|
|
fpga_dir = $(firesim_base_dir)/../platforms/$(PLATFORM)/aws-fpga
|
|
|
|
$(f1): export CXXFLAGS := $(CXXFLAGS) $(common_cxx_flags) $(DRIVER_CXXOPTS) -I$(fpga_dir)/sdk/userspace/include
|
|
# Statically link libfesvr to make it easier to distribute drivers to f1 instances
|
|
# We will copy shared libs into same directory as driver on runhost, so add $ORIGIN to rpath
|
|
$(f1): export LDFLAGS := $(LDFLAGS) $(common_ld_flags) -Wl,-rpath='$$$$ORIGIN' -L /usr/local/lib64 -lfpga_mgmt
|
|
|
|
# Compile Driver
|
|
$(f1): $(header) $(DRIVER_CC) $(DRIVER_H) $(midas_cc) $(midas_h)
|
|
mkdir -p $(OUTPUT_DIR)/build
|
|
cp $(header) $(OUTPUT_DIR)/build/
|
|
# The manager expects to find the default conf in output/ by this name
|
|
cp -f $(GENERATED_DIR)/$(CONF_NAME) $(OUTPUT_DIR)/runtime.conf
|
|
$(MAKE) -C $(simif_dir) f1 PLATFORM=f1 DRIVER_NAME=$(DESIGN) GEN_FILE_BASENAME=$(BASE_FILE_NAME) \
|
|
GEN_DIR=$(OUTPUT_DIR)/build OUT_DIR=$(OUTPUT_DIR) DRIVER="$(DRIVER_CC)" \
|
|
TOP_DIR=$(chipyard_dir)
|
|
|
|
#############################
|
|
# FPGA Build Initialization #
|
|
#############################
|
|
board_dir := $(fpga_dir)/hdk/cl/developer_designs
|
|
fpga_work_dir := $(board_dir)/cl_$(name_tuple)
|
|
fpga_build_dir := $(fpga_work_dir)/build
|
|
verif_dir := $(fpga_work_dir)/verif
|
|
repo_state := $(fpga_work_dir)/design/repo_state
|
|
|
|
# Enumerates the subset of generated files that must be copied over for FPGA compilation
|
|
fpga_delivery_files = $(addprefix $(fpga_work_dir)/design/$(BASE_FILE_NAME), \
|
|
.sv .defines.vh .env.tcl \
|
|
.synthesis.xdc .implementation.xdc \
|
|
.ila_insert_inst.v .ila_insert_ports.v .ila_insert_wires.v .ila_insert_vivado.tcl)
|
|
|
|
$(fpga_work_dir)/stamp: $(shell find $(board_dir)/cl_firesim -name '*')
|
|
mkdir -p $(@D)
|
|
cp -rf $(board_dir)/cl_firesim -T $(fpga_work_dir)
|
|
touch $@
|
|
|
|
$(repo_state): $(simulator_verilog) $(fpga_work_dir)/stamp
|
|
$(firesim_base_dir)/../scripts/repo_state_summary.sh > $(repo_state)
|
|
|
|
$(fpga_work_dir)/design/$(BASE_FILE_NAME)%: $(simulator_verilog) $(fpga_work_dir)/stamp
|
|
cp -f $(GENERATED_DIR)/$(@F) $@
|
|
|
|
# Goes as far as setting up the build directory without running the cad job
|
|
# Used by the manager before passing a build to a remote machine
|
|
replace-rtl: $(fpga_delivery_files)
|
|
|
|
.PHONY: replace-rtl
|
|
|
|
$(firesim_base_dir)/scripts/checkpoints/$(target_sim_tuple): $(fpga_work_dir)/stamp
|
|
mkdir -p $(@D)
|
|
ln -sf $(fpga_build_dir)/checkpoints/to_aws $@
|
|
|
|
# Runs a local fpga-bitstream build. Strongly consider using the manager instead.
|
|
fpga: export CL_DIR := $(fpga_work_dir)
|
|
fpga: $(fpga_delivery_files) $(base_dir)/scripts/checkpoints/$(target_sim_tuple)
|
|
cd $(fpga_build_dir)/scripts && ./aws_build_dcp_from_cl.sh -notify
|
|
|
|
|
|
#############################
|
|
# FPGA-level RTL Simulation #
|
|
#############################
|
|
|
|
# Run XSIM DUT
|
|
.PHONY: xsim-dut
|
|
xsim-dut: replace-rtl $(fpga_work_dir)/stamp
|
|
cd $(verif_dir)/scripts && $(MAKE) C_TEST=test_firesim
|
|
|
|
# Compile XSIM Driver #
|
|
xsim = $(GENERATED_DIR)/$(DESIGN)-$(PLATFORM)
|
|
|
|
$(xsim): export CXXFLAGS := $(CXXFLAGS) $(common_cxx_flags) -D SIMULATION_XSIM -D NO_MAIN
|
|
$(xsim): export LDFLAGS := $(LDFLAGS) $(common_ld_flags)
|
|
$(xsim): $(header) $(DRIVER_CC) $(DRIVER_H) $(midas_cc) $(midas_h)
|
|
$(MAKE) -C $(simif_dir) f1 PLATFORM=f1 DRIVER_NAME=$(DESIGN) GEN_FILE_BASENAME=$(BASE_FILE_NAME) \
|
|
GEN_DIR=$(GENERATED_DIR) OUT_DIR=$(GENERATED_DIR) DRIVER="$(DRIVER_CC)" \
|
|
TOP_DIR=$(chipyard_dir)
|
|
|
|
.PHONY: xsim
|
|
xsim: $(xsim)
|
|
|
|
#########################
|
|
# MIDAS Unit Tests #
|
|
#########################
|
|
UNITTEST_CONFIG ?= AllUnitTests
|
|
|
|
rocketchip_dir := $(chipyard_dir)/generators/rocket-chip
|
|
unittest_generated_dir := $(base_dir)/generated-src/unittests/$(UNITTEST_CONFIG)
|
|
unittest_args = \
|
|
BASE_DIR=$(base_dir) \
|
|
EMUL=$(EMUL) \
|
|
ROCKETCHIP_DIR=$(rocketchip_dir) \
|
|
GEN_DIR=$(unittest_generated_dir) \
|
|
SBT="$(SBT)" \
|
|
SBT_PROJECT=$(firesim_root_sbt_project) \
|
|
CONFIG=$(UNITTEST_CONFIG) \
|
|
TOP_DIR=$(chipyard_dir)
|
|
|
|
.PHONY:compile-midas-unittests
|
|
compile-midas-unittests: $(chisel_srcs)
|
|
$(MAKE) -f $(simif_dir)/unittest/Makefrag $(unittest_args)
|
|
|
|
.PHONY:run-midas-unittests
|
|
run-midas-unittests: $(chisel_srcs)
|
|
$(MAKE) -f $(simif_dir)/unittest/Makefrag $@ $(unittest_args)
|
|
|
|
.PHONY:run-midas-unittests-debug
|
|
run-midas-unittests-debug: $(chisel_srcs)
|
|
$(MAKE) -f $(simif_dir)/unittest/Makefrag $@ $(unittest_args)
|
|
|
|
#########################
|
|
# ScalaDoc #
|
|
#########################
|
|
scaladoc:
|
|
cd $(base_dir) && $(SBT) "project {file:$(firesim_base_dir)}firesim" "unidoc"
|
|
|
|
.PHONY: scaladoc
|
|
#########################
|
|
# Cleaning Recipes #
|
|
#########################
|
|
cleanfpga:
|
|
rm -rf $(fpga_work_dir)
|
|
|
|
mostlyclean:
|
|
rm -rf $(verilator) $(verilator_debug) $(vcs) $(vcs_debug) $($(PLATFORM)) $(OUTPUT_DIR)
|
|
|
|
clean:
|
|
rm -rf $(GENERATED_DIR) $(OUTPUT_DIR)
|
|
|
|
veryclean:
|
|
rm -rf generated-src output
|
|
|
|
tags: $(header) $(DRIVER_CC) $(DRIVER_H) $(midas_cc) $(midas_h)
|
|
ctags -R --exclude=@.ctagsignore .
|
|
|
|
.PHONY: $(PLATFORM)-driver fpga
|
|
.PHONY: mostlyclean clean
|
|
|
|
.PRECIOUS: $(OUTPUT_DIR)/%.vpd $(OUTPUT_DIR)/%.out $(OUTPUT_DIR)/%.run
|
|
|
|
# Remove all implicit suffix rules; This improves make performance substantially as it no longer
|
|
# attempts to resolve implicit rules on 1000+ scala files.
|
|
.SUFFIXES:
|