# CMake build system ## Variables * `USE_CONDA` - Whether to rely on conda to supply external binaries (e.g. yosys, vpr). * `VPR_BASE_ARGS` - Base VPR arguments used during pack, place and route. {ghsrc}`Default arguments `. * `VPR_EXTRA_ARGS` - Additional arguments to pass to VPR during pack, place and route. To set CMake variable, use the -D flag during the configuration process. Example: ```bash mkdir build cd build cmake -DUSE_CONDA=FALSE .. make ``` ## Terminology The CMake system in f4pga-arch-defs uses the following hierarchy: * `ARCH` - Architecture is the high level grouping of a set of "similar" FPGA types. An example would be the "Lattice iCE40 Series" (ice40) or the "Xilinx Artix 7 Series" (artix7). * `DEVICE_TYPE` - A type of device. This is defined as an `ARCH` and the arch.xml which defines the units with this device type. * `DEVICE` - A specific instance of a `DEVICE_TYPE`. A device definition is a `DEVICE_TYPE`, a `PACKAGE` list, and IO map definitions for each package if needed. Each `DEVICE` should correspond with a layout definition within the `DEVICE_TYPE`. * `BOARD` - A specific `DEVICE` and `PACKAGE` instance, along with a `PROG_TOOL`/`PROG_CMD` (e.g. commands to program a specified board). ## Creating a new FPGA target If you are familiar with cmake, `ADD_FPGA_TARGET` is the rough equivalent to the normal `ADD_EXECUTABLE` target you would use with a C project. `ADD_FPGA_TARGET` will create the targets needed to take a design from Verilog to bitstream through the synthesis, place and route, bitstream and potentially even programming. The required arguments are the `BOARD` and input files see {ghsrc}`ADD_FPGA_TARGET documentation ` for further information on other target configuration options. If you want to target multiple boards, `ADD_FPGA_TARGET_BOARDS` exists that will call `ADD_FPGA_TARGET` correctly for each board you request. See {ghsrc}`ADD_FPGA_TARGET_BOARDS documentation `. ### Note on `ADD_FILE_TARGET` and `ADD_FPGA_BOARD` All source files in the f4pga-arch-defs are required to have a file target associated with them. This is done via {ghsrc}`ADD_FILE_TARGET `. By default `ADD_FPGA_TARGET` and `ADD_FPGA_TARGET_BOARDS` will both implicitly invoke `ADD_FILE_TARGET` for you. This handles the common case where input sources are not generated files. However, if you are using generated files, then you will need to add `ADD_FILE_TARGET` calls for all inputs to `ADD_FPGA_TARGET`. For non-generated verilog, `ADD_FILE_TARGET` should be invoked like: ```cmake add_file_target(FILE SCANNER_TYPE verilog) ``` For generated verilog, `ADD_FILE_TARGET` should be invoked like: ```cmake add_file_target(FILE GENERATED) ``` Note that the input path must be current source dir relative, not absolute, and not relative to the cmake current binary dir. Also note that CMake cannot take depedendencies during build time, so for generated files you must supply the dependencies for the target. See {ghsrc}`APPEND_FILE_DEPENDENCY ` for adding dependencies to other file targets. It is generally suggested that all source forms within f4pga-arch-defs are file targets, but it is required for verilog files because of how verilog handles relative include paths. Verilog defines relative paths as relative to the location of the file, not to the location of the compiler. As a result, if you use relative includes to include both a generated and non-generated file, unless the files are moved to a unified source tree, verilog relative includes will not work. `ADD_FILE_TARGET` solves this by copying non-generated files to the binary directory.