From a6f3271e24c93c7806798e76d9fb5b0571013f5f Mon Sep 17 00:00:00 2001 From: Jan Kowalewski Date: Mon, 10 May 2021 10:41:45 +0200 Subject: [PATCH] WIP: Bel Chains v.1 Signed-off-by: Jan Kowalewski --- fpga_interchange/chip_info.py | 110 ++++++++++++++++++++++++- fpga_interchange/nextpnr.py | 4 +- fpga_interchange/populate_chip_info.py | 14 +++- test_data/series7_bel_chains.yaml | 11 +++ 4 files changed, 135 insertions(+), 4 deletions(-) create mode 100644 test_data/series7_bel_chains.yaml diff --git a/fpga_interchange/chip_info.py b/fpga_interchange/chip_info.py index 62954245..eea53a29 100644 --- a/fpga_interchange/chip_info.py +++ b/fpga_interchange/chip_info.py @@ -19,6 +19,11 @@ class ConstraintType(Enum): TAG_REQUIRES = 1 +class ChainCoordinate(Enum): + x = 0 + y = 1 + + class BelInfo(): str_id_fields = ['ports'] int_fields = ['types', 'wires'] @@ -646,6 +651,107 @@ def append_bba(self, bba, label_prefix): bba.u32(len(getattr(self, field))) +class ChainPattern(): + def __init__(self, source, sink): + self.source = source + self.sink = sink + + def append_children_bba(self, bba, label_prefix): + pass + + def append_bba(self, bba, label_prefix): + bba.str_id(self.source) + bba.str_id(self.sink) + + +class ChainCoordConfig(): + def __init__(self, coord, step): + self.coord = coord + self.step = step + + def append_children_bba(self, bba, label_prefix): + pass + + def append_bba(self, bba, label_prefix): + bba.u8(self.coord) + bba.u8(self.step) + bba.u16(0) + + +class ChainCell(): + def __init__(self, cell, input_pins, output_pins): + self.cell = cell + + def append_children_bba(self, bba, label_prefix): + pass + + def append_bba(self, bba, label_prefix): + bba.str_id(self.cell) + + +class BelChain(): + children_fields = [ + 'patterns', 'coord_configs' + ] + children_types = [ + 'ChainPatternPOD', 'ChainCoordConfigPOD' + ] + + def __init__(self, name, patterns, sites, coord_configs, chain_cells): + # Chain name + self.name = name + + # Chain patterns + self.patterns = [] + for pattern in patterns: + self.patterns.append(ChainPattern(pattern.source, pattern.sink)) + + # Sites for which chain patterns apply + self.sites = sites + + # Coordinates configurations + # which coordinate by what step should be incremented + self.coord_configs = [] + if coord_configs is not None: + for coord_config in coord_configs: + self.coord_configs.append(ChainCoordConfig(coord_config.coord, coord_config.step)) + + # Chain cells used in BEL chain + self.chain_cells = chain_cells + + def field_label(self, label_prefix, field): + prefix = '{}.{}.{}'.format(label_prefix, self.name, field) + return prefix + + def append_children_bba(self, bba, label_prefix): + label = label_prefix + + bba.label(self.field_label(label_prefix, 'sites'), 'constid') + for s in self.sites: + bba.str(s) + + for field, field_type in zip(self.children_fields, + self.children_types): + prefix = self.field_label(label, field) + for value in getattr(self, field): + value.append_children_bba(bba, prefix) + + bba.label(prefix, field_type) + for value in getattr(self, field): + value.append_bba(bba, prefix) + + def append_bba(self, bba, label_prefix): + bba.str_id(self.name) + bba.ref(self.field_label(label_prefix, 'sites')) + bba.u32(len(self.sites)) + for cell in self.chain_cells: + bba.str_id(cell) + + for field in self.children_fields: + bba.ref(self.field_label(label_prefix, field)) + bba.u32(len(getattr(self, field))) + + class PackagePin(): def __init__(self): self.package_pin = '' @@ -857,6 +963,7 @@ def __init__(self): self.packages = [] self.wire_types = [] self.global_cells = [] + self.bel_chains = [] # str, constids self.bel_buckets = [] @@ -869,7 +976,7 @@ def append_bba(self, bba, label_prefix): children_fields = [ 'tile_types', 'sites', 'tiles', 'nodes', 'packages', 'wire_types', - 'global_cells' + 'global_cells', 'bel_chains', ] children_types = [ 'TileTypeInfoPOD', @@ -879,6 +986,7 @@ def append_bba(self, bba, label_prefix): 'PackagePOD', 'WireTypePOD', 'GlobalCellPOD', + 'BelChainPOD', ] for field, field_type in zip(children_fields, children_types): prefix = '{}.{}'.format(label, field) diff --git a/fpga_interchange/nextpnr.py b/fpga_interchange/nextpnr.py index 2bbe4124..87a934ad 100644 --- a/fpga_interchange/nextpnr.py +++ b/fpga_interchange/nextpnr.py @@ -81,5 +81,5 @@ def pop(self): def check_labels(self): refs_and_labels = self.refs & self.labels - assert len(refs_and_labels) == len(self.refs) - assert len(refs_and_labels) == len(self.labels) + assert len(refs_and_labels) == len(self.refs), "{} vs. {}".format(len(refs_and_labels), len(self.refs)) + assert len(refs_and_labels) == len(self.labels), "{} vs. {}".format(len(refs_and_labels), len(self.labels)) diff --git a/fpga_interchange/populate_chip_info.py b/fpga_interchange/populate_chip_info.py index 4ac2c881..46f523c3 100644 --- a/fpga_interchange/populate_chip_info.py +++ b/fpga_interchange/populate_chip_info.py @@ -16,7 +16,7 @@ TileWireRef, CellBelMap, ParameterPins, CellBelPin, ConstraintTag, \ CellConstraint, ConstraintType, Package, PackagePin, LutCell, \ LutElement, LutBel, CellParameter, DefaultCellConnections, DefaultCellConnection, \ - WireType, GlobalCell, GlobalCellPin + WireType, GlobalCell, GlobalCellPin, BelChain from fpga_interchange.constraints.model import Tag, Placement, \ ImpliesConstraint, RequiresConstraint from fpga_interchange.constraint_generator import ConstraintPrototype @@ -1733,6 +1733,18 @@ def populate_chip_info(device, constids, device_config): assert lut_element.site not in lut_elements lut_elements[lut_element.site] = LutElementsEmitter(lut_element.luts) + bel_chains = {} + for bel_chain in device.device_resource_capnp.belChainsDefinitions.belChains: + assert bel_chain.name not in bel_chains.keys() + cfgs_present = bel_chain.which() == "coordConfigs" + bel_chains[bel_chain.name] = BelChain(bel_chain.name, + bel_chain.patterns, + bel_chain.sites, + bel_chain.coordConfigs if cfgs_present else None, + bel_chain.chainCells) + + chip_info.bel_chains.append(bel_chains[bel_chain.name]) + for tile_type_index, tile_type in enumerate( device.device_resource_capnp.tileTypeList): flattened_tile_type = FlattenedTileType( diff --git a/test_data/series7_bel_chains.yaml b/test_data/series7_bel_chains.yaml new file mode 100644 index 00000000..9ef47048 --- /dev/null +++ b/test_data/series7_bel_chains.yaml @@ -0,0 +1,11 @@ +belChains: + - name: carryChain + patterns: + - {source: "CARRY4.CO[3]", sink: "CARRY4.CI"} + sites: + - SLICEL + - SLICEM + chainCells: + - XORCY + - MUXCY + - CARRY4