The build system is built on GNU Makefile with helper scripts that provide the following functionality:
- Perform dependency analysis that enables discovery and compilation of dependent files from a top level file
- Generate simulation scripts, synthesis projects, as well as QSYS systems and megafunction IP cores
- Execute simulation and synthesis target programs after completing all preparatory steps.
Run make help
for a list of targets, and make helpall
for descriptions.
To get started
- clone or copy the hdl_build repository
- to choose global default tools, create
defaults.mk
, or locally setSIM_TOOL
and/orSYNTH_TOOL
in your makefiledefaults.mk
is placed in the root of the hdl_build repo. Seeexamples/example-defaults.mk
for a template
- copy the
examples/example.mk
file to your project build directory and rename it toMakefile
example.mk
has the minimum for both sim and synth targets, with a QSF_EXTRA setting that will allow synthesis without worrying about pin assignments.- See
examples/example-full-sim.mk
andexamples/example-full-synth.mk
for examples of more options
- edit
Makefile
- add the correct simulation top module name as
TOP_SIM
and/or correct synthesis top module name asTOP_SYNTH
- set correct path to the hdl_build repository. For flexibility, the examples use an environment variable
$HDL_BUILD_PATH
to help committed build files work in multiple environments, but a fixed path would work too.
- add the correct simulation top module name as
- run
make sim
ormake synth
- synthesis projects require setting
FAMILY
andDEVICE
- synthesis projects require setting
See the full makefile examples for adding other features to your project Makefile.
This build system depends on Intel Quartus, Siemens Questa or Modelsim, and Vivado xsim for synthesis and simulation. Other tools could be added.
The tool commands (vsim
, quartus
, etc.) need to be in the path already.
Quartus synthesis requires two variables in the use Makefile to create a project:
FAMILY
, for exampleFAMILY := "Arria 10"
DEVICE
, for exampleDEVICE := 10AS123N2F40I2SG
Quartus install path must have the string "pro" in it if using Quartus Pro, and must not have "pro" in it if using Quartus Standard. The default path name of intelFPGA_pro
meets this requirement.
Python 3.6 or higher is required, with the PyYAML yaml package installed for substitution files. If Python 3.6 is not available, replace all the 'f' strings with .format strings.
The build system is designed to run within a git repository. To work outside of a repo see section "Outside of git".
To add new makefiles that are not upstreamed, create *_addon.mk
or *_custom.mk
makefiles in the base directory. These files will be included by build.mk
, but keeping them as separate files reduces merge/rebase conflicts. The _custom.mk
suffix is ignored by git and is intended to be used for files you do not want committed at all.
Module, package, and include dependencies are automatically determined for verilog sources.
- Modules can only be implemented in files with
.v
or.sv
extensions. Non-HDL modules like vendor IP are not discovered automatically and must be specified as asubtitution
. - The module name must be the same as the "base" of the filename. For example, module
fifo
could be implemented asfifo.sv
.- Megafunction IP cores should be saved using the
_qmw.v
suffix. This is the only exception where the filename can be different than the module name. For example, a PLL calledclkgen
should be stored asclkgen_qmw.v
(this is the file that has the megawizard settings embedded as comments). The module name in the code should still beclkgen
without the_qmw
extension. The build system will automatically handle building the megafunction for synthesis.
- Megafunction IP cores should be saved using the
- Only a single module definition is allowed per file.
- Header files included by preprocessor
`include
must use.svh
or.vh
extension. - In cases where a module needs to be replaced with a sim-only or synth-only module, use
SIM_SUBSTITUTIONS
orSYNTH_SUBSTITUTIONS
. Modules used as substitutions do not need follow any naming conventions because they will be found by direct path rather than the built-in search capability, but the module name used in the substitution must match the module being substituted.
The build system can be included in a local Makefile with the following include line in the makefile:
include $(HDL_BUILD_PATH)/build.mk
or
include /path/to/hdl_build/build.mk
- As a general guide:
- variables used under
build.mk
need to be set before the include. - hooks are rules defined under
build.mk
need to be tied into after the include.
- variables used under
- The tool chain needs an entry point defined, such as
TOP_SIM
for simulation andTOP_SYNTH
for synthesis.
The build.mk
file provides the entry point and the basic structure for the build system. Use make help
for an up-to-date list of targets provided.
VERBOSE
: Set VERBOSE=1 for a call to make to run fully verbose commandsNOUPDATE
: Set NOUPDATE=1 for a call to make to print every line instead of updatingSLOW
: Set SLOW=1 for a call to make to disable parallel buildingGIT_REPO
: this variable is only defined if the Makefile is in a git repository (test if git repo with make'sifdef
)SRC_BASE_DIR
: directory that holds all relevant source code. Will be determined automatically if in a git repository.IGNORE_FILE
:touch .ignore_build_system
in a directory that should be ignored by the build systemBLD_DIR
: directory where build results are stored$(predependency_hook)
: target hook to run something before dependency analysisSIM_TOOL
: select which simulation tool should be used: modelsim, questa or qverify, vivadoSYNTH_TOOL
: select which synthesis tool should be used: quartuspro, quartus or vivadoIGNORE_DIRS
: a list of space delineated directory names to ignore during dependency searchEXTRA_DIRS
: a list of space delineated directory names to add during dependency search. This is only useful for directories normally ignored by the build system or a directory outside theSRC_BASE_DIR
directory.clean
: target to force redo of build steps and remove previous logscleanall
: target to remove all build resultsnuke
: target to alias for cleanalllist_targets
: target to list all available Makefile targetsprint-%
: target to usemake print-VARIABLE_NAME
to examineVARIABLE_NAME
's value.make print-BLD_DIR
print-Makefiles
: target to print a list of all included makefileshelp
: target to show brief help.helpall
: target to show this help.
The modelsim.mk
or questa.mk
file provides simulator related targets and consumes the dependency analysis results of build.mk
.
TOP_SIM
: identify the top module to be simulated withTOP_SIM
. If not set,TOP
will be used.SIM_SUBSTITUTIONS
: a space delineated list of eithermodule:filename
mappings, or paths to a yaml file defining mappings. If a mapping is blank, dependency matching for the module is blocked. Seeexamples/example-subs.yml
.SIM_SUBSTITUTIONS = $(shell git_root_path sim_models/sim_all_ipcores.yml) eth_1g:$(shell git_root_path sim_models/1g_sim_model.sv ignorememodule:
SIM_LIB_APPEND
: library string to appned to the library list, like-L $(SIM_LIB_DIR)/customlib
deps
: target to figure out sim dependencies onlycomp
: target to compile simulation filesvopt
: target to perform vopt after compilefilelist_sim
: target to print list of files used in simmodules_sim
: target to print list of modules used in simAC_DIRECTIVES
: Autocheck directives filename, default is ac_directives.tclprintquesta-%
: usemake printquesta-VAR_NAME
to print variable after questa processing$(presimlib_hook)
: target hook to run before sim libraries$(precomp_hook)
: target hook to run before compilation$(presim_hook)
: target hook to run before starting simRESTART_SCRIPT
:bld/restart.do
can be used in the simulator to recompile source and restart the simulation usingrestart -f
. The current session and waveform is backed up first. The first optional parameter islog
which will log all signals and memories after restart. Following parameters will be executed after restart.do bld/restart.do log run 100 ns
will log things and then run for 100 ns. It can be helpful to tie the command to a keyboard shortcut.
RESIM_SCRIPT
:bld/resim.do
can be used in the simulator to recompile source and restart the simulation usingquit -sim
. The current session and waveform is backed up first and the transcript is archived and cleared. The first optional parameter islog
which will log all signals and memories after restart. Following parameters will be executed after restart.do bld/resim.do log run 100 ns
will log things and then run for 100 ns. It can be helpful to tie the command to a keyboard shortcut.
VLOG_OPTIONS
: extra options forvlog
commandVOPT_OPTIONS
: extra options forvopt
commandVSIM_OPTIONS
: extra options forvsim
commandPARAM_*
: monitors variables prefixed withPARAM_
and passes them to simulator.PARAM_NUM_PACKETS := 20
passes a parameter named NUM_PACKETS with value of 20.sim
: target to run simulation in GUIelab_sim
: target to run elaboration batchbatch
: target to run simulation batchautocheck_batch
: (orac_batch
) Run autocheck in console onlyautocheck
: (orac
) Run autocheck GUICOV_COVER_OPT
: Coverage options forvopt
commandCOV_MERGED_UCDB
: Location to store result of accumulated coverage reportCOV_VSIM_OPT
: Coverage options forvsim
commandCOVERAGE_COMMANDS
: commands to add to batch for coveragevopt_coverage
: target to perform vopt for coverage after compilesim_coverage
: target to run simulation in GUI with coverageelab_coverage
: target to run elaboration batch for coveragebatch_coverage
: target to run simulation batch with coveragebatch_accumulate_coverage
: target to run simulation batch with coverage that accumulatescoverage_view
: target to view coveragecoverage_view_all
: target to view accumulated coverageclean_cover_db
: target to remove accumulated coverage ucdb file
The xsim.mk
file provides Vivado simulator targets and consumes the dependency analysis results of build.mk
.
TOP_SIM
: identify the top module to be simulated withTOP_TB
. If not set,TOP
will be used.printxsim-%
: usemake printxsim-VAR_NAME
to print variable after xsim processing$(prexsimlib_hook)
: target hook to run before xsim libraries$(prexcomp_hook)
: target hook to run before compilation$(prexsim_hook)
: target hook to run before starting xsimXVLOG_OPTIONS
: options forxvlog
commandXELAB_OPTIONS
: options for thexelab
commandXSIM_OPTIONS
: options forxsim
commandSIM_SUBSTITUTIONS
: a space delineated list of eithermodule:filename
mappings, or paths to a yaml file defining mappings. If a mapping is blank, dependency matching for the module is blocked. Seeexample-subs.yml
XSIM_LIB_APPEND
: library string to appned to the library list, like-L $(XSIM_LIB_DIR)/customlib
deps
: target to figure out xsim dependencies onlycomp
: target to compile simulation filesfilelist_xsim
: target to print list of files used in xsimmodules_xsim
: target to print list of modules used in xsimPARAM_*
: monitors variables prefixed withPARAM_
and passes them to xsimulator.PARAM_NUM_PACKETS := 20
passes a parameter named NUM_PACKETS with value of 20.elab_sim
: target to run elaboration batchsim
: target to run simulation in GUIbatch
: target to run simulation batch
The quartus.mk
file provides Quartus related targets and consumes the dependency analysis results of build.mk
.
TOP_SYNTH
: identify the top module to be simulated withTOP_SYNTH
. If not set,TOP
will be used.FAMILY
: identify the FPGA product family, like "Stratix 10" or "Agilex". Should match Quartus string in project settingsDEVICE
: identify the FPGA device part number, should match Quartus string in project settingsNUM_TIMING_TRIES
: tell synth_timing number of tries before giving up on timing$(presynth_hook)
: target hook to run before any synth work$(post_qgen_ip_hook)
: target hook to run after ip generation is done, before mappingprintquartus-%
: usemake printquartus-VAR_NAME
to print variable after Quartus processingSYNTH_OVERRIDE
: synthesis enforcesSYNTH_TOOL
version match against tool onPATH
. Run make withSYNTH_OVERRIDE=1
to ignore the check.SYNTH_SUBSTITUTIONS
: a space delineated list of eithermodule:filename
mappings, or paths to a yaml file defining mappings. If a mapping is blank, dependency matching for the module is blocked. Seeexamples/example-subs.yml
.SYNTH_SUBSTITUTIONS = $(shell git_root_path mocks/s10_mocks.yml) eth_100g:$(shell git_root_path mocks/100g_core.ip simonly_check:
QUARTUS_FILE
: file path to a tcl file for Quartus settings that will be included in the QSFXCVR_SETTINGS
: file path to a tcl file for transciever settings that will be included in the QSFSDC_FILE
: file path to an SDC timing constraints file that will be used in the QSFQSF_EXTRA
: a variable string that will be included directly in QSFfilelist_synth
: print list of files used in synthmodules_synth
: print list of modules used in synthPRO_RESULT
: track whether Quartus Pro or Std is being used. If Std, setsVERILOG_MACRO STD_QUARTUS=1
. Always setsVERILOG_MACRO SYNTHESIS=1
PARAM_*
: monitors variables prefixed withPARAM_
and passes them to Quartus.PARAM_NUM_PORTS := 2
passes a parameter named NUM_PORTS with value of 2.synth_tcl.mk
: all QSF files get the values set insynth_tcl.mk
global settings, including jtag.sdcproject
: target to create Quartus projectquartus
: target to open Quartus GUIquartus_fast
: target to open Quartus GUI without waiting for ip generationgit_info
: target to archive git info in project directoryipgen
: target to generate Quartus IPelab_synth
: target to run through Quartus analysis and elaborationmap
: target to run through Quartus synthesis/mappingfit
: target to run through Quartus fitasm
: target to run through Quartus assembler (no timing)timing
: target to run through Quartus timing (no assembler)gen_timing_rpt
: target to generate TQ_timing_report.txtrun_timing_rpt
: target to generate TQ_timing_report.txt without checking dependenciesfit_timing
: target to run fit until timing is madeasm_timing
: target to Quartus assembler after running fit until timing is madesynth
: target to run full synthesis: map fit asm timingsynth_timing
: target to run full synthesis, running fit until timing is madeARCHIVE_DIR
: archive base location, default is$(BLD_DIR)/archive
ARCHIVE_SUB_DIR
: archive subdirectory location, default isbuild_YYYY_MM_DD-HH.MM-gitbranch
ARCHIVE_FILE_PREFIX
: prefix archive files, default isarchive_
ARCHIVE_DEST
: path archive files will be copied. Default is$(ARCHIVE_DIR)/$(ARCHIVE_SUB_DIR)
archive_synth_results
: target to archive synthesis results toARCHIVE_DEST
synth_archive
: target to run full synthesis and archive when donesynth_archive_timing
: target to run full synthesis, running fit until timing is made, and archive when donetiming_rpt
: target to print timing reporttiming_rpt_timing
: target to print timing report after repeating fit until timing is mettiming_check_all
: target to report timing problemstiming_check_all_timing
: target to report timing problems after repeating fit until timing is met
If you want to use this outside of a git repository, you will need to set the source path in your Makefile like this:
SRC_BASE_DIR := /path/to/current/src_base_dir
TOP_SIM = test_mod
include $(HDL_BUILD_PATH)/build.mk
If you are in a git repository, the SRC_BASE_DIR
defaults to the root of the repository.