From d5836959595b8d19a7f696a3fa2c82b373dacf60 Mon Sep 17 00:00:00 2001 From: mrg Date: Wed, 2 Oct 2019 23:26:02 +0000 Subject: [PATCH] Remove some flake8 errors/warnings. --- compiler/base/contact.py | 126 +++++++++++++++++++++--------------- compiler/base/delay_data.py | 7 +- compiler/base/design.py | 23 +++---- compiler/base/geometry.py | 107 +++++++++++++++--------------- compiler/debug.py | 2 +- compiler/gen_stimulus.py | 5 +- compiler/openram.py | 33 +++++----- compiler/options.py | 28 ++++---- compiler/sram_factory.py | 38 +++++------ compiler/view_profile.py | 4 +- 10 files changed, 199 insertions(+), 174 deletions(-) diff --git a/compiler/base/contact.py b/compiler/base/contact.py index be3af1ce..30f6870b 100644 --- a/compiler/base/contact.py +++ b/compiler/base/contact.py @@ -7,39 +7,44 @@ # import hierarchy_design import debug -import utils -from tech import drc,layer +from tech import drc, layer from vector import vector class contact(hierarchy_design.hierarchy_design): """ - Object for a contact shape with its conductor enclosures. - Creates a contact array minimum active or poly enclosure and metal1 enclosure. - This class has enclosure on two or four sides of the contact. - The direction specifies whether the first and second layer have asymmetric extension in the H or V direction. + Object for a contact shape with its conductor enclosures. Creates + a contact array minimum active or poly enclosure and metal1 + enclosure. This class has enclosure on two or four sides of the + contact. The direction specifies whether the first and second + layer have asymmetric extension in the H or V direction. + + The well/implant_type is an option to add a select/implant layer + enclosing the contact. This is necessary to import layouts into + Magic which requires the select to be in the same GDS hierarchy as + the contact. - The well/implant_type is an option to add a select/implant layer enclosing the contact. This is - necessary to import layouts into Magic which requires the select to be in the same GDS - hierarchy as the contact. """ - def __init__(self, layer_stack, dimensions=(1,1), directions=("V","V"), implant_type=None, well_type=None, name=""): - # This will ignore the name parameter since we can guarantee a unique name here + def __init__(self, layer_stack, dimensions=(1, 1), directions=("V", "V"), + implant_type=None, well_type=None, name=""): + # This will ignore the name parameter since + # we can guarantee a unique name here hierarchy_design.hierarchy_design.__init__(self, name) debug.info(4, "create contact object {0}".format(name)) self.add_comment("layers: {0}".format(layer_stack)) self.add_comment("dimensions: {0}".format(dimensions)) if implant_type or well_type: - self.add_comment("implant type: {0}\nwell_type: {1}".format(implant_type,well_type)) + self.add_comment("implant type: {}\n".format(implant_type)) + self.add_comment("well_type: {}\n".format(well_type)) self.layer_stack = layer_stack self.dimensions = dimensions self.directions = directions - self.offset = vector(0,0) + self.offset = vector(0, 0) self.implant_type = implant_type - self.well_type = well_type + self.well_type = well_type # Module does not have pins, but has empty pin list. self.pins = [] self.create_layout() @@ -59,7 +64,7 @@ class contact(hierarchy_design.hierarchy_design): if self.implant_type and self.well_type: self.create_implant_well_enclosures() elif self.implant_type or self.well_type: - debug.error(-1,"Must define both implant and well type or none at all.") + debug.error(-1, "Must define both implant and well type or none at all.") def setup_layers(self): """ Locally assign the layer names. """ @@ -67,10 +72,11 @@ class contact(hierarchy_design.hierarchy_design): (first_layer, via_layer, second_layer) = self.layer_stack self.first_layer_name = first_layer self.via_layer_name = via_layer - # Some technologies have a separate active contact from the poly contact + # Some technologies have a separate active + # contact from the poly contact # We will use contact for DRC, but active_contact for output - if first_layer=="active" or second_layer=="active": - self.via_layer_name_expanded = "active_"+via_layer + if first_layer == "active" or second_layer == "active": + self.via_layer_name_expanded = "active_" + via_layer else: self.via_layer_name_expanded = via_layer self.second_layer_name = second_layer @@ -97,19 +103,19 @@ class contact(hierarchy_design.hierarchy_design): second_layer_enclosure = drc("{0}_enclosure_{1}".format(self.second_layer_name, self.via_layer_name)) second_layer_extend = drc("{0}_extend_{1}".format(self.second_layer_name, self.via_layer_name)) - - # In some technologies, the minimum width may be larger than the overlap requirement around the via, so + # In some technologies, the minimum width may be larger + # than the overlap requirement around the via, so # check this for each dimension. if self.directions[0] == "V": self.first_layer_horizontal_enclosure = max(first_layer_enclosure, - (first_layer_minwidth - self.contact_array_width)/2) + (first_layer_minwidth - self.contact_array_width) / 2) self.first_layer_vertical_enclosure = max(first_layer_extend, - (first_layer_minwidth - self.contact_array_height)/2) + (first_layer_minwidth - self.contact_array_height) / 2) elif self.directions[0] == "H": self.first_layer_horizontal_enclosure = max(first_layer_extend, - (first_layer_minwidth - self.contact_array_width)/2) + (first_layer_minwidth - self.contact_array_width) / 2) self.first_layer_vertical_enclosure = max(first_layer_enclosure, - (first_layer_minwidth - self.contact_array_height)/2) + (first_layer_minwidth - self.contact_array_height) / 2) else: debug.error("Invalid first layer direction.", -1) @@ -117,23 +123,23 @@ class contact(hierarchy_design.hierarchy_design): # check this for each dimension. if self.directions[1] == "V": self.second_layer_horizontal_enclosure = max(second_layer_enclosure, - (second_layer_minwidth - self.contact_array_width)/2) + (second_layer_minwidth - self.contact_array_width) / 2) self.second_layer_vertical_enclosure = max(second_layer_extend, - (second_layer_minwidth - self.contact_array_height)/2) + (second_layer_minwidth - self.contact_array_height) / 2) elif self.directions[1] == "H": self.second_layer_horizontal_enclosure = max(second_layer_extend, - (second_layer_minwidth - self.contact_array_height)/2) + (second_layer_minwidth - self.contact_array_height) / 2) self.second_layer_vertical_enclosure = max(second_layer_enclosure, - (second_layer_minwidth - self.contact_array_width)/2) + (second_layer_minwidth - self.contact_array_width) / 2) else: debug.error("Invalid second layer direction.", -1) - def create_contact_array(self): """ Create the contact array at the origin""" # offset for the via array - self.via_layer_position =vector(max(self.first_layer_horizontal_enclosure,self.second_layer_horizontal_enclosure), - max(self.first_layer_vertical_enclosure,self.second_layer_vertical_enclosure)) + self.via_layer_position = vector( + max(self.first_layer_horizontal_enclosure, self.second_layer_horizontal_enclosure), + max(self.first_layer_vertical_enclosure, self.second_layer_vertical_enclosure)) for i in range(self.dimensions[1]): offset = self.via_layer_position + vector(0, self.contact_pitch * i) @@ -142,15 +148,16 @@ class contact(hierarchy_design.hierarchy_design): offset=offset, width=self.contact_width, height=self.contact_width) - offset = offset + vector(self.contact_pitch,0) + offset = offset + vector(self.contact_pitch, 0) def create_first_layer_enclosure(self): # this is if the first and second layers are different - self.first_layer_position = vector(max(self.second_layer_horizontal_enclosure - self.first_layer_horizontal_enclosure,0), - max(self.second_layer_vertical_enclosure - self.first_layer_vertical_enclosure,0)) + self.first_layer_position = vector( + max(self.second_layer_horizontal_enclosure - self.first_layer_horizontal_enclosure, 0), + max(self.second_layer_vertical_enclosure - self.first_layer_vertical_enclosure, 0)) - self.first_layer_width = self.contact_array_width + 2*self.first_layer_horizontal_enclosure - self.first_layer_height = self.contact_array_height + 2*self.first_layer_vertical_enclosure + self.first_layer_width = self.contact_array_width + 2 * self.first_layer_horizontal_enclosure + self.first_layer_height = self.contact_array_height + 2 * self.first_layer_vertical_enclosure self.add_rect(layer=self.first_layer_name, offset=self.first_layer_position, width=self.first_layer_width, @@ -158,27 +165,28 @@ class contact(hierarchy_design.hierarchy_design): def create_second_layer_enclosure(self): # this is if the first and second layers are different - self.second_layer_position = vector(max(self.first_layer_horizontal_enclosure - self.second_layer_horizontal_enclosure,0), - max(self.first_layer_vertical_enclosure - self.second_layer_vertical_enclosure,0)) + self.second_layer_position = vector( + max(self.first_layer_horizontal_enclosure - self.second_layer_horizontal_enclosure, 0), + max(self.first_layer_vertical_enclosure - self.second_layer_vertical_enclosure, 0)) - self.second_layer_width = self.contact_array_width + 2*self.second_layer_horizontal_enclosure - self.second_layer_height = self.contact_array_height + 2*self.second_layer_vertical_enclosure + self.second_layer_width = self.contact_array_width + 2 * self.second_layer_horizontal_enclosure + self.second_layer_height = self.contact_array_height + 2 * self.second_layer_vertical_enclosure self.add_rect(layer=self.second_layer_name, offset=self.second_layer_position, width=self.second_layer_width, height=self.second_layer_height) def create_implant_well_enclosures(self): - implant_position = self.first_layer_position - [drc("implant_enclosure_active")]*2 - implant_width = self.first_layer_width + 2*drc("implant_enclosure_active") - implant_height = self.first_layer_height + 2*drc("implant_enclosure_active") + implant_position = self.first_layer_position - [drc("implant_enclosure_active")] * 2 + implant_width = self.first_layer_width + 2 * drc("implant_enclosure_active") + implant_height = self.first_layer_height + 2 * drc("implant_enclosure_active") self.add_rect(layer="{}implant".format(self.implant_type), offset=implant_position, width=implant_width, height=implant_height) - well_position = self.first_layer_position - [drc("well_enclosure_active")]*2 - well_width = self.first_layer_width + 2*drc("well_enclosure_active") - well_height = self.first_layer_height + 2*drc("well_enclosure_active") + well_position = self.first_layer_position - [drc("well_enclosure_active")] * 2 + well_width = self.first_layer_width + 2 * drc("well_enclosure_active") + well_height = self.first_layer_height + 2 * drc("well_enclosure_active") self.add_rect(layer="{}well".format(self.well_type), offset=well_position, width=well_width, @@ -188,16 +196,30 @@ class contact(hierarchy_design.hierarchy_design): """ Get total power of a module """ return self.return_power() + from sram_factory import factory + # This is not instantiated and used for calculations only. # These are static 1x1 contacts to reuse in all the design modules. -well = factory.create(module_type="contact", layer_stack=("active", "contact", "metal1"), directions=("H","V")) -active = factory.create(module_type="contact", layer_stack=("active", "contact", "metal1"), directions=("H","V")) -poly = factory.create(module_type="contact", layer_stack=("poly", "contact", "metal1"), directions=("V","H")) -m1m2 = factory.create(module_type="contact", layer_stack=("metal1", "via1", "metal2"), directions=("H","V")) -m2m3 = factory.create(module_type="contact", layer_stack=("metal2", "via2", "metal3"), directions=("V","H")) +well = factory.create(module_type="contact", + layer_stack=("active", "contact", "metal1"), + directions=("H", "V")) +active = factory.create(module_type="contact", + layer_stack=("active", "contact", "metal1"), + directions=("H", "V")) +poly = factory.create(module_type="contact", + layer_stack=("poly", "contact", "metal1"), + directions=("V", "H")) +m1m2 = factory.create(module_type="contact", + layer_stack=("metal1", "via1", "metal2"), + directions=("H", "V")) +m2m3 = factory.create(module_type="contact", + layer_stack=("metal2", "via2", "metal3"), + directions=("V", "H")) if "metal4" in layer.keys(): - m3m4 = factory.create(module_type="contact", layer_stack=("metal3", "via3", "metal4"), directions=("H","V")) + m3m4 = factory.create(module_type="contact", + layer_stack=("metal3", "via3", "metal4"), + directions=("H", "V")) else: m3m4 = None diff --git a/compiler/base/delay_data.py b/compiler/base/delay_data.py index e3d5a8bc..97fe9867 100644 --- a/compiler/base/delay_data.py +++ b/compiler/base/delay_data.py @@ -6,6 +6,7 @@ # All rights reserved. # + class delay_data(): """ This is the delay class to represent the delay information @@ -20,13 +21,13 @@ class delay_data(): def __str__(self): """ override print function output """ - return "Delay Data: Delay "+str(self.delay)+", Slew "+str(self.slew)+"" + return "Delta Data: Delay {} Slew {}".format(self.delay, self.slew) def __add__(self, other): """ Override - function (left), for delay_data: a+b != b+a """ - assert isinstance(other,delay_data) + assert isinstance(other, delay_data) return delay_data(other.delay + self.delay, other.slew) @@ -34,7 +35,7 @@ class delay_data(): """ Override - function (right), for delay_data: a+b != b+a """ - assert isinstance(other,delay_data) + assert isinstance(other, delay_data) return delay_data(other.delay + self.delay, self.slew) diff --git a/compiler/base/design.py b/compiler/base/design.py index da23aa9e..33914358 100644 --- a/compiler/base/design.py +++ b/compiler/base/design.py @@ -7,12 +7,9 @@ # from hierarchy_design import hierarchy_design import contact -import globals -import verify -import debug -import os from globals import OPTS + class design(hierarchy_design): """ This is the same as the hierarchy_design class except it contains @@ -21,29 +18,29 @@ class design(hierarchy_design): """ def __init__(self, name): - hierarchy_design.__init__(self,name) + hierarchy_design.__init__(self, name) self.setup_drc_constants() self.setup_multiport_constants() from tech import layer - self.m1_pitch = max(contact.m1m2.width,contact.m1m2.height) + max(self.m1_space, self.m2_space) - self.m2_pitch = max(contact.m2m3.width,contact.m2m3.height) + max(self.m2_space, self.m3_space) + self.m1_pitch = max(contact.m1m2.width, contact.m1m2.height) + max(self.m1_space, self.m2_space) + self.m2_pitch = max(contact.m2m3.width, contact.m2m3.height) + max(self.m2_space, self.m3_space) if "metal4" in layer: - self.m3_pitch = max(contact.m3m4.width,contact.m3m4.height) + max(self.m3_space, self.m4_space) + self.m3_pitch = max(contact.m3m4.width, contact.m3m4.height) + max(self.m3_space, self.m4_space) else: self.m3_pitch = self.m2_pitch def setup_drc_constants(self): """ These are some DRC constants used in many places in the compiler.""" - from tech import drc,layer + from tech import drc, layer self.well_width = drc("minwidth_well") self.poly_width = drc("minwidth_poly") - self.poly_space = drc("poly_to_poly") + self.poly_space = drc("poly_to_poly") self.m1_width = drc("minwidth_metal1") self.m1_space = drc("metal1_to_metal1") self.m2_width = drc("minwidth_metal2") - self.m2_space = drc("metal2_to_metal2") + self.m2_space = drc("metal2_to_metal2") self.m3_width = drc("minwidth_metal3") self.m3_space = drc("metal3_to_metal3") if "metal4" in layer: @@ -93,12 +90,12 @@ class design(hierarchy_design): port_number += 1 for port in range(OPTS.num_w_ports): self.write_ports.append(port_number) - self.writeonly_ports.append(port_number) + self.writeonly_ports.append(port_number) port_number += 1 for port in range(OPTS.num_r_ports): self.read_ports.append(port_number) self.readonly_ports.append(port_number) - port_number += 1 + port_number += 1 def analytical_power(self, corner, load): """ Get total power of a module """ diff --git a/compiler/base/geometry.py b/compiler/base/geometry.py index 7063cf81..74b02f5f 100644 --- a/compiler/base/geometry.py +++ b/compiler/base/geometry.py @@ -6,7 +6,7 @@ # All rights reserved. # """ -This provides a set of useful generic types for the gdsMill interface. +This provides a set of useful generic types for the gdsMill interface. """ import debug from vector import vector @@ -15,6 +15,7 @@ import math from globals import OPTS from utils import round_to_grid + class geometry: """ A specific path, shape, or text geometry. Base class for shared @@ -27,11 +28,11 @@ class geometry: def __str__(self): """ override print function output """ - debug.error("__str__ must be overridden by all geometry types.",1) + debug.error("__str__ must be overridden by all geometry types.", 1) def __repr__(self): """ override print function output """ - debug.error("__repr__ must be overridden by all geometry types.",1) + debug.error("__repr__ must be overridden by all geometry types.", 1) # def translate_coords(self, coords, mirr, angle, xyShift): # """Calculate coordinates after flip, rotate, and shift""" @@ -46,50 +47,52 @@ class geometry: """Calculate coordinates after flip, rotate, and shift""" coordinate = [] for item in coords: - x = item[0]*math.cos(angle) - item[1]*mirr*math.sin(angle) + offset[0] - y = item[0]*math.sin(angle) + item[1]*mirr*math.cos(angle) + offset[1] + x = item[0] * math.cos(angle) - item[1] * mirr * math.sin(angle) + offset[0] + y = item[0] * math.sin(angle) + item[1] * mirr * math.cos(angle) + offset[1] coordinate += [[x, y]] return coordinate def normalize(self): """ Re-find the LL and UR points after a transform """ - (first,second)=self.boundary - ll = vector(min(first[0],second[0]),min(first[1],second[1])).snap_to_grid() - ur = vector(max(first[0],second[0]),max(first[1],second[1])).snap_to_grid() - self.boundary=[ll,ur] + (first, second) = self.boundary + ll = vector(min(first[0], second[0]), + min(first[1], second[1])).snap_to_grid() + ur = vector(max(first[0], second[0]), + max(first[1], second[1])).snap_to_grid() + self.boundary = [ll, ur] def update_boundary(self): """ Update the boundary with a new placement. """ - self.compute_boundary(self.offset,self.mirror,self.rotate) + self.compute_boundary(self.offset, self.mirror, self.rotate) - def compute_boundary(self,offset=vector(0,0),mirror="",rotate=0): - """ Transform with offset, mirror and rotation to get the absolute pin location. + def compute_boundary(self, offset=vector(0, 0), mirror="", rotate=0): + """ Transform with offset, mirror and rotation to get the absolute pin location. We must then re-find the ll and ur. The master is the cell instance. """ if OPTS.netlist_only: return - (ll,ur) = [vector(0,0),vector(self.width,self.height)] + (ll, ur) = [vector(0, 0), vector(self.width, self.height)] - if mirror=="MX": - ll=ll.scale(1,-1) - ur=ur.scale(1,-1) - elif mirror=="MY": - ll=ll.scale(-1,1) - ur=ur.scale(-1,1) - elif mirror=="XY": - ll=ll.scale(-1,-1) - ur=ur.scale(-1,-1) + if mirror == "MX": + ll = ll.scale(1, -1) + ur = ur.scale(1, -1) + elif mirror == "MY": + ll = ll.scale(-1, 1) + ur = ur.scale(-1, 1) + elif mirror == "XY": + ll = ll.scale(-1, -1) + ur = ur.scale(-1, -1) - if rotate==90: - ll=ll.rotate_scale(-1,1) - ur=ur.rotate_scale(-1,1) - elif rotate==180: - ll=ll.scale(-1,-1) - ur=ur.scale(-1,-1) - elif rotate==270: - ll=ll.rotate_scale(1,-1) - ur=ur.rotate_scale(1,-1) + if rotate == 90: + ll = ll.rotate_scale(-1, 1) + ur = ur.rotate_scale(-1, 1) + elif rotate == 180: + ll = ll.scale(-1, -1) + ur = ur.scale(-1, -1) + elif rotate == 270: + ll = ll.rotate_scale(1, -1) + ur = ur.rotate_scale(1, -1) - self.boundary=[offset+ll,offset+ur] + self.boundary = [offset + ll, offset + ur] self.normalize() def ll(self): @@ -108,7 +111,6 @@ class geometry: """ Return the upper left corner """ return vector(self.boundary[0].x, self.boundary[1].y) - def uy(self): """ Return the upper edge """ return self.boundary[1].y @@ -127,11 +129,11 @@ class geometry: def cx(self): """ Return the center x """ - return 0.5*(self.boundary[0].x + self.boundary[1].x) + return 0.5 * (self.boundary[0].x + self.boundary[1].x) def cy(self): """ Return the center y """ - return 0.5*(self.boundary[0].y + self.boundary[1].y) + return 0.5 * (self.boundary[0].y + self.boundary[1].y) class instance(geometry): @@ -139,10 +141,11 @@ class instance(geometry): An instance of an instance/module with a specified location and rotation """ - def __init__(self, name, mod, offset=[0,0], mirror="R0", rotate=0): + def __init__(self, name, mod, offset=[0, 0], mirror="R0", rotate=0): """Initializes an instance to represent a module""" geometry.__init__(self) - debug.check(mirror not in ["R90","R180","R270"], "Please use rotation and not mirroring during instantiation.") + debug.check(mirror not in ["R90", "R180", "R270"], + "Please use rotation and not mirroring during instantiation.") self.name = name self.mod = mod @@ -154,13 +157,13 @@ class instance(geometry): self.width = 0 self.height = 0 else: - if mirror in ["R90","R270"] or rotate in [90,270]: + if mirror in ["R90", "R270"] or rotate in [90, 270]: self.width = round_to_grid(mod.height) self.height = round_to_grid(mod.width) else: self.width = round_to_grid(mod.width) self.height = round_to_grid(mod.height) - self.compute_boundary(offset,mirror,rotate) + self.compute_boundary(offset, mirror, rotate) debug.info(4, "creating instance: " + self.name) @@ -169,18 +172,18 @@ class instance(geometry): Apply the transform of the instance placement to give absolute blockages.""" angle = math.radians(float(self.rotate)) mirr = 1 - if self.mirror=="R90": + if self.mirror == "R90": angle += math.radians(90.0) - elif self.mirror=="R180": + elif self.mirror == "R180": angle += math.radians(180.0) - elif self.mirror=="R270": + elif self.mirror == "R270": angle += math.radians(270.0) - elif self.mirror=="MX": + elif self.mirror == "MX": mirr = -1 - elif self.mirror=="MY": + elif self.mirror == "MY": mirr = -1 angle += math.radians(180.0) - elif self.mirror=="XY": + elif self.mirror == "XY": mirr = 1 angle += math.radians(180.0) @@ -226,7 +229,7 @@ class instance(geometry): this instance location. Index will return one of several pins.""" import copy - if index==-1: + if index == -1: pin = copy.deepcopy(self.mod.get_pin(name)) pin.transform(self.offset,self.mirror,self.rotate) return pin @@ -339,6 +342,7 @@ class label(geometry): """ override print function output """ return "( label: " + self.text + " @" + str(self.offset) + " layer=" + str(self.layerNumber) + " )" + class rectangle(geometry): """Represents a rectangular shape""" @@ -351,22 +355,23 @@ class rectangle(geometry): self.size = vector(width, height).snap_to_grid() self.width = round_to_grid(self.size.x) self.height = round_to_grid(self.size.y) - self.compute_boundary(offset,"",0) + self.compute_boundary(offset, "", 0) - debug.info(4, "creating rectangle (" + str(self.layerNumber) + "): " + debug.info(4, "creating rectangle (" + str(self.layerNumber) + "): " + str(self.width) + "x" + str(self.height) + " @ " + str(self.offset)) - def get_blockages(self, layer): """ Returns a list of one rectangle if it is on this layer""" if self.layerNumber == layer: - return [[self.offset, vector(self.offset.x+self.width,self.offset.y+self.height)]] + return [[self.offset, + vector(self.offset.x + self.width, + self.offset.y + self.height)]] else: return [] def gds_write_file(self, new_layout): """Writes the rectangular shape to GDS""" - debug.info(4, "writing rectangle (" + str(self.layerNumber) + "):" + debug.info(4, "writing rectangle (" + str(self.layerNumber) + "):" + str(self.width) + "x" + str(self.height) + " @ " + str(self.offset)) new_layout.addBox(layerNumber=self.layerNumber, purposeNumber=0, diff --git a/compiler/debug.py b/compiler/debug.py index 02a28c22..15876f22 100644 --- a/compiler/debug.py +++ b/compiler/debug.py @@ -94,7 +94,7 @@ def info(lev, str): frm = inspect.stack()[1] mod = inspect.getmodule(frm[0]) # classname = frm.f_globals['__name__'] - if mod.__name__ == None: + if mod.__name__ is None: class_name = "" else: class_name = mod.__name__ diff --git a/compiler/gen_stimulus.py b/compiler/gen_stimulus.py index 6a6be1d1..0c5d988c 100755 --- a/compiler/gen_stimulus.py +++ b/compiler/gen_stimulus.py @@ -13,10 +13,7 @@ created without re-running the entire process. Right now, it assumes the nominal corner, but should probably be extended. """ -import sys,os -import datetime -import re -import importlib +import sys from globals import * (OPTS, args) = parse_args() diff --git a/compiler/openram.py b/compiler/openram.py index 97ada256..5fec7102 100755 --- a/compiler/openram.py +++ b/compiler/openram.py @@ -16,34 +16,32 @@ a LEF (.lef) file for preliminary P&R (real one should be from layout) a Liberty (.lib) file for timing analysis/optimization """ -import sys,os +import sys import datetime -import re -import importlib -from globals import * +import globals as g -(OPTS, args) = parse_args() +(OPTS, args) = g.parse_args() # Check that we are left with a single configuration file as argument. if len(args) != 1: - print(USAGE) + print(g.USAGE) sys.exit(2) # These depend on arguments, so don't load them until now. import debug -init_openram(config_file=args[0], is_unit_test=False) +g.init_openram(config_file=args[0], is_unit_test=False) # Only print banner here so it's not in unit tests -print_banner() +g.print_banner() # Keep track of running stats start_time = datetime.datetime.now() -print_time("Start",start_time) +g.print_time("Start", start_time) # Output info about this run -report_status() +g.report_status() from sram_config import sram_config @@ -54,15 +52,16 @@ c = sram_config(word_size=OPTS.word_size, write_size=OPTS.write_size) debug.print_raw("Words per row: {}".format(c.words_per_row)) -#from parser import * -output_extensions = ["sp","v","lib","py","html","log"] +output_extensions = ["sp", "v", "lib", "py", "html", "log"] # Only output lef/gds if back-end if not OPTS.netlist_only: - output_extensions.extend(["lef","gds"]) + output_extensions.extend(["lef", "gds"]) -output_files = ["{0}{1}.{2}".format(OPTS.output_path,OPTS.output_name,x) for x in output_extensions] +output_files = ["{0}{1}.{2}".format(OPTS.output_path, + OPTS.output_name, x) + for x in output_extensions] debug.print_raw("Output files are: ") -for path in output_files: +for path in output_files: debug.print_raw(path) @@ -74,7 +73,7 @@ s = sram(sram_config=c, s.save() # Delete temp files etc. -end_openram() -print_time("End",datetime.datetime.now(), start_time) +g.end_openram() +g.print_time("End", datetime.datetime.now(), start_time) diff --git a/compiler/options.py b/compiler/options.py index ce974d63..56bd1757 100644 --- a/compiler/options.py +++ b/compiler/options.py @@ -6,13 +6,13 @@ # All rights reserved. # import optparse -import getpass +import getpass import os -#import sram_config class options(optparse.Values): """ - Class for holding all of the OpenRAM options. All of these options can be over-riden in a configuration file + Class for holding all of the OpenRAM options. All + of these options can be over-riden in a configuration file that is the sole required command-line positional argument for openram.py. """ @@ -39,15 +39,16 @@ class options(optparse.Values): process_corners = "" # Size parameters must be specified by user in config file. - #num_words = 0 - #word_size = 0 + # num_words = 0 + # word_size = 0 # You can manually specify banks, but it is better to auto-detect it. num_banks = 1 ################### # Optimization options ################### - rbl_delay_percentage = 0.5 #Approximate percentage of delay compared to bitlines + # Approximate percentage of delay compared to bitlines + rbl_delay_percentage = 0.5 # Allow manual adjustment of the delay chain over automatic use_tech_delay_chain_size = False @@ -65,7 +66,8 @@ class options(optparse.Values): openram_temp = os.path.abspath(os.environ.get("OPENRAM_TMP")) except: # Else use a unique temporary directory - openram_temp = "/tmp/openram_{0}_{1}_temp/".format(getpass.getuser(),os.getpid()) + openram_temp = "/tmp/openram_{0}_{1}_temp/".format(getpass.getuser(), + os.getpid()) # This is the verbosity level to control debug information. 0 is none, 1 # is minimal, etc. debug_level = 0 @@ -100,7 +102,8 @@ class options(optparse.Values): drc_name = "" lvs_name = "" pex_name = "" - # The DRC/LVS/PEX executable being used which is derived from the user PATH. + # The DRC/LVS/PEX executable being used + # which is derived from the user PATH. drc_exe = None lvs_exe = None pex_exe = None @@ -113,15 +116,14 @@ class options(optparse.Values): output_path = "." # Define the output file base name output_name = "" - # Use analytical delay models by default rather than (slow) characterization + # Use analytical delay models by default + # rather than (slow) characterization analytical_delay = True - # Purge the temp directory after a successful run (doesn't purge on errors, anyhow) + # Purge the temp directory after a successful + # run (doesn't purge on errors, anyhow) purge_temp = True - - ################### # These are the default modules that can be over-riden - ################### bank_select = "bank_select" bitcell_array = "bitcell_array" bitcell = "bitcell" diff --git a/compiler/sram_factory.py b/compiler/sram_factory.py index 0083841d..bd602980 100644 --- a/compiler/sram_factory.py +++ b/compiler/sram_factory.py @@ -5,9 +5,9 @@ # (acting for and on behalf of Oklahoma State University) # All rights reserved. # -import debug from globals import OPTS + class sram_factory: """ This is a factory pattern to create modules for usage in an SRAM. @@ -19,7 +19,7 @@ class sram_factory: """ def __init__(self): - # A dictionary of modules indexed by module type + # A dictionary of modules indexed by module type self.modules = {} # These are the indices to append to name to make unique object names self.module_indices = {} @@ -34,8 +34,8 @@ class sram_factory: def create(self, module_type, **kwargs): """ - A generic function to create a module with a given module_type. The args - are passed directly to the module constructor. + A generic function to create a module with a given module_type. + The args are passed directly to the module constructor. """ # if name!="": # # This is a special case where the name and type don't match @@ -58,28 +58,30 @@ class sram_factory: self.objects[module_type] = [] # Either retreive a previous object or create a new one - #print("new",kwargs) for obj in self.objects[module_type]: (obj_kwargs, obj_item) = obj # Must have the same dictionary exactly (conservative) if obj_kwargs == kwargs: - #debug.info(0, "Existing module: type={0} name={1} kwargs={2}".format(module_type, obj_item.name, str(kwargs))) return obj_item - #else: - # print("obj",obj_kwargs) # Use the default name if there are default arguments - # This is especially for library cells so that the spice and gds files can be found. - if len(kwargs)>0: + # This is especially for library cells so that the + # spice and gds files can be found. + if len(kwargs) > 0: # Create a unique name and increment the index - module_name = "{0}_{1}".format(module_type, self.module_indices[module_type]) + module_name = "{0}_{1}".format(module_type, + self.module_indices[module_type]) self.module_indices[module_type] += 1 else: module_name = module_type - - #debug.info(0, "New module: type={0} name={1} kwargs={2}".format(module_type,module_name,str(kwargs))) - obj = mod(name=module_name,**kwargs) - self.objects[module_type].append((kwargs,obj)) + + # type_str = "type={}".format(module_type) + # name_str = "name={}".format(module_name) + # kwargs_str = "kwargs={}".format(str(kwargs)) + # import debug + # debug.info(0, "New module:" + type_str + name_str + kwargs_str) + obj = mod(name=module_name, **kwargs) + self.objects[module_type].append((kwargs, obj)) return obj def get_mods(self, module_type): @@ -90,11 +92,11 @@ class sram_factory: module_type = getattr(OPTS, module_type) try: mod_tuples = self.objects[module_type] - mods = [mod for kwargs,mod in mod_tuples] + mods = [mod for kwargs, mod in mod_tuples] except KeyError: mods = [] return mods - + + # Make a factory factory = sram_factory() - diff --git a/compiler/view_profile.py b/compiler/view_profile.py index cad8e9ae..1d8e3f50 100755 --- a/compiler/view_profile.py +++ b/compiler/view_profile.py @@ -9,8 +9,8 @@ import pstats p = pstats.Stats("profile.dat") p.strip_dirs() -#p.sort_stats("cumulative") +# p.sort_stats("cumulative") p.sort_stats("tottime") -#p.print_stats(50) +# p.print_stats(50) p.print_stats()