Simplify pin creation.
authorJock Tanner <tanner.of.kha@gmail.com>
Wed, 18 Mar 2020 13:37:12 +0000 (13:37 +0000)
committerJock Tanner <tanner.of.kha@gmail.com>
Wed, 18 Mar 2020 13:37:12 +0000 (13:37 +0000)
experiments7/doAlu16.py

index 032f216af2149a0e806ccbe6169ec340bce53999..2fcdd1c9e2451272c1f8defcd23dd14b52566360 100755 (executable)
@@ -33,10 +33,77 @@ def get_layer(name, layer_cache={}):
     return layer
 
 
-def toDbU(l):
+def to_DbU(l):
     return DbU.fromLambda(l)
 
 
+def create_pins(
+    cell, net, name, direction, status=Pin.PlacementStatus.FIXED, layer=None,
+    x=0.0, y=0.0, width=2.0, height=2.0, repeat=1, delta=0.0, external=True,
+):
+    """
+    Creates a series of pins in a cell.
+
+    :param cell: Hurricane.Cell object to place pins onto, or object name,
+    :param net: Hurricane.Net object name or name template, taking a pin
+      enumeration parameter, i. e. pin number,
+    :param name: pin name or name template taking a pin enumeration parameter,
+    :param direction: Pin.Direction value,
+    :param status: Pin.PlacementStatus value (default is FIXED),
+    :param layer: Hurricane.Layer object or name (METAL3),
+    :param x: starting pin position (left to right, 0.0),
+    :param y: starting pin position (bottom to top, 0.0),
+    :param width: pin width (2,0),
+    :param height: pin height (2.0),
+    :param repeat: a number of pins to be placed or an iterable containing
+      pin template parameters (i. e. pin number, 1),
+    :param delta: next pin position offset (0.0),
+    :param external: mark pin as external (yes),
+    :return: tuple of next pin coordinates, or just (x, y), if delta was not
+      provided.
+    """
+    if isinstance(cell, basestring):
+        cell = CRL.AllianceFramework.get().getCell(
+            cell, CRL.Catalog.State.Logical
+        )
+
+    if layer is None:
+        layer = get_layer('METAL3')
+    elif isinstance(layer, basestring):
+        layer = get_layer(layer)
+
+    if isinstance(repeat, int):
+        if repeat > 1 and delta == 0.0:
+            raise Warning('You are trying to place pins on each other.')
+        iterator = range(repeat)
+    else:
+        iterator = repeat
+
+    for i in iterator:
+        pin = Pin.create(
+            cell.getNet(net.format(i)),
+            name.format(i),
+            direction,
+            status,
+            layer,
+            l(x),
+            l(y),
+            l(width),
+            l(height),
+        )
+        if direction in (Pin.Direction.NORTH, Pin.Direction.SOUTH):
+            x += delta
+        else:
+            # EAST or WEST
+            y += delta
+
+        if external:
+            pin.getNet().setExternal(True)
+            NetExternalComponents.setExternal(pin)
+
+    return x, y
+
+
 def placeAndRoute(cell):
     etesian = Etesian.EtesianEngine.create(cell)
     etesian.place()
@@ -120,14 +187,14 @@ def add(**kwargs):
 
     ab = Box(l(0.0), l(0.0), l(width), l(height))
 
-    cellGauge = af.getCellGauge()
+    cell_gauge = af.getCellGauge()
     margin_as_percentage = Cfg.getParamPercentage(
         'etesian.spaceMargin'
     ).asPercentage()
-    spaceMargin = (margin_as_percentage + 5) / 100.0
-    aspectRatio = margin_as_percentage / 100.0
+    space_margin = (margin_as_percentage + 5) / 100.0
+    aspect_ratio = margin_as_percentage / 100.0
     clocktree.ClockTree.computeAbutmentBox(
-        cell, spaceMargin, aspectRatio, cellGauge,
+        cell, space_margin, aspect_ratio, cell_gauge,
     )
     ab2 = cell.getAbutmentBox()
     print("box", ab, ab.getHeight(), ab.getWidth())
@@ -136,56 +203,18 @@ def add(**kwargs):
     UpdateSession.open()
     cell.setAbutmentBox(ab)
 
