From dff2e8b6ebd30d45d5019c97102cab8f1d7c1375 Mon Sep 17 00:00:00 2001 From: Connor Young Date: Fri, 12 Jul 2024 00:18:44 -0600 Subject: [PATCH 1/4] gave dsps a special checking function --- bfasst/utils/structural.py | 108 +++++++++++++++++++++++++++++++++++-- 1 file changed, 103 insertions(+), 5 deletions(-) diff --git a/bfasst/utils/structural.py b/bfasst/utils/structural.py index d6acb56a..ef295c23 100644 --- a/bfasst/utils/structural.py +++ b/bfasst/utils/structural.py @@ -74,6 +74,7 @@ def __set_cell_props(self): "RAM32X1D_1", "RAM256X1S", "SRL16E", + "SRLC16E", "SRLC32E", "LDCE", ) @@ -102,6 +103,33 @@ def __set_cell_props(self): "PRESELECT_I0", "PRESELECT_I1", ) + _cell_props["DSP48E1"] = ( + "ACASCREG", + "ADREG", + "A_INPUT", + "ALUMODEREG", + "AREG", + "AUTORESET_PATDET", + "BCASCREG", + "B_INPUT", + "BREG", + "CARRYINREG", + "CARRYINSELREG", + "CREG", + "DREG", + "INMODEREG", + "MASK", + "MREG", + "OPMODEREG", + "PATTERN", + "PREG", + "SEL_MASK", + "SEL_PATTERN", + "USE_DPORT", + "USE_MULT", + "USE_PATTERN_DETECT", + "USE_SIMD", + ) self._cell_props = _cell_props @@ -329,12 +357,12 @@ def potential_mapping_wrapper(self, instance): logging.info("Considering %s (%s)", instance.name, instance.cell_type) # Get the implemented potential instance to map - if not instance.cell_type.startswith("RAMB"): - instances_matching = self.check_for_potential_mapping(instance) - else: + if instance.cell_type.startswith("RAMB"): instances_matching = self.check_for_potential_bram_mapping(instance) - - # self.log(f" {instances_matching} matches") + elif instance.cell_type.startswith("DSP48E1"): + instances_matching = self.check_for_potential_dsp_mapping(instance) + else: + instances_matching = self.check_for_potential_mapping(instance) if not instances_matching: raise StructuralCompareError( @@ -664,6 +692,76 @@ def check_for_potential_bram_mapping(self, named_instance): self.possible_matches[named_instance] = instances_matching_connections return instances_matching_connections + def check_for_potential_dsp_mapping(self, named_instance): + """Special check for dsp's + some of the pins have an INVERSION property + so if the pin is inverted, I invert it back to + it's original state + """ + + instances_matching_connections = [ + i for i in self.possible_matches[named_instance] if i not in self.block_mapping.inverse + ] + + for pin in named_instance.pins: + if pin.net not in self.net_mapping: + continue + + if name in {"ALUMODE", "OPMODE", "INMODE", "CLK", "CARRYIN"}: + for instance in instances_matching_connections: + if int(instance.properties[f"IS_{name}_INVERTED"][-1 - idx]) == 1: + net = instance.get_pin(name, idx).net + assert net.is_vdd or net.is_gnd + if net.is_vdd: + net.is_gnd = True + net.is_vdd = False + elif net.is_gnd: + net.is_gnd = False + net.is_vdd = True + + other_net = self.net_mapping[pin.net] + + logging.info(" Filtering on pin %s, %s", pin.name_with_index, other_net.name) + + name = pin.name + idx = pin.index + + tmp = [ + instance + for instance in instances_matching_connections + if instance.get_pin(name, idx).net == other_net + ] + + if not tmp: + if other_net.is_gnd: + tmp = [ + instance + for instance in instances_matching_connections + if instance.get_pin(name, idx).net.is_gnd + ] + elif other_net.is_vdd: + tmp = [ + instance + for instance in instances_matching_connections + if instance.get_pin(name, idx).net.is_vdd + ] + + instances_matching_connections = tmp + + num_instances = len(instances_matching_connections) + info = ( + ": " + ",".join(i.name for i in instances_matching_connections) + if num_instances <= 10 + else "" + ) + logging.info(" %s remaining%s", num_instances, info) + + logging.info( + " %s instance(s) after filtering on connections", len(instances_matching_connections) + ) + self.possible_matches[named_instance] = instances_matching_connections + return instances_matching_connections + def check_for_potential_mapping(self, named_instance): """Returns cells that could map to the named_instance""" From 5e21febe51e65119f494272e7f90bc093a60df4b Mon Sep 17 00:00:00 2001 From: Connor Young Date: Fri, 12 Jul 2024 14:09:17 -0600 Subject: [PATCH 2/4] got rid of dsp function --- bfasst/utils/structural.py | 106 +++++++++---------------------------- 1 file changed, 26 insertions(+), 80 deletions(-) diff --git a/bfasst/utils/structural.py b/bfasst/utils/structural.py index ef295c23..69e4a9cb 100644 --- a/bfasst/utils/structural.py +++ b/bfasst/utils/structural.py @@ -357,12 +357,10 @@ def potential_mapping_wrapper(self, instance): logging.info("Considering %s (%s)", instance.name, instance.cell_type) # Get the implemented potential instance to map - if instance.cell_type.startswith("RAMB"): - instances_matching = self.check_for_potential_bram_mapping(instance) - elif instance.cell_type.startswith("DSP48E1"): - instances_matching = self.check_for_potential_dsp_mapping(instance) - else: + if not instance.cell_type.startswith("RAMB"): instances_matching = self.check_for_potential_mapping(instance) + else: + instances_matching = self.check_for_potential_bram_mapping(instance) if not instances_matching: raise StructuralCompareError( @@ -692,75 +690,6 @@ def check_for_potential_bram_mapping(self, named_instance): self.possible_matches[named_instance] = instances_matching_connections return instances_matching_connections - def check_for_potential_dsp_mapping(self, named_instance): - """Special check for dsp's - some of the pins have an INVERSION property - so if the pin is inverted, I invert it back to - it's original state - """ - - instances_matching_connections = [ - i for i in self.possible_matches[named_instance] if i not in self.block_mapping.inverse - ] - - for pin in named_instance.pins: - if pin.net not in self.net_mapping: - continue - - if name in {"ALUMODE", "OPMODE", "INMODE", "CLK", "CARRYIN"}: - for instance in instances_matching_connections: - if int(instance.properties[f"IS_{name}_INVERTED"][-1 - idx]) == 1: - net = instance.get_pin(name, idx).net - assert net.is_vdd or net.is_gnd - if net.is_vdd: - net.is_gnd = True - net.is_vdd = False - elif net.is_gnd: - net.is_gnd = False - net.is_vdd = True - - other_net = self.net_mapping[pin.net] - - logging.info(" Filtering on pin %s, %s", pin.name_with_index, other_net.name) - - name = pin.name - idx = pin.index - - tmp = [ - instance - for instance in instances_matching_connections - if instance.get_pin(name, idx).net == other_net - ] - - if not tmp: - if other_net.is_gnd: - tmp = [ - instance - for instance in instances_matching_connections - if instance.get_pin(name, idx).net.is_gnd - ] - elif other_net.is_vdd: - tmp = [ - instance - for instance in instances_matching_connections - if instance.get_pin(name, idx).net.is_vdd - ] - - instances_matching_connections = tmp - - num_instances = len(instances_matching_connections) - info = ( - ": " + ",".join(i.name for i in instances_matching_connections) - if num_instances <= 10 - else "" - ) - logging.info(" %s remaining%s", num_instances, info) - - logging.info( - " %s instance(s) after filtering on connections", len(instances_matching_connections) - ) - self.possible_matches[named_instance] = instances_matching_connections - return instances_matching_connections def check_for_potential_mapping(self, named_instance): """Returns cells that could map to the named_instance""" @@ -791,19 +720,36 @@ def check_for_potential_mapping(self, named_instance): idx = pin.index else: idx = 0 if pin.index == 1 else 1 + + name = pin.name + + if named_instance.cell_type == "DSP48E1" and name in {"ALUMODE", "OPMODE", "INMODE", "CLK", "CARRYIN"}: + for instance in instances_matching_connections: + # [3:] : gets rid of the "{# of bits}'b" at the beginning of the prop + # [::-1] : reverses the string since the pins index the opposite as python strings + reversed_prop = instance.properties[f"IS_{name}_INVERTED"][3:][::-1] + if int(reversed_prop[idx]) == 1: + net = instance.get_pin(name, idx).net + if (other_net.is_gnd and net.is_vdd) or (other_net.is_vdd and net.is_gnd): + pin.ignore_net_equivalency = True + + if pin.ignore_net_equivalency: + continue + + tmp = [ instance for instance in instances_matching_connections - if instance.get_pin(pin.name, idx).net == other_net + if instance.get_pin(name, idx).net == other_net ] if named_instance.cell_type == "BUFGCTRL" and pin.name[0] == "I" and not tmp: # sometimes f2b routes the clk net to both inputs - other_pin = f"I{'1' if pin.name[1] == '0' else '0'}" + other_pin = f"I{'1' if name[1] == '0' else '0'}" tmp = [ inst for inst in instances_matching_connections - if inst.get_pin(pin.name, idx).net == inst.get_pin(other_pin, idx).net + if inst.get_pin(name, idx).net == inst.get_pin(other_pin, idx).net ] pin.ignore_net_equivalency = True @@ -812,14 +758,14 @@ def check_for_potential_mapping(self, named_instance): tmp = [ instance for instance in instances_matching_connections - if instance.get_pin(pin.name, idx).net is None - or instance.get_pin(pin.name, idx).net.is_gnd + if instance.get_pin(name, idx).net is None + or instance.get_pin(name, idx).net.is_gnd ] elif other_net.is_vdd: tmp = [ instance for instance in instances_matching_connections - if instance.get_pin(pin.name, idx).net.is_vdd + if instance.get_pin(name, idx).net.is_vdd ] instances_matching_connections = tmp From 7233d7e06c3ee2357ee1da5ec52995c1df5e6cf2 Mon Sep 17 00:00:00 2001 From: Connor Young Date: Fri, 12 Jul 2024 14:10:12 -0600 Subject: [PATCH 3/4] pylint --- bfasst/utils/structural.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/bfasst/utils/structural.py b/bfasst/utils/structural.py index 69e4a9cb..95ffa895 100644 --- a/bfasst/utils/structural.py +++ b/bfasst/utils/structural.py @@ -357,7 +357,7 @@ def potential_mapping_wrapper(self, instance): logging.info("Considering %s (%s)", instance.name, instance.cell_type) # Get the implemented potential instance to map - if not instance.cell_type.startswith("RAMB"): + if not instance.cell_type.startswith("RAMB"): instances_matching = self.check_for_potential_mapping(instance) else: instances_matching = self.check_for_potential_bram_mapping(instance) @@ -690,7 +690,6 @@ def check_for_potential_bram_mapping(self, named_instance): self.possible_matches[named_instance] = instances_matching_connections return instances_matching_connections - def check_for_potential_mapping(self, named_instance): """Returns cells that could map to the named_instance""" @@ -723,7 +722,13 @@ def check_for_potential_mapping(self, named_instance): name = pin.name - if named_instance.cell_type == "DSP48E1" and name in {"ALUMODE", "OPMODE", "INMODE", "CLK", "CARRYIN"}: + if named_instance.cell_type == "DSP48E1" and name in { + "ALUMODE", + "OPMODE", + "INMODE", + "CLK", + "CARRYIN", + }: for instance in instances_matching_connections: # [3:] : gets rid of the "{# of bits}'b" at the beginning of the prop # [::-1] : reverses the string since the pins index the opposite as python strings @@ -735,7 +740,6 @@ def check_for_potential_mapping(self, named_instance): if pin.ignore_net_equivalency: continue - tmp = [ instance From 5b75c15adbc57d6c3a57ba7170a6bf4b2ab1b93c Mon Sep 17 00:00:00 2001 From: Connor Young Date: Fri, 12 Jul 2024 14:15:11 -0600 Subject: [PATCH 4/4] pylint --- bfasst/utils/structural.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/bfasst/utils/structural.py b/bfasst/utils/structural.py index 95ffa895..2dd363b1 100644 --- a/bfasst/utils/structural.py +++ b/bfasst/utils/structural.py @@ -731,12 +731,13 @@ def check_for_potential_mapping(self, named_instance): }: for instance in instances_matching_connections: # [3:] : gets rid of the "{# of bits}'b" at the beginning of the prop - # [::-1] : reverses the string since the pins index the opposite as python strings + # [::-1] : reverses the string since the pins index the opposite as strings reversed_prop = instance.properties[f"IS_{name}_INVERTED"][3:][::-1] - if int(reversed_prop[idx]) == 1: - net = instance.get_pin(name, idx).net - if (other_net.is_gnd and net.is_vdd) or (other_net.is_vdd and net.is_gnd): - pin.ignore_net_equivalency = True + if int(reversed_prop[idx]) == 1 and ( + (other_net.is_gnd and instance.get_pin(name, idx).net.is_vdd) + or (other_net.is_vdd and instance.get_pin(name, idx).net.is_gnd) + ): + pin.ignore_net_equivalency = True if pin.ignore_net_equivalency: continue