diff options
author | gatecat <gatecat@ds0.me> | 2021-03-17 14:05:49 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-03-17 14:05:49 +0000 |
commit | 5feea4497f416eafdf54f34c2b9c67ddcef3f26f (patch) | |
tree | e92427a879159b38441e6b3fc4f0e45ebc75e579 /fpga_interchange | |
parent | 701587241fb8d4b490c4998ab3f2590bc09d7f55 (diff) | |
parent | 01a95faf211d5947415ed6a9ea2b1fbedf1074cd (diff) | |
download | nextpnr-5feea4497f416eafdf54f34c2b9c67ddcef3f26f.tar.gz nextpnr-5feea4497f416eafdf54f34c2b9c67ddcef3f26f.tar.bz2 nextpnr-5feea4497f416eafdf54f34c2b9c67ddcef3f26f.zip |
Merge pull request #619 from acomodi/add-cmake-infra-fpga-interchange
Add CMake infrastructure for fpga interchange
Diffstat (limited to 'fpga_interchange')
42 files changed, 783 insertions, 215 deletions
diff --git a/fpga_interchange/examples/README.md b/fpga_interchange/examples/README.md new file mode 100644 index 00000000..c7df6d5a --- /dev/null +++ b/fpga_interchange/examples/README.md @@ -0,0 +1,69 @@ +## FPGA interchange instructions + +These are instructions on how to get the dependencies, generate the FPGA interchange architecture build system and +run some example designs. + + +### Installing dependencies + +Install java and javac if not already installed: +``` +# Or equivalent for your local system. +sudo apt-get install openjdk-10-jdk +``` + +Install capnproto if not already installed. Version 0.8.0 is required. +As stated in the [official instructions](https://capnproto.org/install.html), the version on the common package managers +might not be up to date with the latest version, hence it is suggested to install +from the archive or, in alternative, directly from the git repository. + +Install capnproto-java if not already installed: +``` +git clone https://github.com/capnproto/capnproto-java.git +cd capnproto-java +make +sudo make install +``` + +Install python-fpga-interchange if not already installed: +``` +git clone https://github.com/SymbiFlow/python-fpga-interchange.git +cd python-fpga-interchange.git +python -m pip install -e . +``` + +Clone RapidWright, if not already cloned: +``` +git clone https://github.com/Xilinx/RapidWright.git +cd RapidWright +make update_jars +``` + +### Build instructions + +Once dependencies are installed/cloned, configure the build system for the FPGA interchange. + +From the nextpnr root dir run: + +``` +mkdir build +cd build +cmake .. --DARCH=fpga_interchange -DRAPIDWRIGHT_PATH=<RapidWright path> -DINTERCHANGE_SCHEMA_PATH=<fpga-interchange-schema path> -DPYTHON_INTERCHANGE_PATH=<python-fpga-interchange path> +``` + +To build the xc7a35t architecture, run: +``` +make chipdb-xc7a35t-bin +``` + +To build the example designs run: +``` +make test-fpga_interchange-wire_arty-dcp +``` + +The make targets for the example designs follow the same pattern: `test-fpga_interchange-<test_name>-<output>`, where `output` is the name of the intermediate step of the build which can be: + +- `json`: synthesis output +- `netlist`: logical netlist +- `phys`: physical netlist +- `dcp`: design checkpoint diff --git a/fpga_interchange/examples/archcheck/Makefile b/fpga_interchange/examples/archcheck/Makefile deleted file mode 100644 index 02e1c08e..00000000 --- a/fpga_interchange/examples/archcheck/Makefile +++ /dev/null @@ -1,23 +0,0 @@ -include ../common.mk - -PACKAGE := csg324 - -.PHONY: check check_test_data - -check: check_test_data - $(NEXTPNR_BIN) \ - --chipdb $(BBA_PATH) \ - --package $(PACKAGE) \ - --test - -check_test_data: - $(NEXTPNR_BIN) \ - --chipdb $(BBA_PATH) \ - --package $(PACKAGE) \ - --run $(NEXTPNR_PATH)/python/check_arch_api.py - -debug_check_test_data: - gdb --args $(NEXTPNR_BIN) \ - --chipdb $(BBA_PATH) \ - --package $(PACKAGE) \ - --run $(NEXTPNR_PATH)/python/check_arch_api.py diff --git a/fpga_interchange/examples/chipdb.cmake b/fpga_interchange/examples/chipdb.cmake new file mode 100644 index 00000000..e0cf2c13 --- /dev/null +++ b/fpga_interchange/examples/chipdb.cmake @@ -0,0 +1,334 @@ +function(create_rapidwright_device_db) + # ~~~ + # create_rapidwright_device_db( + # device <common device> + # part <part> + # output_target <output device target> + # ) + # ~~~ + # + # Generates a device database from RapidWright + # + # If output_target is specified, the output_target_name variable + # is set to the generated output_device_file target. + # + # Arguments: + # - device: common device name of a set of parts. E.g. xc7a35tcsg324-1 and xc7a35tcpg236-1 + # share the same xc7a35t device prefix + # - part: one among the parts available for a given device + # - output_target: variable name that will hold the output device target for the parent scope + # + # Targets generated: + # - rapidwright-<device>-device + + set(options) + set(oneValueArgs device part output_target) + set(multiValueArgs) + + cmake_parse_arguments( + create_rapidwright_device_db + "${options}" + "${oneValueArgs}" + "${multiValueArgs}" + ${ARGN} + ) + + set(device ${create_rapidwright_device_db_device}) + set(part ${create_rapidwright_device_db_part}) + set(output_target ${create_rapidwright_device_db_output_target}) + set(rapidwright_device_db ${CMAKE_CURRENT_BINARY_DIR}/${part}.device) + add_custom_command( + OUTPUT ${rapidwright_device_db} + COMMAND + RAPIDWRIGHT_PATH=${RAPIDWRIGHT_PATH} + ${INVOKE_RAPIDWRIGHT} + com.xilinx.rapidwright.interchange.DeviceResourcesExample + ${part} + DEPENDS + ${INVOKE_RAPIDWRIGHT} + ) + + add_custom_target(rapidwright-${device}-device DEPENDS ${rapidwright_device_db}) + set_property(TARGET rapidwright-${device}-device PROPERTY LOCATION ${rapidwright_device_db}) + + if (DEFINED output_target) + set(${output_target} rapidwright-${device}-device PARENT_SCOPE) + endif() +endfunction() + +function(create_patched_device_db) + # ~~~ + # create_patched_device_db( + # device <common device> + # patch_name <patch_name> + # patch_path <patch_path> + # patch_format <patch_format> + # patch_data <patch_data> + # input_device <input device target> + # output_target <output device target> + # ) + # ~~~ + # + # Generates a patched device database starting from an input device + # + # If output_target is specified, the variable named as the output_target + # parameter value is set to the generated output_device_file target. + # + # Arguments: + # - device: common device name of a set of parts. E.g. xc7a35tcsg324-1 and xc7a35tcpg236-1 + # share the same xc7a35t device prefix. + # - patch_name: name of the patch which determines the target name + # - patch_path: patch_path argument for the fpga_interchange.patch call + # - patch_format: patch_format argument for the fpga_interchange.patch call + # - patch_data: path to the patch_data required for the fpga_interchange.patch call + # - input_device: target for the device that needs to be patched + # - output_target: variable name that will hold the output device target for the parent scope + # + # Targets generated: + # - <patch_name>-<device>-device + + set(options) + set(oneValueArgs device patch_name patch_path patch_format patch_data input_device output_target) + set(multiValueArgs) + + cmake_parse_arguments( + create_patched_device_db + "${options}" + "${oneValueArgs}" + "${multiValueArgs}" + ${ARGN} + ) + + set(device ${create_patched_device_db_device}) + set(patch_name ${create_patched_device_db_patch_name}) + set(patch_path ${create_patched_device_db_patch_path}) + set(patch_format ${create_patched_device_db_patch_format}) + set(patch_data ${create_patched_device_db_patch_data}) + set(input_device ${create_patched_device_db_input_device}) + set(output_target ${create_patched_device_db_output_target}) + + get_target_property(input_device_loc ${input_device} LOCATION) + set(output_device_file ${CMAKE_CURRENT_BINARY_DIR}/${device}_${patch_name}.device) + add_custom_command( + OUTPUT ${output_device_file} + COMMAND + ${PYTHON_EXECUTABLE} -mfpga_interchange.patch + --schema_dir ${INTERCHANGE_SCHEMA_PATH} + --schema device + --patch_path ${patch_path} + --patch_format ${patch_format} + ${input_device_loc} + ${patch_data} + ${output_device_file} + DEPENDS + ${patch_data} + ${input_device} + ${input_device_loc} + ) + + add_custom_target(${patch_name}-${device}-device DEPENDS ${output_device_file}) + set_property(TARGET ${patch_name}-${device}-device PROPERTY LOCATION ${output_device_file}) + + if (DEFINED output_target) + set(${output_target} ${patch_name}-${device}-device PARENT_SCOPE) + endif() +endfunction() + +function(generate_xc7_device_db) + # ~~~ + # generate_xc7_device_db( + # device <common device> + # part <part> + # device_target <variable name for device target> + # ) + # ~~~ + # + # Generates a chipdb BBA file, starting from a RapidWright device database which is then patched. + # Patches applied: + # - constraints patch + # - luts patch + # + # Arguments: + # - device: common device name of a set of parts. E.g. xc7a35tcsg324-1 and xc7a35tcpg236-1 + # share the same xc7a35t device prefix + # - part: one among the parts available for a given device + # - device_target: variable name that will hold the output device target for the parent scope + + set(options) + set(oneValueArgs device part device_target) + set(multiValueArgs) + + cmake_parse_arguments( + create_rapidwright_device_db + "${options}" + "${oneValueArgs}" + "${multiValueArgs}" + ${ARGN} + ) + + set(device ${create_rapidwright_device_db_device}) + set(part ${create_rapidwright_device_db_part}) + set(device_target ${create_rapidwright_device_db_device_target}) + + create_rapidwright_device_db( + device ${device} + part ${part} + output_target rapidwright_device + ) + + # Generate constraints patch + create_patched_device_db( + device ${device} + patch_name constraints + patch_path constraints + patch_format yaml + patch_data ${PYTHON_INTERCHANGE_PATH}/test_data/series7_constraints.yaml + input_device ${rapidwright_device} + output_target constraints_device + ) + + # Generate lut constraints patch + create_patched_device_db( + device ${device} + patch_name constraints-luts + patch_path lutDefinitions + patch_format yaml + patch_data ${PYTHON_INTERCHANGE_PATH}/test_data/series7_luts.yaml + input_device ${constraints_device} + output_target constraints_luts_device + ) + + if(DEFINED device_target) + set(${device_target} ${constraints_luts_device} PARENT_SCOPE) + endif() +endfunction() + +function(generate_chipdb) + # ~~~ + # generate_chipdb( + # family <family> + # device <common device> + # part <part> + # device_target <device target> + # bel_bucket_seeds <bel bucket seeds> + # test_package <test_package> + # ) + # ~~~ + # + # Generates a chipdb BBA file, starting from a device database. + # + # The chipdb binary file is directly generated to the + # <nextpnr-root>/build/fpga_interchange/chipdb/ directory. + # + # The package argument is only used to run the architecture check target. + # + # Arguments: + # - family: nextpnr architecture family (e.g. fpga_interchange) + # - device: common device name of a set of parts. E.g. xc7a35tcsg324-1 and xc7a35tcpg236-1 + # share the same xc7a35t device prefix + # - part: one among the parts available for a given device + # - device_target: target for the device from which the chipdb is generated + # - bel_bucket_seeds: path to the bel bucket seeds YAML file + # - test_package: package among the ones available for the device. This is used for architecture + # testing only + # + # Targets generated: + # - chipdb-${device}-bba + # - chipdb-${device}-bin + # - device-${device} + # + # The device-${device} target contains properties to get the interchange device as well + # as the binary chipdb + + set(options) + set(oneValueArgs family device part device_target bel_bucket_seeds test_package) + set(multiValueArgs) + + cmake_parse_arguments( + generate_chipdb + "${options}" + "${oneValueArgs}" + "${multiValueArgs}" + ${ARGN} + ) + + set(family ${generate_chipdb_family}) + set(device ${generate_chipdb_device}) + set(part ${generate_chipdb_part}) + set(device_target ${generate_chipdb_device_target}) + set(bel_bucket_seeds ${generate_chipdb_bel_bucket_seeds}) + set(test_package ${generate_chipdb_test_package}) + + get_target_property(device_loc ${device_target} LOCATION) + set(chipdb_bba ${CMAKE_CURRENT_BINARY_DIR}/chipdb.bba) + add_custom_command( + OUTPUT ${chipdb_bba} + COMMAND + ${PYTHON_EXECUTABLE} -mfpga_interchange.nextpnr_emit + --schema_dir ${INTERCHANGE_SCHEMA_PATH} + --output_dir ${CMAKE_CURRENT_BINARY_DIR} + --bel_bucket_seeds ${bel_bucket_seeds} + --device ${device_loc} + DEPENDS + ${bel_bucket_seeds} + ${device_target} + ${device_loc} + ) + + add_custom_target(chipdb-${device}-bba DEPENDS ${chipdb_bba}) + + set(chipdb_bin ${chipdb_dir}/chipdb-${device}.bin) + add_custom_command( + OUTPUT ${chipdb_bin} + COMMAND + bbasm -l ${chipdb_bba} ${chipdb_bin} + DEPENDS + chipdb-${device}-bba + ${chipdb_bba} + bbasm + ) + + add_custom_target(chipdb-${device}-bin DEPENDS ${chipdb_bin}) + + # Setting device target properties + add_custom_target(device-${device}) + set_target_properties( + device-${device} + PROPERTIES + DEVICE_LOC ${device_loc} + DEVICE_TARGET ${device_target} + CHIPDB_BIN_LOC ${chipdb_bin} + CHIPDB_BIN_TARGET chipdb-${device}-bin + ) + + # Generate architecture check target + add_custom_target( + chipdb-${device}-bin-check + COMMAND + nextpnr-fpga_interchange + --chipdb ${chipdb_bin} + --package ${test_package} + --test + DEPENDS + ${chipdb_bin} + chipdb-${device}-bin + ) + + add_custom_target( + chipdb-${device}-bin-check-test-data + COMMAND + nextpnr-fpga_interchange + --chipdb ${chipdb_bin} + --package ${test_package} + --run ${PROJECT_SOURCE_DIR}/python/check_arch_api.py + DEPENDS + ${chipdb_bin} + chipdb-${device}-bin + ${test_data_binary} + WORKING_DIRECTORY + ${CMAKE_CURRENT_SOURCE_DIR} + ) + +add_dependencies(all-${family}-archcheck-tests chipdb-${device}-bin-check-test-data chipdb-${device}-bin-check) +endfunction() + diff --git a/fpga_interchange/examples/const_wire/Makefile b/fpga_interchange/examples/const_wire/Makefile deleted file mode 100644 index 49194f53..00000000 --- a/fpga_interchange/examples/const_wire/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -DESIGN := wire -DESIGN_TOP := top -PACKAGE := csg324 - -include ../template.mk - -build/wire.json: wire.v | build - yosys -c run.tcl diff --git a/fpga_interchange/examples/counter/Makefile b/fpga_interchange/examples/counter/Makefile deleted file mode 100644 index 27d20cdf..00000000 --- a/fpga_interchange/examples/counter/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -DESIGN := counter -DESIGN_TOP := top -PACKAGE := cpg236 - -include ../template.mk - -build/counter.json: counter.v | build - yosys -c run.tcl diff --git a/fpga_interchange/examples/create_bba/Makefile b/fpga_interchange/examples/create_bba/Makefile deleted file mode 100644 index c29bfa82..00000000 --- a/fpga_interchange/examples/create_bba/Makefile +++ /dev/null @@ -1,93 +0,0 @@ -# -# nextpnr -- Next Generation Place and Route -# -# Copyright (C) 2021 Symbiflow Authors -# -# -# Permission to use, copy, modify, and/or distribute this software for any -# purpose with or without fee is hereby granted, provided that the above -# copyright notice and this permission notice appear in all copies. -# -# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - -# This Makefile provides a streamlined way to create an example -# FPGA interchange BBA suitable for placing and routing on Xilinx A35 parts. -# -# FPGA interchange device database is generated via RapidWright. -# -# Currently FPGA interchange physical netlist (e.g. place and route route) to -# FASM support is not done, so bitstream generation relies on RapidWright to -# convert FPGA interchange logical and physical netlist into a Vivado DCP. - -include ../common.mk - -.DELETE_ON_ERROR: - -.PHONY: all chipdb test debug_test - -all: chipdb - -build: - mkdir build - -build/RapidWright: | build - cd build && git clone https://github.com/Xilinx/RapidWright.git - -build/env: | build - python3 -mvenv build/env - -build/python-fpga-interchange: | build - cd build && git clone https://github.com/SymbiFlow/python-fpga-interchange.git - -build/fpga-interchange-schema: | build - cd build && git clone https://github.com/SymbiFlow/fpga-interchange-schema.git - -build/.setup: | build/env build/fpga-interchange-schema build/python-fpga-interchange build/RapidWright - source build/env/bin/activate && \ - cd build/python-fpga-interchange/ && \ - pip install -r requirements.txt - touch build/.setup - -$(NEXTPNR_PATH)/build: - mkdir $(NEXTPNR_PATH)/build - -$(NEXTPNR_PATH)/build/bba/bbasm: | $(NEXTPNR_PATH)/build - cd $(NEXTPNR_PATH)/build && cmake -DARCH=fpga_interchange .. - make -j -C $(NEXTPNR_PATH)/build - -build/nextpnr/fpga_interchange/chipdb.bba: build/.setup - mkdir -p build/nextpnr/fpga_interchange - source build/env/bin/activate && \ - cd build/python-fpga-interchange/ && \ - make \ - -f Makefile.rapidwright \ - NEXTPNR_PATH=$(realpath .)/build/nextpnr \ - RAPIDWRIGHT_PATH=$(RAPIDWRIGHT_PATH) \ - INTERCHANGE_PATH=$(INTERCHANGE_PATH) - -$(BBA_PATH): $(NEXTPNR_PATH)/build/bba/bbasm build/nextpnr/fpga_interchange/chipdb.bba - $(NEXTPNR_PATH)/build/bba/bbasm -l build/nextpnr/fpga_interchange/chipdb.bba $(BBA_PATH) - -chipdb: $(BBA_PATH) - -test: chipdb - $(NEXTPNR_PATH)/build/nextpnr-fpga_interchange \ - --chipdb $(BBA_PATH) \ - --package csg324 \ - --test - -debug_test: chipdb - gdb --args $(NEXTPNR_PATH)/build/nextpnr-fpga_interchange \ - --chipdb $(BBA_PATH) \ - --package csg324 \ - --test - -clean: - rm -rf build diff --git a/fpga_interchange/examples/create_bba/README.md b/fpga_interchange/examples/create_bba/README.md deleted file mode 100644 index d2ca5188..00000000 --- a/fpga_interchange/examples/create_bba/README.md +++ /dev/null @@ -1,40 +0,0 @@ -## Makefile-driven BBA creation - -This Makefile will generate a Xilinx A35 chipdb if java, capnproto and -capnproto-java are installed. - -### Installing dependencies - -Install java and javac if not already installed: -``` -# Or equivalent for your local system. -sudo apt-get install openjdk-10-jdk -``` - -Install capnproto if not already installed: -``` -# Or equivalent for your local system. -sudo apt-get install capnproto libcapnp-dev -``` - -Install capnproto-java if not already installed: -``` -git clone https://github.com/capnproto/capnproto-java.git -cd capnproto-java -make -sudo make install -``` - -### Instructions - -Once dependencies are installed, just run "make". This should download -remaining dependencies and build the chipdb and build nextpnr if not built. - -#### Re-building the chipdb - -``` -# Remove the text BBA -rm build/nextpnr/fpga_interchange/chipdb.bba -# Build the BBA -make -``` diff --git a/fpga_interchange/examples/devices/CMakeLists.txt b/fpga_interchange/examples/devices/CMakeLists.txt new file mode 100644 index 00000000..5b96ac80 --- /dev/null +++ b/fpga_interchange/examples/devices/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(xc7a35t) diff --git a/fpga_interchange/examples/devices/xc7a35t/CMakeLists.txt b/fpga_interchange/examples/devices/xc7a35t/CMakeLists.txt new file mode 100644 index 00000000..ce5d5d2d --- /dev/null +++ b/fpga_interchange/examples/devices/xc7a35t/CMakeLists.txt @@ -0,0 +1,14 @@ +generate_xc7_device_db( + device xc7a35t + part xc7a35tcsg324-1 + device_target xc7a35t_target +) + +generate_chipdb( + family ${family} + device xc7a35t + part xc7a35tcsg324-1 + device_target ${xc7a35t_target} + bel_bucket_seeds ${PYTHON_INTERCHANGE_PATH}/test_data/series7_bel_buckets.yaml + test_package csg324 +) diff --git a/fpga_interchange/examples/archcheck/test_data.yaml b/fpga_interchange/examples/devices/xc7a35t/test_data.yaml index 268d180a..268d180a 100644 --- a/fpga_interchange/examples/archcheck/test_data.yaml +++ b/fpga_interchange/examples/devices/xc7a35t/test_data.yaml diff --git a/fpga_interchange/examples/ff/Makefile b/fpga_interchange/examples/ff/Makefile deleted file mode 100644 index c6118ff7..00000000 --- a/fpga_interchange/examples/ff/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -DESIGN := ff -DESIGN_TOP := top -PACKAGE := csg324 - -include ../template.mk - -build/ff.json: ff.v | build - yosys -c run.tcl diff --git a/fpga_interchange/examples/lut/Makefile b/fpga_interchange/examples/lut/Makefile deleted file mode 100644 index 54fc8994..00000000 --- a/fpga_interchange/examples/lut/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -DESIGN := lut -DESIGN_TOP := top -PACKAGE := csg324 - -include ../template.mk - -build/lut.json: lut.v | build - yosys -c run.tcl diff --git a/fpga_interchange/examples/tests.cmake b/fpga_interchange/examples/tests.cmake new file mode 100644 index 00000000..7598d25c --- /dev/null +++ b/fpga_interchange/examples/tests.cmake @@ -0,0 +1,179 @@ +function(add_interchange_test) + # ~~~ + # add_interchange_test( + # name <name> + # family <family> + # device <common device> + # package <package> + # tcl <tcl> + # xdc <xdc> + # sources <sources list> + # [top <top name>] + # [techmap <techmap file>] + # ) + # + # Generates targets to run desired tests + # + # Arguments: + # - name: test name. This must be unique and no other tests with the same + # name should exist + # - family: nextpnr architecture family (e.g. fpga_interchange) + # - device: common device name of a set of parts. E.g. xc7a35tcsg324-1 and xc7a35tcpg236-1 + # share the same xc7a35t device prefix + # - package: package among the ones available for the device + # - tcl: tcl script used for synthesis + # - xdc: constraints file used in the physical netlist generation step + # - sources: list of HDL sources + # - top (optional): name of the top level module. + # If not provided, "top" is assigned as top level module + # - techmap (optional): techmap file used during synthesis + # + # Targets generated: + # - test-fpga_interchange-<name>-json : synthesis output + # - test-fpga_interchange-<name>-netlist : interchange logical netlist + # - test-fpga_interchange-<name>-phys : interchange physical netlist + # - test-fpga_interchange-<name>-dcp : design checkpoint with RapidWright + + set(options) + set(oneValueArgs name family device package tcl xdc top techmap) + set(multiValueArgs sources) + + cmake_parse_arguments( + add_interchange_test + "${options}" + "${oneValueArgs}" + "${multiValueArgs}" + ${ARGN} + ) + + set(name ${add_interchange_test_name}) + set(family ${add_interchange_test_family}) + set(device ${add_interchange_test_device}) + set(package ${add_interchange_test_package}) + set(top ${add_interchange_test_top}) + set(tcl ${CMAKE_CURRENT_SOURCE_DIR}/${add_interchange_test_tcl}) + set(xdc ${CMAKE_CURRENT_SOURCE_DIR}/${add_interchange_test_xdc}) + set(techmap ${CMAKE_CURRENT_SOURCE_DIR}/${add_interchange_test_techmap}) + + set(sources) + foreach(source ${add_interchange_test_sources}) + list(APPEND sources ${CMAKE_CURRENT_SOURCE_DIR}/${source}) + endforeach() + + if (NOT DEFINED top) + # Setting default top value + set(top "top") + endif() + + # Synthesis + set(synth_json ${CMAKE_CURRENT_BINARY_DIR}/${name}.json) + add_custom_command( + OUTPUT ${synth_json} + COMMAND + SOURCES=${sources} + OUT_JSON=${synth_json} + TECHMAP=${techmap} + yosys -c ${tcl} + DEPENDS ${sources} + ) + + add_custom_target(test-${family}-${name}-json DEPENDS ${synth_json}) + + # Logical Netlist + get_property(device_target TARGET device-${device} PROPERTY DEVICE_TARGET) + get_property(device_loc TARGET device-${device} PROPERTY DEVICE_LOC) + + set(netlist ${CMAKE_CURRENT_BINARY_DIR}/${name}.netlist) + add_custom_command( + OUTPUT ${netlist} + COMMAND + ${PYTHON_EXECUTABLE} -mfpga_interchange.yosys_json + --schema_dir ${INTERCHANGE_SCHEMA_PATH} + --device ${device_loc} + --top ${top} + ${synth_json} + ${netlist} + DEPENDS + ${synth_json} + ${device_target} + ${device_loc} + ) + + add_custom_target(test-${family}-${name}-netlist DEPENDS ${netlist}) + + # Logical Netlist YAML + set(netlist_yaml ${CMAKE_CURRENT_BINARY_DIR}/${name}.netlist.yaml) + add_custom_command( + OUTPUT ${netlist_yaml} + COMMAND + ${PYTHON_EXECUTABLE} -mfpga_interchange.convert + --schema_dir ${INTERCHANGE_SCHEMA_PATH} + --schema logical + --input_format capnp + --output_format yaml + ${netlist} + ${netlist_yaml} + DEPENDS + ${netlist} + ) + + add_custom_target(test-${family}-${name}-netlist-yaml DEPENDS ${netlist_yaml}) + + # Physical Netlist + get_property(chipdb_bin_target TARGET device-${device} PROPERTY CHIPDB_BIN_TARGET) + get_property(chipdb_bin_loc TARGET device-${device} PROPERTY CHIPDB_BIN_LOC) + + set(phys ${CMAKE_CURRENT_BINARY_DIR}/${name}.phys) + add_custom_command( + OUTPUT ${phys} + COMMAND + nextpnr-fpga_interchange + --chipdb ${chipdb_bin_loc} + --xdc ${xdc} + --netlist ${netlist} + --phys ${phys} + --package ${package} + DEPENDS + ${netlist} + ${xdc} + ${chipdb_bin_target} + ${chipdb_bin_loc} + ) + + add_custom_target(test-${family}-${name}-phys DEPENDS ${phys}) + + # Physical Netlist YAML + set(phys_yaml ${CMAKE_CURRENT_BINARY_DIR}/${name}.phys.yaml) + add_custom_command( + OUTPUT ${phys_yaml} + COMMAND + ${PYTHON_EXECUTABLE} -mfpga_interchange.convert + --schema_dir ${INTERCHANGE_SCHEMA_PATH} + --schema physical + --input_format capnp + --output_format yaml + ${phys} + ${phys_yaml} + DEPENDS + ${phys} + ) + + add_custom_target(test-${family}-${name}-phys-yaml DEPENDS ${phys_yaml}) + + set(dcp ${CMAKE_CURRENT_BINARY_DIR}/${name}.dcp) + add_custom_command( + OUTPUT ${dcp} + COMMAND + RAPIDWRIGHT_PATH=${RAPIDWRIGHT_PATH} + ${INVOKE_RAPIDWRIGHT} + com.xilinx.rapidwright.interchange.PhysicalNetlistToDcp + ${netlist} ${phys} ${xdc} ${dcp} + DEPENDS + ${INVOKE_RAPIDWRIGHT} + ${phys} + ${netlist} + ) + + add_custom_target(test-${family}-${name}-dcp DEPENDS ${dcp}) + add_dependencies(all-${family}-tests test-${family}-${name}-dcp) +endfunction() diff --git a/fpga_interchange/examples/tests/CMakeLists.txt b/fpga_interchange/examples/tests/CMakeLists.txt new file mode 100644 index 00000000..f0c6c53d --- /dev/null +++ b/fpga_interchange/examples/tests/CMakeLists.txt @@ -0,0 +1,6 @@ +add_subdirectory(wire) +add_subdirectory(const_wire) +# FIXME: re-enable counter test as soon as post placement validity check completes successfully. +#add_subdirectory(counter) +add_subdirectory(ff) +add_subdirectory(lut) diff --git a/fpga_interchange/examples/tests/const_wire/CMakeLists.txt b/fpga_interchange/examples/tests/const_wire/CMakeLists.txt new file mode 100644 index 00000000..ba013e47 --- /dev/null +++ b/fpga_interchange/examples/tests/const_wire/CMakeLists.txt @@ -0,0 +1,19 @@ +add_interchange_test( + name const_wire_basys3 + family ${family} + device xc7a35t + package cpg236 + tcl run.tcl + xdc wire_basys3.xdc + sources wire.v +) + +add_interchange_test( + name const_wire_arty + family ${family} + device xc7a35t + package csg324 + tcl run.tcl + xdc wire_arty.xdc + sources wire.v +) diff --git a/fpga_interchange/examples/ff/run.tcl b/fpga_interchange/examples/tests/const_wire/run.tcl index 726d86eb..b8d0df72 100644 --- a/fpga_interchange/examples/ff/run.tcl +++ b/fpga_interchange/examples/tests/const_wire/run.tcl @@ -1,6 +1,6 @@ yosys -import -read_verilog ff.v +read_verilog $::env(SOURCES) synth_xilinx -nolutram -nowidelut -nosrl -nocarry -nodsp @@ -11,4 +11,4 @@ opt_clean setundef -zero -params -write_json build/ff.json +write_json $::env(OUT_JSON) diff --git a/fpga_interchange/examples/const_wire/wire.v b/fpga_interchange/examples/tests/const_wire/wire.v index 5b1ab692..5b1ab692 100644 --- a/fpga_interchange/examples/const_wire/wire.v +++ b/fpga_interchange/examples/tests/const_wire/wire.v diff --git a/fpga_interchange/examples/const_wire/wire.xdc b/fpga_interchange/examples/tests/const_wire/wire_arty.xdc index 0d96fc45..0d96fc45 100644 --- a/fpga_interchange/examples/const_wire/wire.xdc +++ b/fpga_interchange/examples/tests/const_wire/wire_arty.xdc diff --git a/fpga_interchange/examples/tests/const_wire/wire_basys3.xdc b/fpga_interchange/examples/tests/const_wire/wire_basys3.xdc new file mode 100644 index 00000000..f8435580 --- /dev/null +++ b/fpga_interchange/examples/tests/const_wire/wire_basys3.xdc @@ -0,0 +1,9 @@ +set_property PACKAGE_PIN U16 [get_ports o] +set_property PACKAGE_PIN E19 [get_ports o2] +set_property PACKAGE_PIN U19 [get_ports o3] +set_property PACKAGE_PIN V19 [get_ports o4] + +set_property IOSTANDARD LVCMOS33 [get_ports o] +set_property IOSTANDARD LVCMOS33 [get_ports o2] +set_property IOSTANDARD LVCMOS33 [get_ports o3] +set_property IOSTANDARD LVCMOS33 [get_ports o4] diff --git a/fpga_interchange/examples/tests/counter/CMakeLists.txt b/fpga_interchange/examples/tests/counter/CMakeLists.txt new file mode 100644 index 00000000..dc41d8da --- /dev/null +++ b/fpga_interchange/examples/tests/counter/CMakeLists.txt @@ -0,0 +1,21 @@ +add_interchange_test( + name counter_basys3 + family ${family} + device xc7a35t + package cpg236 + tcl run.tcl + xdc counter_basys3.xdc + sources counter.v + techmap remap.v +) + +add_interchange_test( + name counter_arty + family ${family} + device xc7a35t + package csg324 + tcl run.tcl + xdc counter_arty.xdc + sources counter.v + techmap remap.v +) diff --git a/fpga_interchange/examples/counter/counter.v b/fpga_interchange/examples/tests/counter/counter.v index 00f52a20..00f52a20 100644 --- a/fpga_interchange/examples/counter/counter.v +++ b/fpga_interchange/examples/tests/counter/counter.v diff --git a/fpga_interchange/examples/tests/counter/counter_arty.xdc b/fpga_interchange/examples/tests/counter/counter_arty.xdc new file mode 100644 index 00000000..c6873df5 --- /dev/null +++ b/fpga_interchange/examples/tests/counter/counter_arty.xdc @@ -0,0 +1,14 @@ +## basys3 breakout board +set_property PACKAGE_PIN E3 [get_ports clk] +set_property PACKAGE_PIN C2 [get_ports rst] +set_property PACKAGE_PIN N15 [get_ports io_led[4]] +set_property PACKAGE_PIN N16 [get_ports io_led[5]] +set_property PACKAGE_PIN P17 [get_ports io_led[6]] +set_property PACKAGE_PIN R17 [get_ports io_led[7]] + +set_property IOSTANDARD LVCMOS33 [get_ports clk] +set_property IOSTANDARD LVCMOS33 [get_ports rst] +set_property IOSTANDARD LVCMOS33 [get_ports io_led[4]] +set_property IOSTANDARD LVCMOS33 [get_ports io_led[5]] +set_property IOSTANDARD LVCMOS33 [get_ports io_led[6]] +set_property IOSTANDARD LVCMOS33 [get_ports io_led[7]] diff --git a/fpga_interchange/examples/counter/counter.xdc b/fpga_interchange/examples/tests/counter/counter_basys3.xdc index 7cbe67f6..09446b5f 100644 --- a/fpga_interchange/examples/counter/counter.xdc +++ b/fpga_interchange/examples/tests/counter/counter_basys3.xdc @@ -1,10 +1,6 @@ ## basys3 breakout board set_property PACKAGE_PIN W5 [get_ports clk] set_property PACKAGE_PIN V17 [get_ports rst] -#set_property PACKAGE_PIN U16 [get_ports io_led[0]] -#set_property PACKAGE_PIN E19 [get_ports io_led[1]] -#set_property PACKAGE_PIN U19 [get_ports io_led[2]] -#set_property PACKAGE_PIN V19 [get_ports io_led[3]] set_property PACKAGE_PIN U16 [get_ports io_led[4]] set_property PACKAGE_PIN E19 [get_ports io_led[5]] set_property PACKAGE_PIN U19 [get_ports io_led[6]] @@ -16,7 +12,3 @@ set_property IOSTANDARD LVCMOS33 [get_ports io_led[4]] set_property IOSTANDARD LVCMOS33 [get_ports io_led[5]] set_property IOSTANDARD LVCMOS33 [get_ports io_led[6]] set_property IOSTANDARD LVCMOS33 [get_ports io_led[7]] -#set_property IOSTANDARD LVCMOS33 [get_ports io_led[0]] -#set_property IOSTANDARD LVCMOS33 [get_ports io_led[1]] -#set_property IOSTANDARD LVCMOS33 [get_ports io_led[2]] -#set_property IOSTANDARD LVCMOS33 [get_ports io_led[3]] diff --git a/fpga_interchange/examples/tests/counter/remap.v b/fpga_interchange/examples/tests/counter/remap.v new file mode 100644 index 00000000..6dfc0b4a --- /dev/null +++ b/fpga_interchange/examples/tests/counter/remap.v @@ -0,0 +1,11 @@ +module INV(input I, output O); + +LUT1 #(.INIT(2'b01)) _TECHMAP_REPLACE_ (.I0(I), .O(O)); + +endmodule + +module BUF(input I, output O); + +LUT1 #(.INIT(2'b10)) _TECHMAP_REPLACE_ (.I0(I), .O(O)); + +endmodule diff --git a/fpga_interchange/examples/counter/run.tcl b/fpga_interchange/examples/tests/counter/run.tcl index 245aab04..ffea3b2e 100644 --- a/fpga_interchange/examples/counter/run.tcl +++ b/fpga_interchange/examples/tests/counter/run.tcl @@ -1,9 +1,9 @@ yosys -import -read_verilog counter.v +read_verilog $::env(SOURCES) synth_xilinx -nolutram -nowidelut -nosrl -nocarry -nodsp -techmap -map ../remap.v +techmap -map $::env(TECHMAP) # opt_expr -undriven makes sure all nets are driven, if only by the $undef # net. @@ -12,4 +12,4 @@ opt_clean setundef -zero -params -write_json build/counter.json +write_json $::env(OUT_JSON) diff --git a/fpga_interchange/examples/tests/ff/CMakeLists.txt b/fpga_interchange/examples/tests/ff/CMakeLists.txt new file mode 100644 index 00000000..ccf16d44 --- /dev/null +++ b/fpga_interchange/examples/tests/ff/CMakeLists.txt @@ -0,0 +1,19 @@ +add_interchange_test( + name ff_basys3 + family ${family} + device xc7a35t + package cpg236 + tcl run.tcl + xdc ff_basys3.xdc + sources ff.v +) + +add_interchange_test( + name ff_arty + family ${family} + device xc7a35t + package csg324 + tcl run.tcl + xdc ff_arty.xdc + sources ff.v +) diff --git a/fpga_interchange/examples/ff/ff.v b/fpga_interchange/examples/tests/ff/ff.v index 1c271042..1c271042 100644 --- a/fpga_interchange/examples/ff/ff.v +++ b/fpga_interchange/examples/tests/ff/ff.v diff --git a/fpga_interchange/examples/ff/ff.xdc b/fpga_interchange/examples/tests/ff/ff_arty.xdc index 3c132f1d..3c132f1d 100644 --- a/fpga_interchange/examples/ff/ff.xdc +++ b/fpga_interchange/examples/tests/ff/ff_arty.xdc diff --git a/fpga_interchange/examples/tests/ff/ff_basys3.xdc b/fpga_interchange/examples/tests/ff/ff_basys3.xdc new file mode 100644 index 00000000..ef65112a --- /dev/null +++ b/fpga_interchange/examples/tests/ff/ff_basys3.xdc @@ -0,0 +1,9 @@ +set_property PACKAGE_PIN W5 [get_ports clk] +set_property PACKAGE_PIN U16 [get_ports d] +set_property PACKAGE_PIN E19 [get_ports r] +set_property PACKAGE_PIN U19 [get_ports q] + +set_property IOSTANDARD LVCMOS33 [get_ports clk] +set_property IOSTANDARD LVCMOS33 [get_ports d] +set_property IOSTANDARD LVCMOS33 [get_ports r] +set_property IOSTANDARD LVCMOS33 [get_ports q] diff --git a/fpga_interchange/examples/lut/run.tcl b/fpga_interchange/examples/tests/ff/run.tcl index 1edd8bb7..b8d0df72 100644 --- a/fpga_interchange/examples/lut/run.tcl +++ b/fpga_interchange/examples/tests/ff/run.tcl @@ -1,6 +1,6 @@ yosys -import -read_verilog lut.v +read_verilog $::env(SOURCES) synth_xilinx -nolutram -nowidelut -nosrl -nocarry -nodsp @@ -11,4 +11,4 @@ opt_clean setundef -zero -params -write_json build/lut.json +write_json $::env(OUT_JSON) diff --git a/fpga_interchange/examples/tests/lut/CMakeLists.txt b/fpga_interchange/examples/tests/lut/CMakeLists.txt new file mode 100644 index 00000000..f5503f71 --- /dev/null +++ b/fpga_interchange/examples/tests/lut/CMakeLists.txt @@ -0,0 +1,19 @@ +add_interchange_test( + name lut_basys3 + family ${family} + device xc7a35t + package cpg236 + tcl run.tcl + xdc lut_basys3.xdc + sources lut.v +) + +add_interchange_test( + name lut_arty + family ${family} + device xc7a35t + package csg324 + tcl run.tcl + xdc lut_arty.xdc + sources lut.v +) diff --git a/fpga_interchange/examples/lut/lut.v b/fpga_interchange/examples/tests/lut/lut.v index ca18e665..ca18e665 100644 --- a/fpga_interchange/examples/lut/lut.v +++ b/fpga_interchange/examples/tests/lut/lut.v diff --git a/fpga_interchange/examples/lut/lut.xdc b/fpga_interchange/examples/tests/lut/lut_arty.xdc index 4f390f25..4f390f25 100644 --- a/fpga_interchange/examples/lut/lut.xdc +++ b/fpga_interchange/examples/tests/lut/lut_arty.xdc diff --git a/fpga_interchange/examples/tests/lut/lut_basys3.xdc b/fpga_interchange/examples/tests/lut/lut_basys3.xdc new file mode 100644 index 00000000..aef287ee --- /dev/null +++ b/fpga_interchange/examples/tests/lut/lut_basys3.xdc @@ -0,0 +1,7 @@ +set_property PACKAGE_PIN V17 [get_ports i0] +set_property PACKAGE_PIN V16 [get_ports i1] +set_property PACKAGE_PIN U16 [get_ports o] + +set_property IOSTANDARD LVCMOS33 [get_ports i0] +set_property IOSTANDARD LVCMOS33 [get_ports i1] +set_property IOSTANDARD LVCMOS33 [get_ports o] diff --git a/fpga_interchange/examples/wire/run.tcl b/fpga_interchange/examples/tests/lut/run.tcl index 9127be20..b8d0df72 100644 --- a/fpga_interchange/examples/wire/run.tcl +++ b/fpga_interchange/examples/tests/lut/run.tcl @@ -1,6 +1,6 @@ yosys -import -read_verilog wire.v +read_verilog $::env(SOURCES) synth_xilinx -nolutram -nowidelut -nosrl -nocarry -nodsp @@ -11,4 +11,4 @@ opt_clean setundef -zero -params -write_json build/wire.json +write_json $::env(OUT_JSON) diff --git a/fpga_interchange/examples/tests/wire/CMakeLists.txt b/fpga_interchange/examples/tests/wire/CMakeLists.txt new file mode 100644 index 00000000..59faf402 --- /dev/null +++ b/fpga_interchange/examples/tests/wire/CMakeLists.txt @@ -0,0 +1,19 @@ +add_interchange_test( + name wire_basys3 + family ${family} + device xc7a35t + package cpg236 + tcl run.tcl + xdc wire_basys3.xdc + sources wire.v +) + +add_interchange_test( + name wire_arty + family ${family} + device xc7a35t + package csg324 + tcl run.tcl + xdc wire_arty.xdc + sources wire.v +) diff --git a/fpga_interchange/examples/const_wire/run.tcl b/fpga_interchange/examples/tests/wire/run.tcl index 9127be20..b8d0df72 100644 --- a/fpga_interchange/examples/const_wire/run.tcl +++ b/fpga_interchange/examples/tests/wire/run.tcl @@ -1,6 +1,6 @@ yosys -import -read_verilog wire.v +read_verilog $::env(SOURCES) synth_xilinx -nolutram -nowidelut -nosrl -nocarry -nodsp @@ -11,4 +11,4 @@ opt_clean setundef -zero -params -write_json build/wire.json +write_json $::env(OUT_JSON) diff --git a/fpga_interchange/examples/wire/wire.v b/fpga_interchange/examples/tests/wire/wire.v index 429d05ff..429d05ff 100644 --- a/fpga_interchange/examples/wire/wire.v +++ b/fpga_interchange/examples/tests/wire/wire.v diff --git a/fpga_interchange/examples/wire/wire.xdc b/fpga_interchange/examples/tests/wire/wire_arty.xdc index c923f0fc..c923f0fc 100644 --- a/fpga_interchange/examples/wire/wire.xdc +++ b/fpga_interchange/examples/tests/wire/wire_arty.xdc diff --git a/fpga_interchange/examples/tests/wire/wire_basys3.xdc b/fpga_interchange/examples/tests/wire/wire_basys3.xdc new file mode 100644 index 00000000..317d5acc --- /dev/null +++ b/fpga_interchange/examples/tests/wire/wire_basys3.xdc @@ -0,0 +1,5 @@ +set_property PACKAGE_PIN V17 [get_ports i] +set_property PACKAGE_PIN U16 [get_ports o] + +set_property IOSTANDARD LVCMOS33 [get_ports i] +set_property IOSTANDARD LVCMOS33 [get_ports o] diff --git a/fpga_interchange/examples/wire/Makefile b/fpga_interchange/examples/wire/Makefile deleted file mode 100644 index 49194f53..00000000 --- a/fpga_interchange/examples/wire/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -DESIGN := wire -DESIGN_TOP := top -PACKAGE := csg324 - -include ../template.mk - -build/wire.json: wire.v | build - yosys -c run.tcl diff --git a/fpga_interchange/family.cmake b/fpga_interchange/family.cmake index e62ab458..bad439f8 100644 --- a/fpga_interchange/family.cmake +++ b/fpga_interchange/family.cmake @@ -5,8 +5,25 @@ endif() find_package(ZLIB REQUIRED) +set(RAPIDWRIGHT_PATH $ENV{HOME}/RapidWright CACHE PATH "Path to RapidWright") +set(INVOKE_RAPIDWRIGHT ${RAPIDWRIGHT_PATH}/scripts/invoke_rapidwright.sh CACHE PATH "Path to RapidWright invocation script") +# FIXME: Make patch data available in the python package and remove this cached var +set(PYTHON_INTERCHANGE_PATH $ENV{HOME}/python-fpga-interchange CACHE PATH "Path to the FPGA interchange python library") +set(INTERCHANGE_SCHEMA_PATH $ENV{HOME}/fpga_interchange_schema CACHE PATH "Path to the FPGA interchange schema dir") + add_subdirectory(3rdparty/fpga-interchange-schema/cmake/cxx_static) +include(${family}/examples/chipdb.cmake) +include(${family}/examples/tests.cmake) + +set(chipdb_dir ${CMAKE_CURRENT_BINARY_DIR}/${family}/chipdb) +file(MAKE_DIRECTORY ${chipdb_dir}) + +add_custom_target(all-${family}-tests) +add_custom_target(all-${family}-archcheck-tests) +add_subdirectory(${family}/examples/devices) +add_subdirectory(${family}/examples/tests) + foreach (target ${family_targets}) target_include_directories(${target} PRIVATE ${TCL_INCLUDE_PATH}) target_link_libraries(${target} PRIVATE ${TCL_LIBRARY}) |