FABulous-FPGA 2__py3-none-any.whl
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.
- fabulous/__init__.py +5 -0
- fabulous/custom_exception.py +66 -0
- fabulous/fabric_cad/README.md +152 -0
- fabulous/fabric_cad/__init__.py +5 -0
- fabulous/fabric_cad/gen_bitstream_spec.py +286 -0
- fabulous/fabric_cad/gen_design_top_wrapper.py +246 -0
- fabulous/fabric_cad/gen_npnr_model.py +253 -0
- fabulous/fabric_cad/timing_model/FABulous_timing_model.py +1037 -0
- fabulous/fabric_cad/timing_model/FABulous_timing_model_interface.py +104 -0
- fabulous/fabric_cad/timing_model/__init__.py +8 -0
- fabulous/fabric_cad/timing_model/hdlnx/__init__.py +7 -0
- fabulous/fabric_cad/timing_model/hdlnx/hdlnx_timing_model.py +89 -0
- fabulous/fabric_cad/timing_model/hdlnx/sdfnx/__init__.py +6 -0
- fabulous/fabric_cad/timing_model/hdlnx/sdfnx/sdf_to_graph.py +362 -0
- fabulous/fabric_cad/timing_model/hdlnx/sdfnx/sdf_to_graph_base.py +200 -0
- fabulous/fabric_cad/timing_model/hdlnx/sdfnx/timing_graph.py +329 -0
- fabulous/fabric_cad/timing_model/hdlnx/verilog_gate_level.py +1046 -0
- fabulous/fabric_cad/timing_model/models.py +427 -0
- fabulous/fabric_cad/timing_model/tools/__init__.py +6 -0
- fabulous/fabric_cad/timing_model/tools/specification.py +248 -0
- fabulous/fabric_cad/timing_model/tools/sta_tools/__init__.py +6 -0
- fabulous/fabric_cad/timing_model/tools/sta_tools/opensta.py +359 -0
- fabulous/fabric_cad/timing_model/tools/synth_tools/__init__.py +4 -0
- fabulous/fabric_cad/timing_model/tools/synth_tools/yosys.py +467 -0
- fabulous/fabric_definition/__init__.py +17 -0
- fabulous/fabric_definition/bel.py +167 -0
- fabulous/fabric_definition/cell_spec.py +230 -0
- fabulous/fabric_definition/configmem.py +35 -0
- fabulous/fabric_definition/define.py +163 -0
- fabulous/fabric_definition/fabric.py +726 -0
- fabulous/fabric_definition/gen_io.py +64 -0
- fabulous/fabric_definition/port.py +292 -0
- fabulous/fabric_definition/supertile.py +311 -0
- fabulous/fabric_definition/switch_matrix.py +71 -0
- fabulous/fabric_definition/tile.py +428 -0
- fabulous/fabric_definition/wire.py +107 -0
- fabulous/fabric_definition/yosys_obj.py +521 -0
- fabulous/fabric_files/FABulous_project_template_common/Fabric/gds_config.yaml +61 -0
- fabulous/fabric_files/FABulous_project_template_common/Fabric/std_cell_library.yaml +96 -0
- fabulous/fabric_files/FABulous_project_template_common/Test/.gitignore +17 -0
- fabulous/fabric_files/FABulous_project_template_common/Test/build_fabulous_fabric.tcl +4 -0
- fabulous/fabric_files/FABulous_project_template_common/Test/compile.Taskfile.yml +62 -0
- fabulous/fabric_files/FABulous_project_template_common/Test/makehex.py +28 -0
- fabulous/fabric_files/FABulous_project_template_common/Tile/DSP/DSP.csv +4 -0
- fabulous/fabric_files/FABulous_project_template_common/Tile/DSP/DSP_bot/DSP_bot.csv +8 -0
- fabulous/fabric_files/FABulous_project_template_common/Tile/DSP/DSP_bot/DSP_bot_switch_matrix.list +230 -0
- fabulous/fabric_files/FABulous_project_template_common/Tile/DSP/DSP_top/DSP_top.csv +7 -0
- fabulous/fabric_files/FABulous_project_template_common/Tile/DSP/DSP_top/DSP_top_switch_matrix.list +215 -0
- fabulous/fabric_files/FABulous_project_template_common/Tile/DSP/gds_config.yaml +6 -0
- fabulous/fabric_files/FABulous_project_template_common/Tile/LUT4AB/LUT4AB.csv +17 -0
- fabulous/fabric_files/FABulous_project_template_common/Tile/LUT4AB/LUT4AB_ConfigMem.csv +21 -0
- fabulous/fabric_files/FABulous_project_template_common/Tile/LUT4AB/LUT4AB_switch_matrix.list +301 -0
- fabulous/fabric_files/FABulous_project_template_common/Tile/LUT4AB/gds_config.yaml +6 -0
- fabulous/fabric_files/FABulous_project_template_common/Tile/N_term_DSP/N_term_DSP.csv +14 -0
- fabulous/fabric_files/FABulous_project_template_common/Tile/N_term_DSP/N_term_DSP_switch_matrix.list +15 -0
- fabulous/fabric_files/FABulous_project_template_common/Tile/N_term_DSP/gds_config.yaml +4 -0
- fabulous/fabric_files/FABulous_project_template_common/Tile/N_term_RAM_IO/N_term_RAM_IO.csv +12 -0
- fabulous/fabric_files/FABulous_project_template_common/Tile/N_term_RAM_IO/N_term_RAM_IO_switch_matrix.list +16 -0
- fabulous/fabric_files/FABulous_project_template_common/Tile/N_term_RAM_IO/gds_config.yaml +4 -0
- fabulous/fabric_files/FABulous_project_template_common/Tile/N_term_single/N_term_single.csv +15 -0
- fabulous/fabric_files/FABulous_project_template_common/Tile/N_term_single/N_term_single_switch_matrix.list +15 -0
- fabulous/fabric_files/FABulous_project_template_common/Tile/N_term_single/gds_config.yaml +4 -0
- fabulous/fabric_files/FABulous_project_template_common/Tile/N_term_single2/N_term_single2.csv +14 -0
- fabulous/fabric_files/FABulous_project_template_common/Tile/N_term_single2/N_term_single2_switch_matrix.list +15 -0
- fabulous/fabric_files/FABulous_project_template_common/Tile/N_term_single2/gds_config.yaml +4 -0
- fabulous/fabric_files/FABulous_project_template_common/Tile/RAM_IO/RAM_IO.csv +45 -0
- fabulous/fabric_files/FABulous_project_template_common/Tile/RAM_IO/RAM_IO_switch_matrix.list +230 -0
- fabulous/fabric_files/FABulous_project_template_common/Tile/RAM_IO/gds_config.yaml +4 -0
- fabulous/fabric_files/FABulous_project_template_common/Tile/RegFile/RegFile.csv +6 -0
- fabulous/fabric_files/FABulous_project_template_common/Tile/RegFile/RegFile_switch_matrix.list +222 -0
- fabulous/fabric_files/FABulous_project_template_common/Tile/RegFile/gds_config.yaml +6 -0
- fabulous/fabric_files/FABulous_project_template_common/Tile/S_term_DSP/S_term_DSP.csv +14 -0
- fabulous/fabric_files/FABulous_project_template_common/Tile/S_term_DSP/S_term_DSP_switch_matrix.list +15 -0
- fabulous/fabric_files/FABulous_project_template_common/Tile/S_term_DSP/gds_config.yaml +4 -0
- fabulous/fabric_files/FABulous_project_template_common/Tile/S_term_RAM_IO/S_term_RAM_IO.csv +12 -0
- fabulous/fabric_files/FABulous_project_template_common/Tile/S_term_RAM_IO/S_term_RAM_IO_switch_matrix.list +16 -0
- fabulous/fabric_files/FABulous_project_template_common/Tile/S_term_RAM_IO/gds_config.yaml +4 -0
- fabulous/fabric_files/FABulous_project_template_common/Tile/S_term_single/S_term_single.csv +16 -0
- fabulous/fabric_files/FABulous_project_template_common/Tile/S_term_single/S_term_single_switch_matrix.list +17 -0
- fabulous/fabric_files/FABulous_project_template_common/Tile/S_term_single/gds_config.yaml +4 -0
- fabulous/fabric_files/FABulous_project_template_common/Tile/S_term_single2/S_term_single2.csv +14 -0
- fabulous/fabric_files/FABulous_project_template_common/Tile/S_term_single2/S_term_single2_switch_matrix.list +15 -0
- fabulous/fabric_files/FABulous_project_template_common/Tile/S_term_single2/gds_config.yaml +4 -0
- fabulous/fabric_files/FABulous_project_template_common/Tile/W_IO/W_IO.csv +22 -0
- fabulous/fabric_files/FABulous_project_template_common/Tile/W_IO/W_IO_switch_matrix.list +69 -0
- fabulous/fabric_files/FABulous_project_template_common/Tile/W_IO/gds_config.yaml +4 -0
- fabulous/fabric_files/FABulous_project_template_common/Tile/include/Base.csv +43 -0
- fabulous/fabric_files/FABulous_project_template_common/Tile/include/Base.list +75 -0
- fabulous/fabric_files/FABulous_project_template_common/Tile/include/gds_config.yaml +61 -0
- fabulous/fabric_files/FABulous_project_template_common/Tile/include/gf180mcuD_latchmap.v +7 -0
- fabulous/fabric_files/FABulous_project_template_common/fabric.csv +47 -0
- fabulous/fabric_files/FABulous_project_template_common/user_design/top_wrapper.v +159 -0
- fabulous/fabric_files/FABulous_project_template_verilog/FABulous.tcl +7 -0
- fabulous/fabric_files/FABulous_project_template_verilog/Fabric/BlockRAM_1KB.v +216 -0
- fabulous/fabric_files/FABulous_project_template_verilog/Fabric/ConfigFSM.v +106 -0
- fabulous/fabric_files/FABulous_project_template_verilog/Fabric/Frame_Data_Reg.v +19 -0
- fabulous/fabric_files/FABulous_project_template_verilog/Fabric/Frame_Select.v +21 -0
- fabulous/fabric_files/FABulous_project_template_verilog/Fabric/bitbang.v +84 -0
- fabulous/fabric_files/FABulous_project_template_verilog/Fabric/config_UART.v +633 -0
- fabulous/fabric_files/FABulous_project_template_verilog/Fabric/eFPGA_Config.v +99 -0
- fabulous/fabric_files/FABulous_project_template_verilog/Fabric/models_pack.v +204 -0
- fabulous/fabric_files/FABulous_project_template_verilog/Test/Makefile +83 -0
- fabulous/fabric_files/FABulous_project_template_verilog/Test/README.md +28 -0
- fabulous/fabric_files/FABulous_project_template_verilog/Test/Taskfile.yml +232 -0
- fabulous/fabric_files/FABulous_project_template_verilog/Test/gen_gl_xinit.py +303 -0
- fabulous/fabric_files/FABulous_project_template_verilog/Test/sequential_16bit_en_tb.v +126 -0
- fabulous/fabric_files/FABulous_project_template_verilog/Tile/DSP/DSP_bot/MULADD.v +86 -0
- fabulous/fabric_files/FABulous_project_template_verilog/Tile/LUT4AB/LUT4c_frame_config_dffesr.v +123 -0
- fabulous/fabric_files/FABulous_project_template_verilog/Tile/LUT4AB/MUX8LUT_frame_config_mux.v +156 -0
- fabulous/fabric_files/FABulous_project_template_verilog/Tile/RAM_IO/Config_access.v +21 -0
- fabulous/fabric_files/FABulous_project_template_verilog/Tile/RAM_IO/InPass4_frame_config_mux.v +75 -0
- fabulous/fabric_files/FABulous_project_template_verilog/Tile/RAM_IO/OutPass4_frame_config_mux.v +79 -0
- fabulous/fabric_files/FABulous_project_template_verilog/Tile/RegFile/RegFile_32x4.v +77 -0
- fabulous/fabric_files/FABulous_project_template_verilog/Tile/W_IO/Config_access.v +23 -0
- fabulous/fabric_files/FABulous_project_template_verilog/Tile/W_IO/IO_1_bidirectional_frame_config_pass.v +50 -0
- fabulous/fabric_files/FABulous_project_template_verilog/user_design/sequential_16bit_en.v +22 -0
- fabulous/fabric_files/FABulous_project_template_vhdl/FABulous.tcl +2 -0
- fabulous/fabric_files/FABulous_project_template_vhdl/Fabric/BlockRAM_1KB.vhdl +262 -0
- fabulous/fabric_files/FABulous_project_template_vhdl/Fabric/ConfigFSM.vhdl +160 -0
- fabulous/fabric_files/FABulous_project_template_vhdl/Fabric/Frame_Data_Reg.vhdl +52 -0
- fabulous/fabric_files/FABulous_project_template_vhdl/Fabric/Frame_Select.vhdl +52 -0
- fabulous/fabric_files/FABulous_project_template_vhdl/Fabric/bitbang.vhdl +124 -0
- fabulous/fabric_files/FABulous_project_template_vhdl/Fabric/config_UART.vhdl +716 -0
- fabulous/fabric_files/FABulous_project_template_vhdl/Fabric/eFPGA_Config.vhdl +166 -0
- fabulous/fabric_files/FABulous_project_template_vhdl/Fabric/models_pack.vhdl +456 -0
- fabulous/fabric_files/FABulous_project_template_vhdl/Test/Makefile +155 -0
- fabulous/fabric_files/FABulous_project_template_vhdl/Test/README.md +33 -0
- fabulous/fabric_files/FABulous_project_template_vhdl/Test/Taskfile.yml +195 -0
- fabulous/fabric_files/FABulous_project_template_vhdl/Test/sequential_16bit_en_tb.vhdl +270 -0
- fabulous/fabric_files/FABulous_project_template_vhdl/Tile/DSP/DSP_bot/MULADD.vhdl +106 -0
- fabulous/fabric_files/FABulous_project_template_vhdl/Tile/LUT4AB/LUT4c_frame_config_dffesr.vhdl +228 -0
- fabulous/fabric_files/FABulous_project_template_vhdl/Tile/LUT4AB/MUX8LUT_frame_config_mux.vhdl +202 -0
- fabulous/fabric_files/FABulous_project_template_vhdl/Tile/RAM_IO/Config_access.vhdl +50 -0
- fabulous/fabric_files/FABulous_project_template_vhdl/Tile/RAM_IO/InPass4_frame_config_mux.vhdl +115 -0
- fabulous/fabric_files/FABulous_project_template_vhdl/Tile/RAM_IO/OutPass4_frame_config_mux.vhdl +113 -0
- fabulous/fabric_files/FABulous_project_template_vhdl/Tile/RegFile/RegFile_32x4.vhdl +90 -0
- fabulous/fabric_files/FABulous_project_template_vhdl/Tile/W_IO/Config_access.vhdl +50 -0
- fabulous/fabric_files/FABulous_project_template_vhdl/Tile/W_IO/IO_1_bidirectional_frame_config_pass.vhdl +83 -0
- fabulous/fabric_files/FABulous_project_template_vhdl/user_design/sequential_16bit_en.vhdl +45 -0
- fabulous/fabric_files/__init__.py +1 -0
- fabulous/fabric_files/dummy_files/DUMMY_switch_matrix.list +310 -0
- fabulous/fabric_generator/.gitignore +13 -0
- fabulous/fabric_generator/__init__.py +17 -0
- fabulous/fabric_generator/code_generator/__init__.py +6 -0
- fabulous/fabric_generator/code_generator/code_generator.py +853 -0
- fabulous/fabric_generator/code_generator/code_generator_VHDL.py +745 -0
- fabulous/fabric_generator/code_generator/code_generator_Verilog.py +546 -0
- fabulous/fabric_generator/gds_generator/__init__.py +1 -0
- fabulous/fabric_generator/gds_generator/flows/__init__.py +5 -0
- fabulous/fabric_generator/gds_generator/flows/fabric_macro_flow.py +729 -0
- fabulous/fabric_generator/gds_generator/flows/fabric_optimisation_flow.py +616 -0
- fabulous/fabric_generator/gds_generator/flows/flow_define.py +188 -0
- fabulous/fabric_generator/gds_generator/flows/tile_macro_flow.py +286 -0
- fabulous/fabric_generator/gds_generator/gen_io_pin_config_yaml.py +298 -0
- fabulous/fabric_generator/gds_generator/helper.py +167 -0
- fabulous/fabric_generator/gds_generator/script/__init__.py +1 -0
- fabulous/fabric_generator/gds_generator/script/add_buffers.tcl +57 -0
- fabulous/fabric_generator/gds_generator/script/extract_site_info.tcl +20 -0
- fabulous/fabric_generator/gds_generator/script/fabric_io_place.py +205 -0
- fabulous/fabric_generator/gds_generator/script/odb_power.py +130 -0
- fabulous/fabric_generator/gds_generator/script/odb_protocol.py +46 -0
- fabulous/fabric_generator/gds_generator/script/pdn.tcl +55 -0
- fabulous/fabric_generator/gds_generator/script/pdn_config.tcl +138 -0
- fabulous/fabric_generator/gds_generator/script/tile_io_place.py +1179 -0
- fabulous/fabric_generator/gds_generator/script/vhdl_json_header.py +73 -0
- fabulous/fabric_generator/gds_generator/steps/__init__.py +5 -0
- fabulous/fabric_generator/gds_generator/steps/add_buffer.py +76 -0
- fabulous/fabric_generator/gds_generator/steps/auto_diode.py +148 -0
- fabulous/fabric_generator/gds_generator/steps/condition_magic_drc.py +24 -0
- fabulous/fabric_generator/gds_generator/steps/custom_pdn.py +46 -0
- fabulous/fabric_generator/gds_generator/steps/diodes_on_ports.py +34 -0
- fabulous/fabric_generator/gds_generator/steps/extract_pdk_info.py +58 -0
- fabulous/fabric_generator/gds_generator/steps/fabric_IO_placement.py +72 -0
- fabulous/fabric_generator/gds_generator/steps/fabric_area_opt.py +846 -0
- fabulous/fabric_generator/gds_generator/steps/magic_streamout.py +38 -0
- fabulous/fabric_generator/gds_generator/steps/odb_connect_pdn.py +44 -0
- fabulous/fabric_generator/gds_generator/steps/round_die_area.py +56 -0
- fabulous/fabric_generator/gds_generator/steps/tile_IO_placement.py +97 -0
- fabulous/fabric_generator/gds_generator/steps/tile_area_opt.py +673 -0
- fabulous/fabric_generator/gds_generator/steps/timed_detailed_routing.py +109 -0
- fabulous/fabric_generator/gds_generator/steps/vhdl_json_header.py +45 -0
- fabulous/fabric_generator/gds_generator/steps/while_step.py +171 -0
- fabulous/fabric_generator/gen_fabric/__init__.py +14 -0
- fabulous/fabric_generator/gen_fabric/fabric_automation.py +879 -0
- fabulous/fabric_generator/gen_fabric/gen_configmem.py +532 -0
- fabulous/fabric_generator/gen_fabric/gen_fabric.py +602 -0
- fabulous/fabric_generator/gen_fabric/gen_helper.py +200 -0
- fabulous/fabric_generator/gen_fabric/gen_switchmatrix.py +591 -0
- fabulous/fabric_generator/gen_fabric/gen_tile.py +1137 -0
- fabulous/fabric_generator/gen_fabric/gen_top_wrapper.py +368 -0
- fabulous/fabric_generator/parser/__init__.py +1 -0
- fabulous/fabric_generator/parser/parse_configmem.py +178 -0
- fabulous/fabric_generator/parser/parse_csv.py +887 -0
- fabulous/fabric_generator/parser/parse_hdl.py +336 -0
- fabulous/fabric_generator/parser/parse_switchmatrix.py +216 -0
- fabulous/fabulous.py +992 -0
- fabulous/fabulous_api.py +916 -0
- fabulous/fabulous_cli/__init__.py +5 -0
- fabulous/fabulous_cli/cmd_compile_design.py +235 -0
- fabulous/fabulous_cli/cmd_run_simulation.py +343 -0
- fabulous/fabulous_cli/fabulous_cli.py +1846 -0
- fabulous/fabulous_cli/helper.py +1000 -0
- fabulous/fabulous_settings.py +692 -0
- fabulous/geometry_generator/__init__.py +22 -0
- fabulous/geometry_generator/bel_geometry.py +223 -0
- fabulous/geometry_generator/fabric_geometry.py +420 -0
- fabulous/geometry_generator/geometry_gen.py +71 -0
- fabulous/geometry_generator/geometry_obj.py +55 -0
- fabulous/geometry_generator/port_geometry.py +138 -0
- fabulous/geometry_generator/sm_geometry.py +531 -0
- fabulous/geometry_generator/tile_geometry.py +696 -0
- fabulous/geometry_generator/wire_geometry.py +391 -0
- fabulous/processpool.py +43 -0
- fabulous_fpga-2.dist-info/METADATA +226 -0
- fabulous_fpga-2.dist-info/RECORD +233 -0
- fabulous_fpga-2.dist-info/WHEEL +5 -0
- fabulous_fpga-2.dist-info/entry_points.txt +3 -0
- fabulous_fpga-2.dist-info/licenses/AUTHORS.md +21 -0
- fabulous_fpga-2.dist-info/licenses/LICENSE +201 -0
- fabulous_fpga-2.dist-info/top_level.txt +2 -0
- fabulous_nix/__init__.py +1 -0
- fabulous_nix/build_hooks.py +58 -0
- fabulous_nix/flake.lock +305 -0
- fabulous_nix/flake.nix +394 -0
- fabulous_nix/nix/default.nix +53 -0
- fabulous_nix/nix/overlay/python.nix +60 -0
- fabulous_nix/nix/tools/fabulator.nix +114 -0
- fabulous_nix/nix/tools/ghdl-bin.nix +69 -0
- fabulous_nix/nix/tools/nextpnr.nix +53 -0
- fabulous_nix/nix/tools/yosys.nix +102 -0
- fabulous_nix/pyproject.toml +182 -0
- fabulous_nix/uv.lock +2373 -0
- schema/std_cell_library.schema.json +91 -0
fabulous/__init__.py
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"""Custom exception classes for the FABulous framework.
|
|
2
|
+
|
|
3
|
+
This module defines all custom exceptions used throughout the FABulous framework for
|
|
4
|
+
better error handling and debugging. Each exception class is designed for specific error
|
|
5
|
+
scenarios that can occur during fabric generation, parsing, and configuration.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class CommandError(Exception):
|
|
10
|
+
"""Exception raised for errors in the command execution."""
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class EnvironmentNotSet(Exception):
|
|
14
|
+
"""Exception raised when the environment is not set."""
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class InvalidFileType(Exception):
|
|
18
|
+
"""Exception raised for unsupported file types."""
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class FabricParsingError(Exception):
|
|
22
|
+
"""Exception raised for errors in fabric parsing."""
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class SpecMissMatch(Exception):
|
|
26
|
+
"""Exception raised when a required FASM file is missing."""
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class InvalidPortType(Exception):
|
|
30
|
+
"""Exception raised for invalid port types."""
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class InvalidFabricDefinition(Exception):
|
|
34
|
+
"""Exception raised for invalid fabric definitions."""
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class InvalidFabricParameter(Exception):
|
|
38
|
+
"""Exception raised for invalid fabric parameters."""
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class InvalidSwitchMatrixDefinition(Exception):
|
|
42
|
+
"""Exception raised for invalid matrix definitions."""
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class InvalidListFileDefinition(Exception):
|
|
46
|
+
"""Exception raised for invalid list file formats."""
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class InvalidTileDefinition(Exception):
|
|
50
|
+
"""Exception raised for invalid tile definitions."""
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
class InvalidSupertileDefinition(Exception):
|
|
54
|
+
"""Exception raised for invalid supertile definitions."""
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
class InvalidBelDefinition(Exception):
|
|
58
|
+
"""Exception raised for invalid BEL definitions."""
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
class PipelineCommandError(Exception):
|
|
62
|
+
"""Exception raised for errors in command line arguments."""
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
class InvalidState(Exception):
|
|
66
|
+
"""Exception raised for invalid state during fabric generation."""
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
# FABulous bitstream generation
|
|
2
|
+
|
|
3
|
+
## Bitstream for a single tile
|
|
4
|
+
|
|
5
|
+
The fabric description file contains a table with the allocation of all tiles, like for example:
|
|
6
|
+
|
|
7
|
+
|FabricBegin| | | | | | | | | |
|
|
8
|
+
|---|---|---|---|---|---|---|---|---|---|
|
|
9
|
+
|NULL|N_term_single2|N_term_single2|N_term_single|N_term_single|N_term_single|N_term_single|N_term_single|N_term_single|NULL|
|
|
10
|
+
|W_IO|RegFile|DSP_top|LUT4AB|LUT4AB|LUT4AB|LUT4AB|LUT4AB|LUT4AB|CPU_IO|
|
|
11
|
+
|W_IO|RegFile|DSP_bot|LUT4AB|LUT4AB|LUT4AB|LUT4AB|LUT4AB|LUT4AB|CPU_IO|
|
|
12
|
+
|W_IO|RegFile|DSP_top|LUT4AB|LUT4AB|LUT4AB|LUT4AB|LUT4AB|LUT4AB|CPU_IO|
|
|
13
|
+
|W_IO|RegFile|DSP_bot|LUT4AB|LUT4AB|LUT4AB|LUT4AB|LUT4AB|LUT4AB|CPU_IO|
|
|
14
|
+
|W_IO|RegFile|DSP_top|LUT4AB|LUT4AB|LUT4AB|LUT4AB|LUT4AB|LUT4AB|CPU_IO|
|
|
15
|
+
|W_IO|RegFile|DSP_bot|LUT4AB|LUT4AB|LUT4AB|LUT4AB|LUT4AB|LUT4AB|CPU_IO|
|
|
16
|
+
|W_IO|RegFile|DSP_top|LUT4AB|LUT4AB|LUT4AB|LUT4AB|LUT4AB|LUT4AB|CPU_IO|
|
|
17
|
+
|W_IO|RegFile|DSP_bot|LUT4AB|LUT4AB|LUT4AB|LUT4AB|LUT4AB|LUT4AB|CPU_IO|
|
|
18
|
+
|NULL|S_term_single2|S_term_single2|S_term_single|S_term_single|S_term_single|S_term_single|S_term_single|S_term_single|NULL|
|
|
19
|
+
|**FabricEnd**|
|
|
20
|
+
|
|
21
|
+
Let us take tile type LUT4AB as an example for the bitstream. This tile has the following BELs:
|
|
22
|
+
|
|
23
|
+
| | | |
|
|
24
|
+
|---|---|---|
|
|
25
|
+
|BEL|LUT4c_frame_config.vhdl|LA_|
|
|
26
|
+
|BEL|LUT4c_frame_config.vhdl|LB_|
|
|
27
|
+
|BEL|LUT4c_frame_config.vhdl|LC_|
|
|
28
|
+
|BEL|LUT4c_frame_config.vhdl|LD_|
|
|
29
|
+
|BEL|LUT4c_frame_config.vhdl|LE_|
|
|
30
|
+
|BEL|LUT4c_frame_config.vhdl|LF_|
|
|
31
|
+
|BEL|LUT4c_frame_config.vhdl|LG_|
|
|
32
|
+
|BEL|LUT4c_frame_config.vhdl|LH_|
|
|
33
|
+
|BEL|MUX8LUT_frame_config.vhdl|
|
|
34
|
+
|MATRIX|LUT4AB_switch_matrix.VHDL|
|
|
35
|
+
|EndTILE|
|
|
36
|
+
|
|
37
|
+
These are 8 LUT BELs (each of which use 18 configuration bits) and a MUX8LUT (which uses 2 configuration bits). The latter BEL is used to cascade multiple smaller LUTs to implement one or more larger LUTs, if needed. The LUT4AB tile also provides a switch matrix (which uses 392 configuration bits).
|
|
38
|
+
|
|
39
|
+
The configuration bits for each LUT4c BEL are:
|
|
40
|
+
|
|
41
|
+
- [15…0] LUT init value (the truth table)
|
|
42
|
+
- [16] c_out_mux; ‘1’: use flip flop output, ‘0’: use combinatorial LUT output
|
|
43
|
+
- [17] c_I0mux; ‘1’: use I0 as Carry in; ‘0’ normal mode (I0 driven by input routing multiplexer)
|
|
44
|
+
|
|
45
|
+
The 2 configuration bits of the MUX8LUT BEL describe if we cascade to implement 4 x LUT5, 2 x LUT6 or 1 x LUT7.
|
|
46
|
+
|
|
47
|
+
The switch matrix is generated from the adjacency table ```LUT4AB_switch_matrix.csv```.
|
|
48
|
+
|
|
49
|
+
In that file, each row describes one configurable switch matrix multiplexer. The exact encoding of switch matrix multiplexers is defined in function TODO where we generate the multiplexer and where we write a dictionary for the final bitstream assembly.
|
|
50
|
+
The configuration bits of the individual switch matrix multiplexers are concatenated in the order they appear in the adjacency table, as can be seen in the generated RTL code:
|
|
51
|
+
|
|
52
|
+
```
|
|
53
|
+
-- switch matrix multiplexer N1BEG0 MUX-4
|
|
54
|
+
N1BEG0_input <= J_l_CD_END1 & JW2END3 & J2MID_CDb_END3 & LC_O after 80 ps;
|
|
55
|
+
N1BEG0 <= N1BEG0_input(TO_INTEGER(UNSIGNED(ConfigBits(1 downto 0))));
|
|
56
|
+
|
|
57
|
+
-- switch matrix multiplexer N1BEG1 MUX-4
|
|
58
|
+
N1BEG1_input <= J_l_EF_END2 & JW2END0 & J2MID_EFb_END0 & LD_O after 80 ps;
|
|
59
|
+
N1BEG1 <= N1BEG1_input(TO_INTEGER(UNSIGNED(ConfigBits(3 downto 2))));
|
|
60
|
+
|
|
61
|
+
…
|
|
62
|
+
|
|
63
|
+
-- switch matrix multiplexer J_l_GH_BEG3 MUX-4
|
|
64
|
+
J_l_GH_BEG3_input <= JW2END4 & W2END0 & E6END0 & N4END0 after 80 ps;
|
|
65
|
+
J_l_GH_BEG3 <= J_l_GH_BEG3_input(TO_INTEGER(UNSIGNED(ConfigBits(391 downto 390))));
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
When generating the Multiplexers, FABulous is writing metadata that contains a dictionary that denotes for each possible switch matrix multiplexer setting the corresponding bits.
|
|
69
|
+
|
|
70
|
+
A tile bitstream is formed by concatenating all configuration bits of all BELs in exactly the order as specified in the LUT4AB tile descriptor followed by the switch matrix configuration bits.
|
|
71
|
+
Note that all BELs (including the LUTs, DSPs, etc.) and the switch matrix expose their configuration bits in the respective BEL interface and the configuration bits are stored centralized in a module <tile_type>_ConfigMem, which is provided in each tile.
|
|
72
|
+
For a LUT4AB tile, the concatenated tile bitstream is:
|
|
73
|
+
|
|
74
|
+
| | |
|
|
75
|
+
|---|---|
|
|
76
|
+
|[17…0]|LUT LA|
|
|
77
|
+
|[35…18]|LUT LB|
|
|
78
|
+
|[53…36]|LUT LC|
|
|
79
|
+
|[71…54]|LUT LD|
|
|
80
|
+
|[89…72]|LUT LE|
|
|
81
|
+
|[107…90]|LUT LF|
|
|
82
|
+
|[125…108]|LUT LG|
|
|
83
|
+
|[143…126]|LUT LH|
|
|
84
|
+
|[145…144]|MUX8LUT|
|
|
85
|
+
|[537…146]|Switch matrix|
|
|
86
|
+
|
|
87
|
+
The bold numbers are the base configuration bit offsets for the different BELs and the switch matrix. For instance, to configure the C-LUT (LC) as a 4-input AND gate using the flip-flop output and not using the carry chain, we have to set the tile configuration bits:
|
|
88
|
+
|
|
89
|
+
| | |
|
|
90
|
+
|---|---|
|
|
91
|
+
|[53]|‘0’ # no carry chain|
|
|
92
|
+
|[52]|‘1’ # use flip-flop output|
|
|
93
|
+
|[51…36]|‘1000_0000_0000_0000’ # AND truth table|
|
|
94
|
+
|
|
95
|
+
In order to translate a FASM switch matrix routing entry into the tile configuration, we look up the FASM entry in the corresponding tile type switch matrix routing dictionary (file TODO) and add the base bit offset (here 146) to the reported bits.
|
|
96
|
+
For instance, to configure the switch matrix setting JW2END0 N1BEG1, we set tile configuration bits [149]=’1’ and [148]=’0’.
|
|
97
|
+
|
|
98
|
+
## Shift register configuration mode
|
|
99
|
+
|
|
100
|
+
In shift register configuration mode, the tile configuration bitstream is implemented as a single long shift register. At the moment we configure bitserial. To speed this up, multiple parallel chains (e.g., 32) maybe used. However, bitserial mode is expensive as it needs flip flops (rather than latches) and it is not well suited for partial reconfiguration.
|
|
101
|
+
Therefore, we recommend shift register configuration only for tiny fabrics (less than 200 LUTs) as frame-based reconfiguration is in almost any case superior.
|
|
102
|
+
|
|
103
|
+
## Frame-based configuration
|
|
104
|
+
|
|
105
|
+
A typical CLB tile with 8 LUTs will have somewhere between 500 and 1500 configuration bits. This is mostly depending on the LUT size and switch matrix multiplexer encoding (e.g. binary encoded versus one-hot).
|
|
106
|
+
These configuration bits have to be packed into i configuration frames with a tile frame data width of j bits. Ideally, i and j are about the same for minimal wire cost. In FABulous, we use j horizontal frame data bits per CLB row. This means that we use the same number of horizontal fame data bits for all tile types. The number of configuration frames (which correspond to an equal number of vertical select frame lines), will be adjusted for the actual total number of required tile configuration bits. For example, a DSP tile commonly needs fewer configuration bits as a LUT tile.
|
|
107
|
+
|
|
108
|
+
As a pragmatic solution, we defined the frame data width j=32 bits in FABulous. This fits well most practical requirements and makes it easy to interface the configuration logic with standard buses.
|
|
109
|
+
|
|
110
|
+
For the LUT2AB tile with 538 tile configuration bits, we have selected i=20 configuration frames. This results in i x j = 640 addressable configuration bits. In this example, we will leave 640 – 538 = 102 addressable configuration bits unused in each LUT4AB tile. Note that no latches will be generated for those unused configuration bits.
|
|
111
|
+
|
|
112
|
+
By default, FABulous is tightly packing the used configuration bits (538 for the LUT4AB example) in their original order into 32-bit frames (starting with frame 0).
|
|
113
|
+
However, a user can specify a tile configuration mapping file that looks as follows (see file LUT4AB_ConfigMem.csv for the full example):
|
|
114
|
+
|
|
115
|
+
```
|
|
116
|
+
#frame_name,frame_index,bits_used_in_frame,used_bits_mask,ConfigBits_ranges
|
|
117
|
+
frame0,0,32,1111_1111_1111_1111_0001_0001_0001_0001,15:00,16,17,144,145
|
|
118
|
+
frame1,1,32,1111_1111_1111_1111_0001_0001_0000_0000,33:18,34,35
|
|
119
|
+
frame2,2,32,1111_1111_1111_1111_0001_0001_0011_0011,51:36,52,53,515:514,517:516,#,J_l_CD_BEG0,J_l_CD_BEG1
|
|
120
|
+
frame3,3,32,1111_1111_1111_1111_0001_0001_0011_0011,69:54,70,71,519:518,521:520,#,J_l_CD_BEG2,J_l_CD_BEG3
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
The important information in each line (i.e. a tile configuration frame) is a bitmask that is for each frame denoting which addressable configuration bits will be used. For instance in frame0, we are using 20 configuration bits (out of the 32 possible configuration bits). The bitmask is specified MSB to LSB index [31…0].
|
|
124
|
+
|
|
125
|
+
After the bit mask, we specify a list of tile configuration bits in exactly the same order as the bit mask. These tile configuration bits will be mapped to the frame configuration bits.
|
|
126
|
+
|
|
127
|
+
For example, the 20 bits of frame0 are specified as:
|
|
128
|
+
|
|
129
|
+
```frame0,0,32,1111_1111_1111_1111_0001_0001_0001_0001,15:00,16,17,144,145```
|
|
130
|
+
|
|
131
|
+
This will map tile configuration bit [15] to bit 31 in frame0, 14 to bit 30 and so forth until tile configuration bit 145 is mapped to bit 0 in frame0. Therefore, the number of tile configuration bits has to match the number of ones in the frame mask. Ranges of tile configuration bits can be specified with the : operator. In the example, the tile configuration bits 15:0 are the init values of the A-LUT and they will be mapped to the 16 MSBs in frame0.
|
|
132
|
+
|
|
133
|
+
Future versions of FABulous will use the bitstream mapping feature for optimizing the physical implementation. In our first test chip, we used this feature to create a more human readable bitstream. For instance, we use this to locate the A-LUT to H-LUT init values in the first 8 frames at the high word position. The configuration modes are shown by nibbles (which will show up as one digit in a hex editor). Similarly, most multiplexers are represented by a single hex digit.
|
|
134
|
+
|
|
135
|
+
## Bitstream assembly and configuration frame addressing
|
|
136
|
+
|
|
137
|
+
Configuration frames are composed by concatenating the same configuration frame index for an entire resource column. For instance, in our example, we are considering an FPGA fabric with 8 rows and 10 columns. This corresponds to resource columns with 8 CLBs, 8 RegFiles or 4 DSPs (DSPs take two vertically aligned tiles).
|
|
138
|
+
Each configuration frame is masked by a frame_address_mask in 32 bits. ```frame_address_mask[31:27]``` performs as binary index to indicate the column index. ```frame_address_mask[19:0]``` performs as one-hot data code to index the frame address.
|
|
139
|
+
|
|
140
|
+
In the following example, the first line is the frame_address_mask, ```frame_address_mask[31:27] = 00100``` presents the 8th column (X7), ```frame_address_mask[19:0] = 0000_0000_0000_0000_0010``` presents 2nd frame (frame1). The rest 8 lines binary bits will be masked to all LUT4ABs' frame1 at column X7.
|
|
141
|
+
|
|
142
|
+
```
|
|
143
|
+
20 00 00 02
|
|
144
|
+
FF FE FF FE
|
|
145
|
+
FF FE 00 00
|
|
146
|
+
FF FF FF FF
|
|
147
|
+
00 00 00 00
|
|
148
|
+
FF FF FF FF
|
|
149
|
+
00 00 00 00
|
|
150
|
+
FF FE FF FE
|
|
151
|
+
FF FE FF FE
|
|
152
|
+
```
|
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
"""Bitstream specification generation module.
|
|
2
|
+
|
|
3
|
+
This module provides functionality to generate bitstream specifications from FPGA fabric
|
|
4
|
+
definitions. The specification defines how configuration bits map to physical frame
|
|
5
|
+
locations and is used during bitstream generation.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import string
|
|
9
|
+
from importlib.metadata import version
|
|
10
|
+
from typing import TYPE_CHECKING
|
|
11
|
+
|
|
12
|
+
from loguru import logger
|
|
13
|
+
|
|
14
|
+
from fabulous.fabric_definition.fabric import Fabric
|
|
15
|
+
from fabulous.fabric_generator.parser.parse_configmem import parseConfigMem
|
|
16
|
+
from fabulous.fabric_generator.parser.parse_switchmatrix import parseList, parseMatrix
|
|
17
|
+
from fabulous.fabulous_settings import get_context
|
|
18
|
+
|
|
19
|
+
if TYPE_CHECKING:
|
|
20
|
+
from fabulous.fabric_definition.configmem import ConfigMem
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def generateBitstreamSpec(fabric: Fabric) -> dict[str, dict]:
|
|
24
|
+
"""Generate the fabric's bitstream specification.
|
|
25
|
+
|
|
26
|
+
This is needed to tell where each FASM configuration is mapped to the physical
|
|
27
|
+
bitstream
|
|
28
|
+
The result file will be further parsed by `bit_gen.py`.
|
|
29
|
+
|
|
30
|
+
Parameters
|
|
31
|
+
----------
|
|
32
|
+
fabric : Fabric
|
|
33
|
+
The fabric object for generating the bitstream specification
|
|
34
|
+
|
|
35
|
+
Returns
|
|
36
|
+
-------
|
|
37
|
+
dict[str, dict]
|
|
38
|
+
The bits stream specification of the fabric.
|
|
39
|
+
"""
|
|
40
|
+
specData = {
|
|
41
|
+
"TileMap": {},
|
|
42
|
+
"TileSpecs": {},
|
|
43
|
+
"TileSpecs_No_Mask": {},
|
|
44
|
+
"FrameMap": {},
|
|
45
|
+
"FrameMapEncode": {},
|
|
46
|
+
"ArchSpecs": {
|
|
47
|
+
"MaxFramesPerCol": fabric.maxFramesPerCol,
|
|
48
|
+
"FrameBitsPerRow": fabric.frameBitsPerRow,
|
|
49
|
+
"FrameSelectWidth": fabric.frameSelectWidth,
|
|
50
|
+
"DesyncBit": fabric.desync_flag,
|
|
51
|
+
"SyncHeaderHex": fabric.syncHeaderHex,
|
|
52
|
+
"IncludeBorderRows": False, # Currently not supported in FABulous
|
|
53
|
+
"FABulousVersion": version("FABulous-FPGA"),
|
|
54
|
+
},
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
tileMap = {}
|
|
58
|
+
for y, row in enumerate(fabric.tile):
|
|
59
|
+
for x, tile in enumerate(row):
|
|
60
|
+
if tile is not None:
|
|
61
|
+
tileMap[f"X{x}Y{y}"] = tile.name
|
|
62
|
+
else:
|
|
63
|
+
tileMap[f"X{x}Y{y}"] = "NULL"
|
|
64
|
+
|
|
65
|
+
specData["TileMap"] = tileMap
|
|
66
|
+
configMemList: list[ConfigMem] = []
|
|
67
|
+
for y, row in enumerate(fabric.tile):
|
|
68
|
+
for x, tile in enumerate(row):
|
|
69
|
+
if tile is None:
|
|
70
|
+
continue
|
|
71
|
+
if "fabric.csv" in str(tile.tileDir):
|
|
72
|
+
# backward compatibility for old project structure
|
|
73
|
+
# We need to take the matrixDir from the tile, since there
|
|
74
|
+
# is the actual path to the tile defined in the fabric.csv
|
|
75
|
+
if tile.matrixDir.is_file():
|
|
76
|
+
configMemPath = tile.matrixDir.parent / f"{tile.name}_ConfigMem.csv"
|
|
77
|
+
elif tile.matrixDir.is_dir():
|
|
78
|
+
configMemPath = tile.matrixDir / f"{tile.name}_ConfigMem.csv"
|
|
79
|
+
else:
|
|
80
|
+
configMemPath = (
|
|
81
|
+
get_context().proj_dir
|
|
82
|
+
/ "Tile"
|
|
83
|
+
/ tile.name
|
|
84
|
+
/ f"{tile.name}_ConfigMem.csv"
|
|
85
|
+
)
|
|
86
|
+
logger.warning(
|
|
87
|
+
f"MatrixDir for {tile.name} is not a valid file or directory. "
|
|
88
|
+
f"Assuming default path: {configMemPath}"
|
|
89
|
+
)
|
|
90
|
+
else:
|
|
91
|
+
configMemPath = tile.tileDir.parent.joinpath(
|
|
92
|
+
f"{tile.name}_ConfigMem.csv"
|
|
93
|
+
)
|
|
94
|
+
logger.info(f"ConfigMemPath: {configMemPath}")
|
|
95
|
+
|
|
96
|
+
if configMemPath.exists() and configMemPath.is_file():
|
|
97
|
+
configMemList = parseConfigMem(
|
|
98
|
+
configMemPath,
|
|
99
|
+
fabric.maxFramesPerCol,
|
|
100
|
+
fabric.frameBitsPerRow,
|
|
101
|
+
tile.globalConfigBits,
|
|
102
|
+
)
|
|
103
|
+
elif tile.globalConfigBits > 0:
|
|
104
|
+
logger.critical(
|
|
105
|
+
f"No ConfigMem csv file found for {tile.name} which "
|
|
106
|
+
"have config bits"
|
|
107
|
+
)
|
|
108
|
+
configMemList = []
|
|
109
|
+
else:
|
|
110
|
+
logger.info(f"No config memory for {tile.name}.")
|
|
111
|
+
configMemList = []
|
|
112
|
+
|
|
113
|
+
encodeDict = [-1] * (fabric.maxFramesPerCol * fabric.frameBitsPerRow)
|
|
114
|
+
maskDic = {}
|
|
115
|
+
for cfm in configMemList:
|
|
116
|
+
maskDic[cfm.frameIndex] = cfm.usedBitMask
|
|
117
|
+
# matching the value in the configBitRanges with the reversedBitMask
|
|
118
|
+
# bit 0 in bit mask is the first value in the configBitRanges
|
|
119
|
+
for i, char in enumerate(cfm.usedBitMask):
|
|
120
|
+
if char == "1":
|
|
121
|
+
encodeDict[cfm.configBitRanges.pop(0)] = (
|
|
122
|
+
fabric.frameBitsPerRow - 1 - i
|
|
123
|
+
) + fabric.frameBitsPerRow * cfm.frameIndex
|
|
124
|
+
|
|
125
|
+
# filling the maskDic with the unused frames
|
|
126
|
+
for i in range(fabric.maxFramesPerCol - len(configMemList)):
|
|
127
|
+
maskDic[len(configMemList) + i] = "0" * fabric.frameBitsPerRow
|
|
128
|
+
|
|
129
|
+
specData["FrameMap"][tile.name] = maskDic
|
|
130
|
+
if tile.globalConfigBits == 0:
|
|
131
|
+
logger.info(f"No config memory for X{x}Y{y}_{tile.name}.")
|
|
132
|
+
specData["FrameMap"][tile.name] = {}
|
|
133
|
+
specData["FrameMapEncode"][tile.name] = {}
|
|
134
|
+
|
|
135
|
+
curBitOffset = 0
|
|
136
|
+
curTileMap = {}
|
|
137
|
+
curTileMapNoMask = {}
|
|
138
|
+
|
|
139
|
+
for i, bel in enumerate(tile.bels):
|
|
140
|
+
for featureKey, keyDict in bel.belFeatureMap.items():
|
|
141
|
+
for entry in keyDict:
|
|
142
|
+
if isinstance(entry, int):
|
|
143
|
+
for v in keyDict[entry]:
|
|
144
|
+
curTileMap[
|
|
145
|
+
f"{string.ascii_uppercase[i]}.{featureKey}"
|
|
146
|
+
] = {encodeDict[curBitOffset + v]: keyDict[entry][v]}
|
|
147
|
+
curTileMapNoMask[
|
|
148
|
+
f"{string.ascii_uppercase[i]}.{featureKey}"
|
|
149
|
+
] = {encodeDict[curBitOffset + v]: keyDict[entry][v]}
|
|
150
|
+
curBitOffset += len(keyDict[entry])
|
|
151
|
+
|
|
152
|
+
# All the generation will be working on the tile level with the tileDic
|
|
153
|
+
# This is added to propagate the updated switch matrix to each of the tile
|
|
154
|
+
# in the fabric
|
|
155
|
+
if tile.matrixDir.suffix == ".list":
|
|
156
|
+
tile.matrixDir = tile.matrixDir.with_suffix(".csv")
|
|
157
|
+
|
|
158
|
+
result = parseMatrix(tile.matrixDir, tile.name)
|
|
159
|
+
for source, sinkList in result.items():
|
|
160
|
+
controlWidth = 0
|
|
161
|
+
for i, sink in enumerate(reversed(sinkList)):
|
|
162
|
+
controlWidth = (len(sinkList) - 1).bit_length()
|
|
163
|
+
controlValue = f"{len(sinkList) - 1 - i:0{controlWidth}b}"
|
|
164
|
+
pip = f"{sink}.{source}"
|
|
165
|
+
if len(sinkList) < 2:
|
|
166
|
+
curTileMap[pip] = {}
|
|
167
|
+
curTileMapNoMask[pip] = {}
|
|
168
|
+
continue
|
|
169
|
+
|
|
170
|
+
for c, curChar in enumerate(controlValue[::-1]):
|
|
171
|
+
if pip not in curTileMap:
|
|
172
|
+
curTileMap[pip] = {}
|
|
173
|
+
curTileMapNoMask[pip] = {}
|
|
174
|
+
|
|
175
|
+
curTileMap[pip][encodeDict[curBitOffset + c]] = curChar
|
|
176
|
+
curTileMapNoMask[pip][encodeDict[curBitOffset + c]] = curChar
|
|
177
|
+
|
|
178
|
+
curBitOffset += controlWidth
|
|
179
|
+
|
|
180
|
+
# And now we add empty config bit mappings for immutable connections
|
|
181
|
+
# (i.e. wires), as nextpnr sees these the same as normal pips
|
|
182
|
+
for wire in tile.wireList:
|
|
183
|
+
curTileMap[f"{wire.source}.{wire.destination}"] = {}
|
|
184
|
+
curTileMapNoMask[f"{wire.source}.{wire.destination}"] = {}
|
|
185
|
+
|
|
186
|
+
specData["TileSpecs"][f"X{x}Y{y}"] = curTileMap
|
|
187
|
+
specData["TileSpecs_No_Mask"][f"X{x}Y{y}"] = curTileMapNoMask
|
|
188
|
+
|
|
189
|
+
# Supertile bitstream features. A supertile's config bits physically live in
|
|
190
|
+
# its master tile's frame column (the master tile's own ConfigMem leaves those
|
|
191
|
+
# bits free). Within the supertile config space the bit order is
|
|
192
|
+
# [switch-matrix bits][BEL bits], matching genSuperTile()'s ST_ConfigBits
|
|
193
|
+
# slicing. The BEL and switch-matrix features are added to the master tile's
|
|
194
|
+
# TileSpecs entry alongside the master tile's own features.
|
|
195
|
+
st_bel_count: dict[tuple[int, int], int] = {}
|
|
196
|
+
for superTile in fabric.superTileDic.values():
|
|
197
|
+
if not superTile.bels and superTile.supertile_matrix_dir is None:
|
|
198
|
+
continue
|
|
199
|
+
|
|
200
|
+
st_config_bits = superTile.total_config_bits
|
|
201
|
+
|
|
202
|
+
st_encode_dict = [-1] * (fabric.maxFramesPerCol * fabric.frameBitsPerRow)
|
|
203
|
+
st_mask_dic: dict[int, str] = {}
|
|
204
|
+
if st_config_bits > 0:
|
|
205
|
+
st_config_mem_list = parseConfigMem(
|
|
206
|
+
superTile.tileDir.parent / f"{superTile.name}_ConfigMem.csv",
|
|
207
|
+
fabric.maxFramesPerCol,
|
|
208
|
+
fabric.frameBitsPerRow,
|
|
209
|
+
st_config_bits,
|
|
210
|
+
)
|
|
211
|
+
for cfm in st_config_mem_list:
|
|
212
|
+
st_mask_dic[cfm.frameIndex] = cfm.usedBitMask
|
|
213
|
+
for i, char in enumerate(cfm.usedBitMask):
|
|
214
|
+
if char == "1":
|
|
215
|
+
st_encode_dict[cfm.configBitRanges.pop(0)] = (
|
|
216
|
+
fabric.frameBitsPerRow - 1 - i
|
|
217
|
+
) + fabric.frameBitsPerRow * cfm.frameIndex
|
|
218
|
+
|
|
219
|
+
sm_connections: dict[str, list[str]] = {}
|
|
220
|
+
if superTile.supertile_matrix_dir is not None:
|
|
221
|
+
mat_path = superTile.supertile_matrix_dir
|
|
222
|
+
if mat_path.suffix == ".list":
|
|
223
|
+
for dest, src in parseList(mat_path):
|
|
224
|
+
sm_connections.setdefault(dest, []).append(src)
|
|
225
|
+
else:
|
|
226
|
+
sm_connections = parseMatrix(mat_path, superTile.name)
|
|
227
|
+
|
|
228
|
+
tx_local, ty_local = superTile.get_master_tile_coords()
|
|
229
|
+
|
|
230
|
+
for base_fx, base_fy, _ in fabric.iter_super_tile_placements(superTile):
|
|
231
|
+
ftx = base_fx + tx_local
|
|
232
|
+
fty = base_fy + ty_local
|
|
233
|
+
master_tile = fabric.tile[fty][ftx]
|
|
234
|
+
|
|
235
|
+
frame_map = specData["FrameMap"].setdefault(master_tile.name, {})
|
|
236
|
+
for frame_idx, mask in st_mask_dic.items():
|
|
237
|
+
existing = frame_map.get(frame_idx, "0" * fabric.frameBitsPerRow)
|
|
238
|
+
frame_map[frame_idx] = "".join(
|
|
239
|
+
"1" if a == "1" or b == "1" else "0"
|
|
240
|
+
for a, b in zip(existing, mask, strict=True)
|
|
241
|
+
)
|
|
242
|
+
|
|
243
|
+
curTileMap = specData["TileSpecs"].setdefault(f"X{ftx}Y{fty}", {})
|
|
244
|
+
curTileMapNoMask = specData["TileSpecs_No_Mask"].setdefault(
|
|
245
|
+
f"X{ftx}Y{fty}", {}
|
|
246
|
+
)
|
|
247
|
+
|
|
248
|
+
curBitOffset = 0
|
|
249
|
+
for source, sinkList in sm_connections.items():
|
|
250
|
+
controlWidth = (len(sinkList) - 1).bit_length()
|
|
251
|
+
if st_config_bits == 0:
|
|
252
|
+
# No config bits — all connections are passthrough.
|
|
253
|
+
for sink in sinkList:
|
|
254
|
+
for t in (curTileMap, curTileMapNoMask):
|
|
255
|
+
t[f"{sink}.{source}"] = {}
|
|
256
|
+
continue
|
|
257
|
+
for i, sink in enumerate(reversed(sinkList)):
|
|
258
|
+
pip = f"{sink}.{source}"
|
|
259
|
+
if len(sinkList) < 2:
|
|
260
|
+
for t in (curTileMap, curTileMapNoMask):
|
|
261
|
+
t[pip] = {}
|
|
262
|
+
continue
|
|
263
|
+
controlValue = f"{len(sinkList) - 1 - i:0{controlWidth}b}"
|
|
264
|
+
for c, curChar in enumerate(controlValue[::-1]):
|
|
265
|
+
for t in (curTileMap, curTileMapNoMask):
|
|
266
|
+
t.setdefault(pip, {})
|
|
267
|
+
t[pip][st_encode_dict[curBitOffset + c]] = curChar
|
|
268
|
+
curBitOffset += controlWidth
|
|
269
|
+
|
|
270
|
+
bel_coord = (ftx, fty)
|
|
271
|
+
bel_offset = len(master_tile.bels) + st_bel_count.get(bel_coord, 0)
|
|
272
|
+
for i, bel in enumerate(superTile.bels):
|
|
273
|
+
letter = string.ascii_uppercase[bel_offset + i]
|
|
274
|
+
for featureKey, keyDict in bel.belFeatureMap.items():
|
|
275
|
+
for entry in keyDict:
|
|
276
|
+
if not isinstance(entry, int):
|
|
277
|
+
continue
|
|
278
|
+
for v in keyDict[entry]:
|
|
279
|
+
for t in (curTileMap, curTileMapNoMask):
|
|
280
|
+
t[f"{letter}.{featureKey}"] = {
|
|
281
|
+
st_encode_dict[curBitOffset + v]: keyDict[entry][v]
|
|
282
|
+
}
|
|
283
|
+
curBitOffset += len(keyDict[entry])
|
|
284
|
+
st_bel_count[bel_coord] = bel_offset + len(superTile.bels)
|
|
285
|
+
|
|
286
|
+
return specData
|