Use new file emission trait + makefile naming cleanup
This commit is contained in:
parent
fa8b1a98f8
commit
2e30100d35
|
@ -42,7 +42,7 @@ def replace_rtl(conf, buildconfig):
|
|||
InfoStreamLogger('stderr'):
|
||||
run(buildconfig.make_recipe("replace-rtl"))
|
||||
run("""mkdir -p {}/results-build/{}/""".format(ddir, builddir))
|
||||
run("""cp $CL_DIR/design/cl_firesim_generated.sv {}/results-build/{}/cl_firesim_generated.sv""".format(ddir, builddir))
|
||||
run("""cp $CL_DIR/design/FireSim-generated.sv {}/results-build/{}/FireSim-generated.sv""".format(ddir, builddir))
|
||||
|
||||
# build the fpga driver that corresponds with this version of the RTL
|
||||
with prefix('cd ' + ddir + '/../'), \
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
.. _auto-ila:
|
||||
|
||||
AutoILA: Simple Integrated Logic Analyzer (ILA) Insertion
|
||||
===================================================================
|
||||
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
Output Files
|
||||
============
|
||||
|
||||
Golden Gate generates many output files, we describe them here. Note, the GG
|
||||
CML-argument ``--output-filename-base=<BASE>`` defines defines a common prefix
|
||||
for all output files.
|
||||
|
||||
|
||||
Core Files
|
||||
-------------------------------------
|
||||
These are used in nearly all flows.
|
||||
|
||||
* **<BASE>.v**: The verilog implementation of the simulator which will be synthesized onto the FPGA. The top-level is the Shim module specified in the ``PLATFORM_CONFIG``.
|
||||
* **<BASE>_const.h**: A target-specific header containing all necessary metadata to instantiate bridge drivers. This is linked into the simulator driver and meta-simulators (FPGA-level / MIDAS-level). Often referred to as "the header".
|
||||
* **<BASE>_runtime.conf**: Default plus args for generated FASED memory timing models. Most other bridges have their defaults baked into the driver.
|
||||
|
||||
FPGA Synthesis Files
|
||||
-------------------------------------
|
||||
These are additional files passed to the FPGA build directory.
|
||||
|
||||
* **<BASE>_defines.vh**: Verilog macro definitions for FPGA synthesis.
|
||||
* **<BASE>_env.tcl**: Used a means to inject arbitrary TCL into the start of the build flow. Controls synthesis and implementation strategies, and sets the host_clock frequency before the clock generator (MCMM) is synthesized.
|
||||
* **<BASE>_ila_insert_vivado.tcl**: Synthesizes an ILA for the design. See :ref:`auto-ila` for more details about using ILAs in FireSim.
|
||||
* **<BASE>_ila_insert_{inst, ports, wires}.v**: Instantiated in the FPGA project via ```include`` directives to instantiate the generated ILA.
|
||||
|
||||
Meta-simulation Files
|
||||
-------------------------------------
|
||||
These are additional sources used only in MIDAS-level simulators
|
||||
|
||||
* **<BASE>_const.vh**: Verilog macros to define variable width fields.
|
|
@ -33,7 +33,7 @@ New to FireSim? Jump to the :ref:`firesim-basics` page for more info.
|
|||
|
||||
.. toctree::
|
||||
:maxdepth: 3
|
||||
:caption: Golden Gate (MIDAS II) Docs:
|
||||
:caption: Compiler (Golden Gate) Docs:
|
||||
|
||||
Golden-Gate/Overview
|
||||
Golden-Gate/LI-BDN
|
||||
|
@ -41,6 +41,7 @@ New to FireSim? Jump to the :ref:`firesim-basics` page for more info.
|
|||
Golden-Gate/Bridge-Walkthrough
|
||||
Golden-Gate/Triggers
|
||||
Golden-Gate/Resource-Optimizations
|
||||
Golden-Gate/Output-Files
|
||||
|
||||
Indices and tables
|
||||
==================
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit cb2cc9b1b146c0302bf5b74993dfd45de1569f9a
|
||||
Subproject commit e0745fae2d8c92054b4defcf76ce81f166635612
|
|
@ -6,19 +6,20 @@ endif
|
|||
|
||||
firesim_base_dir := $(abspath .)
|
||||
|
||||
.PHONY: default
|
||||
default: compile
|
||||
|
||||
##################
|
||||
# Parameters #
|
||||
##################
|
||||
|
||||
# Multiple target-projects, each with it's own chisel generator, co-exist in firesim.
|
||||
# Multiple target-projects, each with their own chisel generator, co-exist in firesim.
|
||||
# Their sources exist in:
|
||||
# src/main/{cc, scala, makefrag}/<target-project-name>
|
||||
#
|
||||
# Currently these projects are:
|
||||
# firesim: the default, rocket-chip-based target-designs
|
||||
# midasexamples: simple chisel designs demonstrating how to build midas-style simulators
|
||||
# firesim: the default, Chipyard-based target-designs
|
||||
# midasexamples: simple chisel designs demonstrating FireSim's features
|
||||
TARGET_PROJECT ?= firesim
|
||||
|
||||
# Users can override this to point at a makefrag defined in a parent project
|
||||
|
@ -92,8 +93,6 @@ endif
|
|||
# Include target-specific sources and input generation recipes
|
||||
include $(TARGET_PROJECT_MAKEFRAG)
|
||||
|
||||
verilog: $(VERILOG)
|
||||
compile: $(VERILOG)
|
||||
|
||||
# Phony targets for launching the sbt shell and running scalatests
|
||||
SBT_COMMAND ?= shell
|
||||
|
|
|
@ -4,6 +4,7 @@ package firesim.passes
|
|||
|
||||
import firesim.util.{DesiredHostFrequency, BuildStrategy}
|
||||
import midas.stage.phases.ConfigParametersAnnotation
|
||||
import midas.stage.GoldenGateOutputFileAnnotation
|
||||
|
||||
import freechips.rocketchip.config.Parameters
|
||||
|
||||
|
@ -19,40 +20,28 @@ import java.io.{File, FileWriter}
|
|||
object EC2F1Artefacts extends Transform {
|
||||
def inputForm: CircuitForm = LowForm
|
||||
def outputForm: CircuitForm = LowForm
|
||||
override def name = "[FireSim] EC2 F1 Artefact Generation"
|
||||
|
||||
def writeOutputFile(f: File, contents: String): File = {
|
||||
val fw = new FileWriter(f)
|
||||
fw.write(contents)
|
||||
fw.close
|
||||
f
|
||||
}
|
||||
override def name = "[Golden Gate] EC2 F1 Artefact Generation"
|
||||
|
||||
// Capture FPGA-toolflow related verilog defines
|
||||
def generateHostVerilogHeader(targetDir: File) {
|
||||
val headerName = "cl_firesim_generated_defines.vh"
|
||||
writeOutputFile(new File(targetDir, headerName), s"\n")
|
||||
}
|
||||
def verilogHeaderAnno = GoldenGateOutputFileAnnotation(
|
||||
"""| // Don't let Vivado see $random, which is the default if this is not set
|
||||
| `define RANDOM 64'b0
|
||||
|""".stripMargin,
|
||||
fileSuffix = ".defines.vh")
|
||||
|
||||
// Emit TCL variables to control the FPGA compilation flow
|
||||
def generateTclEnvFile(targetDir: File)(implicit hostParams: Parameters) {
|
||||
val headerName = "cl_firesim_generated_env.tcl"
|
||||
def tclEnvAnno(implicit hostParams: Parameters): GoldenGateOutputFileAnnotation = {
|
||||
val requestedFrequency = hostParams(DesiredHostFrequency)
|
||||
val buildStrategy = hostParams(BuildStrategy)
|
||||
val constraints = s"""# FireSim Generated Environment Variables
|
||||
set desired_host_frequency ${requestedFrequency}
|
||||
${buildStrategy.emitTcl}
|
||||
"""
|
||||
writeOutputFile(new File(targetDir, headerName), constraints)
|
||||
GoldenGateOutputFileAnnotation(constraints, fileSuffix = ".env.tcl")
|
||||
}
|
||||
|
||||
def execute(state: CircuitState): CircuitState = {
|
||||
implicit val p = state.annotations.collectFirst({ case ConfigParametersAnnotation(p) => p }).get
|
||||
val targetDir = state.annotations.collectFirst({
|
||||
case TargetDirAnnotation(dir) => new File(dir)
|
||||
}).get
|
||||
generateHostVerilogHeader(targetDir)
|
||||
generateTclEnvFile(targetDir)
|
||||
state
|
||||
state.copy(annotations = verilogHeaderAnno +: tclEnvAnno +: state.annotations)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ package firesim.passes
|
|||
|
||||
import midas.EnableAutoILA
|
||||
import midas.targetutils.FirrtlFpgaDebugAnnotation
|
||||
import midas.stage.{OutputFileBuilder, GoldenGateOutputFileAnnotation}
|
||||
import midas.stage.phases.ConfigParametersAnnotation
|
||||
|
||||
import firrtl._
|
||||
|
@ -30,26 +31,23 @@ class ILATopWiringTransform extends Transform with DependencyAPIMigration {
|
|||
|
||||
type InstPath = Seq[String]
|
||||
|
||||
val addedFileAnnos = new mutable.ArrayBuffer[GoldenGateOutputFileAnnotation]
|
||||
|
||||
def ILAWiringOutputFiles(dataDepth: Int)(
|
||||
dir: String,
|
||||
mapping: Seq[((ComponentName, Type, Boolean, InstPath, String), Int)],
|
||||
state: CircuitState): CircuitState = {
|
||||
|
||||
//val targetFile: Option[String] = state.annotations.collectFirst { case ILADebugFileAnnotation(fn) => fn }
|
||||
|
||||
//output vivado tcl file
|
||||
val tclOutputFile = new PrintWriter(new File(dir, "firesim_ila_insert_vivado.tcl" ))
|
||||
//output verilog 'include' file with ports
|
||||
val portsOutputFile = new PrintWriter(new File(dir, "firesim_ila_insert_ports.v" ))
|
||||
//output verilog 'include' file with wires
|
||||
val wiresOutputFile = new PrintWriter(new File(dir, "firesim_ila_insert_wires.v" ))
|
||||
//output verilog 'include' file with ila instantiation
|
||||
val ilaInstOutputFile = new PrintWriter(new File(dir, "firesim_ila_insert_inst.v" ))
|
||||
|
||||
// vivado >2017.4 encrypt chokes on empty .v files, so put something there...
|
||||
portsOutputFile.append(s" \n \n \n")
|
||||
wiresOutputFile.append(s" \n \n \n")
|
||||
ilaInstOutputFile.append(s" \n \n \n")
|
||||
def fileHeader = " \n \n \n"
|
||||
//output vivado tcl file
|
||||
val tclOutputFile = new OutputFileBuilder(fileHeader, ".ila_insert_vivado.tcl")
|
||||
//output verilog 'include' file with ports
|
||||
val portsOutputFile = new OutputFileBuilder(fileHeader, ".ila_insert_ports.v")
|
||||
//output verilog 'include' file with wires
|
||||
val wiresOutputFile = new OutputFileBuilder(fileHeader, ".ila_insert_wires.v")
|
||||
//output verilog 'include' file with ila instantiation
|
||||
val ilaInstOutputFile = new OutputFileBuilder(fileHeader, ".ila_insert_inst.v")
|
||||
|
||||
//vivado tcl prologue
|
||||
tclOutputFile.append(s"create_project managed_ip_project $$CL_DIR/ip/firesim_ila_ip/managed_ip_project -part xcvu9p-flgb2104-2-i -ip -force\n")
|
||||
|
@ -123,11 +121,12 @@ class ILATopWiringTransform extends Transform with DependencyAPIMigration {
|
|||
ilaInstOutputFile.append(s"\n);\n")
|
||||
}
|
||||
|
||||
tclOutputFile.close()
|
||||
portsOutputFile.close()
|
||||
wiresOutputFile.close()
|
||||
ilaInstOutputFile.close()
|
||||
|
||||
addedFileAnnos ++= Seq(
|
||||
tclOutputFile.toAnnotation,
|
||||
portsOutputFile.toAnnotation,
|
||||
wiresOutputFile.toAnnotation,
|
||||
ilaInstOutputFile.toAnnotation
|
||||
)
|
||||
state
|
||||
}
|
||||
|
||||
|
@ -153,14 +152,16 @@ class ILATopWiringTransform extends Transform with DependencyAPIMigration {
|
|||
case p => p.map { case FirrtlFpgaDebugAnnotation(target) => TopWiringAnnotation(target, s"ila_") }
|
||||
}
|
||||
|
||||
val dir = state.annotations.collectFirst({ case TargetDirAnnotation(targetDir) => new File(targetDir) }).get
|
||||
|
||||
val dataDepth = p(ILADepthKey)
|
||||
//dirname should be some aws-fpga synthesis directory
|
||||
val topwiringannos = targetannos :+
|
||||
TopWiringOutputFilesAnnotation(dir.getPath(), ILAWiringOutputFiles(dataDepth))
|
||||
val topwiringannos = targetannos :+ TopWiringOutputFilesAnnotation("", ILAWiringOutputFiles(dataDepth))
|
||||
val wiredState = (new TopWiringTransform).execute(state.copy(annotations = state.annotations ++ topwiringannos))
|
||||
val cleanedAnnos = wiredState.annotations.filter {
|
||||
case a: TopWiringOutputFilesAnnotation => false
|
||||
case a: FirrtlFpgaDebugAnnotation => false
|
||||
case _ => true
|
||||
}
|
||||
|
||||
def topwiringtransform = new TopWiringTransform
|
||||
topwiringtransform.execute(state.copy(annotations = state.annotations ++ topwiringannos))
|
||||
wiredState.copy(annotations = cleanedAnnos ++ addedFileAnnos)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,24 +7,28 @@ r_dir = $(abspath ../resources)
|
|||
########################################################################
|
||||
# Parameters:
|
||||
# 1) PLATFORM: FPGA platform board(by default zynq)
|
||||
# 2) DESIGN: Target design of midas
|
||||
# 2) DRIVER_NAME: Base name for compiled drivers and ML simulators
|
||||
# 3) GEN_DIR: Directory for generated source code
|
||||
# 4) OUT_DIR: Directory for binary files (by default GEN_DIR)
|
||||
# 5) DRIVER: software driver written by user
|
||||
# 6) CLOCK_PERIOD(optional): clock period of tests
|
||||
# 7) VERILATOR_FLAGS(optional): set of verilator flags to add
|
||||
# 5) GEN_FILE_BASENAME: Common prefix for all GG-emitted output files
|
||||
# 6) DRIVER: software driver written by user
|
||||
# 7) CLOCK_PERIOD(optional): clock period of tests
|
||||
# 8) VERILATOR_FLAGS(optional): set of verilator flags to add
|
||||
########################################################################
|
||||
ifeq ($(strip $(DESIGN)),)
|
||||
$(error Define DESIGN, the target design)
|
||||
ifeq ($(strip $(DRIVER_NAME)),)
|
||||
$(error Define DRIVER_NAME, the base name used for compiled simulators and simulator drivers.)
|
||||
endif
|
||||
ifeq ($(strip $(GEN_FILE_BASENAME)),)
|
||||
$(error Define GEN_FILE_BASENAME, the base name used for all Golden Gate-generated files.)
|
||||
endif
|
||||
ifeq ($(strip $(GEN_DIR)),)
|
||||
$(error Define GEN_DIR, where all midas generated code reside)
|
||||
$(error Define GEN_DIR, the directory containing all Golden Gate-generated files.)
|
||||
endif
|
||||
ifeq ($(strip $(TOP_DIR)),)
|
||||
$(error Define TOP_DIR, the top of the chipyard directory)
|
||||
endif
|
||||
ifeq ($(strip $(DRIVER)),)
|
||||
$(error Define DRIVER, the source code of the simulation driver)
|
||||
$(error Define DRIVER, additional source files for the simulation driver)
|
||||
endif
|
||||
|
||||
PLATFORM ?= zynq
|
||||
|
@ -32,14 +36,10 @@ OUT_DIR ?= $(GEN_DIR)
|
|||
CLOCK_PERIOD ?= 1.0
|
||||
|
||||
$(info platform: $(PLATFORM))
|
||||
$(info target design: $(DESIGN))
|
||||
$(info generated source directory: $(GEN_DIR))
|
||||
$(info output directory: $(OUT_DIR))
|
||||
$(info driver source files: $(DRIVER))
|
||||
$(info clock period: $(CLOCK_PERIOD))
|
||||
|
||||
shim := FPGATop
|
||||
|
||||
testchip_dir=$(TOP_DIR)/generators/testchipip/src/main/resources
|
||||
testchip_csrc_dir=$(testchip_dir)/testchipip/csrc
|
||||
dramsim_dir=$(TOP_DIR)/tools/DRAMSim2
|
||||
|
@ -51,16 +51,13 @@ include $(util_dir)/utils.mk
|
|||
$(OUT_DIR)/dramsim2_ini: $(testchip_dir)/dramsim2_ini
|
||||
ln -sf $< $@
|
||||
|
||||
$(OUT_DIR)/$(DESIGN).chain:
|
||||
$(if $(wildcard $(GEN_DIR)/$(DESIGN).chain),cp $(GEN_DIR)/$(DESIGN).chain $@,)
|
||||
|
||||
override CXXFLAGS += -I$(midas_dir) -I$(util_dir)
|
||||
# The trailing whitespace is important for some reason...
|
||||
override LDFLAGS := $(LDFLAGS) -L$(GEN_DIR) -lstdc++ -lpthread -lgmp -lmidas
|
||||
|
||||
design_v := $(GEN_DIR)/$(shim).v
|
||||
design_h := $(GEN_DIR)/$(DESIGN)-const.h
|
||||
design_vh := $(GEN_DIR)/$(DESIGN)-const.vh
|
||||
design_v := $(GEN_DIR)/$(GEN_FILE_BASENAME).sv
|
||||
design_h := $(GEN_DIR)/$(GEN_FILE_BASENAME).const.h
|
||||
design_vh := $(GEN_DIR)/$(GEN_FILE_BASENAME).const.vh
|
||||
driver_h = $(foreach t, $(DRIVER), $(wildcard $(dir $(t))/*.h))
|
||||
bridge_h := $(wildcard $(bridge_dir)/*.h)
|
||||
bridge_cc := $(wildcard $(bridge_dir)/*.cc)
|
||||
|
@ -77,12 +74,12 @@ $(platform_o): $(GEN_DIR)/%.o: $(midas_dir)/%.cc $(design_h) $(platform_h)
|
|||
mkdir -p $(dir $@)
|
||||
$(CXX) $(CXXFLAGS) -c -o $@ $< -include $(word 2, $^)
|
||||
|
||||
$(OUT_DIR)/$(DESIGN)-$(PLATFORM): $(design_h) $(lib) $(DRIVER) $(driver_h) $(platform_o) $(bridge_o)
|
||||
$(OUT_DIR)/$(DRIVER_NAME)-$(PLATFORM): $(design_h) $(lib) $(DRIVER) $(driver_h) $(platform_o) $(bridge_o)
|
||||
mkdir -p $(OUT_DIR)
|
||||
$(CXX) $(CXXFLAGS) -include $< \
|
||||
-o $@ $(DRIVER) $(lib_o) $(platform_o) $(bridge_o) $(LDFLAGS)
|
||||
|
||||
$(PLATFORM): $(OUT_DIR)/$(DESIGN)-$(PLATFORM) $(OUT_DIR)/$(DESIGN).chain
|
||||
$(PLATFORM): $(OUT_DIR)/$(DRIVER_NAME)-$(PLATFORM)
|
||||
|
||||
# Sources for building MIDAS-level simulators. Must be defined before sources VCS/Verilator Makefrags
|
||||
override CFLAGS += -include $(design_h)
|
||||
|
@ -102,8 +99,8 @@ verilator_harness := emul/verilator-harness.cc
|
|||
top_module := verilator_top
|
||||
include rtlsim/Makefrag-verilator
|
||||
|
||||
verilator: $(OUT_DIR)/V$(DESIGN) $(OUT_DIR)/$(DESIGN).chain $(OUT_DIR)/dramsim2_ini
|
||||
verilator-debug: $(OUT_DIR)/V$(DESIGN)-debug $(OUT_DIR)/$(DESIGN).chain $(OUT_DIR)/dramsim2_ini
|
||||
verilator: $(OUT_DIR)/V$(DRIVER_NAME) $(OUT_DIR)/dramsim2_ini
|
||||
verilator-debug: $(OUT_DIR)/V$(DRIVER_NAME)-debug $(OUT_DIR)/dramsim2_ini
|
||||
|
||||
# Add an extra wrapper source for VCS simulators
|
||||
vcs_wrapper_v := $(v_dir)/vcs_top.v
|
||||
|
@ -112,7 +109,7 @@ TB := emul
|
|||
VCS_FLAGS := -e vcs_main
|
||||
include rtlsim/Makefrag-vcs
|
||||
|
||||
vcs: $(OUT_DIR)/$(DESIGN) $(OUT_DIR)/$(DESIGN).chain $(OUT_DIR)/dramsim2_ini
|
||||
vcs-debug: $(OUT_DIR)/$(DESIGN)-debug $(OUT_DIR)/$(DESIGN).chain $(OUT_DIR)/dramsim2_ini
|
||||
vcs: $(OUT_DIR)/$(DRIVER_NAME) $(OUT_DIR)/dramsim2_ini
|
||||
vcs-debug: $(OUT_DIR)/$(DRIVER_NAME)-debug $(OUT_DIR)/dramsim2_ini
|
||||
|
||||
.PHONY: $(PLATFORM) verilator verilator-debug vcs vcs-debug
|
||||
|
|
|
@ -19,7 +19,7 @@ VCS ?= vcs -full64
|
|||
override VCS_FLAGS := -quiet -timescale=1ns/1ps +v2k +rad +vcs+initreg+random +vcs+lic+wait \
|
||||
-notice -line +lint=all,noVCDE,noONGS,noUI -quiet -debug_pp +no_notifier -cpp $(CXX) \
|
||||
-top $(TB) \
|
||||
-Mdir=$(GEN_DIR)/$(DESIGN)-debug.csrc \
|
||||
-Mdir=$(GEN_DIR)/$(DRIVER_NAME)-debug.csrc \
|
||||
+vc+list \
|
||||
-CFLAGS "$(CXXFLAGS) $(CFLAGS) -D_GNU_SOURCE -DVCS -I$(VCS_HOME)/include" \
|
||||
-LDFLAGS "$(LDFLAGS)" \
|
||||
|
@ -35,16 +35,16 @@ override VCS_FLAGS := -quiet -timescale=1ns/1ps +v2k +rad +vcs+initreg+random +v
|
|||
vcs_v := $(emul_v) $(vcs_wrapper_v)
|
||||
vcs_cc := $(emul_cc) $(vcs_harness)
|
||||
|
||||
$(OUT_DIR)/$(DESIGN): $(vcs_v) $(vcs_cc) $(emul_h)
|
||||
$(OUT_DIR)/$(DRIVER_NAME): $(vcs_v) $(vcs_cc) $(emul_h)
|
||||
mkdir -p $(OUT_DIR)
|
||||
rm -rf $(GEN_DIR)/$(DESIGN).csrc
|
||||
rm -rf $(OUT_DIR)/$(DESIGN).daidir
|
||||
rm -rf $(GEN_DIR)/$(DRIVER_NAME).csrc
|
||||
rm -rf $(OUT_DIR)/$(DRIVER_NAME).daidir
|
||||
$(VCS) $(VCS_FLAGS) \
|
||||
-o $@ $(vcs_v) $(vcs_cc)
|
||||
|
||||
$(OUT_DIR)/$(DESIGN)-debug: $(vcs_v) $(vcs_cc) $(emul_h)
|
||||
$(OUT_DIR)/$(DRIVER_NAME)-debug: $(vcs_v) $(vcs_cc) $(emul_h)
|
||||
mkdir -p $(OUT_DIR)
|
||||
rm -rf $(GEN_DIR)/$(DESIGN)-debug.csrc
|
||||
rm -rf $(OUT_DIR)/$(DESIGN)-debug.daidir
|
||||
rm -rf $(GEN_DIR)/$(DRIVER_NAME)-debug.csrc
|
||||
rm -rf $(OUT_DIR)/$(DRIVER_NAME)-debug.daidir
|
||||
$(VCS) $(VCS_FLAGS) +define+DEBUG \
|
||||
-o $@ $(vcs_v) $(vcs_cc)
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
# Compulsory variables:
|
||||
# OUT_DIR: See Makefile
|
||||
# GEN_DIR: See Makefile
|
||||
# DESIGN: See Makefile
|
||||
# DRIVER_NAME: See Makefile
|
||||
# emul_cc: C++ sources
|
||||
# emul_h: C++ headers
|
||||
# emul_v: verilog sources and headers
|
||||
|
@ -33,18 +33,18 @@ override VERILATOR_FLAGS := \
|
|||
-LDFLAGS "$(LDFLAGS) " \
|
||||
$(VERILATOR_FLAGS)
|
||||
|
||||
$(OUT_DIR)/V$(DESIGN): $(verilator_v) $(verilator_cc) $(emul_h)
|
||||
$(OUT_DIR)/V$(DRIVER_NAME): $(verilator_v) $(verilator_cc) $(emul_h)
|
||||
mkdir -p $(OUT_DIR)
|
||||
rm -rf $(GEN_DIR)/V$(DESIGN).csrc
|
||||
$(VERILATOR) $(VERILATOR_FLAGS) -Mdir $(GEN_DIR)/V$(DESIGN).csrc \
|
||||
-CFLAGS "-include $(GEN_DIR)/V$(DESIGN).csrc/V$(top_module).h" \
|
||||
rm -rf $(GEN_DIR)/V$(DRIVER_NAME).csrc
|
||||
$(VERILATOR) $(VERILATOR_FLAGS) -Mdir $(GEN_DIR)/V$(DRIVER_NAME).csrc \
|
||||
-CFLAGS "-include $(GEN_DIR)/V$(DRIVER_NAME).csrc/V$(top_module).h" \
|
||||
-o $@ $(verilator_v) $(verilator_conf) $(verilator_cc)
|
||||
$(MAKE) -C $(GEN_DIR)/V$(DESIGN).csrc -f V$(top_module).mk
|
||||
$(MAKE) -C $(GEN_DIR)/V$(DRIVER_NAME).csrc -f V$(top_module).mk
|
||||
|
||||
$(OUT_DIR)/V$(DESIGN)-debug: $(verilator_v) $(verilator_cc) $(emul_h)
|
||||
$(OUT_DIR)/V$(DRIVER_NAME)-debug: $(verilator_v) $(verilator_cc) $(emul_h)
|
||||
mkdir -p $(OUT_DIR)
|
||||
rm -rf $(GEN_DIR)/V$(DESIGN)-debug.csrc
|
||||
$(VERILATOR) $(VERILATOR_FLAGS) --trace -Mdir $(GEN_DIR)/V$(DESIGN)-debug.csrc \
|
||||
-CFLAGS "-include $(GEN_DIR)/V$(DESIGN)-debug.csrc/V$(top_module).h" \
|
||||
rm -rf $(GEN_DIR)/V$(DRIVER_NAME)-debug.csrc
|
||||
$(VERILATOR) $(VERILATOR_FLAGS) --trace -Mdir $(GEN_DIR)/V$(DRIVER_NAME)-debug.csrc \
|
||||
-CFLAGS "-include $(GEN_DIR)/V$(DRIVER_NAME)-debug.csrc/V$(top_module).h" \
|
||||
-o $@ $(verilator_v) $(verilator_conf) $(verilator_cc)
|
||||
$(MAKE) -C $(GEN_DIR)/V$(DESIGN)-debug.csrc -f V$(top_module).mk
|
||||
$(MAKE) -C $(GEN_DIR)/V$(DRIVER_NAME)-debug.csrc -f V$(top_module).mk
|
||||
|
|
|
@ -257,7 +257,8 @@ class FPGATopImp(outer: FPGATop)(implicit p: Parameters) extends LazyModuleImp(o
|
|||
}
|
||||
|
||||
outer.genCtrlIO(ctrl)
|
||||
outer.printHostDRAMSummary
|
||||
outer.printHostDRAMSummary()
|
||||
outer.emitDefaultPlusArgsFile()
|
||||
|
||||
val addrConsts = dmaAddrMap.map {
|
||||
case AddrMapEntry(name, MemRange(addr, _, _)) =>
|
||||
|
|
|
@ -552,7 +552,6 @@ class FASEDMemoryTimingModel(completeConfig: CompleteConfig, hostParams: Paramet
|
|||
genCRFile()
|
||||
dontTouch(targetFire)
|
||||
chisel3.experimental.annotate(Fame1ChiselAnnotation(model, "targetFire"))
|
||||
getDefaultSettings("runtime.conf")
|
||||
|
||||
override def genHeader(base: BigInt, sb: StringBuilder) {
|
||||
def genCPPmap(mapName: String, map: Map[String, BigInt]): String = {
|
||||
|
@ -581,29 +580,30 @@ class FASEDMemoryTimingModel(completeConfig: CompleteConfig, hostParams: Paramet
|
|||
case None => println(" No LLC Model Instantiated\n")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Accepts an elaborated memory model and generates a runtime configuration for it
|
||||
private def emitSettings(fileName: String, settings: Seq[(String, String)])(implicit p: Parameters): Unit = {
|
||||
val file = new File(p(OutputDir), fileName)
|
||||
val writer = new FileWriter(file, wId != 0)
|
||||
settings.foreach({
|
||||
case (field, value) => writer.write(s"+mm_${field}_${wId}=${value}\n")
|
||||
})
|
||||
writer.close
|
||||
}
|
||||
/**
|
||||
* Disambiguates between multiple fased instances by using wId (this
|
||||
* increments for each instantion of widgets of the same class), which
|
||||
* is defined in Widget
|
||||
*/
|
||||
def settingsToString(settings: Seq[(String, String)]): String =
|
||||
settings.map { case (field, value) => s"+mm_${field}_${wId}=${value}" }.mkString("\n")
|
||||
|
||||
def getSettings(fileName: String)(implicit p: Parameters) {
|
||||
println("\nGenerating a Midas Memory Model Configuration File")
|
||||
val functionalModelSettings = funcModelRegs.getFuncModelSettings()
|
||||
val timingModelSettings = model.io.mmReg.getTimingModelSettings()
|
||||
emitSettings(fileName, functionalModelSettings ++ timingModelSettings)
|
||||
}
|
||||
/**
|
||||
* Used by the runtime configuration generator, and not the main GG flow.
|
||||
*/
|
||||
def getSettings: String = {
|
||||
println("\nGenerating a Midas Memory Model Configuration File")
|
||||
val functionalModelSettings = module.funcModelRegs.getFuncModelSettings()
|
||||
val timingModelSettings = module.model.io.mmReg.getTimingModelSettings()
|
||||
settingsToString(functionalModelSettings ++ timingModelSettings)
|
||||
}
|
||||
|
||||
def getDefaultSettings(fileName: String)(implicit p: Parameters) {
|
||||
val functionalModelSettings = funcModelRegs.getDefaults()
|
||||
val timingModelSettings = model.io.mmReg.getDefaults()
|
||||
emitSettings(fileName, functionalModelSettings ++ timingModelSettings)
|
||||
}
|
||||
override def defaultPlusArgs: Option[String] = {
|
||||
val functionalModelSettings = module.funcModelRegs.getDefaults()
|
||||
val timingModelSettings = module.model.io.mmReg.getDefaults()
|
||||
Some(settingsToString(functionalModelSettings ++ timingModelSettings))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -24,39 +24,39 @@ import freechips.rocketchip.diplomacy.LazyModule
|
|||
|
||||
import midas.core._
|
||||
import midas.platform.PlatformShim
|
||||
import midas.stage.{OutputFileBuilder, GoldenGateOutputFileAnnotation}
|
||||
|
||||
private[passes] class SimulationMapping(targetName: String) extends firrtl.Transform {
|
||||
def inputForm = LowForm
|
||||
def outputForm = HighForm
|
||||
override def name = "[Golden Gate] Simulation Mapping"
|
||||
|
||||
private def dumpHeader(c: PlatformShim, dir: File) {
|
||||
private def generateHeaderAnnos(c: PlatformShim): Seq[GoldenGateOutputFileAnnotation] = {
|
||||
def vMacro(arg: (String, Long)): String = s"`define ${arg._1} ${arg._2}\n"
|
||||
|
||||
val csb = new StringBuilder
|
||||
val csb = new OutputFileBuilder(
|
||||
"""// Golden Gate-generated Driver Header
|
||||
|// This contains target-specific preprocessor macro definitions,
|
||||
|// and encodes all required bridge metadata to instantiate bridge drivers.
|
||||
|""".stripMargin,
|
||||
fileSuffix = ".const.h")
|
||||
csb append "#ifndef __%s_H\n".format(targetName.toUpperCase)
|
||||
csb append "#define __%s_H\n".format(targetName.toUpperCase)
|
||||
c.genHeader(csb, targetName)
|
||||
c.genHeader(csb.getBuilder, targetName)
|
||||
csb append "#endif // __%s_H\n".format(targetName.toUpperCase)
|
||||
|
||||
val vsb = new StringBuilder
|
||||
val vsb = new OutputFileBuilder(
|
||||
"""// Golden Gate-generated Verilog Header
|
||||
|// This file encodes variable width fields used in MIDAS-level simulation
|
||||
|// and is not used in FPGA compilation flows.
|
||||
|""".stripMargin,
|
||||
fileSuffix = ".const.vh")
|
||||
|
||||
vsb append "`ifndef __%s_H\n".format(targetName.toUpperCase)
|
||||
vsb append "`define __%s_H\n".format(targetName.toUpperCase)
|
||||
c.top.module.headerConsts map vMacro addString vsb
|
||||
c.top.module.headerConsts map vMacro foreach vsb.append
|
||||
vsb append "`endif // __%s_H\n".format(targetName.toUpperCase)
|
||||
|
||||
val ch = new FileWriter(new File(dir, s"${targetName}-const.h"))
|
||||
val vh = new FileWriter(new File(dir, s"${targetName}-const.vh"))
|
||||
|
||||
try {
|
||||
ch write csb.result
|
||||
vh write vsb.result
|
||||
} finally {
|
||||
ch.close
|
||||
vh.close
|
||||
csb.clear
|
||||
vsb.clear
|
||||
}
|
||||
Seq(csb.toAnnotation, vsb.toAnnotation)
|
||||
}
|
||||
|
||||
// Note: this only runs on the SimulationWrapper Module
|
||||
|
@ -110,9 +110,9 @@ private[passes] class SimulationMapping(targetName: String) extends firrtl.Trans
|
|||
}).getOrElse(throw new Exception("TargetBoxAnnotation not found or annotated top module!"))
|
||||
val targetBoxParent = targetBoxInstTarget.encapsulatingModule
|
||||
val targetBoxInst = targetBoxInstTarget.instance
|
||||
val modules = innerCircuit.modules ++ (outerCircuit.modules flatMap
|
||||
init(innerCircuit.info, innerCircuit.main, targetType, targetBoxParent, targetBoxInst))
|
||||
|
||||
val modules = (outerCircuit.modules flatMap
|
||||
init(innerCircuit.info, innerCircuit.main, targetType, targetBoxParent, targetBoxInst)) ++
|
||||
innerCircuit.modules
|
||||
// Rename the annotations from the inner module, which are using an obsolete CircuitName
|
||||
val renameMap = RenameMap(
|
||||
Map(CircuitName(innerCircuit.main) -> Seq(CircuitName(outerCircuit.main))))
|
||||
|
@ -129,8 +129,7 @@ private[passes] class SimulationMapping(targetName: String) extends firrtl.Trans
|
|||
renames = Some(renameMap)
|
||||
)
|
||||
writeState(linkedState, "post-sim-mapping.fir")
|
||||
dumpHeader(shim, p(OutputDir))
|
||||
linkedState
|
||||
linkedState.copy(annotations = linkedState.annotations ++ generateHeaderAnnos(shim))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -48,3 +48,16 @@ object RuntimeConfigNameAnnotation extends HasShellOptions {
|
|||
shortOption = Some("ggrc"),
|
||||
helpValueName = Some("<filename>") ) )
|
||||
}
|
||||
|
||||
case class OutputBaseFilenameAnnotation(name: String) extends NoTargetAnnotation with GoldenGateOption
|
||||
|
||||
object OutputBaseFilenameAnnotation extends HasShellOptions {
|
||||
val options = Seq(
|
||||
new ShellOption[String](
|
||||
longOption = "output-filename-base",
|
||||
toAnnotationSeq = (a: String) => Seq(OutputBaseFilenameAnnotation(a)),
|
||||
helpText = "Specifies the base (prefix) used on Golden Gate generated files.",
|
||||
shortOption = Some("ofb"),
|
||||
helpValueName = Some("<output-filename-base>") ) )
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ trait GoldenGateCli { this: Shell =>
|
|||
parser.note("Golden Gate Compiler Options")
|
||||
Seq(ConfigPackageAnnotation,
|
||||
ConfigStringAnnotation,
|
||||
OutputBaseFilenameAnnotation,
|
||||
firrtl.stage.FirrtlFileAnnotation,
|
||||
firrtl.stage.OutputFileAnnotation,
|
||||
firrtl.stage.FirrtlSourceAnnotation,
|
||||
|
|
|
@ -40,7 +40,7 @@ class GoldenGateCompilerPhase extends Phase {
|
|||
|
||||
// Lower and emit simulator RTL and run user-requested host-transforms
|
||||
val hostLoweringCompiler = new Compiler(
|
||||
Dependency[firrtl.VerilogEmitter] +:
|
||||
Dependency[firrtl.SystemVerilogEmitter] +:
|
||||
p(HostTransforms),Forms.LowForm)
|
||||
logger.info("Post-GG Host Transformation Ordering\n")
|
||||
logger.info(hostLoweringCompiler.prettyPrint(" "))
|
||||
|
|
|
@ -5,28 +5,36 @@ package midas.stage
|
|||
import firrtl.annotations.{NoTargetAnnotation, Annotation}
|
||||
import firrtl.options.{CustomFileEmission}
|
||||
|
||||
import chisel3.experimental.{annotate, ChiselAnnotation}
|
||||
|
||||
trait GoldenGateFileEmission extends CustomFileEmission { this: Annotation =>
|
||||
|
||||
// workaround CustomFileEmission's requirement that suffixes begin with ".".
|
||||
// by shadowing the same feature, and appending it ourselves. This is the
|
||||
// easiest way to preserve most of the existing output file names.
|
||||
def fileSuffix: String
|
||||
final def suffix = None
|
||||
|
||||
override def baseFileName(annotations: firrtl.AnnotationSeq) = {
|
||||
val baseName = annotations.collectFirst{ case OutputBaseFileNameAnnotation(name) => name }.get
|
||||
baseName + fileSuffix
|
||||
annotations.collectFirst{ case OutputBaseFilenameAnnotation(name) => name }.get
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A generic wrapper for output files that have no targets.
|
||||
*
|
||||
* @param body the body of the file
|
||||
* @param fileSuffix The string to append to base output file name
|
||||
*
|
||||
*/
|
||||
case class GoldenGateOutputFileAnnotation(body: String, fileSuffix: String)
|
||||
extends NoTargetAnnotation with GoldenGateFileEmission {
|
||||
def suffix = Some(fileSuffix)
|
||||
def getBytes = body.getBytes
|
||||
}
|
||||
|
||||
object GoldenGateOutputFileAnnotation {
|
||||
/**
|
||||
* Sugar to add a new output file from a chisel source (e.g., in a bridge, platform shim)
|
||||
*/
|
||||
def annotateFromChisel(body: String, fileSuffix: String): Unit = {
|
||||
annotate(new ChiselAnnotation { def toFirrtl = GoldenGateOutputFileAnnotation(body, fileSuffix) })
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps a StringBuilder to incrementally build up an output file annotation.
|
||||
*/
|
||||
|
|
|
@ -10,13 +10,19 @@ import midas.platform.PlatformShim
|
|||
import freechips.rocketchip.diplomacy.{LazyModule, ValName}
|
||||
|
||||
import firrtl.ir.Port
|
||||
import firrtl.annotations.ReferenceTarget
|
||||
import firrtl.annotations.{ReferenceTarget, NoTargetAnnotation}
|
||||
import firrtl.{Transform, CircuitState, AnnotationSeq}
|
||||
import firrtl.options.{Phase, TargetDirAnnotation, Dependency}
|
||||
import firrtl.options.{Phase, TargetDirAnnotation, Dependency, CustomFileEmission}
|
||||
|
||||
import java.io.{File, FileWriter, Writer}
|
||||
import logger._
|
||||
|
||||
private [stage] case class RuntimeConfigurationFile(name: String, body: String) extends NoTargetAnnotation with CustomFileEmission {
|
||||
override def suffix = None
|
||||
def baseFileName(annos: AnnotationSeq) = name
|
||||
def getBytes = body.getBytes
|
||||
}
|
||||
|
||||
class RuntimeConfigGenerationPhase extends Phase {
|
||||
|
||||
override val prerequisites = Seq(Dependency[CreateParametersInstancePhase])
|
||||
|
@ -32,11 +38,12 @@ class RuntimeConfigGenerationPhase extends Phase {
|
|||
val fasedBridges = shim.top.bridgeModuleMap.values.collect { case f: FASEDMemoryTimingModel => f }
|
||||
// Since presently all memory models share the same runtime configuration. Grab only the first
|
||||
// FASED BridgeAnnotation, and use that to elaborate a memory model
|
||||
fasedBridges.headOption.map({ lm =>
|
||||
lazy val fasedBridge = lm.module
|
||||
chisel3.stage.ChiselStage.elaborate(fasedBridge)
|
||||
fasedBridge.getSettings(runtimeConfigName)
|
||||
val settings = fasedBridges.headOption.map({ lm =>
|
||||
lazy val fasedBridge = lm
|
||||
chisel3.stage.ChiselStage.elaborate(fasedBridge.module)
|
||||
fasedBridge.getSettings
|
||||
})
|
||||
annotations
|
||||
|
||||
RuntimeConfigurationFile(runtimeConfigName, settings.getOrElse("\n")) +: annotations
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// See LICENSE.SiFive for license details.
|
||||
// See LICENSE for license details.
|
||||
|
||||
package midas.widgets
|
||||
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
package midas
|
||||
package widgets
|
||||
|
||||
import midas.stage.GoldenGateOutputFileAnnotation
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
import chisel3.experimental.DataMirror
|
||||
|
@ -55,6 +57,8 @@ abstract class Widget()(implicit p: Parameters) extends LazyModule()(p) {
|
|||
def memRegionSize = customSize.getOrElse(BigInt(1 << log2Up(module.numRegs * (module.io.ctrl.nastiXDataBits/8))))
|
||||
|
||||
def printCRs = module.crRegistry.printCRs
|
||||
|
||||
def defaultPlusArgs: Option[String] = None
|
||||
}
|
||||
|
||||
abstract class WidgetImp(wrapper: Widget) extends LazyModuleImp(wrapper) {
|
||||
|
@ -254,4 +258,17 @@ trait HasWidgets {
|
|||
val base = (addrMap(w.getWName).start >> log2Up(channelWidth/8))
|
||||
base + w.getCRAddr(crName)
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterates through all bound widgets requesting default plusArgs if
|
||||
* applicable, which are then serialized to a file. This is mostly useful
|
||||
* for bridges that do not have defaults baked into the driver, such as
|
||||
* FASED, where plus args _must_ be provided.
|
||||
*/
|
||||
def emitDefaultPlusArgsFile(): Unit =
|
||||
GoldenGateOutputFileAnnotation.annotateFromChisel(
|
||||
// Append an extra \n to prevent the file from being empty.
|
||||
body = widgets.map(_.defaultPlusArgs).flatten.mkString("\n") + "\n",
|
||||
fileSuffix = ".runtime.conf"
|
||||
)
|
||||
}
|
||||
|
|
|
@ -19,6 +19,9 @@ name_tuple := $(DESIGN)-$(TARGET_CONFIG)-$(PLATFORM_CONFIG)
|
|||
GENERATED_DIR := $(firesim_base_dir)/generated-src/$(PLATFORM)/$(name_tuple)
|
||||
OUTPUT_DIR := $(firesim_base_dir)/output/$(PLATFORM)/$(name_tuple)
|
||||
|
||||
# This is prefix is currently assumed by the fpga build flow
|
||||
BASE_FILE_NAME := FireSim-generated
|
||||
|
||||
##################
|
||||
# RTL Generation #
|
||||
##################
|
||||
|
@ -26,10 +29,6 @@ long_name := $(DESIGN_PACKAGE).$(DESIGN).$(TARGET_CONFIG)
|
|||
FIRRTL_FILE := $(GENERATED_DIR)/$(long_name).fir
|
||||
ANNO_FILE := $(GENERATED_DIR)/$(long_name).anno.json
|
||||
|
||||
VERILOG := $(GENERATED_DIR)/FPGATop.v
|
||||
HEADER := $(GENERATED_DIR)/$(DESIGN)-const.h
|
||||
|
||||
CONF_NAME ?= runtime.conf
|
||||
firesim_sbt_project := {file:${firesim_base_dir}/}firesim
|
||||
chisel_src_dirs = \
|
||||
$(addprefix $(firesim_base_dir)/,. midas midas/targetutils firesim-lib) \
|
||||
|
|
|
@ -19,6 +19,9 @@ name_tuple := $(DESIGN)-$(TARGET_CONFIG)-$(PLATFORM_CONFIG)
|
|||
GENERATED_DIR := $(firesim_base_dir)/generated-src/$(PLATFORM)/$(name_tuple)
|
||||
OUTPUT_DIR := $(firesim_base_dir)/output/$(PLATFORM)/$(name_tuple)
|
||||
|
||||
# This is prefix is currently assumed by the fpga build flow
|
||||
BASE_FILE_NAME := FireSim-generated
|
||||
|
||||
##################
|
||||
# RTL Generation #
|
||||
##################
|
||||
|
@ -26,9 +29,6 @@ long_name := $(DESIGN_PACKAGE).$(DESIGN).$(TARGET_CONFIG)
|
|||
FIRRTL_FILE := $(GENERATED_DIR)/$(long_name).fir
|
||||
ANNO_FILE := $(GENERATED_DIR)/$(long_name).anno.json
|
||||
|
||||
VERILOG := $(GENERATED_DIR)/FPGATop.v
|
||||
HEADER := $(GENERATED_DIR)/$(DESIGN)-const.h
|
||||
|
||||
ifdef FIRESIM_STANDALONE
|
||||
firesim_sbt_project := {file:${chipyard_dir}}firechip
|
||||
|
||||
|
@ -72,7 +72,7 @@ DROMAJO_DTB = $(GENERATED_DIR)/$(long_name).dtb
|
|||
$(DROMAJO_LIB):
|
||||
$(MAKE) -C $(DROMAJO_DIR)
|
||||
|
||||
$(DROMAJO_LONG_H) $(DTS_FILE): $(VERILOG)
|
||||
$(DROMAJO_LONG_H) $(DTS_FILE): $(simulator_verilog)
|
||||
|
||||
$(DROMAJO_H): $(DROMAJO_LONG_H)
|
||||
rm -rf $(DROMAJO_H)
|
||||
|
@ -133,7 +133,7 @@ DEFAULT_MIDAS_VERILATOR_FLAGS = \
|
|||
|
||||
# AJG: this must be evaluated after verilog generation to work (hence the =)
|
||||
EXTRA_VERILATOR_FLAGS = \
|
||||
$(shell if ! grep -iq "module.*cva6" $(VERILOG); then echo "$(DEFAULT_MIDAS_VERILATOR_FLAGS)"; else echo "$(CVA6_VERILATOR_FLAGS)"; fi)
|
||||
$(shell if ! grep -iq "module.*cva6" $(simulator_verilog); then echo "$(DEFAULT_MIDAS_VERILATOR_FLAGS)"; else echo "$(CVA6_VERILATOR_FLAGS)"; fi)
|
||||
|
||||
################################################################
|
||||
# SW RTL Simulation Args -- for MIDAS- & FPGA-level Simulation #
|
||||
|
|
|
@ -14,6 +14,9 @@ name_tuple := $(DESIGN)-$(TARGET_CONFIG)-$(PLATFORM_CONFIG)
|
|||
GENERATED_DIR := $(firesim_base_dir)/generated-src/$(PLATFORM)/$(name_tuple)
|
||||
OUTPUT_DIR := $(firesim_base_dir)/output/$(PLATFORM)/$(name_tuple)
|
||||
|
||||
# This is prefix is currently assumed by the fpga build flow
|
||||
BASE_FILE_NAME := FireSim-generated
|
||||
|
||||
##########################
|
||||
# RTL Generation #
|
||||
##########################
|
||||
|
@ -21,9 +24,6 @@ long_name := $(DESIGN_PACKAGE).$(DESIGN).$(TARGET_CONFIG)
|
|||
FIRRTL_FILE := $(GENERATED_DIR)/$(long_name).fir
|
||||
ANNO_FILE := $(GENERATED_DIR)/$(long_name).anno.json
|
||||
|
||||
VERILOG := $(GENERATED_DIR)/FPGATop.v
|
||||
HEADER := $(GENERATED_DIR)/$(DESIGN)-const.h
|
||||
|
||||
ifdef FIRESIM_STANDALONE
|
||||
firesim_sbt_project := firesim
|
||||
else
|
||||
|
@ -37,8 +37,6 @@ chisel_src_dirs = \
|
|||
chisel_srcs = $(foreach submodule,$(chisel_src_dirs),\
|
||||
$(shell find $(submodule)/ -iname "[!.]*.scala" -print 2> /dev/null | grep 'src/main/scala'))
|
||||
|
||||
CONF_NAME ?= runtime.conf
|
||||
|
||||
SIM_RUNTIME_CONF ?= $(GENERATED_DIR)/$(CONF_NAME)
|
||||
mem_model_args = $(shell cat $(SIM_RUNTIME_CONF))
|
||||
COMMON_SIM_ARGS ?= $(mem_model_args)
|
||||
|
@ -51,8 +49,6 @@ $(FIRRTL_FILE) $(ANNO_FILE): $(chisel_srcs) $(FIRRTL_JAR) $(SCALA_BUILDTOOL_DEPS
|
|||
--name $(long_name) \
|
||||
--top-module $(DESIGN_PACKAGE).$(DESIGN) \
|
||||
--legacy-configs $(TARGET_CONFIG_PACKAGE):$(TARGET_CONFIG))
|
||||
# Remove once runtime conf generation is generalized, and something is always emitted
|
||||
touch $(GENERATED_DIR)/$(CONF_NAME)
|
||||
|
||||
##########################
|
||||
# Driver Sources & Flags #
|
||||
|
@ -75,7 +71,7 @@ TARGET_LD_FLAGS :=
|
|||
# PointerChaser requires a custom memory initialization
|
||||
ifeq ($(DESIGN),PointerChaser)
|
||||
LOADMEM ?= $(GENERATED_DIR)/mem_init.hex
|
||||
ARGS ?= `cat runtime.conf`
|
||||
ARGS ?= `cat $(SIM_RUNTIME_CONF)`
|
||||
|
||||
$(LOADMEM): src/main/resources/midasexamples/generate_memory_init.py
|
||||
$< --output_file $@
|
||||
|
|
|
@ -1,6 +1,18 @@
|
|||
# See LICENSE for license details.
|
||||
|
||||
# FireSim MAKEFRAG interface - Compulsory variables follow
|
||||
# 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 ?=
|
||||
|
@ -9,16 +21,7 @@ OUTPUT_DIR ?=
|
|||
# Root name for generated binaries
|
||||
DESIGN ?=
|
||||
|
||||
# SOURCE FILES
|
||||
# Driver source files
|
||||
DRIVER_CC ?=
|
||||
DRIVER_H ?=
|
||||
# Simulation memory map emitted by the MIDAS compiler
|
||||
HEADER ?=
|
||||
# The midas-generated simulator RTL which will be baked into the FPGA shell project
|
||||
VERILOG ?=
|
||||
|
||||
# The target's FIRRTL and associated anotations
|
||||
# The target's FIRRTL and associated anotations; inputs to Golden Gate
|
||||
FIRRTL_FILE ?=
|
||||
ANNO_FILE ?=
|
||||
|
||||
|
@ -27,12 +30,16 @@ PLATFORM_CONFIG_PACKAGE ?= firesim.midasexamples
|
|||
PLATFORM_CONFIG ?= DefaultF1Config
|
||||
|
||||
# The name of the generated runtime configuration file
|
||||
CONF_NAME ?= runtime.conf
|
||||
CONF_NAME ?= $(BASE_FILE_NAME).runtime.conf
|
||||
|
||||
# The host platform type
|
||||
PLATFORM ?= f1
|
||||
# The host platform type, currently only f1 is supported
|
||||
PLATFORM ?=
|
||||
|
||||
# Target-specific CXX and LD flags
|
||||
# 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 ?=
|
||||
|
||||
|
@ -43,6 +50,11 @@ 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 #
|
||||
####################################
|
||||
|
@ -51,20 +63,30 @@ firesim_root_sbt_project := {file:$(firesim_base_dir)}firesim
|
|||
# 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
|
||||
$(VERILOG) $(HEADER) $(fame_annos): $(FIRRTL_FILE) $(ANNO_FILE) $(SCALA_BUILDTOOL_DEPS)
|
||||
$(simulator_verilog).intermediate: $(FIRRTL_FILE) $(ANNO_FILE) $(SCALA_BUILDTOOL_DEPS)
|
||||
$(call run_scala_main,$(firesim_sbt_project),midas.stage.GoldenGateMain,\
|
||||
-o $(VERILOG) -i $(FIRRTL_FILE) -td $(GENERATED_DIR) \
|
||||
-o $(simulator_verilog) -i $(FIRRTL_FILE) -td $(GENERATED_DIR) \
|
||||
-faf $(ANNO_FILE) \
|
||||
-ggcp $(PLATFORM_CONFIG_PACKAGE) \
|
||||
-ggcs $(PLATFORM_CONFIG) \
|
||||
--output-filename-base $(BASE_FILE_NAME) \
|
||||
--no-dedup \
|
||||
-E verilog \
|
||||
-E sverilog \
|
||||
)
|
||||
grep -sh ^ $(GENERATED_DIR)/firrtl_black_box_resource_files.f | \
|
||||
xargs cat >> $(VERILOG) # Append blackboxes to FPGA wrapper, if any
|
||||
xargs cat >> $(simulator_verilog) # Append blackboxes to FPGA wrapper, if any
|
||||
|
||||
####################################
|
||||
# Runtime-Configuration Generation #
|
||||
|
@ -77,8 +99,6 @@ $(VERILOG) $(HEADER) $(fame_annos): $(FIRRTL_FILE) $(ANNO_FILE) $(SCALA_BUILDTOO
|
|||
.PHONY: conf
|
||||
conf: $(fame_annos)
|
||||
mkdir -p $(GENERATED_DIR)
|
||||
# Runtime configuration generator must run under SBT currently; When
|
||||
# launched via bloop some Console input and output is lost.
|
||||
cd $(base_dir) && $(SBT) "project $(firesim_sbt_project)" "runMain midas.stage.RuntimeConfigGeneratorMain \
|
||||
-td $(GENERATED_DIR) \
|
||||
-faf $(fame_annos) \
|
||||
|
@ -99,12 +119,12 @@ 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) $(VERILOG)
|
||||
$(MAKE) $(VERILATOR_MAKEFLAGS) -C $(simif_dir) verilator PLATFORM=$(PLATFORM) DESIGN=$(DESIGN) \
|
||||
$(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) $(VERILOG)
|
||||
$(MAKE) $(VERILATOR_MAKEFLAGS) -C $(simif_dir) verilator-debug PLATFORM=$(PLATFORM) DESIGN=$(DESIGN) \
|
||||
$(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
|
||||
|
@ -123,12 +143,12 @@ 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) $(VERILOG)
|
||||
$(MAKE) -C $(simif_dir) vcs PLATFORM=$(PLATFORM) DESIGN=$(DESIGN) \
|
||||
$(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) $(VERILOG)
|
||||
$(MAKE) -C $(simif_dir) vcs-debug PLATFORM=$(PLATFORM) DESIGN=$(DESIGN) \
|
||||
$(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
|
||||
|
@ -140,12 +160,8 @@ vcs-debug: $(vcs_debug)
|
|||
############################
|
||||
DRIVER_CXXOPTS ?= -O2
|
||||
|
||||
$(OUTPUT_DIR)/$(DESIGN).chain: $(VERILOG)
|
||||
mkdir -p $(OUTPUT_DIR)
|
||||
$(if $(wildcard $(GENERATED_DIR)/$(DESIGN).chain),cp $(GENERATED_DIR)/$(DESIGN).chain $@,)
|
||||
|
||||
$(PLATFORM) = $(OUTPUT_DIR)/$(DESIGN)-$(PLATFORM)
|
||||
$(PLATFORM): $($(PLATFORM)) $(OUTPUT_DIR)/$(DESIGN).chain
|
||||
$(PLATFORM): $($(PLATFORM))
|
||||
|
||||
fpga_dir = $(firesim_base_dir)/../platforms/$(PLATFORM)/aws-fpga
|
||||
|
||||
|
@ -154,11 +170,12 @@ $(f1): export CXXFLAGS := $(CXXFLAGS) $(common_cxx_flags) $(DRIVER_CXXOPTS) -I$(
|
|||
$(f1): export LDFLAGS := $(LDFLAGS) $(common_ld_flags) -lfpga_mgmt
|
||||
|
||||
# Compile Driver
|
||||
$(f1): $(HEADER) $(DRIVER_CC) $(DRIVER_H) $(midas_cc) $(midas_h) $(runtime_conf)
|
||||
$(f1): $(header) $(DRIVER_CC) $(DRIVER_H) $(midas_cc) $(midas_h)
|
||||
mkdir -p $(OUTPUT_DIR)/build
|
||||
cp $(HEADER) $(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 DESIGN=$(DESIGN) \
|
||||
$(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)
|
||||
|
||||
|
@ -169,38 +186,27 @@ 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
|
||||
fpga_v := $(fpga_work_dir)/design/cl_firesim_generated.sv
|
||||
ila_work_dir := $(fpga_work_dir)/design/ila_files/
|
||||
fpga_vh := $(fpga_work_dir)/design/cl_firesim_generated_defines.vh
|
||||
fpga_tcl_env := $(fpga_work_dir)/design/cl_firesim_generated_env.tcl
|
||||
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 \
|
||||
.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 $@
|
||||
|
||||
$(fpga_v): $(VERILOG) $(fpga_work_dir)/stamp
|
||||
$(repo_state): $(simulator_verilog) $(fpga_work_dir)/stamp
|
||||
$(firesim_base_dir)/../scripts/repo_state_summary.sh > $(repo_state)
|
||||
cp -f $< $@
|
||||
sed -i "s/\$$random/64'b0/g" $@
|
||||
sed -i "s/\(^ *\)fatal;\( *$$\)/\1fatal(0, \"\");\2/g" $@
|
||||
|
||||
$(fpga_vh): $(VERILOG) $(fpga_work_dir)/stamp
|
||||
$(fpga_work_dir)/design/$(BASE_FILE_NAME)%: $(simulator_verilog) $(fpga_work_dir)/stamp
|
||||
cp -f $(GENERATED_DIR)/$(@F) $@
|
||||
|
||||
$(fpga_tcl_env): $(VERILOG) $(fpga_work_dir)/stamp
|
||||
cp -f $(GENERATED_DIR)/$(@F) $@
|
||||
|
||||
.PHONY: $(ila_work_dir)
|
||||
$(ila_work_dir): $(verilog) $(fpga_work_dir)/stamp
|
||||
cp -f $(GENERATED_DIR)/firesim_ila_insert_* $(fpga_work_dir)/design/ila_files/
|
||||
sed -i "s/\$$random/64'b0/g" $(fpga_work_dir)/design/ila_files/*
|
||||
sed -i "s/\(^ *\)fatal;\( *$$\)/\1fatal(0, \"\");\2/g" $(fpga_work_dir)/design/ila_files/*
|
||||
|
||||
# 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_v) $(ila_work_dir) $(fpga_vh) $(fpga_tcl_env)
|
||||
replace-rtl: $(fpga_delivery_files)
|
||||
|
||||
.PHONY: replace-rtl
|
||||
|
||||
|
@ -210,7 +216,7 @@ $(firesim_base_dir)/scripts/checkpoints/$(target_sim_tuple): $(fpga_work_dir)/st
|
|||
|
||||
# Runs a local fpga-bitstream build. Strongly consider using the manager instead.
|
||||
fpga: export CL_DIR := $(fpga_work_dir)
|
||||
fpga: $(fpga_v) $(base_dir)/scripts/checkpoints/$(target_sim_tuple)
|
||||
fpga: $(fpga_delivery_files) $(base_dir)/scripts/checkpoints/$(target_sim_tuple)
|
||||
cd $(fpga_build_dir)/scripts && ./aws_build_dcp_from_cl.sh -notify
|
||||
|
||||
|
||||
|
@ -228,8 +234,8 @@ 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 DESIGN=$(DESIGN) \
|
||||
$(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)
|
||||
|
||||
|
@ -287,10 +293,9 @@ clean:
|
|||
veryclean:
|
||||
rm -rf generated-src output
|
||||
|
||||
tags: $(HEADER) $(DRIVER_CC) $(DRIVER_H) $(midas_cc) $(midas_h)
|
||||
tags: $(header) $(DRIVER_CC) $(DRIVER_H) $(midas_cc) $(midas_h)
|
||||
ctags -R --exclude=@.ctagsignore .
|
||||
|
||||
.PHONY: default verilog compile
|
||||
.PHONY: $(PLATFORM)-driver fpga
|
||||
.PHONY: mostlyclean clean
|
||||
|
||||
|
|
Loading…
Reference in New Issue