fusesoc 2.3__tar.gz → 2.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {fusesoc-2.3 → fusesoc-2.4}/.github/workflows/ci.yml +11 -4
- {fusesoc-2.3 → fusesoc-2.4}/.github/workflows/lint.yml +2 -2
- {fusesoc-2.3 → fusesoc-2.4}/NEWS +16 -0
- {fusesoc-2.3 → fusesoc-2.4}/PKG-INFO +17 -9
- {fusesoc-2.3 → fusesoc-2.4}/README.md +0 -1
- {fusesoc-2.3 → fusesoc-2.4}/doc/source/conf.py +6 -1
- fusesoc-2.4/doc/source/user/build_system/filters.rst +99 -0
- {fusesoc-2.3 → fusesoc-2.4}/doc/source/user/build_system/index.rst +1 -0
- fusesoc-2.4/doc/source/user/knowledgebase.rst +119 -0
- fusesoc-2.4/doc/source/user/optional_deps.png +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/fusesoc/capi2/core.py +7 -1
- {fusesoc-2.3 → fusesoc-2.4}/fusesoc/capi2/json_schema.py +14 -7
- {fusesoc-2.3 → fusesoc-2.4}/fusesoc/config.py +11 -1
- {fusesoc-2.3 → fusesoc-2.4}/fusesoc/coremanager.py +35 -0
- {fusesoc-2.3 → fusesoc-2.4}/fusesoc/edalizer.py +35 -14
- fusesoc-2.4/fusesoc/filters/autotype.py +28 -0
- fusesoc-2.4/fusesoc/filters/custom.py +31 -0
- fusesoc-2.4/fusesoc/filters/dot.py +24 -0
- {fusesoc-2.3 → fusesoc-2.4}/fusesoc/fusesoc.py +5 -4
- {fusesoc-2.3 → fusesoc-2.4}/fusesoc/librarymanager.py +1 -1
- {fusesoc-2.3 → fusesoc-2.4}/fusesoc/main.py +34 -9
- {fusesoc-2.3 → fusesoc-2.4}/fusesoc/provider/provider.py +6 -0
- fusesoc-2.4/fusesoc/version.py +16 -0
- {fusesoc-2.3 → fusesoc-2.4}/fusesoc.egg-info/PKG-INFO +17 -9
- {fusesoc-2.3 → fusesoc-2.4}/fusesoc.egg-info/SOURCES.txt +9 -5
- fusesoc-2.4/pyproject.toml +61 -0
- fusesoc-2.4/tests/capi2_cores/misc/filters.core +15 -0
- fusesoc-2.4/tests/capi2_cores/virtual/top_impl1.core +21 -0
- fusesoc-2.4/tests/capi2_cores/virtual/top_impl2.core +21 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/test_capi2.py +15 -1
- {fusesoc-2.3 → fusesoc-2.4}/tests/test_config.py +30 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/test_coremanager.py +21 -13
- {fusesoc-2.3 → fusesoc-2.4}/tests/test_edalizer.py +88 -1
- fusesoc-2.3/doc/source/user/knowledgebase.rst +0 -28
- fusesoc-2.3/fusesoc/__init__.py +0 -8
- fusesoc-2.3/fusesoc/capi2/__init__.py +0 -3
- fusesoc-2.3/fusesoc/parser/__init__.py +0 -3
- fusesoc-2.3/fusesoc/provider/__init__.py +0 -9
- fusesoc-2.3/fusesoc/version.py +0 -4
- fusesoc-2.3/setup.py +0 -63
- {fusesoc-2.3 → fusesoc-2.4}/.editorconfig +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/.flake8 +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/.git-blame-ignore-revs +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/.gitignore +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/.pre-commit-config.yaml +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/.readthedocs.yml +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/LICENSE +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/dev-requirements.txt +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/doc/requirements.txt +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/doc/source/_static/theme_overrides.css +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/doc/source/dev/devsetup.rst +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/doc/source/dev/index.rst +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/doc/source/index.rst +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/doc/source/ref/capi1.rst +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/doc/source/ref/glossary.rst +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/doc/source/ref/index.rst +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/doc/source/ref/migrations.rst +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/doc/source/user/build_system/core_files.rst +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/doc/source/user/build_system/dependencies.rst +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/doc/source/user/build_system/eda_flows.rst +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/doc/source/user/build_system/flags.rst +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/doc/source/user/build_system/flow_options.rst +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/doc/source/user/build_system/generators.rst +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/doc/source/user/build_system/hooks.rst +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/doc/source/user/build_system/tool_options.rst +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/doc/source/user/build_system/vpi.rst +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/doc/source/user/cli.rst +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/doc/source/user/index.rst +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/doc/source/user/installation.rst +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/doc/source/user/introduction.rst +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/doc/source/user/overview.rst +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/doc/source/user/package_manager/index.rst +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/extras/bash-completion +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/fusesoc/capi2/coredata.py +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/fusesoc/capi2/coreparser.py +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/fusesoc/capi2/exprs.py +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/fusesoc/capi2/generator.py +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/fusesoc/capi2/inheritance.py +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/fusesoc/core.py +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/fusesoc/parser/coreparser.py +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/fusesoc/provider/git.py +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/fusesoc/provider/github.py +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/fusesoc/provider/local.py +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/fusesoc/provider/opencores.py +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/fusesoc/provider/url.py +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/fusesoc/utils.py +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/fusesoc/vlnv.py +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/fusesoc.egg-info/dependency_links.txt +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/fusesoc.egg-info/entry_points.txt +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/fusesoc.egg-info/requires.txt +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/fusesoc.egg-info/top_level.txt +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/setup.cfg +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/capi2_cores/deptree/child1.core +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/capi2_cores/deptree/child2.core +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/capi2_cores/deptree/child3.core +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/capi2_cores/deptree/child4.core +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/capi2_cores/deptree/generated_child_a.core +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/capi2_cores/deptree/generated_child_a.py +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/capi2_cores/deptree/root.core +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/capi2_cores/files_out_of_hierarchy/bad.sv +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/capi2_cores/files_out_of_hierarchy/subdir/files_out_of_hierarchy.core +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/capi2_cores/files_out_of_hierarchy/subdir/good.sv +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/capi2_cores/misc/append.core +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/capi2_cores/misc/depends.core +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/capi2_cores/misc/dontpickthisfile +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/capi2_cores/misc/dummy.tcl +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/capi2_cores/misc/empty.core +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/capi2_cores/misc/f1 +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/capi2_cores/misc/f2 +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/capi2_cores/misc/f3 +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/capi2_cores/misc/f4 +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/capi2_cores/misc/files.core +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/capi2_cores/misc/flags.core +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/capi2_cores/misc/flow.core +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/capi2_cores/misc/generate/file_cachetest +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/capi2_cores/misc/generate/generate.core +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/capi2_cores/misc/generate/generators.core +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/capi2_cores/misc/generate/testgen.py +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/capi2_cores/misc/hooks.core +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/capi2_cores/misc/parameters.core +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/capi2_cores/misc/scriptfile +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/capi2_cores/misc/subdir/dummy.extra +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/capi2_cores/misc/syntax_error.core +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/capi2_cores/misc/targets.core +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/capi2_cores/misc/toplevel.core +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/capi2_cores/misc/typecheck.core +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/capi2_cores/misc/uncachable.core +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/capi2_cores/misc/vhdlfile +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/capi2_cores/misc/vlogfile +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/capi2_cores/misc/vpi.core +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/capi2_cores/misc/vpifile +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/capi2_cores/override/1/basic.core +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/capi2_cores/override/2/basic.core +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/capi2_cores/parser/inheritance.core +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/capi2_cores/parser/no_additional_properties.core +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/capi2_cores/parser/with_additional_properties.core +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/capi2_cores/providers/url_simple.core +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/capi2_cores/providers/url_simple_with_user_agent.core +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/capi2_cores/providers/url_tar.core +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/capi2_cores/providers/url_zip.core +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/capi2_cores/virtual/impl1.core +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/capi2_cores/virtual/impl2.core +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/capi2_cores/virtual/user.core +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/cores/adv_debug_sys/adv_debug_sys.core +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/cores/atlys/atlys.core +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/cores/atlys/data/atlys.ucf +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/cores/atlys/data/dummy_backend_tcl_file.tcl +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/cores/elf-loader/check_libelf.sh +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/cores/elf-loader/elf-loader.c +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/cores/elf-loader/elf-loader.core +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/cores/elf-loader/vpi_wrapper.c +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/cores/gpio/gpio.core +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/cores/jtag_tap/jtag_tap-1.13.core +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/cores/libstorage/libstorage-1.0.core +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/cores/misc/c3demo.core +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/cores/misc/c3demo.pcf +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/cores/misc/copytocore/copytocore.core +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/cores/misc/copytocore/dummy.tcl +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/cores/misc/copytocore/subdir/dummy.extra +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/cores/misc/dummy.tcl +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/cores/misc/dummy.xci +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/cores/misc/filetypes.core +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/cores/misc/ghdltest.core +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/cores/misc/gitcore.core +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/cores/misc/no_exe_script.core +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/cores/misc/nomain.core +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/cores/misc/opencorescore.core +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/cores/misc/paramtest.core +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/cores/misc/scripts/no_exe_script +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/cores/misc/scripts/post_build_script +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/cores/misc/scripts/post_run_script +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/cores/misc/scripts/pre_build_script +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/cores/misc/scripts/pre_run_script +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/cores/misc/scriptscore.core +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/cores/misc/subdir/dummy.extra +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/cores/mor1kx/mor1kx-3.1.core +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/cores/mor1kx-arty/mor1kx-arty.core +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/cores/mor1kx-arty/mor1kx-arty.system +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/cores/mor1kx-generic/mor1kx-generic.core +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/cores/mor1kx-generic/scripts/post_run_script +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/cores/mor1kx-generic/scripts/pre_build_script +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/cores/mor1kx-generic/scripts/pre_run_script +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/cores/sockit/sockit.core +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/cores/uart16550/uart16550-1.5.core +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/cores/verilator_tb_utils/verilator_tb_utils.core +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/cores/verilog-arbiter/verilog-arbiter-r1.core +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/cores/verilog_utils/verilog_utils.core +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/cores/verilog_utils/verilog_utils.vh +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/cores/vga_lcd/vga_lcd.core +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/cores/vlog_tb_utils/files/0001-testpatch.patch +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/cores/vlog_tb_utils/vlog_tb_utils-1.1.core +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/cores/wb_common/wb_common.core +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/cores/wb_common/wb_common.v +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/cores/wb_common/wb_common_params.v +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/cores/wb_intercon/dummy_icarus.v +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/cores/wb_intercon/wb_intercon-1.0.core +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/test_capi2/generators.info +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/test_capi2/targets.info +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/test_common.py +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/test_exprs.py +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/test_ignored_dirs.py +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/test_libraries.py +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/test_provider/file.tar.gz +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/test_provider/file.v +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/test_provider/file.zip +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/test_provider/vlog_functions.v +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/test_provider.py +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/test_vlnv.py +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/userguide/blinky/blinky.core +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/userguide/blinky/data/nexys_video.xdc +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/userguide/blinky/rtl/blinky.sv +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/userguide/blinky/rtl/macros.svh +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/userguide/blinky/tb/blinky_tb.sv +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/userguide/dualblinky/data/nexys_video.xdc +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/userguide/dualblinky/dualblinky.core +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tests/userguide/dualblinky/rtl/dualblinky.sv +0 -0
- {fusesoc-2.3 → fusesoc-2.4}/tox.ini +0 -0
|
@@ -23,21 +23,28 @@ jobs:
|
|
|
23
23
|
# https://github.com/olofk/fusesoc/issues/528
|
|
24
24
|
#- { icon: 🧊, name: windows-latest }
|
|
25
25
|
pyver:
|
|
26
|
-
- '3.6'
|
|
27
26
|
- '3.7'
|
|
28
27
|
- '3.8'
|
|
29
28
|
- '3.9'
|
|
30
29
|
- '3.10'
|
|
31
|
-
- '3.11
|
|
30
|
+
- '3.11'
|
|
31
|
+
- '3.12'
|
|
32
|
+
exclude:
|
|
33
|
+
#Fails because github can't find an arm64 image for Python 3.7???
|
|
34
|
+
- os: {name: macos-latest}
|
|
35
|
+
pyver: '3.7'
|
|
36
|
+
#Fails because one test expects a different output during an exception
|
|
37
|
+
- os: {name: macos-latest}
|
|
38
|
+
pyver: '3.8'
|
|
32
39
|
runs-on: ${{ matrix.os.name }}
|
|
33
40
|
name: ${{ matrix.os.icon }} ${{ matrix.os.name }} | ${{ matrix.pyver }}
|
|
34
41
|
steps:
|
|
35
42
|
|
|
36
43
|
- name: 🧰 Repository Checkout
|
|
37
|
-
uses: actions/checkout@
|
|
44
|
+
uses: actions/checkout@v4
|
|
38
45
|
|
|
39
46
|
- name: 🐍 Set up Python ${{ matrix.pyver }}
|
|
40
|
-
uses: actions/setup-python@
|
|
47
|
+
uses: actions/setup-python@v5
|
|
41
48
|
with:
|
|
42
49
|
python-version: ${{ matrix.pyver }}
|
|
43
50
|
|
{fusesoc-2.3 → fusesoc-2.4}/NEWS
RENAMED
|
@@ -1,3 +1,19 @@
|
|
|
1
|
+
2.4 2024-10-02 Olof Kindgren <olof.kindgren@gmail.com>
|
|
2
|
+
======================================================
|
|
3
|
+
* Add conflict handling for virtual cores
|
|
4
|
+
* Connect generated cores in EDAM dependency graph
|
|
5
|
+
* Support implicit name in library add command
|
|
6
|
+
* Migrate from setup.py to pyproject.toml
|
|
7
|
+
* Add support for EDAM filter plugins
|
|
8
|
+
|
|
9
|
+
Contributors:
|
|
10
|
+
Alexander Williams <awill@opentitan.org>
|
|
11
|
+
Alfred E Neuman <quinky@gmx.ch>
|
|
12
|
+
Daniel Copley <djcopley@users.noreply.github.com>
|
|
13
|
+
Jelle van der Waa <jelle@vdwaa.nl>
|
|
14
|
+
Olof Kindgren <olof.kindgren@gmail.com>
|
|
15
|
+
Phillipe Jean-Jumeau <pljeanjumeau@gmail.com>
|
|
16
|
+
|
|
1
17
|
2.3 2023-11-17 Olof Kindgren <olof.kindgren@gmail.com>
|
|
2
18
|
======================================================
|
|
3
19
|
* Add CLI to read/write config settings
|
|
@@ -1,25 +1,33 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: fusesoc
|
|
3
|
-
Version: 2.
|
|
4
|
-
Summary:
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
3
|
+
Version: 2.4
|
|
4
|
+
Summary: Award-winnning package manager and build abstraction tool for HDL code
|
|
5
|
+
Author-email: Olof Kindgren <olof@award-winning.me>
|
|
6
|
+
Maintainer-email: Olof Kindgren <olof@award-winning.me>
|
|
7
|
+
Project-URL: Homepage, https://fusesoc.net
|
|
8
|
+
Project-URL: Documentation, https://fusesoc.readthedocs.io
|
|
9
|
+
Project-URL: Repository, https://github.com/olofk/fusesoc
|
|
10
|
+
Project-URL: Issues, https://github.com/olofk/fusesoc/issues
|
|
11
|
+
Project-URL: Changelog, https://github.com/olofk/fusesoc/blob/main/NEWS
|
|
12
|
+
Keywords: VHDL,verilog,hdl,rtl,synthesis,FPGA,simulation,ASIC
|
|
10
13
|
Classifier: Development Status :: 5 - Production/Stable
|
|
11
14
|
Classifier: Topic :: Utilities
|
|
12
15
|
Classifier: Topic :: Software Development :: Build Tools
|
|
13
16
|
Classifier: License :: OSI Approved :: BSD License
|
|
14
|
-
Requires-Python:
|
|
17
|
+
Requires-Python: <4,>=3.6
|
|
15
18
|
Description-Content-Type: text/markdown
|
|
16
19
|
License-File: LICENSE
|
|
20
|
+
Requires-Dist: edalize>=0.4.1
|
|
21
|
+
Requires-Dist: pyparsing>=2.3.1
|
|
22
|
+
Requires-Dist: pyyaml>=6.0
|
|
23
|
+
Requires-Dist: simplesat>=0.8.0
|
|
24
|
+
Requires-Dist: fastjsonschema
|
|
25
|
+
Requires-Dist: jsonschema2md
|
|
17
26
|
|
|
18
27
|
# FuseSoC
|
|
19
28
|
|
|
20
29
|
[](https://github.com/olofk/fusesoc/actions?query=workflow%3ACI)
|
|
21
30
|
[](https://pypi.org/project/fusesoc/)
|
|
22
|
-
[](https://www.librecores.org/olofk/FuseSoC)
|
|
23
31
|
|
|
24
32
|
## Introduction
|
|
25
33
|
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://github.com/olofk/fusesoc/actions?query=workflow%3ACI)
|
|
4
4
|
[](https://pypi.org/project/fusesoc/)
|
|
5
|
-
[](https://www.librecores.org/olofk/FuseSoC)
|
|
6
5
|
|
|
7
6
|
## Introduction
|
|
8
7
|
|
|
@@ -36,7 +36,12 @@ copyright = f"2018-{datetime.now().year}, Olof Kindgren"
|
|
|
36
36
|
author = "Olof Kindgren"
|
|
37
37
|
|
|
38
38
|
# The full version, including alpha/beta/rc tags.
|
|
39
|
-
|
|
39
|
+
try:
|
|
40
|
+
from fusesoc.version import version as __version__
|
|
41
|
+
except ImportError:
|
|
42
|
+
__version__ = "unknown"
|
|
43
|
+
|
|
44
|
+
release = __version__
|
|
40
45
|
# The short X.Y version.
|
|
41
46
|
v_major, v_minor = LooseVersion(release).version[:2]
|
|
42
47
|
version = f"{v_major}.{v_minor}"
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
.. _ug_build_system_filters:
|
|
2
|
+
|
|
3
|
+
Filters: Make system-wide modifications to the EDAM structure
|
|
4
|
+
=============================================================
|
|
5
|
+
|
|
6
|
+
The last thing FuseSoC does before handing over to Edalize, is to prepare an EDAM file containing a description of the complete system and everything that the EDA tools need to know. It is sometimes useful to make system-wide changes after the system is assembled, and this is where filters come in. Filters are additional tasks that can be run to analyze and modify the EDAM structure, and through that structure the filters have access to the complete dependency tree and all source files.
|
|
7
|
+
|
|
8
|
+
FuseSoC ships with a few built-in filters for generally useful tasks:
|
|
9
|
+
|
|
10
|
+
* autotype: Sets file types according to the file name prefix for files that don't have an explicit file type set.
|
|
11
|
+
* custom: Runs the command specified with the environment variable `FUSESOC_CUSTOM_FILTER`. Two arguments are passed to the command. The first specifies the EDAM (yaml) file the custom command is supposed to read. The second specifies the name of the file that the filter should use to return the modified EDAM struct.
|
|
12
|
+
* dot: Creates a GraphViz dot file of the dependency tree
|
|
13
|
+
|
|
14
|
+
All filters are run from the work root directory.
|
|
15
|
+
|
|
16
|
+
.. note::
|
|
17
|
+
Technically, an Edalize frontend can perform the exact same task as a FuseSoC EDAM filter. The difference is more philosophical in that a filter can be seen as something that fixes up the system before it is ready to be consumed by an EDA tool, while an Edalize frontend typically *is* an EDA tool. The filters will also possibly have access to more FuseSoC internals in the future.
|
|
18
|
+
|
|
19
|
+
Using filters
|
|
20
|
+
-------------
|
|
21
|
+
|
|
22
|
+
There are three way to enable which filters to be applied. These three options have various use-cases.
|
|
23
|
+
|
|
24
|
+
Filters in targets
|
|
25
|
+
~~~~~~~~~~~~~~~~~~
|
|
26
|
+
|
|
27
|
+
Filters specified in a target section of a core are typically required for the the build to work. In order to enable a filter for a target, add a list of filters using the `filters` key.
|
|
28
|
+
|
|
29
|
+
.. code-block:: yaml
|
|
30
|
+
|
|
31
|
+
# An excerpt from a core file.
|
|
32
|
+
targets:
|
|
33
|
+
sim:
|
|
34
|
+
# ...
|
|
35
|
+
filters: [autotype, dot] # Apply the autotype and dot filters in that order
|
|
36
|
+
|
|
37
|
+
Filters in the configuration file
|
|
38
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
39
|
+
|
|
40
|
+
Filters can be set in the configuration file as a list of space-separated strings in the `main` section. These can be set with the fusesoc config cli, e.g. `fusesoc config filters "filter1 filter2"`. Filters set in the config file are typically used when all targets of the cores in the workspace need some filter to be applied, or just as a convenienence for users who like to have som particular filter always enabled. These filters are applied after the ones from the core file targets.
|
|
41
|
+
|
|
42
|
+
Filters on the command-line
|
|
43
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
44
|
+
|
|
45
|
+
It is also possible to set filters on the command-line. This is typically used for one-off filters, e.g. to generate some debug info. They are enabled with the `--filter` parameters, e.g. `fusesoc run --filter=dot --target=sim ...`. The `--filter` parameter can be specified multiple times to add more filters. Filters on the command-line are applied after the ones from the configuration file.
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
Creating additional filters
|
|
49
|
+
---------------------------
|
|
50
|
+
|
|
51
|
+
A filter is a Python module that contains a class with the same name as the module, but capitalized. The class needs to implement a function called `run` which takes the EDAM struct as the first argumen and the work root as the second argument. The function needs to return the new EDAM struct even if it is unmodified.
|
|
52
|
+
|
|
53
|
+
Filter template::
|
|
54
|
+
|
|
55
|
+
import logging
|
|
56
|
+
import os
|
|
57
|
+
|
|
58
|
+
logger = logging.getLogger(__name__)
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
class Customfilter:
|
|
62
|
+
def run(self, edam, work_root):
|
|
63
|
+
# Print file sizes of all verilog files in the system
|
|
64
|
+
for f in edam["files"]:
|
|
65
|
+
if f["file_type"].startswith("verilogSource"):
|
|
66
|
+
size = os.path.getsize(os.path.join(work_root, f["name"]))
|
|
67
|
+
print(f"{f['name']} is {size} bytes")
|
|
68
|
+
|
|
69
|
+
# Add an additional parameter
|
|
70
|
+
edam["parameters"]["my_number"] = {"datatype" : "int",
|
|
71
|
+
"paramtype": "vlogdefine",
|
|
72
|
+
"default" : 5446}
|
|
73
|
+
|
|
74
|
+
# Change the system name
|
|
75
|
+
edam["name"] = "bestsystemever"
|
|
76
|
+
|
|
77
|
+
# Return modified EDAM struct
|
|
78
|
+
return edam
|
|
79
|
+
|
|
80
|
+
FuseSoC implements support for implicit namespace packages (https://peps.python.org/pep-0420/) This means that subclasses that logically belong to FuseSoC can be distributed over several physical locations and is something we can take advantage of to add new filters outside of the FuseSoC code base.
|
|
81
|
+
|
|
82
|
+
In order to do that we will create a directory structure that mirrors the structure of FuseSoC like the example below::
|
|
83
|
+
|
|
84
|
+
externalplugin/
|
|
85
|
+
fusesoc/
|
|
86
|
+
filters/
|
|
87
|
+
customfilter.py
|
|
88
|
+
anothercustomfilter.py
|
|
89
|
+
|
|
90
|
+
There are two common options for making the above `customfilter.py` and `anothercustomfilter.py` available to FuseSoC.
|
|
91
|
+
|
|
92
|
+
The first way is to add the `externalplugin` path to ``PYTHONPATH``. The other is to add a `setup.py` in the `externalplugin` directory and install the filter plugin with pip as with other Python packages.
|
|
93
|
+
|
|
94
|
+
A `setup.py` in its absolutely most minimal form is listed below and is enough to install the plugin as a package in development mode using ``pip install --user -e .`` from the `externalplugin` directory.::
|
|
95
|
+
|
|
96
|
+
from setuptools import setup
|
|
97
|
+
setup()
|
|
98
|
+
|
|
99
|
+
A real `setup.py` like the one used by FuseSoC normally contains a lot more information.
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
*****************************
|
|
2
|
+
Common Problems and Solutions
|
|
3
|
+
*****************************
|
|
4
|
+
|
|
5
|
+
Making changes to cores in a library
|
|
6
|
+
====================================
|
|
7
|
+
|
|
8
|
+
A common situation is that a user wants to use their own copy of a core,
|
|
9
|
+
instead of the one provided by a library, for example to fix a bug or
|
|
10
|
+
add new functionality. The following steps can be used to achieve this:
|
|
11
|
+
|
|
12
|
+
**Example.** Replace a core in a library with a user-specified version
|
|
13
|
+
|
|
14
|
+
#. Create a new directory to keep the user-copies of the cores (this
|
|
15
|
+
directory will be referred to as ``$corelib`` from now on)
|
|
16
|
+
#. Download the core source (the repository or URL can be found in the
|
|
17
|
+
``[provider]`` section of the original core)
|
|
18
|
+
#. *If the downloaded core already contains a .core file, this step is
|
|
19
|
+
ignored* Copy the original .core file to the root of the downloaded
|
|
20
|
+
core. Edit the file and remove the ``[provider]`` section. (This will
|
|
21
|
+
stop FuseSoC from downloading the core and use files from the
|
|
22
|
+
directory containing the .core file instead)
|
|
23
|
+
#. Add ``$corelib`` to the end of your library search path, either by
|
|
24
|
+
editing ``fusesoc.conf`` or by adding ``--cores-root=$corelib`` to
|
|
25
|
+
the command-line arguments
|
|
26
|
+
#. Verify that the new core is found by running fusesoc core-info $core. Check
|
|
27
|
+
the output to see that “Core root:” is set to the directory where the core
|
|
28
|
+
was downloaded
|
|
29
|
+
|
|
30
|
+
Dependency tree for a core with optional components
|
|
31
|
+
===================================================
|
|
32
|
+
|
|
33
|
+
Many cores have a part that is only used in some flows. This could for example be a BFM, VIP or some kind of behavioral model that is only used in simulation flows. Or it could be timing constraints for synthesis. As long as these are only by the core itself, it's easiest to put them into different filesets and let each simulation or synthesis target pick the right subset of filesets.
|
|
34
|
+
|
|
35
|
+
A more complicated situation arises when a user uses this core as a dependency and wants to have different filesets for different flows in the toplevel core. In this case, it is typically better to split out the optional part into its own cores and have the toplevel filesets depend on the different cores.
|
|
36
|
+
|
|
37
|
+
**Example** Let's assume a core (comp) comes with a BFM. We want to use the BFM when doing block-level simulations of the core and when doing full system simulations which uses this core. We don't want to have the BFM present when doing full system synthesis. The most general solution is to split out the BFM to a separate core file. The following example shows a setup with a component (comp.core) that has a BFM (comp_bfm.core) which is used inside a larger system (top.core). The component has a testbench target (sim) and the larger system has two testbenches (tb1 and tb2) which both uses the BFM and the component. The larger system can also be synthesized without the BFM.
|
|
38
|
+
|
|
39
|
+
.. image:: optional_deps.png
|
|
40
|
+
:alt: Alternative text
|
|
41
|
+
|
|
42
|
+
.. code-block:: yaml
|
|
43
|
+
:caption: comp_bfm.core
|
|
44
|
+
|
|
45
|
+
CAPI=2:
|
|
46
|
+
|
|
47
|
+
name : ::comp_bfm:0
|
|
48
|
+
|
|
49
|
+
filesets:
|
|
50
|
+
bfm:
|
|
51
|
+
files: {comp_bfm.sv : {file_type : systemVerilogSource}}
|
|
52
|
+
|
|
53
|
+
targets:
|
|
54
|
+
default:
|
|
55
|
+
filesets : [bfm]
|
|
56
|
+
|
|
57
|
+
.. code-block:: yaml
|
|
58
|
+
:caption: comp.core
|
|
59
|
+
|
|
60
|
+
CAPI=2:
|
|
61
|
+
|
|
62
|
+
name : ::comp:0
|
|
63
|
+
|
|
64
|
+
filesets:
|
|
65
|
+
rtl:
|
|
66
|
+
files: {comp.sv : {file_type : systemVerilogSource}}
|
|
67
|
+
|
|
68
|
+
tb_files:
|
|
69
|
+
files: {comp_tb.sv : {file_type : systemVerilogSource}}
|
|
70
|
+
depend: [comp_bfm]
|
|
71
|
+
|
|
72
|
+
targets:
|
|
73
|
+
default:
|
|
74
|
+
filesets : [rtl]
|
|
75
|
+
|
|
76
|
+
sim:
|
|
77
|
+
filesets : [rtl, tb_files]
|
|
78
|
+
|
|
79
|
+
.. code-block:: yaml
|
|
80
|
+
:caption: top.core
|
|
81
|
+
|
|
82
|
+
CAPI=2:
|
|
83
|
+
|
|
84
|
+
name : ::top:0
|
|
85
|
+
|
|
86
|
+
filesets:
|
|
87
|
+
rtl:
|
|
88
|
+
files: {top.sv : {file_type : systemVerilogSource}}
|
|
89
|
+
depend: [comp]
|
|
90
|
+
|
|
91
|
+
tb_common:
|
|
92
|
+
files: {tb_common.sv : {file_type : systemVerilogSource}}
|
|
93
|
+
depend: [comp_bfm]
|
|
94
|
+
|
|
95
|
+
tb1_files:
|
|
96
|
+
files: {tb1.sv : {file_type : systemVerilogSource}}
|
|
97
|
+
|
|
98
|
+
tb2_files:
|
|
99
|
+
files: {tb1.sv : {file_type : systemVerilogSource}}
|
|
100
|
+
|
|
101
|
+
synth_files:
|
|
102
|
+
files: {constraints.sdc : {file_type : SDC}}
|
|
103
|
+
|
|
104
|
+
targets:
|
|
105
|
+
sim: &sim
|
|
106
|
+
filesets : [rtl, tb_files]
|
|
107
|
+
|
|
108
|
+
tb1:
|
|
109
|
+
<<: *sim
|
|
110
|
+
filesets_append : [tb1_files]
|
|
111
|
+
|
|
112
|
+
tb2:
|
|
113
|
+
<<: *sim
|
|
114
|
+
filesets_append : [tb2_files]
|
|
115
|
+
|
|
116
|
+
synth:
|
|
117
|
+
filesets : [rtl, synth_files]
|
|
118
|
+
|
|
119
|
+
An alternative solution to the above, is to use flags, as described in :ref:`ug_build_system_flags`, where the inclusion of the optional files are controlled by flags. These flags can be assigned default values in the top level targets for convenience.
|
|
Binary file
|
|
@@ -13,7 +13,7 @@ from filecmp import cmp
|
|
|
13
13
|
|
|
14
14
|
from fusesoc import utils
|
|
15
15
|
from fusesoc.capi2.coredata import CoreData
|
|
16
|
-
from fusesoc.provider import get_provider
|
|
16
|
+
from fusesoc.provider.provider import get_provider
|
|
17
17
|
from fusesoc.vlnv import Vlnv
|
|
18
18
|
|
|
19
19
|
logger = logging.getLogger(__name__)
|
|
@@ -172,8 +172,14 @@ class Core:
|
|
|
172
172
|
# Special case for tool as we get it from default_tool
|
|
173
173
|
flags["tool"] = str(target["default_tool"])
|
|
174
174
|
|
|
175
|
+
else:
|
|
176
|
+
raise RuntimeError(f"'{self.name}' has no target '{target_name}'")
|
|
175
177
|
return flags
|
|
176
178
|
|
|
179
|
+
def get_filters(self, flags):
|
|
180
|
+
target_name, target = self._get_target(flags)
|
|
181
|
+
return target.get("filters", [])
|
|
182
|
+
|
|
177
183
|
def get_flow(self, flags):
|
|
178
184
|
self._debug("Getting flow for flags {}".format(str(flags)))
|
|
179
185
|
flow = None
|
|
@@ -110,7 +110,7 @@ capi2_schema = """
|
|
|
110
110
|
"additionalProperties": false,
|
|
111
111
|
"required": [
|
|
112
112
|
"name",
|
|
113
|
-
"repo"
|
|
113
|
+
"repo"
|
|
114
114
|
]
|
|
115
115
|
},
|
|
116
116
|
{
|
|
@@ -272,7 +272,7 @@ capi2_schema = """
|
|
|
272
272
|
}
|
|
273
273
|
}
|
|
274
274
|
},
|
|
275
|
-
"additionalProperties": false
|
|
275
|
+
"additionalProperties": false
|
|
276
276
|
}
|
|
277
277
|
},
|
|
278
278
|
"additionalProperties": false
|
|
@@ -375,7 +375,7 @@ capi2_schema = """
|
|
|
375
375
|
}
|
|
376
376
|
}
|
|
377
377
|
},
|
|
378
|
-
"additionalProperties": false
|
|
378
|
+
"additionalProperties": false
|
|
379
379
|
}
|
|
380
380
|
}
|
|
381
381
|
},
|
|
@@ -386,7 +386,7 @@ capi2_schema = """
|
|
|
386
386
|
"^.+$": {
|
|
387
387
|
"patternProperties": {
|
|
388
388
|
"^default_tool$": {
|
|
389
|
-
"description": "Default tool to use unless overridden with ``--tool=``",
|
|
389
|
+
"description": "Default tool to use unless overridden with ``--tool=`` This key is used by the Edalize Tool API and is ignored if the Flow API is used instead.",
|
|
390
390
|
"type": "string"
|
|
391
391
|
},
|
|
392
392
|
"^description$": {
|
|
@@ -394,11 +394,11 @@ capi2_schema = """
|
|
|
394
394
|
"type": "string"
|
|
395
395
|
},
|
|
396
396
|
"^flow$": {
|
|
397
|
-
"description": "Edalize backend flow to use for target",
|
|
397
|
+
"description": "Edalize backend flow to use for target. Setting this key enables the flow API instead of the legacy Tool API.",
|
|
398
398
|
"type": "string"
|
|
399
399
|
},
|
|
400
400
|
"^flow_options$": {
|
|
401
|
-
"description": "Tool- and flow-specific options",
|
|
401
|
+
"description": "Tool- and flow-specific options. Used by the Flow API. The Edalize documentation contains information on available options for different flows (https://edalize.readthedocs.io/en/latest/edam/api.html#flow-options)",
|
|
402
402
|
"type": "object",
|
|
403
403
|
"patternProperties": {
|
|
404
404
|
"^.+$": {
|
|
@@ -458,7 +458,7 @@ capi2_schema = """
|
|
|
458
458
|
"additionalProperties": false
|
|
459
459
|
},
|
|
460
460
|
"^tools$": {
|
|
461
|
-
"description": "Tool-specific options for target",
|
|
461
|
+
"description": "Tool-specific options for target. Used by the legacy Tool API. The contents of this section is handled by Edalize, and a list of available tool options for each tool can be found in the Edalize documentation (https://edalize.readthedocs.io/en/latest/edam/api.html#tool-options)",
|
|
462
462
|
"type": "object",
|
|
463
463
|
"patternProperties": {
|
|
464
464
|
"^.+$": {
|
|
@@ -508,6 +508,13 @@ capi2_schema = """
|
|
|
508
508
|
"type": "string"
|
|
509
509
|
}
|
|
510
510
|
},
|
|
511
|
+
"^filters(_append)?$": {
|
|
512
|
+
"description": "EDAM filters to apply",
|
|
513
|
+
"type": "array",
|
|
514
|
+
"items": {
|
|
515
|
+
"type": "string"
|
|
516
|
+
}
|
|
517
|
+
},
|
|
511
518
|
"^generate(_append)?$": {
|
|
512
519
|
"description": "Parameterized generators to run for this target with optional parametrization",
|
|
513
520
|
"type": "array",
|
|
@@ -153,6 +153,16 @@ class Config:
|
|
|
153
153
|
else:
|
|
154
154
|
return val
|
|
155
155
|
|
|
156
|
+
@property
|
|
157
|
+
def filters(self):
|
|
158
|
+
return self._cp.get(
|
|
159
|
+
Config.default_section, "filters", fallback=""
|
|
160
|
+
).split() + getattr(self, "args_filters", [])
|
|
161
|
+
|
|
162
|
+
@filters.setter
|
|
163
|
+
def filters(self, val):
|
|
164
|
+
self._set_default_section("filters", val)
|
|
165
|
+
|
|
156
166
|
@property
|
|
157
167
|
def build_root(self):
|
|
158
168
|
return self._arg_or_val("args_build_root", self._get_build_root())
|
|
@@ -263,7 +273,7 @@ class Config:
|
|
|
263
273
|
self._cp.write(conf_file)
|
|
264
274
|
|
|
265
275
|
def add_library(self, library):
|
|
266
|
-
from fusesoc.provider import get_provider
|
|
276
|
+
from fusesoc.provider.provider import get_provider
|
|
267
277
|
|
|
268
278
|
section_name = "library." + library.name
|
|
269
279
|
|
|
@@ -113,6 +113,35 @@ class CoreDB:
|
|
|
113
113
|
def solve(self, top_core, flags):
|
|
114
114
|
return self._solve(top_core, flags)
|
|
115
115
|
|
|
116
|
+
def _get_conflict_map(self):
|
|
117
|
+
"""Return a map of cores to their conflicts
|
|
118
|
+
|
|
119
|
+
Only one core that implements a virtual VLNV may be selected in a
|
|
120
|
+
dependency tree. For each core that implements a virtual VLNV, create a
|
|
121
|
+
set representing all other cores that implement one of the same virtual
|
|
122
|
+
VLNVs. In the resulting package definitions, these must get "conflicts"
|
|
123
|
+
constraints.
|
|
124
|
+
"""
|
|
125
|
+
conflict_map = {}
|
|
126
|
+
virtual_map = {}
|
|
127
|
+
for core_data in self._cores.values():
|
|
128
|
+
core = core_data["core"]
|
|
129
|
+
_virtuals = core.get_virtuals()
|
|
130
|
+
for virtual in _virtuals:
|
|
131
|
+
for simple in virtual.simpleVLNVs():
|
|
132
|
+
virtual_pkg = self._package_name(simple)
|
|
133
|
+
# FIXME: The real package should include version info
|
|
134
|
+
real_pkg = self._package_name(core.name)
|
|
135
|
+
virtual_set = virtual_map.setdefault(virtual_pkg, set())
|
|
136
|
+
virtual_set.add(real_pkg)
|
|
137
|
+
for virtual_pkg, virtual_set in virtual_map.items():
|
|
138
|
+
for real_pkg in virtual_set:
|
|
139
|
+
conflict_set = conflict_map.setdefault(real_pkg, set())
|
|
140
|
+
conflict_set |= virtual_set
|
|
141
|
+
for real_pkg, conflict_set in conflict_map.items():
|
|
142
|
+
conflict_set.remove(real_pkg)
|
|
143
|
+
return conflict_map
|
|
144
|
+
|
|
116
145
|
def _solve(self, top_core, flags={}, only_matching_vlnv=False):
|
|
117
146
|
def eq_vln(this, that):
|
|
118
147
|
return (
|
|
@@ -130,6 +159,8 @@ class CoreDB:
|
|
|
130
159
|
repo = Repository()
|
|
131
160
|
_flags = flags.copy()
|
|
132
161
|
cores = [x["core"] for x in self._cores.values()]
|
|
162
|
+
conflict_map = self._get_conflict_map()
|
|
163
|
+
|
|
133
164
|
for core in cores:
|
|
134
165
|
if only_matching_vlnv:
|
|
135
166
|
if not any(
|
|
@@ -153,6 +184,10 @@ class CoreDB:
|
|
|
153
184
|
if _virtuals:
|
|
154
185
|
_s = "; provides ( {} )"
|
|
155
186
|
package_str += _s.format(self._parse_virtual(_virtuals))
|
|
187
|
+
conflict_set = conflict_map.get(self._package_name(core.name), set())
|
|
188
|
+
if len(conflict_set) > 0:
|
|
189
|
+
_s = "; conflicts ( {} )"
|
|
190
|
+
package_str += _s.format(", ".join(list(conflict_set)))
|
|
156
191
|
|
|
157
192
|
# Add dependencies only if we want to build the whole dependency
|
|
158
193
|
# tree.
|
|
@@ -9,6 +9,7 @@ import os
|
|
|
9
9
|
import pathlib
|
|
10
10
|
import shutil
|
|
11
11
|
from filecmp import cmp
|
|
12
|
+
from importlib import import_module
|
|
12
13
|
|
|
13
14
|
from fusesoc import utils
|
|
14
15
|
from fusesoc.capi2.coreparser import Core2Parser
|
|
@@ -49,7 +50,7 @@ class Edalizer:
|
|
|
49
50
|
system_name=None,
|
|
50
51
|
resolve_env_vars=False,
|
|
51
52
|
):
|
|
52
|
-
logger.debug("Building
|
|
53
|
+
logger.debug("Building EDAM structure")
|
|
53
54
|
|
|
54
55
|
self.toplevel = toplevel
|
|
55
56
|
self.flags = flags
|
|
@@ -89,6 +90,20 @@ class Edalizer:
|
|
|
89
90
|
"""Get a list of all cores found by fusesoc"""
|
|
90
91
|
return self.core_manager.db.find()
|
|
91
92
|
|
|
93
|
+
def apply_filters(self, global_filters):
|
|
94
|
+
filters = self.edam.get("filters", []) + global_filters
|
|
95
|
+
for f in filters:
|
|
96
|
+
try:
|
|
97
|
+
filter_class = getattr(
|
|
98
|
+
import_module(f"fusesoc.filters.{f}"), f.capitalize()
|
|
99
|
+
)
|
|
100
|
+
logger.info(f"Applying filter {f}")
|
|
101
|
+
self.edam = filter_class().run(self.edam, self.work_root)
|
|
102
|
+
except ModuleNotFoundError:
|
|
103
|
+
logger.warning(f"Ignoring unknown EDAM filter '{f}'")
|
|
104
|
+
except Exception as e:
|
|
105
|
+
logger.error(f"Filter error: {str(e)}")
|
|
106
|
+
|
|
92
107
|
def run(self):
|
|
93
108
|
"""Run all steps to create a EDAM file"""
|
|
94
109
|
|
|
@@ -102,7 +117,7 @@ class Edalizer:
|
|
|
102
117
|
# to the list of available cores.
|
|
103
118
|
self.run_generators()
|
|
104
119
|
|
|
105
|
-
# Create
|
|
120
|
+
# Create EDAM file contents
|
|
106
121
|
self.create_edam()
|
|
107
122
|
|
|
108
123
|
return self.edam
|
|
@@ -148,7 +163,16 @@ class Edalizer:
|
|
|
148
163
|
self.work_root if not self.export_root else None,
|
|
149
164
|
resolve_env_vars=self.resolve_env_vars,
|
|
150
165
|
)
|
|
151
|
-
|
|
166
|
+
try:
|
|
167
|
+
gen_cores = _ttptttg.generate()
|
|
168
|
+
except RuntimeError as e:
|
|
169
|
+
logger.error(e)
|
|
170
|
+
raise RuntimeError(
|
|
171
|
+
f"Failed to run generator '{ttptttg_data['name']}'"
|
|
172
|
+
)
|
|
173
|
+
gen_cores = []
|
|
174
|
+
for gen_core in gen_cores:
|
|
175
|
+
core.direct_deps.append(str(gen_core.name))
|
|
152
176
|
gen_core.pos = _ttptttg.pos
|
|
153
177
|
self._resolved_or_generated_cores.append(gen_core)
|
|
154
178
|
if self.export_root and not (
|
|
@@ -199,7 +223,7 @@ class Edalizer:
|
|
|
199
223
|
for core in self.cores:
|
|
200
224
|
snippet = {}
|
|
201
225
|
|
|
202
|
-
logger.debug("Collecting
|
|
226
|
+
logger.debug("Collecting EDAM parameters from {}".format(str(core.name)))
|
|
203
227
|
_flags = self._core_flags(core)
|
|
204
228
|
|
|
205
229
|
# Extract direct dependencies
|
|
@@ -223,6 +247,9 @@ class Edalizer:
|
|
|
223
247
|
self.flags["tool"]: core.get_tool_options(_flags)
|
|
224
248
|
}
|
|
225
249
|
|
|
250
|
+
# Extract EDAM filters
|
|
251
|
+
snippet["filters"] = core.get_filters(_flags)
|
|
252
|
+
|
|
226
253
|
# Extract flow options
|
|
227
254
|
snippet["flow_options"] = core.get_flow_options(_flags)
|
|
228
255
|
|
|
@@ -282,14 +309,8 @@ class Edalizer:
|
|
|
282
309
|
top_core = self.resolved_cores[-1]
|
|
283
310
|
self.edam = {
|
|
284
311
|
"version": "0.2.1",
|
|
285
|
-
"dependencies": {},
|
|
286
|
-
"files": [],
|
|
287
|
-
"hooks": {},
|
|
288
312
|
"name": self.system_name or top_core.name.sanitized_name,
|
|
289
|
-
"parameters": {},
|
|
290
|
-
"tool_options": {},
|
|
291
313
|
"toplevel": top_core.get_toplevel(self.flags),
|
|
292
|
-
"vpi": [],
|
|
293
314
|
}
|
|
294
315
|
|
|
295
316
|
for snippet in first_snippets + snippets + last_snippets:
|
|
@@ -355,7 +376,7 @@ class Edalizer:
|
|
|
355
376
|
)
|
|
356
377
|
param_type_map[name.replace("-", "_")] = _paramtype
|
|
357
378
|
else:
|
|
358
|
-
logging.
|
|
379
|
+
logging.warning(
|
|
359
380
|
"Parameter '{}' has unsupported type '{}' for requested backend".format(
|
|
360
381
|
name, _paramtype
|
|
361
382
|
)
|
|
@@ -480,16 +501,16 @@ class Edalizer:
|
|
|
480
501
|
|
|
481
502
|
return flow_options
|
|
482
503
|
|
|
483
|
-
def parse_args(self, backend_class, backendargs
|
|
504
|
+
def parse_args(self, backend_class, backendargs):
|
|
484
505
|
# First we need to see which flow options are set,
|
|
485
506
|
# in order to know which tool options that are relevant
|
|
486
507
|
# for this configuration of the flow
|
|
487
508
|
if hasattr(backend_class, "get_flow_options"):
|
|
488
509
|
self.activated_flow_options = self._parse_flow_options(
|
|
489
|
-
backend_class, backendargs, edam
|
|
510
|
+
backend_class, backendargs, self.edam
|
|
490
511
|
)
|
|
491
512
|
|
|
492
|
-
parser = self._build_parser(backend_class, edam)
|
|
513
|
+
parser = self._build_parser(backend_class, self.edam)
|
|
493
514
|
parsed_args = parser.parse_args(backendargs)
|
|
494
515
|
|
|
495
516
|
args_dict = {}
|