-    for i in range(BIT_WIDTH):
-        x = 20.0 * i + 10.0
-        y = height
-        pin = Pin.create(
-            cell.getNet('a(%d)' % i),
-            'a(%d).0' % i,
-            Pin.Direction.NORTH,
-            Pin.PlacementStatus.FIXED,
-            METAL3,
-            l(x),
-            l(y - 0),
-            l(2.0),
-            l(2.0),
-        )
-        pin.getNet().setExternal(True)
-        NetExternalComponents.setExternal(pin)
-
-    for i in range(BIT_WIDTH):
-        pin = Pin.create(
-            cell.getNet('o(%d)' % i),
-            'o(%d).0' % i,
-            Pin.Direction.SOUTH,
-            Pin.PlacementStatus.FIXED,
-            METAL3,
-            l(10.0 * i + 100.0),
-            l(0),  # Position.
-            l(2.0),
-            l(2.0),  # Size.
-        )
-        pin.getNet().setExternal(True)
-        NetExternalComponents.setExternal(pin)
-
-    for i in range(BIT_WIDTH):
-        net = cell.getNet('b(%d)' % i)
-        x = 20.0 * i + 10.0 + 10
-        y = height - 0
-        pin = Pin.create(
-            net,
-            'b(%d).0' % i,
-            Pin.Direction.NORTH,
-            Pin.PlacementStatus.FIXED,
-            METAL3,
-            l(x),
-            l(y - 0),  # Position.
-            l(2.0),
-            l(2.0),  # Size.
-        )
-        pin.getNet().setExternal(True)
-        NetExternalComponents.setExternal(pin)
-
+    create_pins(
+        cell, 'a({})', 'a({}).0', Pin.Direction.NORTH,
+        x=10.0, y=height, delta=20.0, repeat=BIT_WIDTH,
+    )
+    create_pins(
+        cell, 'o({})', 'o({}).0', Pin.Direction.SOUTH,
+        x=100.0, y=0.0, delta=10.0, repeat=BIT_WIDTH,
+    )
+    create_pins(
+        cell, 'b({})', 'b({}).0', Pin.Direction.NORTH,
+        x=20.0, y=height, delta=20.0, repeat=BIT_WIDTH,
+    )
     UpdateSession.close()
 
     if editor:
@@ -196,10 +225,13 @@ def add(**kwargs):
     UpdateSession.open()
 
     ab = cell.getAbutmentBox()
-    ab.inflate(toDbU(-5.0))
-    Pad.create(net, BLOCKAGE2, ab)  # do we really want to use net b(15)?
-    Pad.create(net, BLOCKAGE3, ab)
-    Pad.create(net, BLOCKAGE4, ab)
+    ab.inflate(to_DbU(-5.0))
+
+    # do we really want to use net b(15)?
+    last_net = cell.getNet('b({})'.format(BIT_WIDTH-1))
+    Pad.create(last_net, BLOCKAGE2, ab)
+    Pad.create(last_net, BLOCKAGE3, ab)
+    Pad.create(last_net, BLOCKAGE4, ab)
     UpdateSession.close()
 
     RSavePlugin.ScriptMain(**kwargs)
@@ -248,55 +280,18 @@ def sub(**kwargs):
     UpdateSession.open()
     cell.setAbutmentBox(ab)
 
-    for i in range(BIT_WIDTH):
-        x = 20.0 * i + 10.0
-        y = height
-        pin = Pin.create(
-            cell.getNet('a(%d)' % i),
-            'a(%d).0' % i,
-            Pin.Direction.NORTH,
-            Pin.PlacementStatus.FIXED,
-            METAL3,
-            l(x),
-            l(y - 0),  # Position.
-            l(2.0),
-            l(2.0),  # Size.
-        )
-        pin.getNet().setExternal(True)
-        NetExternalComponents.setExternal(pin)
-
-    for i in range(BIT_WIDTH):
-        pin = Pin.create(
-            cell.getNet('o(%d)' % i),
-            'o(%d).0' % i,
-            Pin.Direction.SOUTH,
-            Pin.PlacementStatus.FIXED,
-            METAL3,
-            l(10.0 * i + 100.0),
-            l(0),  # Position.
-            l(2.0),
-            l(2.0),  # Size.
-        )
-        pin.getNet().setExternal(True)
-        NetExternalComponents.setExternal(pin)
-
-    for i in range(BIT_WIDTH):
-        net = cell.getNet('b(%d)' % i)
-        x = 20.0 * i + 10.0 + 10
-        y = height - 0
-        pin = Pin.create(
-            net,
-            'b(%d).0' % i,
-            Pin.Direction.NORTH,
-            Pin.PlacementStatus.FIXED,
-            METAL3,
-            l(x),
-            l(y),  # Position.
-            l(2.0),
-            l(2.0),  # Size.
-        )
-        pin.getNet().setExternal(True)
-        NetExternalComponents.setExternal(pin)
+    create_pins(
+        cell, 'a({})',  'a({}).0', Pin.Direction.NORTH,
+        x=10.0, y=height, delta=20.0, repeat=BIT_WIDTH,
+    )
+    create_pins(
+        cell, 'o({})', 'o({}).0', Pin.Direction.SOUTH,
+        x=100.0, y=0.0, delta=10.0, repeat=BIT_WIDTH,
+    )
+    create_pins(
+        cell, 'b({})', 'b({}).0', Pin.Direction.NORTH,
+        x=20.0, y=height, delta=20.0, repeat=BIT_WIDTH,
+    )
 
     UpdateSession.close()
 
