From: Jock Tanner Date: Thu, 26 Mar 2020 07:24:47 +0000 (+0000) Subject: Recover from awkward merge. X-Git-Tag: partial-core-ls180-gdsii~155 X-Git-Url: https://git.libre-soc.org/?p=soclayout.git;a=commitdiff_plain;h=e0409cae95ea2f4c86c8c8709b6674e6f5ebdf0c Recover from awkward merge. --- diff --git a/experiments7/doAlu16.py b/experiments7/doAlu16.py index 7f9971e..9da6180 100755 --- a/experiments7/doAlu16.py +++ b/experiments7/doAlu16.py @@ -3,133 +3,20 @@ from __future__ import print_function import sys -import Anabatic import CRL import Cfg -import Etesian -import Katana -from Hurricane import ( - DbU, DataBase, UpdateSession, Box, Transformation, Instance, Pin, - NetExternalComponents, -) -from helpers import l +from Hurricane import Box from plugins import RSavePlugin from coriolis2.settings import af -from utils import Module +from utils import Module, SessionManager import symbolic.cmos # do not remove BIT_WIDTH = 16 -def get_layer(name, layer_cache={}): - """ Creates a new layer or returns it from cache. """ - if name in layer_cache: - return layer_cache[name] - - layer = DataBase.getDB().getTechnology().getLayer(name) - layer_cache[name] = layer - return layer - - -def to_DbU(l): - """ - Convert lambdas to database units. (See Hurricane+Python Manual 3.4.) - """ - return DbU.fromLambda(l) - - -def from_DbU(ph): - """ - Convert database units to lambdas. (See Hurricane+Python Manual 3.4.) - """ - return DbU.toLambda(ph) - - -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 = af.getCell(cell, CRL.Catalog.State.Logical) - - if layer is None: - layer = 'METAL3' - if 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 place_and_route(cell): - """ - Places and routes. - - :param cell: Hurricane.Cell object to operate on, - :return: True on success, False otherwise. - """ - etesian = Etesian.EtesianEngine.create(cell) - etesian.place() - - katana = Katana.KatanaEngine.create(cell) - katana.digitalInit() - katana.runGlobalRouter(Katana.Flags.NoFlags) - katana.loadGlobalRouting(Anabatic.EngineLoadGrByNet) - katana.layerAssign(Anabatic.EngineNoNetLayerAssign) - katana.runNegociate(Katana.Flags.NoFlags) - katana.finalizeLayout() - success = katana.isDetailedRoutingSuccess() - katana.destroy() - - return success - - def coriolis_setup(): Cfg.Configuration.pushDefaultPriority(Cfg.Parameter.Priority.UserFile) - - env = af.getEnvironment() - Cfg.getParamBool('misc.catchCore').setBool(False) Cfg.getParamBool('misc.info').setBool(False) Cfg.getParamBool('misc.paranoid').setBool(False) @@ -157,83 +44,73 @@ def coriolis_setup(): Cfg.Configuration.popDefaultPriority() -def alu16(editor=None, **kwargs): +class AddSub(Module): + + def do(self): + """ Main routine. """ + + with SessionManager(): + self.init_abutment_box() + self.create_pins() - db = DataBase.getDB() - print(db, dir(db)) - METAL2 = get_layer('METAL2') + if self.editor: + self.editor.setCell(self.cell) - cell = af.getCell('alu16', CRL.Catalog.State.Logical) - if not cell: - print('[ERROR] Unable to load cell "alu16.vst", aborting .') - return False + result = self.place_and_route() - width, height = 1100.0, 600.0 - ab = Box(l(0.0), l(0.0), l(width), l(height)) + with SessionManager(): + self.create_pads() - UpdateSession.open() - cell.setAbutmentBox(ab) + RSavePlugin.ScriptMain(editor=self.editor, cell=self.cell) + return result - # get instances inside cell - instances = cell.getInstances() - # find adder instance - add_inst = [x for x in instances if x.getName().endswith('add')][0] - add_inst.setTransformation(Transformation(to_DbU(25.0), to_DbU(75.0), - Transformation.Orientation.ID)) - add_inst.setPlacementStatus(Instance.PlacementStatus.FIXED) +class ALU16(Module): - # find subtractor instance - sub_inst = [x for x in instances if x.getName().endswith('sub')][0] - sub_inst.setTransformation(Transformation(to_DbU(725.0), to_DbU(75.0), - Transformation.Orientation.ID)) - sub_inst.setPlacementStatus(Instance.PlacementStatus.FIXED) + def do(self): - 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=from_DbU(y_north), - 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() + if not self.do_submodules(): + return False - if editor: - editor.setCell(cell) + with SessionManager(): + self.init_abutment_box() + self.place_submodules() - print("editor", editor, dir(editor)) + # TODO: replace with some form of lazy evaluation? + y_north = self.from_dbu(self.cell.getAbutmentBox().getYMax()) + for pin_conf in self.north_pins: + pin_conf['y'] = y_north - # place first (in middle, between two) - # this puts all the remaining cells (little ones) - # into this (small) space so that they do not go - # "all over the place" around the add and sub - ab2 = Box(l(400.0), l(50.0), l(700.0), l(500.0)) + self.create_pins() - cell.setAbutmentBox(ab2) - etesian = Etesian.EtesianEngine.create(cell) - etesian.place() + if self.editor: + self.editor.setCell(self.cell) - # then route (globally) - # this connects up not just in the remaining (little) cells, - # it connects *to add and sub and the outside world as well* - cell.setAbutmentBox(ab) + # place first (in middle, between two) + # this puts all the remaining cells (little ones) + # into this (small) space so that they do not go + # "all over the place" around the add and sub + self.ab = Box(self.to_dbu(400.0), self.to_dbu(50.0), + self.to_dbu(700.0), self.to_dbu(500.0)) + self.place() - result = place_and_route(cell) + # then route (globally) + # this connects up not just in the remaining (little) cells, + # it connects *to add and sub and the outside world as well* + self.init_abutment_box() + result = self.place_and_route() - cell.setName(cell.getName()+'_r') - af.saveCell(cell, CRL.Catalog.State.Views) - RSavePlugin.ScriptMain(editor=editor, cell=cell, **kwargs) + self.name = self.name + '_r' + self.af.saveCell(self.cell, CRL.Catalog.State.Views) + RSavePlugin.ScriptMain(editor=self.editor, cell=self.cell) - return result + return result def ScriptMain(editor=None, **kwargs): coriolis_setup() - add = Module( + add = AddSub( 'add', editor, width=350.0, height=400.0, north_pins=[ {'net': 'a({})', 'x': 10.0, 'delta': 20.0, 'repeat': BIT_WIDTH}, @@ -242,10 +119,13 @@ def ScriptMain(editor=None, **kwargs): south_pins=[ {'net': 'o({})', 'x': 100.0, 'delta': 10.0, 'repeat': BIT_WIDTH}, ], - pads={'b(15)': ('BLOCKAGE2', 'BLOCKAGE3', 'BLOCKAGE4')}, + pads={ + 'b({})'.format(BIT_WIDTH-1): ( + 'BLOCKAGE2', 'BLOCKAGE3', 'BLOCKAGE4', + ), + }, ) - - sub = Module( + sub = AddSub( 'sub', editor, width=350.0, height=400.0, north_pins=[ {'net': 'a({})', 'x': 10.0, 'delta': 20.0, 'repeat': BIT_WIDTH}, @@ -254,12 +134,29 @@ def ScriptMain(editor=None, **kwargs): south_pins=[ {'net': 'o({})', 'x': 100.0, 'delta': 10.0, 'repeat': BIT_WIDTH}, ], - pads={'b(15)': ('BLOCKAGE2', 'BLOCKAGE3', 'BLOCKAGE4')}, + pads={ + 'b({})'.format(BIT_WIDTH-1): ( + 'BLOCKAGE2', 'BLOCKAGE3', 'BLOCKAGE4', + ), + }, ) - add.do() - sub.do() - return alu16(editor, **kwargs) + alu16 = ALU16( + 'alu16', editor, width=1100.0, height=600.0, + submodules=[(add, 25.0, 75.0), (sub, 725.0, 75.0)], + north_pins=[ + {'net': 'o({})', 'x': 50.0, 'delta': 60.0, 'repeat': BIT_WIDTH}, + {'net': 'op'}, + ], + south_pins=[ + {'net': 'a({})', 'x': 50.0, 'delta': 60.0, 'repeat': BIT_WIDTH}, + {'net': 'b({})', 'x': 80.0, 'delta': 60.0, 'repeat': BIT_WIDTH}, + ], + west_pins=[ + {'net': 'rst', 'y': 140.0, 'layer': 'METAL2'}, + ], + ) + return alu16.do() if __name__ == '__main__':