@@ -308,10 +303,12 @@ def sub(**kwargs):
     UpdateSession.open()
 
     ab = cell.getAbutmentBox()
-    ab.inflate(toDbU(-5.0))
-    Pad.create(net, BLOCKAGE2, ab)  # do we really want to use net b(15)?
-    Pad.create(net, BLOCKAGE3, ab)
-    Pad.create(net, BLOCKAGE4, ab)
+    ab.inflate(to_DbU(-5.0))
+    # do we really want to use net b(15)?
+    last_net = cell.getNet('b({})'.format(BIT_WIDTH-1))
+    Pad.create(last_net, BLOCKAGE2, ab)
+    Pad.create(last_net, BLOCKAGE3, ab)
+    Pad.create(last_net, BLOCKAGE4, ab)
     UpdateSession.close()
 
     RSavePlugin.ScriptMain(**kwargs)
@@ -331,7 +328,8 @@ def alu16(**kwargs):
         return False
     kwargs['cell'] = cell
 
-    ab = Box(l(0.0), l(0.0), l(1100.0), l(600.0))
+    width, height = 1100.0, 600.0
+    ab = Box(l(0.0), l(0.0), l(width), l(height))
 
     UpdateSession.open()
     cell.setAbutmentBox(ab)
@@ -343,7 +341,7 @@ def alu16(**kwargs):
     add_inst = [x for x in instances if x.getName().endswith('add')][0]
     add_inst.setTransformation(
         Transformation(
-            toDbU(25.0), toDbU(75.0), Transformation.Orientation.ID
+            to_DbU(25.0), to_DbU(75.0), Transformation.Orientation.ID
         )
     )
     add_inst.setPlacementStatus(Instance.PlacementStatus.FIXED)
@@ -352,58 +350,27 @@ def alu16(**kwargs):
     sub_inst = [x for x in instances if x.getName().endswith('sub')][0]
     sub_inst.setTransformation(
         Transformation(
-            toDbU(725.0), toDbU(75.0), Transformation.Orientation.ID
+            to_DbU(725.0), to_DbU(75.0), Transformation.Orientation.ID
         )
     )
     sub_inst.setPlacementStatus(Instance.PlacementStatus.FIXED)
 
-    yNorth = cell.getAbutmentBox().getYMax()
-
-    for i in range(BIT_WIDTH):
-        Pin.create(
-            cell.getNet('a(%d)' % i),
-            'a(%d).0' % i,
-            Pin.Direction.SOUTH,
-            Pin.PlacementStatus.FIXED,
-            METAL3,
-            l(60.0 * i + 50.0),
-            l(0.0),  # Position.
-            l(2.0),
-            l(2.0),  # Size.
-        )
-        Pin.create(
-            cell.getNet('b(%d)' % i),
-            'b(%d).0' % i,
-            Pin.Direction.SOUTH,
-            Pin.PlacementStatus.FIXED,
-            METAL3,
-            l(60.0 * i + 80.0),
-            l(0.0),  # Position.
-            l(2.0),
-            l(2.0),  # Size.
-        )
-        Pin.create(
-            cell.getNet('o(%d)' % i),
-            'o(%d).0' % i,
-            Pin.Direction.NORTH,
-            Pin.PlacementStatus.FIXED,
-            METAL3,
-            l(60.0 * i + 50.0),
-            yNorth,  # Position.
-            l(2.0),
-            l(2.0),  # Size.
-        )
-
-    Pin.create(
-        cell.getNet('rst'),
-        'rst.0',
-        Pin.Direction.WEST,
-        Pin.PlacementStatus.FIXED,
-        METAL2,
-        l(0.0),
-        l(140.0),
-        l(2.0),
-        l(2.0),
+    y_north = cell.getAbutmentBox().getYMax()
+    create_pins(
+        cell, 'a({})', 'a({}).0', Pin.Direction.SOUTH,
+        x=50.0, y=0.0, delta=60.0, repeat=BIT_WIDTH,
+    )
+    create_pins(
+        cell, 'b({})', 'b({}).0', Pin.Direction.SOUTH,
+        x=80.0, y=0.0, delta=60.0, repeat=BIT_WIDTH,
+    )
+    create_pins(
+        cell, 'o({})', 'o({}).0', Pin.Direction.NORTH,
+        x=50.0, y=y_north/l(1),  # converting back to lambdas?
+        delta=60.0, repeat=BIT_WIDTH,
+    )
+    create_pins(
+        cell, 'rst', 'rst.0', Pin.Direction.WEST, layer=METAL2, x=0.0, y=140.0,
     )
     UpdateSession.close()