diff --git a/.coveragerc b/.coveragerc index 0df8ae34..df762ed7 100644 --- a/.coveragerc +++ b/.coveragerc @@ -8,6 +8,8 @@ omit = */tests/* # ignore the debug utilities debug.py + # ignore the no DRC/LVS tool options + none.py [paths] source = ../.. @@ -21,6 +23,8 @@ source = exclude_lines = pragma: no cover def __repr__ + def __str__ + class gdsStreamer except Exception raise AssertionError raise NotImplementedError diff --git a/LICENSE b/LICENSE index 75c009a8..761f6e8b 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ BSD 3-Clause License -Copyright (c) 2018-2019 Regents of the University of California and The Board +Copyright (c) 2019 Regents of the University of California and The Board of Regents for the Oklahoma Agricultural and Mechanical College (acting for and on behalf of Oklahoma State University) All rights reserved. diff --git a/README.md b/README.md index 9acca5b4..d262f75e 100644 --- a/README.md +++ b/README.md @@ -4,13 +4,13 @@ [![License: BSD 3-clause](./images/license_badge.svg)](./LICENSE) Master: -[![Pipeline Status](https://scone.soe.ucsc.edu:8888/mrg/OpenRAM/badges/master/pipeline.svg?private_token=ynB6rSFLzvKUseoBPcwV)](https://github.com/VLSIDA/OpenRAM/commits/master) -![Coverage](https://scone.soe.ucsc.edu:8888/mrg/OpenRAM/badges/master/coverage.svg?private_token=ynB6rSFLzvKUseoBPcwV) +[![Pipeline Status](https://scone.soe.ucsc.edu:8888/mrg/OpenRAM/badges/master/pipeline.svg)](https://github.com/VLSIDA/OpenRAM/commits/master) +![Coverage](https://scone.soe.ucsc.edu:8888/mrg/OpenRAM/badges/master/coverage.svg) [![Download](./images/download-stable-blue.svg)](https://github.com/VLSIDA/OpenRAM/archive/master.zip) Dev: -[![Pipeline Status](https://scone.soe.ucsc.edu:8888/mrg/OpenRAM/badges/dev/pipeline.svg?private_token=ynB6rSFLzvKUseoBPcwV)](https://github.com/VLSIDA/OpenRAM/commits/dev) -![Coverage](https://scone.soe.ucsc.edu:8888/mrg/OpenRAM/badges/dev/coverage.svg?private_token=ynB6rSFLzvKUseoBPcwV) +[![Pipeline Status](https://scone.soe.ucsc.edu:8888/mrg/OpenRAM/badges/dev/pipeline.svg)](https://github.com/VLSIDA/OpenRAM/commits/dev) +![Coverage](https://scone.soe.ucsc.edu:8888/mrg/OpenRAM/badges/dev/coverage.svg) [![Download](./images/download-unstable-blue.svg)](https://github.com/VLSIDA/OpenRAM/archive/dev.zip) An open-source static random access memory (SRAM) compiler. diff --git a/compiler/base/contact.py b/compiler/base/contact.py index 39cb7b52..de1afec6 100644 --- a/compiler/base/contact.py +++ b/compiler/base/contact.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# import hierarchy_design import debug import utils @@ -9,44 +16,36 @@ 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 multiple sides of the contact whereas a via may - have extension on two or four sides. + 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. """ - def __init__(self, layer_stack, dimensions=[1,1], implant_type=None, well_type=None, name=""): + 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 - if implant_type or well_type: - name = "{0}_{1}_{2}_{3}x{4}_{5}{6}".format(layer_stack[0], - layer_stack[1], - layer_stack[2], - dimensions[0], - dimensions[1], - implant_type, - well_type) - - else: - name = "{0}_{1}_{2}_{3}x{4}".format(layer_stack[0], - layer_stack[1], - layer_stack[2], - dimensions[0], - dimensions[1]) - 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.layer_stack = layer_stack self.dimensions = dimensions + self.directions = directions self.offset = vector(0,0) self.implant_type = implant_type self.well_type = well_type - self.pins = [] # used for matching parm lengths + # Module does not have pins, but has empty pin list. + self.pins = [] self.create_layout() def create_layout(self): + self.setup_layers() self.setup_layout_constants() self.create_contact_array() @@ -63,6 +62,8 @@ class contact(hierarchy_design.hierarchy_design): debug.error(-1,"Must define both implant and well type or none at all.") def setup_layers(self): + """ Locally assign the layer names. """ + (first_layer, via_layer, second_layer) = self.layer_stack self.first_layer_name = first_layer self.via_layer_name = via_layer @@ -75,37 +76,58 @@ class contact(hierarchy_design.hierarchy_design): self.second_layer_name = second_layer def setup_layout_constants(self): + """ Determine the design rules for the enclosure layers """ + self.contact_width = drc("minwidth_{0}". format(self.via_layer_name)) contact_to_contact = drc("{0}_to_{0}".format(self.via_layer_name)) self.contact_pitch = self.contact_width + contact_to_contact + self.contact_array_width = self.contact_width + (self.dimensions[0] - 1) * self.contact_pitch self.contact_array_height = self.contact_width + (self.dimensions[1] - 1) * self.contact_pitch # DRC rules + # The extend rule applies to asymmetric enclosures in one direction. + # The enclosure rule applies to symmetric enclosure component. + first_layer_minwidth = drc("minwidth_{0}".format(self.first_layer_name)) - first_layer_minarea = drc("minarea_{0}".format(self.first_layer_name)) first_layer_enclosure = drc("{0}_enclosure_{1}".format(self.first_layer_name, self.via_layer_name)) first_layer_extend = drc("{0}_extend_{1}".format(self.first_layer_name, self.via_layer_name)) + second_layer_minwidth = drc("minwidth_{0}".format(self.second_layer_name)) - second_layer_minarea = drc("minarea_{0}".format(self.second_layer_name)) 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)) - self.first_layer_horizontal_enclosure = max((first_layer_minwidth - self.contact_array_width) / 2, - first_layer_enclosure) - self.first_layer_vertical_enclosure = max(utils.ceil((first_layer_minarea - / (self.contact_array_width + 2*self.first_layer_horizontal_enclosure) - - self.contact_array_height)/2), - (first_layer_minwidth - self.contact_array_height)/2, - first_layer_extend) - self.second_layer_horizontal_enclosure = max((second_layer_minwidth - self.contact_array_width)/2, - second_layer_enclosure) - self.second_layer_vertical_enclosure = max(utils.ceil((second_layer_minarea - / (self.contact_array_width + 2*self.second_layer_horizontal_enclosure) - - self.contact_array_height)/2), - (second_layer_minwidth - self.contact_array_height)/2, - second_layer_extend) + # 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) + self.first_layer_vertical_enclosure = max(first_layer_extend, + (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) + self.first_layer_vertical_enclosure = max(first_layer_enclosure, + (first_layer_minwidth - self.contact_array_height)/2) + else: + debug.error("Invalid first layer direction.", -1) + + # 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[1] == "V": + self.second_layer_horizontal_enclosure = max(second_layer_enclosure, + (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) + elif self.directions[1] == "H": + self.second_layer_horizontal_enclosure = max(second_layer_extend, + (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) + else: + debug.error("Invalid second layer direction.", -1) + def create_contact_array(self): """ Create the contact array at the origin""" @@ -169,10 +191,10 @@ class contact(hierarchy_design.hierarchy_design): 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")) -active = factory.create(module_type="contact", layer_stack=("active", "contact", "poly")) -poly = factory.create(module_type="contact", layer_stack=("poly", "contact", "metal1")) -m1m2 = factory.create(module_type="contact", layer_stack=("metal1", "via1", "metal2")) -m2m3 = factory.create(module_type="contact", layer_stack=("metal2", "via2", "metal3")) -m3m4 = factory.create(module_type="contact", layer_stack=("metal3", "via3", "metal4")) +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")) +m3m4 = factory.create(module_type="contact", layer_stack=("metal3", "via3", "metal4"), directions=("H","V")) diff --git a/compiler/base/design.py b/compiler/base/design.py index 4e76b40a..5a87dd79 100644 --- a/compiler/base/design.py +++ b/compiler/base/design.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# from hierarchy_design import hierarchy_design import contact import globals @@ -95,13 +102,3 @@ class design(hierarchy_design): total_module_power += inst.mod.analytical_power(corner, load) return total_module_power - def __str__(self): - """ override print function output """ - pins = ",".join(self.pins) - insts = [" {}".format(x) for x in self.insts] - objs = [" {}".format(x) for x in self.objs] - s = "********** design {0} **********\n".format(self.name) - s += "\n pins ({0})={1}\n".format(len(self.pins), pins) - s += "\n objs ({0})=\n{1}".format(len(self.objs), "\n".join(objs)) - s += "\n insts ({0})=\n{1}\n".format(len(self.insts), "\n".join(insts)) - return s diff --git a/compiler/base/geometry.py b/compiler/base/geometry.py index 838828df..144043a2 100644 --- a/compiler/base/geometry.py +++ b/compiler/base/geometry.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ This provides a set of useful generic types for the gdsMill interface. """ @@ -371,8 +378,8 @@ class rectangle(geometry): def __str__(self): """ override print function output """ - return "rect: @" + str(self.offset) + " " + str(self.width) + "x" + str(self.height) + " layer=" +str(self.layerNumber) + return self.__repr__() def __repr__(self): """ override print function output """ - return "( rect: @" + str(self.offset) + " " + str(self.width) + "x" + str(self.height) + " layer=" + str(self.layerNumber) + " )" + return "( rect: @" + str(self.offset) + " WxH=" + str(self.width) + "x" + str(self.height) + " layer=" + str(self.layerNumber) + " )" diff --git a/compiler/base/hierarchy_design.py b/compiler/base/hierarchy_design.py index 6a6003a2..dfc275ee 100644 --- a/compiler/base/hierarchy_design.py +++ b/compiler/base/hierarchy_design.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# import hierarchy_layout import hierarchy_spice import globals @@ -21,8 +28,8 @@ class hierarchy_design(hierarchy_spice.spice, hierarchy_layout.layout): self.sp_file = OPTS.openram_tech + "sp_lib/" + name + ".sp" self.name = name - hierarchy_layout.layout.__init__(self, name) hierarchy_spice.spice.__init__(self, name) + hierarchy_layout.layout.__init__(self, name) def get_layout_pins(self,inst): @@ -100,7 +107,14 @@ class hierarchy_design(hierarchy_spice.spice, hierarchy_layout.layout): def __str__(self): """ override print function output """ - return "design: " + self.name + pins = ",".join(self.pins) + insts = [" {}".format(x) for x in self.insts] + objs = [" {}".format(x) for x in self.objs] + s = "********** design {0} **********".format(self.name) + s += "\n pins ({0})={1}\n".format(len(self.pins), pins) + s += "\n objs ({0})=\n{1}\n".format(len(self.objs), "\n".join(objs)) + s += "\n insts ({0})=\n{1}\n".format(len(self.insts), "\n".join(insts)) + return s def __repr__(self): """ override print function output """ diff --git a/compiler/base/hierarchy_layout.py b/compiler/base/hierarchy_layout.py index 26fc6de9..e8c1b0b9 100644 --- a/compiler/base/hierarchy_layout.py +++ b/compiler/base/hierarchy_layout.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# import itertools import geometry import gdsMill @@ -355,75 +362,59 @@ class layout(): layer_stack=layers, position_list=coordinates) - def add_contact(self, layers, offset, size=[1,1], mirror="R0", rotate=0, implant_type=None, well_type=None): - """ This is just an alias for a via.""" - return self.add_via(layers=layers, - offset=offset, - size=size, - mirror=mirror, - rotate=rotate, - implant_type=implant_type, - well_type=well_type) + def get_preferred_direction(self, layer): + """ Return the preferred routing directions """ + if layer in ["metal1", "metal3", "metal5"]: + return "H" + elif layer in ["active", "poly", "metal2", "metal4"]: + return "V" + else: + return "N" - def add_contact_center(self, layers, offset, size=[1,1], mirror="R0", rotate=0, implant_type=None, well_type=None): - """ This is just an alias for a via.""" - return self.add_via_center(layers=layers, - offset=offset, - size=size, - mirror=mirror, - rotate=rotate, - implant_type=implant_type, - well_type=well_type) - - def add_via(self, layers, offset, size=[1,1], mirror="R0", rotate=0, implant_type=None, well_type=None): + + def add_via(self, layers, offset, size=[1,1], directions=None, implant_type=None, well_type=None): """ Add a three layer via structure. """ + + if directions==None: + directions = (self.get_preferred_direction(layers[0]), self.get_preferred_direction(layers[2])) + from sram_factory import factory via = factory.create(module_type="contact", layer_stack=layers, dimensions=size, + directions=directions, implant_type=implant_type, well_type=well_type) self.add_mod(via) inst=self.add_inst(name=via.name, mod=via, - offset=offset, - mirror=mirror, - rotate=rotate) + offset=offset) # We don't model the logical connectivity of wires/paths self.connect_inst([]) return inst - def add_via_center(self, layers, offset, size=[1,1], mirror="R0", rotate=0, implant_type=None, well_type=None): + def add_via_center(self, layers, offset, directions=None, size=[1,1], implant_type=None, well_type=None): """ Add a three layer via structure by the center coordinate accounting for mirroring and rotation. """ + + if directions==None: + directions = (self.get_preferred_direction(layers[0]), self.get_preferred_direction(layers[2])) + from sram_factory import factory via = factory.create(module_type="contact", layer_stack=layers, dimensions=size, + directions=directions, implant_type=implant_type, well_type=well_type) height = via.height width = via.width - debug.check(mirror=="R0","Use rotate to rotate vias instead of mirror.") - if rotate==0: - corrected_offset = offset + vector(-0.5*width,-0.5*height) - elif rotate==90: - corrected_offset = offset + vector(0.5*height,-0.5*width) - elif rotate==180: - corrected_offset = offset + vector(0.5*width,0.5*height) - elif rotate==270: - corrected_offset = offset + vector(-0.5*height,0.5*width) - else: - debug.error("Invalid rotation argument.",-1) - + corrected_offset = offset + vector(-0.5*width,-0.5*height) - #print(rotate,offset,"->",corrected_offset) self.add_mod(via) inst=self.add_inst(name=via.name, mod=via, - offset=corrected_offset, - mirror=mirror, - rotate=rotate) + offset=corrected_offset) # We don't model the logical connectivity of wires/paths self.connect_inst([]) return inst @@ -748,8 +739,7 @@ class layout(): mid = vector(trunk_offset.x, pin.center().y) self.add_path(layer_stack[0], [pin.center(), mid]) self.add_via_center(layers=layer_stack, - offset=mid, - rotate=90) + offset=mid) def create_channel_route(self, netlist, @@ -926,20 +916,27 @@ class layout(): - def add_power_pin(self, name, loc, rotate=90, start_layer="metal1"): + def add_power_pin(self, name, loc, vertical=False, start_layer="metal1"): """ Add a single power pin from M3 down to M1 at the given center location. The starting layer is specified to determine which vias are needed. """ - + if vertical: + direction=("V","V") + else: + direction=("H","H") + if start_layer=="metal1": self.add_via_center(layers=("metal1", "via1", "metal2"), offset=loc, - rotate=float(rotate)) + directions=direction) + + if start_layer=="metal1" or start_layer=="metal2": via=self.add_via_center(layers=("metal2", "via2", "metal3"), offset=loc, - rotate=float(rotate)) + directions=direction) + if start_layer=="metal3": self.add_layout_pin_rect_center(text=name, layer="metal3", diff --git a/compiler/base/hierarchy_spice.py b/compiler/base/hierarchy_spice.py index 5f3245a8..bfa4606c 100644 --- a/compiler/base/hierarchy_spice.py +++ b/compiler/base/hierarchy_spice.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# import debug import re import os @@ -28,7 +35,10 @@ class spice(): # Spice format) self.conns = [] # Keep track of any comments to add the the spice - self.comments = [] + try: + self.commments + except: + self.comments = [] self.sp_read() @@ -38,7 +48,12 @@ class spice(): def add_comment(self, comment): """ Add a comment to the spice file """ - self.comments.append(comment) + try: + self.commments + except: + self.comments = [] + else: + self.comments.append(comment) def add_pin(self, name, pin_type="INOUT"): """ Adds a pin to the pins list. Default type is INOUT signal. """ @@ -235,13 +250,8 @@ class spice(): modeling it as a resistance driving a capacitance """ swing_factor = abs(math.log(1-swing)) # time constant based on swing - proc,vdd,temp = corner - #FIXME: type of delay is needed to know which process to use. - proc_mult = max(self.get_process_delay_factor(proc)) - volt_mult = self.get_voltage_delay_factor(vdd) - temp_mult = self.get_temp_delay_factor(temp) delay = swing_factor * r * c #c is in ff and delay is in fs - delay = delay * proc_mult * volt_mult * temp_mult + delay = self.apply_corners_analytically(delay, corner) delay = delay * 0.001 #make the unit to ps # Output slew should be linear to input slew which is described @@ -254,6 +264,15 @@ class spice(): slew = delay * 0.6 * 2 + 0.005 * slew return delay_data(delay = delay, slew = slew) + def apply_corners_analytically(self, delay, corner): + """Multiply delay by corner factors""" + proc,vdd,temp = corner + #FIXME: type of delay is needed to know which process to use. + proc_mult = max(self.get_process_delay_factor(proc)) + volt_mult = self.get_voltage_delay_factor(vdd) + temp_mult = self.get_temp_delay_factor(temp) + return delay * proc_mult * volt_mult * temp_mult + def get_process_delay_factor(self, proc): """Returns delay increase estimate based off process Currently does +/-10 for fast/slow corners.""" diff --git a/compiler/base/lef.py b/compiler/base/lef.py index 270057cb..5932bb67 100644 --- a/compiler/base/lef.py +++ b/compiler/base/lef.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# import gdsMill import tech import globals diff --git a/compiler/base/pin_layout.py b/compiler/base/pin_layout.py index 44b005f6..4c3528fe 100644 --- a/compiler/base/pin_layout.py +++ b/compiler/base/pin_layout.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# import debug from tech import GDS, drc from vector import vector diff --git a/compiler/base/route.py b/compiler/base/route.py index c6ce906b..c0bc1724 100644 --- a/compiler/base/route.py +++ b/compiler/base/route.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# from tech import drc import debug from design import design @@ -65,7 +72,7 @@ class route(design): for p0,p1 in plist: if p0.z != p1.z: # via via_size = [self.num_vias]*2 - self.obj.add_via_center(self.layer_stack,vector(p0.x,p0.y),size=via_size,rotate=90) + self.obj.add_via_center(self.layer_stack,vector(p0.x,p0.y),size=via_size) elif p0.x != p1.x and p0.y != p1.y: # diagonal! debug.error("Diagonal route! {}".format(self.path),-3) else: diff --git a/compiler/base/utils.py b/compiler/base/utils.py index 8ca22fa9..6642f095 100644 --- a/compiler/base/utils.py +++ b/compiler/base/utils.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# import os import gdsMill import tech diff --git a/compiler/base/vector.py b/compiler/base/vector.py index 6069a1ab..a845b47c 100644 --- a/compiler/base/vector.py +++ b/compiler/base/vector.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# import debug import math import tech diff --git a/compiler/base/verilog.py b/compiler/base/verilog.py index a2ddcadf..8596e5bc 100644 --- a/compiler/base/verilog.py +++ b/compiler/base/verilog.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# import debug class verilog: diff --git a/compiler/base/wire.py b/compiler/base/wire.py index 8bc250fa..2fe36026 100644 --- a/compiler/base/wire.py +++ b/compiler/base/wire.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# from tech import drc import debug from wire_path import wire_path @@ -62,18 +69,15 @@ class wire(wire_path): continue if a[1] == c[1]: continue - via_offset = [offset[0] + 0.5*c_height, - offset[1] - 0.5*c_width] - self.obj.add_via(layers=self.layer_stack, - offset=via_offset, - rotate=90) - corner_offset = [offset[0] - 0.5*(c_height + self.vert_layer_width), - offset[1] + 0.5*(c_width - self.horiz_layer_width)] + self.obj.add_via_center(layers=self.layer_stack, + offset=offset) def create_rectangles(self): - """ Create the actual rectangles on teh appropriate layers - using the position list of the corners. """ + """ + Create the actual rectangles on the appropriate layers + using the position list of the corners. + """ pl = self.position_list # position list for index in range(len(pl) - 1): if pl[index][0] != pl[index + 1][0]: diff --git a/compiler/base/wire_path.py b/compiler/base/wire_path.py index ec5d01bf..71f6af27 100644 --- a/compiler/base/wire_path.py +++ b/compiler/base/wire_path.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# from tech import drc from tech import layer as techlayer import debug diff --git a/compiler/bitcells/bitcell.py b/compiler/bitcells/bitcell.py index ed1647a8..7e2bd2c6 100644 --- a/compiler/bitcells/bitcell.py +++ b/compiler/bitcells/bitcell.py @@ -1,7 +1,15 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# import design import debug import utils from tech import GDS,layer,parameter,drc +import logical_effort class bitcell(design.design): """ @@ -23,19 +31,12 @@ class bitcell(design.design): self.width = bitcell.width self.height = bitcell.height self.pin_map = bitcell.pin_map - + def analytical_delay(self, corner, slew, load=0, swing = 0.5): - # delay of bit cell is not like a driver(from WL) - # so the slew used should be 0 - # it should not be slew dependent? - # because the value is there - # the delay is only over half transsmission gate - from tech import spice - r = spice["min_tx_r"]*3 - c_para = spice["min_tx_drain_c"] - result = self.cal_delay_with_rc(corner, r = r, c = c_para+load, slew = slew, swing = swing) - return result - + parasitic_delay = 1 + size = 0.5 #This accounts for bitline being drained thought the access TX and internal node + cin = 3 #Assumes always a minimum sizes inverter. Could be specified in the tech.py file. + return logical_effort.logical_effort('bitline', size, cin, load, parasitic_delay, False) def list_bitcell_pins(self, col, row): """ Creates a list of connections in the bitcell, indexed by column and row, for instance use in bitcell_array """ diff --git a/compiler/bitcells/bitcell_1rw_1r.py b/compiler/bitcells/bitcell_1rw_1r.py index a96dcff0..2dd9c9fa 100644 --- a/compiler/bitcells/bitcell_1rw_1r.py +++ b/compiler/bitcells/bitcell_1rw_1r.py @@ -1,7 +1,15 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# import design import debug import utils from tech import GDS,layer,parameter,drc +import logical_effort class bitcell_1rw_1r(design.design): """ @@ -25,18 +33,12 @@ class bitcell_1rw_1r(design.design): self.pin_map = bitcell_1rw_1r.pin_map def analytical_delay(self, corner, slew, load=0, swing = 0.5): - # delay of bit cell is not like a driver(from WL) - # so the slew used should be 0 - # it should not be slew dependent? - # because the value is there - # the delay is only over half transsmission gate - from tech import spice - r = spice["min_tx_r"]*3 - c_para = spice["min_tx_drain_c"] - result = self.cal_delay_with_rc(corner, r = r, c = c_para+load, slew = slew, swing = swing) - return result + parasitic_delay = 1 + size = 0.5 #This accounts for bitline being drained thought the access TX and internal node + cin = 3 #Assumes always a minimum sizes inverter. Could be specified in the tech.py file. + read_port_load = 0.5 #min size NMOS gate load + return logical_effort.logical_effort('bitline', size, cin, load+read_port_load, parasitic_delay, False) - def list_bitcell_pins(self, col, row): """ Creates a list of connections in the bitcell, indexed by column and row, for instance use in bitcell_array """ bitcell_pins = ["bl0_{0}".format(col), diff --git a/compiler/bitcells/bitcell_1w_1r.py b/compiler/bitcells/bitcell_1w_1r.py index e2cc662b..9e920327 100644 --- a/compiler/bitcells/bitcell_1w_1r.py +++ b/compiler/bitcells/bitcell_1w_1r.py @@ -1,7 +1,15 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# import design import debug import utils from tech import GDS,layer,parameter,drc +import logical_effort class bitcell_1w_1r(design.design): """ @@ -25,18 +33,12 @@ class bitcell_1w_1r(design.design): self.pin_map = bitcell_1w_1r.pin_map def analytical_delay(self, corner, slew, load=0, swing = 0.5): - # delay of bit cell is not like a driver(from WL) - # so the slew used should be 0 - # it should not be slew dependent? - # because the value is there - # the delay is only over half transsmission gate - from tech import spice - r = spice["min_tx_r"]*3 - c_para = spice["min_tx_drain_c"] - result = self.cal_delay_with_rc(corner, r = r, c = c_para+load, slew = slew, swing = swing) - return result + parasitic_delay = 1 + size = 0.5 #This accounts for bitline being drained thought the access TX and internal node + cin = 3 #Assumes always a minimum sizes inverter. Could be specified in the tech.py file. + read_port_load = 0.5 #min size NMOS gate load + return logical_effort.logical_effort('bitline', size, cin, load+read_port_load, parasitic_delay, False) - def list_bitcell_pins(self, col, row): """ Creates a list of connections in the bitcell, indexed by column and row, for instance use in bitcell_array """ bitcell_pins = ["bl0_{0}".format(col), diff --git a/compiler/bitcells/pbitcell.py b/compiler/bitcells/pbitcell.py index 55712e44..e045b763 100644 --- a/compiler/bitcells/pbitcell.py +++ b/compiler/bitcells/pbitcell.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# import contact import design import debug @@ -5,6 +12,7 @@ from tech import drc, parameter, spice from vector import vector from ptx import ptx from globals import OPTS +import logical_effort class pbitcell(design.design): """ @@ -197,7 +205,7 @@ class pbitcell(design.design): self.read_port_spacing = self.bitline_offset + self.m2_space # spacing between cross coupled inverters - self.inverter_to_inverter_spacing = contact.poly.height + self.m1_space + self.inverter_to_inverter_spacing = contact.poly.width + self.m1_space # calculations related to inverter connections inverter_pmos_contact_extension = 0.5*(self.inverter_pmos.active_contact.height - self.inverter_pmos.active_height) @@ -291,19 +299,24 @@ class pbitcell(design.design): self.add_path("poly", [self.inverter_nmos_right.get_pin("G").uc(), self.inverter_pmos_right.get_pin("G").bc()]) # connect output (drain/source) of inverters - self.add_path("metal1", [self.inverter_nmos_left.get_pin("D").uc(), self.inverter_pmos_left.get_pin("D").bc()], width=contact.well.second_layer_width) - self.add_path("metal1", [self.inverter_nmos_right.get_pin("S").uc(), self.inverter_pmos_right.get_pin("S").bc()], width=contact.well.second_layer_width) + self.add_path("metal1", + [self.inverter_nmos_left.get_pin("D").uc(), self.inverter_pmos_left.get_pin("D").bc()], + width=contact.active.second_layer_width) + self.add_path("metal1", + [self.inverter_nmos_right.get_pin("S").uc(), self.inverter_pmos_right.get_pin("S").bc()], + width=contact.active.second_layer_width) # add contacts to connect gate poly to drain/source metal1 (to connect Q to Q_bar) contact_offset_left = vector(self.inverter_nmos_left.get_pin("D").rc().x + 0.5*contact.poly.height, self.cross_couple_upper_ypos) - self.add_contact_center(layers=("poly", "contact", "metal1"), - offset=contact_offset_left, - rotate=90) + self.add_via_center(layers=("poly", "contact", "metal1"), + offset=contact_offset_left, + directions=("H","H")) + contact_offset_right = vector(self.inverter_nmos_right.get_pin("S").lc().x - 0.5*contact.poly.height, self.cross_couple_lower_ypos) - self.add_contact_center(layers=("poly", "contact", "metal1"), - offset=contact_offset_right, - rotate=90) + self.add_via_center(layers=("poly", "contact", "metal1"), + offset=contact_offset_right, + directions=("H","H")) # connect contacts to gate poly (cross couple connections) gate_offset_right = vector(self.inverter_nmos_right.get_pin("G").lc().x, contact_offset_left.y) @@ -394,7 +407,6 @@ class pbitcell(design.design): self.add_layout_pin_rect_center(text=self.rw_bl_names[k], layer="metal2", offset=self.rwbl_positions[k], - width=drc["minwidth_metal2"], height=self.height) rwbr_xpos = right_readwrite_transistor_xpos + self.readwrite_nmos.active_width + self.bitline_offset - 0.5*self.m2_width @@ -402,7 +414,6 @@ class pbitcell(design.design): self.add_layout_pin_rect_center(text=self.rw_br_names[k], layer="metal2", offset=self.rwbr_positions[k], - width=drc["minwidth_metal2"], height=self.height) # update furthest left and right transistor edges @@ -471,7 +482,6 @@ class pbitcell(design.design): self.add_layout_pin_rect_center(text=self.w_bl_names[k], layer="metal2", offset=self.wbl_positions[k], - width=drc["minwidth_metal2"], height=self.height) wbr_xpos = right_write_transistor_xpos + self.write_nmos.active_width + self.bitline_offset - 0.5*self.m2_width @@ -479,7 +489,6 @@ class pbitcell(design.design): self.add_layout_pin_rect_center(text=self.w_br_names[k], layer="metal2", offset=self.wbr_positions[k], - width=drc["minwidth_metal2"], height=self.height) # update furthest left and right transistor edges @@ -570,7 +579,6 @@ class pbitcell(design.design): self.add_layout_pin_rect_center(text=self.r_bl_names[k], layer="metal2", offset=self.rbl_positions[k], - width=drc["minwidth_metal2"], height=self.height) rbr_xpos = right_read_transistor_xpos + self.read_port_width + self.bitline_offset - 0.5*self.m2_width @@ -578,7 +586,6 @@ class pbitcell(design.design): self.add_layout_pin_rect_center(text=self.r_br_names[k], layer="metal2", offset=self.rbr_positions[k], - width=drc["minwidth_metal2"], height=self.height) def route_wordlines(self): @@ -612,21 +619,21 @@ class pbitcell(design.design): # first transistor on either side of the cross coupled inverters does not need to route to wordline on metal2 if (k == 0) or (k == 1): - self.add_contact_center(layers=("poly", "contact", "metal1"), - offset=port_contact_offset) + self.add_via_center(layers=("poly", "contact", "metal1"), + offset=port_contact_offset) self.add_path("poly", [gate_offset, port_contact_offset]) self.add_path("metal1", [port_contact_offset, wl_contact_offset]) else: - self.add_contact_center(layers=("poly", "contact", "metal1"), - offset=port_contact_offset) - self.add_contact_center(layers=("metal1", "via1", "metal2"), - offset=port_contact_offset) + self.add_via_center(layers=("poly", "contact", "metal1"), + offset=port_contact_offset) + self.add_via_center(layers=("metal1", "via1", "metal2"), + offset=port_contact_offset) - self.add_contact_center(layers=("metal1", "via1", "metal2"), - offset=wl_contact_offset, - rotate=90) + self.add_via_center(layers=("metal1", "via1", "metal2"), + offset=wl_contact_offset, + directions=("H","H")) self.add_path("poly", [gate_offset, port_contact_offset]) self.add_path("metal2", [port_contact_offset, wl_contact_offset]) @@ -661,8 +668,8 @@ class pbitcell(design.design): port_contact_offest = left_port_transistors[k].get_pin("S").center() bl_offset = vector(bl_positions[k].x, port_contact_offest.y) - self.add_contact_center(layers=("metal1", "via1", "metal2"), - offset=port_contact_offest) + self.add_via_center(layers=("metal1", "via1", "metal2"), + offset=port_contact_offest) self.add_path("metal2", [port_contact_offest, bl_offset], width=contact.m1m2.height) @@ -670,8 +677,8 @@ class pbitcell(design.design): port_contact_offest = right_port_transistors[k].get_pin("D").center() br_offset = vector(br_positions[k].x, port_contact_offest.y) - self.add_contact_center(layers=("metal1", "via1", "metal2"), - offset=port_contact_offest) + self.add_via_center(layers=("metal1", "via1", "metal2"), + offset=port_contact_offest) self.add_path("metal2", [port_contact_offest, br_offset], width=contact.m1m2.height) @@ -686,17 +693,17 @@ class pbitcell(design.design): nmos_contact_positions.append(self.read_access_nmos_right[k].get_pin("S").center()) for position in nmos_contact_positions: - self.add_contact_center(layers=("metal1", "via1", "metal2"), - offset=position) + self.add_via_center(layers=("metal1", "via1", "metal2"), + offset=position) if position.x > 0: contact_correct = 0.5*contact.m1m2.height else: contact_correct = -0.5*contact.m1m2.height supply_offset = vector(position.x + contact_correct, self.gnd_position.y) - self.add_contact_center(layers=("metal1", "via1", "metal2"), - offset=supply_offset, - rotate=90) + self.add_via_center(layers=("metal1", "via1", "metal2"), + offset=supply_offset, + directions=("H","H")) self.add_path("metal2", [position, supply_offset]) @@ -712,39 +719,35 @@ class pbitcell(design.design): for k in range(self.num_rw_ports): mid = vector(self.readwrite_nmos_left[k].get_pin("D").uc().x, self.cross_couple_lower_ypos) Q_pos = vector(self.inverter_nmos_left.get_pin("D").lx(), self.cross_couple_lower_ypos) - self.add_path("metal1", [self.readwrite_nmos_left[k].get_pin("D").uc(), mid+vector(0,0.5*self.m1_width)], width=contact.poly.second_layer_width) - self.add_path("metal1", [mid, Q_pos]) + self.add_path("metal1", [self.readwrite_nmos_left[k].get_pin("D").uc(), mid, Q_pos]) mid = vector(self.readwrite_nmos_right[k].get_pin("S").uc().x, self.cross_couple_lower_ypos) Q_bar_pos = vector(self.inverter_nmos_right.get_pin("S").rx(), self.cross_couple_lower_ypos) - self.add_path("metal1", [self.readwrite_nmos_right[k].get_pin("S").uc(), mid+vector(0,0.5*self.m1_width)], width=contact.poly.second_layer_width) - self.add_path("metal1", [mid, Q_bar_pos]) + self.add_path("metal1", [self.readwrite_nmos_right[k].get_pin("S").uc(), mid, Q_bar_pos]) def route_write_access(self): """ Routes read/write transistors to the storage component of the bitcell """ for k in range(self.num_w_ports): mid = vector(self.write_nmos_left[k].get_pin("D").uc().x, self.cross_couple_lower_ypos) Q_pos = vector(self.inverter_nmos_left.get_pin("D").lx(), self.cross_couple_lower_ypos) - self.add_path("metal1", [self.write_nmos_left[k].get_pin("D").uc(), mid+vector(0,0.5*self.m1_width)], width=contact.poly.second_layer_width) - self.add_path("metal1", [mid, Q_pos]) + self.add_path("metal1", [self.write_nmos_left[k].get_pin("D").uc(), mid, Q_pos]) mid = vector(self.write_nmos_right[k].get_pin("S").uc().x, self.cross_couple_lower_ypos) Q_bar_pos = vector(self.inverter_nmos_right.get_pin("S").rx(), self.cross_couple_lower_ypos) - self.add_path("metal1", [self.write_nmos_right[k].get_pin("S").uc(), mid+vector(0,0.5*self.m1_width)], width=contact.poly.second_layer_width) - self.add_path("metal1", [mid, Q_bar_pos]) + self.add_path("metal1", [self.write_nmos_right[k].get_pin("S").uc(), mid, Q_bar_pos]) def route_read_access(self): """ Routes read access transistors to the storage component of the bitcell """ # add poly to metal1 contacts for gates of the inverters - left_storage_contact = vector(self.inverter_nmos_left.get_pin("G").lc().x - drc["poly_to_polycontact"] - 0.5*contact.poly.width, self.cross_couple_upper_ypos) - self.add_contact_center(layers=("poly", "contact", "metal1"), - offset=left_storage_contact, - rotate=90) + left_storage_contact = vector(self.inverter_nmos_left.get_pin("G").lc().x - self.poly_to_polycontact - 0.5*contact.poly.width, self.cross_couple_upper_ypos) + self.add_via_center(layers=("poly", "contact", "metal1"), + offset=left_storage_contact, + directions=("H","H")) - right_storage_contact = vector(self.inverter_nmos_right.get_pin("G").rc().x + drc["poly_to_polycontact"] + 0.5*contact.poly.width, self.cross_couple_upper_ypos) - self.add_contact_center(layers=("poly", "contact", "metal1"), - offset=right_storage_contact, - rotate=90) + right_storage_contact = vector(self.inverter_nmos_right.get_pin("G").rc().x + self.poly_to_polycontact + 0.5*contact.poly.width, self.cross_couple_upper_ypos) + self.add_via_center(layers=("poly", "contact", "metal1"), + offset=right_storage_contact, + directions=("H","H")) inverter_gate_offset_left = vector(self.inverter_nmos_left.get_pin("G").lc().x, self.cross_couple_upper_ypos) self.add_path("poly", [left_storage_contact, inverter_gate_offset_left]) @@ -757,25 +760,23 @@ class pbitcell(design.design): for k in range(self.num_r_ports): port_contact_offset = self.read_access_nmos_left[k].get_pin("G").uc() + vector(0, self.gate_contact_yoffset - self.poly_extend_active) - self.add_contact_center(layers=("poly", "contact", "metal1"), - offset=port_contact_offset) + self.add_via_center(layers=("poly", "contact", "metal1"), + offset=port_contact_offset) self.add_path("poly", [self.read_access_nmos_left[k].get_pin("G").uc(), port_contact_offset]) mid = vector(self.read_access_nmos_left[k].get_pin("G").uc().x, self.cross_couple_upper_ypos) - self.add_path("metal1", [port_contact_offset, mid+vector(0,0.5*self.m1_width)], width=contact.poly.second_layer_width) - self.add_path("metal1", [mid, left_storage_contact]) + self.add_path("metal1", [port_contact_offset, mid, left_storage_contact]) port_contact_offset = self.read_access_nmos_right[k].get_pin("G").uc() + vector(0, self.gate_contact_yoffset - self.poly_extend_active) - self.add_contact_center(layers=("poly", "contact", "metal1"), - offset=port_contact_offset) + self.add_via_center(layers=("poly", "contact", "metal1"), + offset=port_contact_offset) self.add_path("poly", [self.read_access_nmos_right[k].get_pin("G").uc(), port_contact_offset]) mid = vector(self.read_access_nmos_right[k].get_pin("G").uc().x, self.cross_couple_upper_ypos) - self.add_path("metal1", [port_contact_offset, mid+vector(0,0.5*self.m1_width)], width=contact.poly.second_layer_width) - self.add_path("metal1", [mid, right_storage_contact]) + self.add_path("metal1", [port_contact_offset, mid, right_storage_contact]) def extend_well(self): """ @@ -794,13 +795,13 @@ class pbitcell(design.design): # extend nwell to encompass inverter_pmos # calculate offset of the left pmos well - inverter_well_xpos = -(self.inverter_nmos.active_width + 0.5*self.inverter_to_inverter_spacing) - drc["well_enclosure_active"] - inverter_well_ypos = self.inverter_nmos_ypos + self.inverter_nmos.active_height + self.inverter_gap - drc["well_enclosure_active"] + inverter_well_xpos = -(self.inverter_nmos.active_width + 0.5*self.inverter_to_inverter_spacing) - self.well_enclose_active + inverter_well_ypos = self.inverter_nmos_ypos + self.inverter_nmos.active_height + self.inverter_gap - self.well_enclose_active # calculate width of the two combined nwells # calculate height to encompass nimplant connected to vdd - well_width = 2*(self.inverter_nmos.active_width + 0.5*self.inverter_to_inverter_spacing) + 2*drc["well_enclosure_active"] - well_height = self.vdd_position.y - inverter_well_ypos + drc["well_enclosure_active"] + drc["minwidth_tx"] + well_width = 2*(self.inverter_nmos.active_width + 0.5*self.inverter_to_inverter_spacing) + 2*self.well_enclose_active + well_height = self.vdd_position.y - inverter_well_ypos + self.well_enclose_active + drc["minwidth_tx"] offset = [inverter_well_xpos,inverter_well_ypos] self.add_rect(layer="nwell", @@ -811,19 +812,19 @@ class pbitcell(design.design): # add well contacts # connect pimplants to gnd offset = vector(0, self.gnd_position.y) - self.add_contact_center(layers=("active", "contact", "metal1"), - offset=offset, - rotate=90, - implant_type="p", - well_type="p") + self.add_via_center(layers=("active", "contact", "metal1"), + offset=offset, + directions=("H","H"), + implant_type="p", + well_type="p") # connect nimplants to vdd offset = vector(0, self.vdd_position.y) - self.add_contact_center(layers=("active", "contact", "metal1"), - offset=offset, - rotate=90, - implant_type="n", - well_type="n") + self.add_via_center(layers=("active", "contact", "metal1"), + offset=offset, + directions=("H","H"), + implant_type="n", + well_type="n") def list_bitcell_pins(self, col, row): """ Creates a list of connections in the bitcell, indexed by column and row, for instance use in bitcell_array """ @@ -867,12 +868,16 @@ class pbitcell(design.design): self.add_path("metal1", [Q_bar_pos, vdd_pos]) def analytical_delay(self, corner, slew, load=0, swing = 0.5): - #FIXME: Delay copied exactly over from bitcell - from tech import spice - r = spice["min_tx_r"]*3 - c_para = spice["min_tx_drain_c"] - result = self.cal_delay_with_rc(corner, r = r, c = c_para+load, slew = slew, swing = swing) - return result + parasitic_delay = 1 + size = 0.5 #This accounts for bitline being drained thought the access TX and internal node + cin = 3 #Assumes always a minimum sizes inverter. Could be specified in the tech.py file. + + #Internal loads due to port configs are halved. This is to account for the size already being halved + #for stacked TXs, but internal loads do not see this size estimation. + write_port_load = self.num_w_ports*logical_effort.convert_farad_to_relative_c(parameter['bitcell_drain_cap'])/2 + read_port_load = self.num_r_ports/2 #min size NMOS gate load + total_load = load+read_port_load+write_port_load + return logical_effort.logical_effort('bitline', size, cin, load+read_port_load, parasitic_delay, False) def analytical_power(self, corner, load): """Bitcell power in nW. Only characterizes leakage.""" diff --git a/compiler/bitcells/replica_bitcell.py b/compiler/bitcells/replica_bitcell.py index d8b8b76e..0a0e4fbf 100644 --- a/compiler/bitcells/replica_bitcell.py +++ b/compiler/bitcells/replica_bitcell.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# import design import debug import utils diff --git a/compiler/bitcells/replica_bitcell_1rw_1r.py b/compiler/bitcells/replica_bitcell_1rw_1r.py index 8f7b3b38..2ada1381 100644 --- a/compiler/bitcells/replica_bitcell_1rw_1r.py +++ b/compiler/bitcells/replica_bitcell_1rw_1r.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# import design import debug import utils diff --git a/compiler/bitcells/replica_bitcell_1w_1r.py b/compiler/bitcells/replica_bitcell_1w_1r.py index 6f59adec..c079399a 100644 --- a/compiler/bitcells/replica_bitcell_1w_1r.py +++ b/compiler/bitcells/replica_bitcell_1w_1r.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# import design import debug import utils diff --git a/compiler/bitcells/replica_pbitcell.py b/compiler/bitcells/replica_pbitcell.py index 4d2ecd70..30898d82 100644 --- a/compiler/bitcells/replica_pbitcell.py +++ b/compiler/bitcells/replica_pbitcell.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# import debug import design from tech import drc, spice,parameter @@ -67,8 +74,7 @@ class replica_pbitcell(design.design): self.connect_inst(temp) def place_pbitcell(self): - offset = [0,0] - self.prbc_inst.place(offset=offset) + self.prbc_inst.place(offset=vector(0,0)) def route_rbc_connections(self): for port in range(self.total_ports): diff --git a/compiler/characterizer/__init__.py b/compiler/characterizer/__init__.py index fc42a889..4c3cd910 100644 --- a/compiler/characterizer/__init__.py +++ b/compiler/characterizer/__init__.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# import os import debug import globals diff --git a/compiler/characterizer/bitline_delay.py b/compiler/characterizer/bitline_delay.py index c85f06bc..90197619 100644 --- a/compiler/characterizer/bitline_delay.py +++ b/compiler/characterizer/bitline_delay.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# import sys,re,shutil import debug import tech diff --git a/compiler/characterizer/charutils.py b/compiler/characterizer/charutils.py index 061972cf..7081ff85 100644 --- a/compiler/characterizer/charutils.py +++ b/compiler/characterizer/charutils.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# import re import debug from globals import OPTS diff --git a/compiler/characterizer/delay.py b/compiler/characterizer/delay.py index 9c15cd2a..05c8862f 100644 --- a/compiler/characterizer/delay.py +++ b/compiler/characterizer/delay.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# import sys,re,shutil import debug import tech @@ -9,6 +16,7 @@ import utils from globals import OPTS from .simulation import simulation from .measurements import * +import logical_effort class delay(simulation): """Functions to measure the delay and power of an SRAM at a given address and @@ -904,8 +912,9 @@ class delay(simulation): self.create_measurement_names() power = self.analytical_power(slews, loads) port_data = self.get_empty_measure_data_dict() + relative_loads = [logical_effort.convert_farad_to_relative_c(c_farad) for c_farad in loads] for slew in slews: - for load in loads: + for load in relative_loads: self.set_load_slew(load,slew) bank_delay = self.sram.analytical_delay(self.corner, self.slew,self.load) for port in self.all_ports: diff --git a/compiler/characterizer/functional.py b/compiler/characterizer/functional.py index ca05648a..c12b6669 100644 --- a/compiler/characterizer/functional.py +++ b/compiler/characterizer/functional.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# import sys,re,shutil from design import design import debug diff --git a/compiler/characterizer/lib.py b/compiler/characterizer/lib.py index d24c931d..4f709999 100644 --- a/compiler/characterizer/lib.py +++ b/compiler/characterizer/lib.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# import os,sys,re import debug import math diff --git a/compiler/characterizer/logical_effort.py b/compiler/characterizer/logical_effort.py index c80e69a2..13005695 100644 --- a/compiler/characterizer/logical_effort.py +++ b/compiler/characterizer/logical_effort.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# import debug from tech import drc, parameter, spice @@ -9,6 +16,7 @@ class logical_effort(): beta = parameter["beta"] min_inv_cin = 1+beta pinv=parameter["min_inv_para_delay"] + tau = parameter['le_tau'] def __init__(self, name, size, cin, cout, parasitic, out_is_rise=True): self.name = name @@ -30,30 +38,44 @@ class logical_effort(): def get_stage_effort(self): return self.logical_effort*self.eletrical_effort - def get_parasitic_delay(self, pinv): - return pinv * self.parasitic_scale + def get_parasitic_delay(self): + return logical_effort.pinv * self.parasitic_scale - def get_stage_delay(self, pinv): - return self.get_stage_effort()+self.get_parasitic_delay(pinv) + def get_stage_delay(self): + return self.get_stage_effort()+self.get_parasitic_delay() -def calculate_delays(stage_effort_list, pinv): + def get_absolute_delay(self): + return logical_effort.tau*self.get_stage_delay() + +def calculate_delays(stage_effort_list): """Convert stage effort objects to list of delay values""" - return [stage.get_stage_delay(pinv) for stage in stage_effort_list] + return [stage.get_stage_delay() for stage in stage_effort_list] -def calculate_relative_delay(stage_effort_list, pinv=parameter["min_inv_para_delay"]): +def calculate_relative_delay(stage_effort_list): """Calculates the total delay of a given delay path made of a list of logical effort objects.""" - total_rise_delay, total_fall_delay = calculate_relative_rise_fall_delays(stage_effort_list, pinv) + total_rise_delay, total_fall_delay = calculate_relative_rise_fall_delays(stage_effort_list) return total_rise_delay + total_fall_delay + +def calculate_absolute_delay(stage_effort_list): + """Calculates the total delay of a given delay path made of a list of logical effort objects.""" + total_delay = 0 + for stage in stage_effort_list: + total_delay+=stage.get_absolute_delay() + return total_delay -def calculate_relative_rise_fall_delays(stage_effort_list, pinv=parameter["min_inv_para_delay"]): +def calculate_relative_rise_fall_delays(stage_effort_list): """Calculates the rise/fall delays of a given delay path made of a list of logical effort objects.""" debug.info(2, "Calculating rise/fall relative delays") total_rise_delay, total_fall_delay = 0,0 for stage in stage_effort_list: debug.info(2, stage) if stage.is_rise: - total_rise_delay += stage.get_stage_delay(pinv) + total_rise_delay += stage.get_stage_delay() else: - total_fall_delay += stage.get_stage_delay(pinv) + total_fall_delay += stage.get_stage_delay() return total_rise_delay, total_fall_delay + +def convert_farad_to_relative_c(c_farad): + """Converts capacitance in Femto-Farads to relative capacitance.""" + return c_farad*parameter['cap_relative_per_ff'] \ No newline at end of file diff --git a/compiler/characterizer/measurements.py b/compiler/characterizer/measurements.py index e3d16584..01c6fa51 100644 --- a/compiler/characterizer/measurements.py +++ b/compiler/characterizer/measurements.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# import debug from tech import drc, parameter, spice from abc import ABC, abstractmethod diff --git a/compiler/characterizer/model_check.py b/compiler/characterizer/model_check.py index 12bc5d58..c7834602 100644 --- a/compiler/characterizer/model_check.py +++ b/compiler/characterizer/model_check.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# import sys,re,shutil import debug import tech @@ -18,15 +25,18 @@ class model_check(delay): """ - def __init__(self, sram, spfile, corner): + def __init__(self, sram, spfile, corner, custom_delaychain=False): delay.__init__(self,sram,spfile,corner) self.period = tech.spice["feasible_period"] self.create_data_names() + self.custom_delaychain=custom_delaychain def create_data_names(self): self.wl_meas_name, self.wl_model_name = "wl_measures", "wl_model" self.sae_meas_name, self.sae_model_name = "sae_measures", "sae_model" self.wl_slew_name, self.sae_slew_name = "wl_slews", "sae_slews" + self.bl_meas_name, self.bl_slew_name = "bl_measures", "bl_slews" + self.power_name = "total_power" def create_measurement_names(self): """Create measurement names. The names themselves currently define the type of measurement""" @@ -34,21 +44,33 @@ class model_check(delay): wl_en_driver_delay_names = ["delay_wl_en_dvr_{}".format(stage) for stage in range(1,self.get_num_wl_en_driver_stages())] wl_driver_delay_names = ["delay_wl_dvr_{}".format(stage) for stage in range(1,self.get_num_wl_driver_stages())] sen_driver_delay_names = ["delay_sen_dvr_{}".format(stage) for stage in range(1,self.get_num_sen_driver_stages())] - dc_delay_names = ["delay_delay_chain_stage_{}".format(stage) for stage in range(1,self.get_num_delay_stages()+1)] + if self.custom_delaychain: + dc_delay_names = ['delay_dc_out_final'] + else: + dc_delay_names = ["delay_delay_chain_stage_{}".format(stage) for stage in range(1,self.get_num_delay_stages()+1)] self.wl_delay_meas_names = wl_en_driver_delay_names+["delay_wl_en", "delay_wl_bar"]+wl_driver_delay_names+["delay_wl"] self.rbl_delay_meas_names = ["delay_gated_clk_nand", "delay_delay_chain_in"]+dc_delay_names self.sae_delay_meas_names = ["delay_pre_sen"]+sen_driver_delay_names+["delay_sen"] + # if self.custom_delaychain: + # self.delay_chain_indices = (len(self.rbl_delay_meas_names), len(self.rbl_delay_meas_names)+1) + # else: self.delay_chain_indices = (len(self.rbl_delay_meas_names)-len(dc_delay_names), len(self.rbl_delay_meas_names)) #Create slew measurement names wl_en_driver_slew_names = ["slew_wl_en_dvr_{}".format(stage) for stage in range(1,self.get_num_wl_en_driver_stages())] wl_driver_slew_names = ["slew_wl_dvr_{}".format(stage) for stage in range(1,self.get_num_wl_driver_stages())] sen_driver_slew_names = ["slew_sen_dvr_{}".format(stage) for stage in range(1,self.get_num_sen_driver_stages())] - dc_slew_names = ["slew_delay_chain_stage_{}".format(stage) for stage in range(1,self.get_num_delay_stages()+1)] + if self.custom_delaychain: + dc_slew_names = ['slew_dc_out_final'] + else: + dc_slew_names = ["slew_delay_chain_stage_{}".format(stage) for stage in range(1,self.get_num_delay_stages()+1)] self.wl_slew_meas_names = ["slew_wl_gated_clk_bar"]+wl_en_driver_slew_names+["slew_wl_en", "slew_wl_bar"]+wl_driver_slew_names+["slew_wl"] self.rbl_slew_meas_names = ["slew_rbl_gated_clk_bar","slew_gated_clk_nand", "slew_delay_chain_in"]+dc_slew_names self.sae_slew_meas_names = ["slew_replica_bl0", "slew_pre_sen"]+sen_driver_slew_names+["slew_sen"] + self.bitline_meas_names = ["delay_wl_to_bl", "delay_bl_to_dout"] + self.power_meas_names = ['read0_power'] + def create_signal_names(self): """Creates list of the signal names used in the spice file along the wl and sen paths. Names are re-harded coded here; i.e. the names are hardcoded in most of OpenRAM and are @@ -59,7 +81,10 @@ class model_check(delay): wl_en_driver_signals = ["Xsram.Xcontrol0.Xbuf_wl_en.Zb{}_int".format(stage) for stage in range(1,self.get_num_wl_en_driver_stages())] wl_driver_signals = ["Xsram.Xbank0.Xwordline_driver0.Xwl_driver_inv{}.Zb{}_int".format(self.wordline_row, stage) for stage in range(1,self.get_num_wl_driver_stages())] sen_driver_signals = ["Xsram.Xcontrol0.Xbuf_s_en.Zb{}_int".format(stage) for stage in range(1,self.get_num_sen_driver_stages())] - delay_chain_signal_names = ["Xsram.Xcontrol0.Xreplica_bitline.Xdelay_chain.dout_{}".format(stage) for stage in range(1,self.get_num_delay_stages())] + if self.custom_delaychain: + delay_chain_signal_names = [] + else: + delay_chain_signal_names = ["Xsram.Xcontrol0.Xreplica_bitline.Xdelay_chain.dout_{}".format(stage) for stage in range(1,self.get_num_delay_stages())] self.wl_signal_names = ["Xsram.Xcontrol0.gated_clk_bar"]+\ wl_en_driver_signals+\ @@ -70,17 +95,31 @@ class model_check(delay): self.rbl_en_signal_names = pre_delay_chain_names+\ delay_chain_signal_names+\ ["Xsram.Xcontrol0.Xreplica_bitline.delayed_en"] + + self.sae_signal_names = ["Xsram.Xcontrol0.Xreplica_bitline.bl0_0", "Xsram.Xcontrol0.pre_s_en"]+\ sen_driver_signals+\ ["Xsram.s_en0"] + + dout_name = "{0}{1}_{2}".format(self.dout_name,"{}",self.probe_data) #Empty values are the port and probe data bit + self.bl_signal_names = ["Xsram.Xbank0.wl_{}".format(self.wordline_row),\ + "Xsram.Xbank0.bl_{}".format(self.bitline_column),\ + dout_name] def create_measurement_objects(self): """Create the measurements used for read and write ports""" - self.create_wordline_measurement_objects() - self.create_sae_measurement_objects() - self.all_measures = self.wl_meas_objs+self.sae_meas_objs + self.create_wordline_meas_objs() + self.create_sae_meas_objs() + self.create_bl_meas_objs() + self.create_power_meas_objs() + self.all_measures = self.wl_meas_objs+self.sae_meas_objs+self.bl_meas_objs+self.power_meas_objs - def create_wordline_measurement_objects(self): + def create_power_meas_objs(self): + """Create power measurement object. Only one.""" + self.power_meas_objs = [] + self.power_meas_objs.append(power_measure(self.power_meas_names[0], "FALL", measure_scale=1e3)) + + def create_wordline_meas_objs(self): """Create the measurements to measure the wordline path from the gated_clk_bar signal""" self.wl_meas_objs = [] trig_dir = "RISE" @@ -102,7 +141,19 @@ class model_check(delay): targ_dir = temp_dir self.wl_meas_objs.append(slew_measure(self.wl_slew_meas_names[-1], self.wl_signal_names[-1], trig_dir, measure_scale=1e9)) - def create_sae_measurement_objects(self): + def create_bl_meas_objs(self): + """Create the measurements to measure the bitline to dout, static stages""" + #Bitline has slightly different measurements, objects appends hardcoded. + self.bl_meas_objs = [] + trig_dir, targ_dir = "RISE", "FALL" #Only check read 0 + self.bl_meas_objs.append(delay_measure(self.bitline_meas_names[0], + self.bl_signal_names[0], + self.bl_signal_names[-1], + trig_dir, + targ_dir, + measure_scale=1e9)) + + def create_sae_meas_objs(self): """Create the measurements to measure the sense amp enable path from the gated_clk_bar signal. The RBL splits this path into two.""" self.sae_meas_objs = [] @@ -123,6 +174,13 @@ class model_check(delay): temp_dir = trig_dir trig_dir = targ_dir targ_dir = temp_dir + if self.custom_delaychain: #Hack for custom delay chains + self.sae_meas_objs[-2] = delay_measure(self.rbl_delay_meas_names[-1], + self.rbl_en_signal_names[-2], + self.rbl_en_signal_names[-1], + "RISE", + "RISE", + measure_scale=1e9) self.sae_meas_objs.append(slew_measure(self.rbl_slew_meas_names[-1], self.rbl_en_signal_names[-1], trig_dir, @@ -131,7 +189,6 @@ class model_check(delay): #Add measurements from rbl_out to sae. Trigger directions do not invert from previous stage due to RBL. trig_dir = "FALL" targ_dir = "RISE" - #Add measurements from gated_clk_bar to RBL for i in range(1, len(self.sae_signal_names)): self.sae_meas_objs.append(delay_measure(self.sae_delay_meas_names[i-1], self.sae_signal_names[i-1], @@ -169,10 +226,22 @@ class model_check(delay): or port to port (time delays)""" #Return value is intended to match the delay measure format: trig_td, targ_td, vdd, port #Assuming only read 0 for now - if not (type(measure_obj) is delay_measure or type(measure_obj) is slew_measure): + debug.info(3,"Power measurement={}".format(measure_obj)) + if (type(measure_obj) is delay_measure or type(measure_obj) is slew_measure): + meas_cycle_delay = self.cycle_times[self.measure_cycles[port]["read0"]] + self.period/2 + return (meas_cycle_delay, meas_cycle_delay, self.vdd_voltage, port) + elif type(measure_obj) is power_measure: + return self.get_power_measure_variants(port, measure_obj, "read") + else: debug.error("Measurement not recognized by the model checker.",1) - meas_cycle_delay = self.cycle_times[self.measure_cycles[port]["read0"]] + self.period/2 - return (meas_cycle_delay, meas_cycle_delay, self.vdd_voltage, port) + + def get_power_measure_variants(self, port, power_obj, operation): + """Get the measurement values that can either vary port to port (time delays)""" + #Return value is intended to match the power measure format: t_initial, t_final, port + t_initial = self.cycle_times[self.measure_cycles[port]["read0"]] + t_final = self.cycle_times[self.measure_cycles[port]["read0"]+1] + + return (t_initial, t_final, port) def write_measures_read_port(self, port): """ @@ -186,7 +255,8 @@ class model_check(delay): def get_measurement_values(self, meas_objs, port): """Gets the delays and slews from a specified port from the spice output file and returns them as lists.""" delay_meas_list = [] - slew_meas_list = [] + slew_meas_list = [] + power_meas_list=[] for measure in meas_objs: measure_value = measure.retrieve_measure(port=port) if type(measure_value) != float: @@ -195,9 +265,11 @@ class model_check(delay): delay_meas_list.append(measure_value) elif type(measure)is slew_measure: slew_meas_list.append(measure_value) + elif type(measure)is power_measure: + power_meas_list.append(measure_value) else: debug.error("Measurement object not recognized.",1) - return delay_meas_list, slew_meas_list + return delay_meas_list, slew_meas_list,power_meas_list def run_delay_simulation(self): """ @@ -213,6 +285,9 @@ class model_check(delay): wl_slew_result = [[] for i in self.all_ports] sae_delay_result = [[] for i in self.all_ports] sae_slew_result = [[] for i in self.all_ports] + bl_delay_result = [[] for i in self.all_ports] + bl_slew_result = [[] for i in self.all_ports] + power_result = [[] for i in self.all_ports] # Checking from not data_value to data_value self.write_delay_stimulus() @@ -221,9 +296,11 @@ class model_check(delay): #Retrieve the results from the output file for port in self.targ_read_ports: #Parse and check the voltage measurements - wl_delay_result[port], wl_slew_result[port] = self.get_measurement_values(self.wl_meas_objs, port) - sae_delay_result[port], sae_slew_result[port] = self.get_measurement_values(self.sae_meas_objs, port) - return (True,wl_delay_result, sae_delay_result, wl_slew_result, sae_slew_result) + wl_delay_result[port], wl_slew_result[port],_ = self.get_measurement_values(self.wl_meas_objs, port) + sae_delay_result[port], sae_slew_result[port],_ = self.get_measurement_values(self.sae_meas_objs, port) + bl_delay_result[port], bl_slew_result[port],_ = self.get_measurement_values(self.bl_meas_objs, port) + _,__,power_result[port] = self.get_measurement_values(self.power_meas_objs, port) + return (True,wl_delay_result, sae_delay_result, wl_slew_result, sae_slew_result, bl_delay_result, bl_slew_result, power_result) def get_model_delays(self, port): """Get model delays based on port. Currently assumes single RW port.""" @@ -306,23 +383,28 @@ class model_check(delay): self.targ_read_ports = [read_port] self.targ_write_ports = [self.write_ports[0]] debug.info(1,"Model test: corner {}".format(self.corner)) - (success, wl_delays, sae_delays, wl_slews, sae_slews)=self.run_delay_simulation() + (success, wl_delays, sae_delays, wl_slews, sae_slews, bl_delays, bl_slews, powers)=self.run_delay_simulation() debug.check(success, "Model measurements Failed: period={}".format(self.period)) - wl_model_delays, sae_model_delays = self.get_model_delays(read_port) debug.info(1,"Measured Wordline delays (ns):\n\t {}".format(wl_delays[read_port])) - debug.info(1,"Wordline model delays:\n\t {}".format(wl_model_delays)) debug.info(1,"Measured Wordline slews:\n\t {}".format(wl_slews[read_port])) debug.info(1,"Measured SAE delays (ns):\n\t {}".format(sae_delays[read_port])) - debug.info(1,"SAE model delays:\n\t {}".format(sae_model_delays)) debug.info(1,"Measured SAE slews:\n\t {}".format(sae_slews[read_port])) + debug.info(1,"Measured Bitline delays (ns):\n\t {}".format(bl_delays[read_port])) data_dict[self.wl_meas_name] = wl_delays[read_port] - data_dict[self.wl_model_name] = wl_model_delays data_dict[self.sae_meas_name] = sae_delays[read_port] - data_dict[self.sae_model_name] = sae_model_delays data_dict[self.wl_slew_name] = wl_slews[read_port] data_dict[self.sae_slew_name] = sae_slews[read_port] + data_dict[self.bl_meas_name] = bl_delays[read_port] + data_dict[self.power_name] = powers[read_port] + + if not OPTS.use_tech_delay_chain_size: #Model is not used in this case + wl_model_delays, sae_model_delays = self.get_model_delays(read_port) + debug.info(1,"Wordline model delays:\n\t {}".format(wl_model_delays)) + debug.info(1,"SAE model delays:\n\t {}".format(sae_model_delays)) + data_dict[self.wl_model_name] = wl_model_delays + data_dict[self.sae_model_name] = sae_model_delays #Some evaluations of the model and measured values # debug.info(1, "Comparing wordline measurements and model.") @@ -337,11 +419,17 @@ class model_check(delay): name_dict = {} #Signal names are more descriptive than the measurement names, first value trimmed to match size of measurements names. name_dict[self.wl_meas_name] = self.wl_signal_names[1:] - name_dict[self.wl_model_name] = name_dict["wl_measures"] #model uses same names as measured. name_dict[self.sae_meas_name] = self.rbl_en_signal_names[1:]+self.sae_signal_names[1:] - name_dict[self.sae_model_name] = name_dict["sae_measures"] name_dict[self.wl_slew_name] = self.wl_slew_meas_names name_dict[self.sae_slew_name] = self.rbl_slew_meas_names+self.sae_slew_meas_names + name_dict[self.bl_meas_name] = self.bitline_meas_names[0:1] + name_dict[self.power_name] = self.power_meas_names + #name_dict[self.wl_slew_name] = self.wl_slew_meas_names + + if not OPTS.use_tech_delay_chain_size: + name_dict[self.wl_model_name] = name_dict["wl_measures"] #model uses same names as measured. + name_dict[self.sae_model_name] = name_dict["sae_measures"] + return name_dict diff --git a/compiler/characterizer/setup_hold.py b/compiler/characterizer/setup_hold.py index 8a515776..c85a5ad0 100644 --- a/compiler/characterizer/setup_hold.py +++ b/compiler/characterizer/setup_hold.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# import sys import tech from .stimuli import * diff --git a/compiler/characterizer/simulation.py b/compiler/characterizer/simulation.py index beca0502..e6204490 100644 --- a/compiler/characterizer/simulation.py +++ b/compiler/characterizer/simulation.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# import sys,re,shutil from design import design import debug diff --git a/compiler/characterizer/stimuli.py b/compiler/characterizer/stimuli.py index 3b569b2a..ddd1df7e 100644 --- a/compiler/characterizer/stimuli.py +++ b/compiler/characterizer/stimuli.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ This file generates simple spice cards for simulation. There are various functions that can be be used to generate stimulus for other diff --git a/compiler/characterizer/trim_spice.py b/compiler/characterizer/trim_spice.py index 88195fee..b8878db3 100644 --- a/compiler/characterizer/trim_spice.py +++ b/compiler/characterizer/trim_spice.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# import debug from math import log import re diff --git a/compiler/characterizer/worst_case.py b/compiler/characterizer/worst_case.py index 6dad95d9..612d6f9f 100644 --- a/compiler/characterizer/worst_case.py +++ b/compiler/characterizer/worst_case.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# import sys,re,shutil import debug import tech diff --git a/compiler/datasheet/add_db.py b/compiler/datasheet/add_db.py index 862c1d8a..a5984969 100644 --- a/compiler/datasheet/add_db.py +++ b/compiler/datasheet/add_db.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# from pathlib import Path import glob import os diff --git a/compiler/datasheet/datasheet.py b/compiler/datasheet/datasheet.py index b48d217d..0874cd01 100644 --- a/compiler/datasheet/datasheet.py +++ b/compiler/datasheet/datasheet.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# from table_gen import * import os import base64 diff --git a/compiler/datasheet/datasheet_gen.py b/compiler/datasheet/datasheet_gen.py index e6c728f0..c7eecd8d 100644 --- a/compiler/datasheet/datasheet_gen.py +++ b/compiler/datasheet/datasheet_gen.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# #!/usr/bin/env python3 """ This is a script to load data from the characterization and layout processes into diff --git a/compiler/datasheet/table_gen.py b/compiler/datasheet/table_gen.py index 227bb5c4..01479d7f 100644 --- a/compiler/datasheet/table_gen.py +++ b/compiler/datasheet/table_gen.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# class table_gen: """small library of functions to generate the html tables""" diff --git a/compiler/debug.py b/compiler/debug.py index 9ce1bf3f..4fa8b487 100644 --- a/compiler/debug.py +++ b/compiler/debug.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# import os import inspect import globals @@ -58,6 +65,8 @@ def log(str): # in another log file if the path or name changes. if not globals.OPTS.output_path.endswith('/'): globals.OPTS.output_path += "/" + if not os.path.isdir(globals.OPTS.output_path): + os.mkdir(globals.OPTS.output_path) compile_log = open(globals.OPTS.output_path + globals.OPTS.output_name + '.log', "w+") log.create_file = 0 diff --git a/compiler/drc/design_rules.py b/compiler/drc/design_rules.py index 4bc2eaa6..09729144 100644 --- a/compiler/drc/design_rules.py +++ b/compiler/drc/design_rules.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# import debug from drc_value import * from drc_lut import * diff --git a/compiler/drc/drc_lut.py b/compiler/drc/drc_lut.py index 07e482c8..0a214231 100644 --- a/compiler/drc/drc_lut.py +++ b/compiler/drc/drc_lut.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# import debug class drc_lut(): diff --git a/compiler/drc/drc_value.py b/compiler/drc/drc_value.py index c4eab3d4..4c85657f 100644 --- a/compiler/drc/drc_value.py +++ b/compiler/drc/drc_value.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# class drc_value(): """ diff --git a/compiler/gen_stimulus.py b/compiler/gen_stimulus.py index 07bd1b1c..3b24cff7 100755 --- a/compiler/gen_stimulus.py +++ b/compiler/gen_stimulus.py @@ -1,4 +1,11 @@ #!/usr/bin/env python +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ This script will generate a stimulus file for a given period, load, and slew input for the given dimension SRAM. It is useful for debugging after an SRAM has been diff --git a/compiler/globals.py b/compiler/globals.py index 3d4b2129..2fe0ec1b 100644 --- a/compiler/globals.py +++ b/compiler/globals.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ This is called globals.py, but it actually parses all the arguments and performs the global OpenRAM setup as well. @@ -477,11 +484,20 @@ def report_status(): debug.print_raw("Netlist only mode (no physical design is being done, netlist_only=False to disable).") if not OPTS.route_supplies: - debug.print_raw("Design supply routing skipped for run-time (incomplete GDS will not be saved, route_supplies=True to enable).") + debug.print_raw("Design supply routing skipped for run-time (incomplete GDS will not be saved) (route_supplies=True to enable).") if not OPTS.inline_lvsdrc: debug.print_raw("DRC/LVS/PEX is only run on the top-level design to save run-time (inline_lvsdrc=True to enable).") if not OPTS.check_lvsdrc: debug.print_raw("DRC/LVS/PEX is disabled (check_lvsdrc=True to enable).") + + if OPTS.analytical_delay: + debug.print_raw("Characterization is disabled (using analytical delay models) (analytical_delay=False to enable).") + else: + if OPTS.spice_name!="": + debug.print_raw("Performing simulation-based characterization with {}".format(OPTS.spice_name)) + if OPTS.trim_netlist: + debug.print_raw("Trimming netlist to speed up characterization (trim_netlist=False to disable).") + diff --git a/compiler/modules/bank.py b/compiler/modules/bank.py index 7eddc3bb..a854c40b 100644 --- a/compiler/modules/bank.py +++ b/compiler/modules/bank.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# import sys from tech import drc, parameter import debug @@ -800,14 +807,11 @@ class bank(design.design): bus_pos = vector(self.bus_xoffset[port][name].x, out_pos.y) self.add_path("metal3",[out_pos, bus_pos]) self.add_via_center(layers=("metal2", "via2", "metal3"), - offset=bus_pos, - rotate=90) + offset=bus_pos) self.add_via_center(layers=("metal1", "via1", "metal2"), - offset=out_pos, - rotate=90) + offset=out_pos) self.add_via_center(layers=("metal2", "via2", "metal3"), - offset=out_pos, - rotate=90) + offset=out_pos) def setup_routing_constraints(self): @@ -1197,8 +1201,7 @@ class bank(design.design): control_pos = vector(self.bus_xoffset[port][control_signal].x ,pin_pos.y) self.add_path("metal1", [control_pos, pin_pos]) self.add_via_center(layers=("metal1", "via1", "metal2"), - offset=control_pos, - rotate=90) + offset=control_pos) # clk to wordline_driver control_signal = self.prefix+"wl_en{}".format(port) @@ -1212,40 +1215,41 @@ class bank(design.design): control_pos = vector(control_x_offset, mid_pos.y) self.add_wire(("metal1","via1","metal2"),[pin_pos, mid_pos, control_pos]) self.add_via_center(layers=("metal1", "via1", "metal2"), - offset=control_pos, - rotate=90) + offset=control_pos) - - def analytical_delay(self, corner, slew, load): - """ return analytical delay of the bank""" - results = [] - - decoder_delay = self.row_decoder.analytical_delay(corner, slew, self.wordline_driver.input_load()) - - word_driver_delay = self.wordline_driver.analytical_delay(corner, - decoder_delay.slew, - self.bitcell_array.input_load()) + def analytical_delay(self, corner, slew, load, port): + """ return analytical delay of the bank. This will track the clock to output path""" + #FIXME: This delay is determined in the control logic. Should be moved here. + # word_driver_delay = self.wordline_driver.analytical_delay(corner, + # slew, + # self.bitcell_array.input_load()) #FIXME: Array delay is the same for every port. - bitcell_array_delay = self.bitcell_array.analytical_delay(corner, word_driver_delay.slew) + word_driver_slew = 0 + if self.words_per_row > 1: + bitline_ext_load = self.column_mux_array[port].get_drain_cin() + else: + bitline_ext_load = self.sense_amp_array.get_drain_cin() + + bitcell_array_delay = self.bitcell_array.analytical_delay(corner, word_driver_slew, bitline_ext_load) + bitcell_array_slew = 0 #This also essentially creates the same delay for each port. Good structure, no substance - for port in self.all_ports: - if self.words_per_row > 1: - column_mux_delay = self.column_mux_array[port].analytical_delay(corner, - bitcell_array_delay.slew, - self.sense_amp_array.input_load()) - else: - column_mux_delay = self.return_delay(delay = 0.0, slew=word_driver_delay.slew) - - bl_t_data_out_delay = self.sense_amp_array.analytical_delay(corner, - column_mux_delay.slew, - self.bitcell_array.output_load()) - # output load of bitcell_array is set to be only small part of bl for sense amp. - results.append(decoder_delay + word_driver_delay + bitcell_array_delay + column_mux_delay + bl_t_data_out_delay) - - return results - + if self.words_per_row > 1: + sa_load = self.sense_amp_array.get_drain_cin() + column_mux_delay = self.column_mux_array[port].analytical_delay(corner, + bitcell_array_slew, + sa_load) + else: + column_mux_delay = [] + + column_mux_slew = 0 + sense_amp_delay = self.sense_amp_array.analytical_delay(corner, + column_mux_slew, + load) + # output load of bitcell_array is set to be only small part of bl for sense amp. + return bitcell_array_delay + column_mux_delay + sense_amp_delay + def determine_wordline_stage_efforts(self, external_cout, inp_is_rise=True): """Get the all the stage efforts for each stage in the path within the bank clk_buf to a wordline""" #Decoder is assumed to have settled before the negative edge of the clock. Delay model relies on this assumption diff --git a/compiler/modules/bank_select.py b/compiler/modules/bank_select.py index 8e44dfa2..ac866456 100644 --- a/compiler/modules/bank_select.py +++ b/compiler/modules/bank_select.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# import sys from tech import drc, parameter import debug @@ -213,7 +220,7 @@ class bank_select(design.design): end=bank_sel_pin_end) self.add_via_center(layers=("metal2","via2","metal3"), offset=bank_sel_pin_end, - rotate=90) + directions=("H","H")) # bank_sel_bar is vertical wire bank_sel_bar_pin = self.bank_sel_inv.get_pin("Z") @@ -252,7 +259,7 @@ class bank_select(design.design): self.add_path("metal2",[logic_pos, input_pos]) self.add_via_center(layers=("metal1", "via1", "metal2"), offset=logic_pos, - rotate=90) + directions=("H","H")) # Connect the logic A input to the input pin @@ -260,10 +267,10 @@ class bank_select(design.design): input_pos = vector(0,logic_pos.y) self.add_via_center(layers=("metal1", "via1", "metal2"), offset=logic_pos, - rotate=90) + directions=("H","H")) self.add_via_center(layers=("metal2", "via2", "metal3"), offset=logic_pos, - rotate=90) + directions=("H","H")) self.add_layout_pin_segment_center(text=input_name, layer="metal3", start=input_pos, @@ -295,10 +302,10 @@ class bank_select(design.design): pin_pos = vector(xoffset, supply_pin.cy()) self.add_via_center(layers=("metal1", "via1", "metal2"), offset=pin_pos, - rotate=90) + directions=("H","H")) self.add_via_center(layers=("metal2", "via2", "metal3"), offset=pin_pos, - rotate=90) + directions=("H","H")) self.add_layout_pin_rect_center(text=n, layer="metal3", offset=pin_pos) diff --git a/compiler/modules/bitcell_array.py b/compiler/modules/bitcell_array.py index ea8fc3f2..f2ab77ac 100644 --- a/compiler/modules/bitcell_array.py +++ b/compiler/modules/bitcell_array.py @@ -1,9 +1,17 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# import debug import design from tech import drc, spice from vector import vector from globals import OPTS from sram_factory import factory +import logical_effort class bitcell_array(design.design): """ @@ -127,26 +135,18 @@ class bitcell_array(design.design): inst = self.cell_inst[row,col] for pin_name in ["vdd", "gnd"]: for pin in inst.get_pins(pin_name): - self.add_power_pin(pin_name, pin.center(), 0, pin.layer) - - - def analytical_delay(self, corner, slew, load=0): - from tech import drc - wl_wire = self.gen_wl_wire() - wl_wire.return_delay_over_wire(slew) - - wl_to_cell_delay = wl_wire.return_delay_over_wire(slew) - # hypothetical delay from cell to bl end without sense amp - bl_wire = self.gen_bl_wire() - cell_load = 2 * bl_wire.return_input_cap() # we ingore the wire r - # hence just use the whole c - bl_swing = 0.1 - cell_delay = self.cell.analytical_delay(corner, wl_to_cell_delay.slew, cell_load, swing = bl_swing) - - #we do not consider the delay over the wire for now - return self.return_delay(cell_delay.delay+wl_to_cell_delay.delay, - wl_to_cell_delay.slew) - + self.add_power_pin(name=pin_name, loc=pin.center(), vertical=True, start_layer=pin.layer) + + def analytical_delay(self, corner, slew, load): + """Returns relative delay of the bitline in the bitcell array""" + from tech import parameter + #The load being driven/drained is mostly the bitline but could include the sense amp or the column mux. + #The load from the bitlines is due to the drain capacitances from all the other bitlines and wire parasitics. + drain_load = logical_effort.convert_farad_to_relative_c(parameter['bitcell_drain_cap']) + wire_unit_load = .05 * drain_load #Wires add 5% to this. + bitline_load = (drain_load+wire_unit_load)*self.row_size + return [self.cell.analytical_delay(corner, slew, load+bitline_load)] + def analytical_power(self, corner, load): """Power of Bitcell array and bitline in nW.""" from tech import drc, parameter diff --git a/compiler/modules/control_logic.py b/compiler/modules/control_logic.py index ac9aaa1f..0bf309a6 100644 --- a/compiler/modules/control_logic.py +++ b/compiler/modules/control_logic.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# from math import log import design from tech import drc, parameter @@ -33,10 +40,10 @@ class control_logic(design.design): self.num_words = num_rows*words_per_row self.enable_delay_chain_resizing = True + self.inv_parasitic_delay = logical_effort.logical_effort.pinv #Determines how much larger the sen delay should be. Accounts for possible error in model. self.wl_timing_tolerance = 1 - self.parasitic_inv_delay = parameter["min_inv_para_delay"] self.wl_stage_efforts = None self.sen_stage_efforts = None @@ -219,7 +226,7 @@ class control_logic(design.design): def get_dynamic_delay_chain_size(self, previous_stages, previous_fanout): """Determine the size of the delay chain used for the Sense Amp Enable using path delays""" from math import ceil - previous_delay_chain_delay = (previous_fanout+1+self.parasitic_inv_delay)*previous_stages + previous_delay_chain_delay = (previous_fanout+1+self.inv_parasitic_delay)*previous_stages debug.info(2, "Previous delay chain produced {} delay units".format(previous_delay_chain_delay)) delay_fanout = 3 # This can be anything >=2 @@ -227,7 +234,7 @@ class control_logic(design.design): #inverter adds 1 unit of delay (due to minimum size). This also depends on the pinv value required_delay = self.wl_delay*self.wl_timing_tolerance - (self.sen_delay-previous_delay_chain_delay) debug.check(required_delay > 0, "Cannot size delay chain to have negative delay") - delay_stages = ceil(required_delay/(delay_fanout+1+self.parasitic_inv_delay)) + delay_stages = ceil(required_delay/(delay_fanout+1+self.inv_parasitic_delay)) if delay_stages%2 == 1: #force an even number of stages. delay_stages+=1 #Fanout can be varied as well but is a little more complicated but potentially optimal. @@ -237,7 +244,7 @@ class control_logic(design.design): def get_dynamic_delay_fanout_list(self, previous_stages, previous_fanout): """Determine the size of the delay chain used for the Sense Amp Enable using path delays""" - previous_delay_chain_delay = (previous_fanout+1+self.parasitic_inv_delay)*previous_stages + previous_delay_chain_delay = (previous_fanout+1+self.inv_parasitic_delay)*previous_stages debug.info(2, "Previous delay chain produced {} delay units".format(previous_delay_chain_delay)) fanout_rise = fanout_fall = 2 # This can be anything >=2 @@ -284,9 +291,9 @@ class control_logic(design.design): def calculate_stages_with_fixed_fanout(self, required_delay, fanout): from math import ceil #Delay being negative is not an error. It implies that any amount of stages would have a negative effect on the overall delay - if required_delay <= 3+self.parasitic_inv_delay: #3 is the minimum delay per stage (with pinv=0). + if required_delay <= 3+self.inv_parasitic_delay: #3 is the minimum delay per stage (with pinv=0). return 1 - delay_stages = ceil(required_delay/(fanout+1+self.parasitic_inv_delay)) + delay_stages = ceil(required_delay/(fanout+1+self.inv_parasitic_delay)) return delay_stages def calculate_stage_list(self, total_stages, fanout_rise, fanout_fall): @@ -615,11 +622,9 @@ class control_logic(design.design): mid1 = vector(in_pos.x,out_pos.y) self.add_wire(("metal3","via2","metal2"),[out_pos, mid1, in_pos]) self.add_via_center(layers=("metal1","via1","metal2"), - offset=out_pos, - rotate=90) + offset=out_pos) self.add_via_center(layers=("metal2","via2","metal3"), - offset=out_pos, - rotate=90) + offset=out_pos) def create_pen_row(self): if self.port_type == "rw": @@ -759,8 +764,7 @@ class control_logic(design.design): rail_pos = vector(self.rail_offsets["clk_buf"].x, mid_pos.y) self.add_wire(("metal1","via1","metal2"),[in_pos, mid_pos, rail_pos]) self.add_via_center(layers=("metal1","via1","metal2"), - offset=rail_pos, - rotate=90) + offset=rail_pos) self.copy_layout_pin(self.ctrl_dff_inst, "din_0", "csb") if (self.port_type == "rw"): @@ -850,14 +854,14 @@ class control_logic(design.design): def get_delays_to_wl(self): """Get the delay (in delay units) of the clk to a wordline in the bitcell array""" debug.check(self.sram.all_mods_except_control_done, "Cannot calculate sense amp enable delay unless all module have been added.") - self.wl_stage_efforts = self.determine_wordline_stage_efforts() - clk_to_wl_rise,clk_to_wl_fall = logical_effort.calculate_relative_rise_fall_delays(self.wl_stage_efforts, self.parasitic_inv_delay) + self.wl_stage_efforts = self.get_wordline_stage_efforts() + clk_to_wl_rise,clk_to_wl_fall = logical_effort.calculate_relative_rise_fall_delays(self.wl_stage_efforts) total_delay = clk_to_wl_rise + clk_to_wl_fall debug.info(1, "Clock to wl delay is rise={:.3f}, fall={:.3f}, total={:.3f} in delay units".format(clk_to_wl_rise, clk_to_wl_fall,total_delay)) return clk_to_wl_rise,clk_to_wl_fall - def determine_wordline_stage_efforts(self): + def get_wordline_stage_efforts(self): """Follows the gated_clk_bar -> wl_en -> wordline signal for the total path efforts""" stage_effort_list = [] @@ -871,7 +875,7 @@ class control_logic(design.design): last_stage_is_rise = stage_effort_list[-1].is_rise #Then ask the sram for the other path delays (from the bank) - stage_effort_list += self.sram.determine_wordline_stage_efforts(last_stage_is_rise) + stage_effort_list += self.sram.get_wordline_stage_efforts(last_stage_is_rise) return stage_effort_list @@ -880,17 +884,15 @@ class control_logic(design.design): This does not incorporate the delay of the replica bitline. """ debug.check(self.sram.all_mods_except_control_done, "Cannot calculate sense amp enable delay unless all module have been added.") - self.sen_stage_efforts = self.determine_sa_enable_stage_efforts() - clk_to_sen_rise, clk_to_sen_fall = logical_effort.calculate_relative_rise_fall_delays(self.sen_stage_efforts, self.parasitic_inv_delay) + self.sen_stage_efforts = self.get_sa_enable_stage_efforts() + clk_to_sen_rise, clk_to_sen_fall = logical_effort.calculate_relative_rise_fall_delays(self.sen_stage_efforts) total_delay = clk_to_sen_rise + clk_to_sen_fall debug.info(1, "Clock to s_en delay is rise={:.3f}, fall={:.3f}, total={:.3f} in delay units".format(clk_to_sen_rise, clk_to_sen_fall,total_delay)) return clk_to_sen_rise, clk_to_sen_fall - def determine_sa_enable_stage_efforts(self): + def get_sa_enable_stage_efforts(self): """Follows the gated_clk_bar signal to the sense amp enable signal adding each stages stage effort to a list""" stage_effort_list = [] - #Calculate the load on clk_buf_bar - ext_clk_buf_cout = self.sram.get_clk_bar_cin() #Initial direction of clock signal for this path last_stage_rise = True @@ -917,7 +919,54 @@ class control_logic(design.design): """Gets a list of the stages and delays in order of their path.""" if self.sen_stage_efforts == None or self.wl_stage_efforts == None: debug.error("Model delays not calculated for SRAM.", 1) - wl_delays = logical_effort.calculate_delays(self.wl_stage_efforts, self.parasitic_inv_delay) - sen_delays = logical_effort.calculate_delays(self.sen_stage_efforts, self.parasitic_inv_delay) + wl_delays = logical_effort.calculate_delays(self.wl_stage_efforts) + sen_delays = logical_effort.calculate_delays(self.sen_stage_efforts) return wl_delays, sen_delays + def analytical_delay(self, corner, slew, load): + """Gets the analytical delay from clk input to wl_en output""" + stage_effort_list = [] + #Calculate the load on clk_buf_bar + ext_clk_buf_cout = self.sram.get_clk_bar_cin() + + #Operations logic starts on negative edge + last_stage_rise = False + + #First stage(s), clk -(pdriver)-> clk_buf. + clk_buf_cout = self.replica_bitline.get_en_cin() + stage_effort_list += self.clk_buf_driver.get_stage_efforts(clk_buf_cout, last_stage_rise) + last_stage_rise = stage_effort_list[-1].is_rise + + #Second stage, clk_buf -(inv)-> clk_bar + clk_bar_cout = self.and2.get_cin() + stage_effort_list += self.and2.get_stage_efforts(clk_bar_cout, last_stage_rise) + last_stage_rise = stage_effort_list[-1].is_rise + + #Third stage clk_bar -(and)-> gated_clk_bar + gated_clk_bar_cin = self.get_gated_clk_bar_cin() + stage_effort_list.append(self.inv.get_stage_effort(gated_clk_bar_cin, last_stage_rise)) + last_stage_rise = stage_effort_list[-1].is_rise + + #Stages from gated_clk_bar -------> wordline + stage_effort_list += self.get_wordline_stage_efforts() + return stage_effort_list + + def get_clk_buf_cin(self): + """Get the loads that are connected to the buffered clock. + Includes all the DFFs and some logic.""" + + #Control logic internal load + int_clk_buf_cap = self.inv.get_cin() + self.ctrl_dff_array.get_clk_cin() + self.and2.get_cin() + + #Control logic external load (in the other parts of the SRAM) + ext_clk_buf_cap = self.sram.get_clk_bar_cin() + + return int_clk_buf_cap + ext_clk_buf_cap + + def get_gated_clk_bar_cin(self): + """Get intermediates net gated_clk_bar's capacitance""" + total_cin = 0 + total_cin += self.wl_en_driver.get_cin() + if self.port_type == 'rw': + total_cin +=self.and2.get_cin() + return total_cin \ No newline at end of file diff --git a/compiler/modules/delay_chain.py b/compiler/modules/delay_chain.py index f3d15ba3..188efffa 100644 --- a/compiler/modules/delay_chain.py +++ b/compiler/modules/delay_chain.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# import debug import design from tech import drc diff --git a/compiler/modules/dff.py b/compiler/modules/dff.py index 753ae41a..e1139e09 100644 --- a/compiler/modules/dff.py +++ b/compiler/modules/dff.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# import globals import design from math import log diff --git a/compiler/modules/dff_array.py b/compiler/modules/dff_array.py index 9d11b811..8b03fe19 100644 --- a/compiler/modules/dff_array.py +++ b/compiler/modules/dff_array.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# import debug import design from tech import drc diff --git a/compiler/modules/dff_buf.py b/compiler/modules/dff_buf.py index fa3285ba..42e86bc0 100644 --- a/compiler/modules/dff_buf.py +++ b/compiler/modules/dff_buf.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# import debug import design from tech import drc,parameter diff --git a/compiler/modules/dff_buf_array.py b/compiler/modules/dff_buf_array.py index 56b20dfb..dfd38760 100644 --- a/compiler/modules/dff_buf_array.py +++ b/compiler/modules/dff_buf_array.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# import debug import design from tech import drc diff --git a/compiler/modules/dff_inv.py b/compiler/modules/dff_inv.py index 9b901d3b..2f831570 100644 --- a/compiler/modules/dff_inv.py +++ b/compiler/modules/dff_inv.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# import debug import design from tech import drc diff --git a/compiler/modules/dff_inv_array.py b/compiler/modules/dff_inv_array.py index 624e13d0..3ae50a08 100644 --- a/compiler/modules/dff_inv_array.py +++ b/compiler/modules/dff_inv_array.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# import debug import design from tech import drc diff --git a/compiler/modules/hierarchical_decoder.py b/compiler/modules/hierarchical_decoder.py index bd17b37e..1eac268d 100644 --- a/compiler/modules/hierarchical_decoder.py +++ b/compiler/modules/hierarchical_decoder.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# from tech import drc import debug import design @@ -213,11 +220,9 @@ class hierarchical_decoder(design.design): """ Route a vertical M2 coordinate to another vertical M2 coordinate to the predecode inputs """ self.add_via_center(layers=("metal2", "via2", "metal3"), - offset=input_offset, - rotate=90) + offset=input_offset) self.add_via_center(layers=("metal2", "via2", "metal3"), - offset=output_offset, - rotate=90) + offset=output_offset) self.add_path(("metal3"), [input_offset, output_offset]) @@ -575,8 +580,7 @@ class hierarchical_decoder(design.design): rail_pos = vector(self.predecode_rails[rail_name].x,pin.lc().y) self.add_path("metal1", [rail_pos, pin.lc()]) self.add_via_center(layers=("metal1", "via1", "metal2"), - offset=rail_pos, - rotate=90) + offset=rail_pos) def route_predecode_rail_m3(self, rail_name, pin): @@ -586,12 +590,10 @@ class hierarchical_decoder(design.design): mid_point = vector(pin.cx(), pin.cy()+self.inv.height/2) rail_pos = vector(self.predecode_rails[rail_name].x,mid_point.y) self.add_via_center(layers=("metal1", "via1", "metal2"), - offset=pin.center(), - rotate=90) + offset=pin.center()) self.add_wire(("metal3","via2","metal2"), [rail_pos, mid_point, pin.uc()]) self.add_via_center(layers=("metal2", "via2", "metal3"), - offset=rail_pos, - rotate=90) + offset=rail_pos) def analytical_delay(self, corner, slew, load = 0.0): diff --git a/compiler/modules/hierarchical_predecode.py b/compiler/modules/hierarchical_predecode.py index 147c3018..0449280a 100644 --- a/compiler/modules/hierarchical_predecode.py +++ b/compiler/modules/hierarchical_predecode.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# import debug import design import math @@ -178,11 +185,9 @@ class hierarchical_predecode(design.design): a_pos = vector(self.decode_rails[a_pin].x,y_offset) self.add_path("metal1",[in_pos, a_pos]) self.add_via_center(layers = ("metal1", "via1", "metal2"), - offset=[self.input_rails[in_pin].x, y_offset], - rotate=90) + offset=[self.input_rails[in_pin].x, y_offset]) self.add_via_center(layers = ("metal1", "via1", "metal2"), - offset=[self.decode_rails[a_pin].x, y_offset], - rotate=90) + offset=[self.decode_rails[a_pin].x, y_offset]) def route_output_inverters(self): """ @@ -223,8 +228,7 @@ class hierarchical_predecode(design.design): rail_pos = vector(self.decode_rails[out_pin].x,y_offset) self.add_path("metal1", [inv_out_pos, right_pos, vector(right_pos.x, y_offset), rail_pos]) self.add_via_center(layers = ("metal1", "via1", "metal2"), - offset=rail_pos, - rotate=90) + offset=rail_pos) #route input @@ -232,8 +236,7 @@ class hierarchical_predecode(design.design): in_pos = vector(self.input_rails[in_pin].x,inv_in_pos.y) self.add_path("metal1", [in_pos, inv_in_pos]) self.add_via_center(layers=("metal1", "via1", "metal2"), - offset=in_pos, - rotate=90) + offset=in_pos) def route_nand_to_rails(self): @@ -254,8 +257,8 @@ class hierarchical_predecode(design.design): rail_pos = vector(self.decode_rails[rail_pin].x, pin_pos.y) self.add_path("metal1", [rail_pos, pin_pos]) self.add_via_center(layers=("metal1", "via1", "metal2"), - offset=rail_pos, - rotate=90) + offset=rail_pos) + diff --git a/compiler/modules/hierarchical_predecode2x4.py b/compiler/modules/hierarchical_predecode2x4.py index f50a43c1..938196d3 100644 --- a/compiler/modules/hierarchical_predecode2x4.py +++ b/compiler/modules/hierarchical_predecode2x4.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# from tech import drc import debug import design diff --git a/compiler/modules/hierarchical_predecode3x8.py b/compiler/modules/hierarchical_predecode3x8.py index 820427c7..77d9ce01 100644 --- a/compiler/modules/hierarchical_predecode3x8.py +++ b/compiler/modules/hierarchical_predecode3x8.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# from tech import drc import debug import design diff --git a/compiler/modules/multibank.py b/compiler/modules/multibank.py index 15882f8b..667c6380 100644 --- a/compiler/modules/multibank.py +++ b/compiler/modules/multibank.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# import sys from tech import drc, parameter import debug diff --git a/compiler/modules/precharge_array.py b/compiler/modules/precharge_array.py index 67581e1a..f88938c8 100644 --- a/compiler/modules/precharge_array.py +++ b/compiler/modules/precharge_array.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# import design import debug from tech import drc diff --git a/compiler/modules/replica_bitline.py b/compiler/modules/replica_bitline.py index 8d93b257..acd1f5d0 100644 --- a/compiler/modules/replica_bitline.py +++ b/compiler/modules/replica_bitline.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# import debug import design from tech import drc @@ -39,8 +46,8 @@ class replica_bitline(design.design): #self.add_lvs_correspondence_points() # Extra pitch on top and right - self.width = self.rbl_inst.rx() - self.dc_inst.lx() + self.m2_pitch - self.height = max(self.rbl_inst.uy(), self.dc_inst.uy()) + self.m3_pitch + self.width = self.replica_column_inst.rx() - self.delay_chain_inst.lx() + self.m2_pitch + self.height = max(self.replica_column_inst.uy(), self.delay_chain_inst.uy()) + self.m3_pitch self.DRC_LVS() @@ -111,12 +118,12 @@ class replica_bitline(design.design): self.connect_inst(["vdd", "delayed_en", "bl0_0", "vdd"]) # add the well and poly contact - self.dc_inst=self.add_inst(name="delay_chain", - mod=self.delay_chain) + self.delay_chain_inst=self.add_inst(name="delay_chain", + mod=self.delay_chain) self.connect_inst(["en", "delayed_en", "vdd", "gnd"]) - self.rbc_inst=self.add_inst(name="bitcell", - mod=self.replica_bitcell) + self.replica_cell_inst=self.add_inst(name="bitcell", + mod=self.replica_bitcell) temp = [] for port in self.all_ports: temp.append("bl{}_0".format(port)) @@ -127,8 +134,8 @@ class replica_bitline(design.design): temp.append("gnd") self.connect_inst(temp) - self.rbl_inst=self.add_inst(name="load", - mod=self.rbl) + self.replica_column_inst=self.add_inst(name="load", + mod=self.rbl) temp = [] for port in self.all_ports: @@ -153,12 +160,12 @@ class replica_bitline(design.design): self.tx_inst.place(self.access_tx_offset) - self.dc_inst.place(self.delay_chain_offset) + self.delay_chain_inst.place(self.delay_chain_offset) - self.rbc_inst.place(offset=self.bitcell_offset, + self.replica_cell_inst.place(offset=self.bitcell_offset, mirror="MX") - self.rbl_inst.place(self.rbl_offset) + self.replica_column_inst.place(self.rbl_offset) def route(self): @@ -172,7 +179,7 @@ class replica_bitline(design.design): # Connect the WL and gnd pins directly to the center and right gnd rails for row in range(self.bitcell_loads): wl = self.wl_list[0]+"_{}".format(row) - pin = self.rbl_inst.get_pin(wl) + pin = self.replica_column_inst.get_pin(wl) # Route the connection to the right so that it doesn't interfere with the cells # Wordlines may be close to each other when tiled, so gnd connections are routed in opposite directions @@ -188,7 +195,7 @@ class replica_bitline(design.design): # for multiport, need to short wordlines to each other so they all connect to gnd. wl_last = self.wl_list[-1]+"_{}".format(row) - pin_last = self.rbl_inst.get_pin(wl_last) + pin_last = self.replica_column_inst.get_pin(wl_last) self.short_wordlines(pin, pin_last, "right", False, row, vector(self.m3_pitch,0)) def short_wordlines(self, wl_pin_a, wl_pin_b, pin_side, is_replica_cell, cell_row=0, offset_x_vec=None): @@ -229,10 +236,10 @@ class replica_bitline(design.design): for port in self.all_ports: if is_replica_cell: wl = self.wl_list[port] - pin = self.rbc_inst.get_pin(wl) + pin = self.replica_cell_inst.get_pin(wl) else: wl = self.wl_list[port]+"_{}".format(cell_row) - pin = self.rbl_inst.get_pin(wl) + pin = self.replica_column_inst.get_pin(wl) if pin_side == "left": self.add_path("metal1", [pin.lc()-correct_x, pin.lc()]) @@ -245,8 +252,8 @@ class replica_bitline(design.design): """ Propagate all vdd/gnd pins up to this level for all modules """ # These are the instances that every bank has - top_instances = [self.rbl_inst, - self.dc_inst] + top_instances = [self.replica_column_inst, + self.delay_chain_inst] for inst in top_instances: self.copy_layout_pin(inst, "vdd") self.copy_layout_pin(inst, "gnd") @@ -257,11 +264,11 @@ class replica_bitline(design.design): pin = self.rbl_inv_inst.get_pin("vdd") self.add_power_pin("vdd", pin.lc()) - pin=self.rbc_inst.get_pin("vdd") - self.add_power_pin("vdd", pin.center(), 0, pin.layer) + for pin in self.replica_cell_inst.get_pins("vdd"): + self.add_power_pin(name="vdd", loc=pin.center(), vertical=True, start_layer=pin.layer) - for pin in self.rbc_inst.get_pins("gnd"): - self.add_power_pin("gnd", pin.center()) + for pin in self.replica_cell_inst.get_pins("gnd"): + self.add_power_pin("gnd", pin.center(), vertical=True, start_layer=pin.layer) @@ -275,10 +282,10 @@ class replica_bitline(design.design): poly_offset = poly_pin.uc() # This centers the contact above the poly by one pitch contact_offset = poly_offset + vector(0,self.m2_pitch) - self.add_contact_center(layers=("poly", "contact", "metal1"), - offset=contact_offset) - self.add_contact_center(layers=("metal1", "via1", "metal2"), - offset=contact_offset) + self.add_via_center(layers=("poly", "contact", "metal1"), + offset=contact_offset) + self.add_via_center(layers=("metal1", "via1", "metal2"), + offset=contact_offset) self.add_segment_center(layer="poly", start=poly_offset, end=contact_offset) @@ -289,12 +296,12 @@ class replica_bitline(design.design): # height=self.delay_chain_offset.y-nwell_offset.y) # 2. Route delay chain output to access tx gate - delay_en_offset = self.dc_inst.get_pin("out").bc() + delay_en_offset = self.delay_chain_inst.get_pin("out").bc() self.add_path("metal2", [delay_en_offset,contact_offset]) # 3. Route the contact of previous route to the bitcell WL # route bend of previous net to bitcell WL - wl_offset = self.rbc_inst.get_pin(self.wl_list[0]).lc() + wl_offset = self.replica_cell_inst.get_pin(self.wl_list[0]).lc() wl_mid1 = wl_offset - vector(1.5*drc("minwidth_metal1"), 0) wl_mid2 = vector(wl_mid1.x, contact_offset.y) #xmid_point= 0.5*(wl_offset.x+contact_offset.x) @@ -305,8 +312,8 @@ class replica_bitline(design.design): # 4. Short wodlines if multiport wl = self.wl_list[0] wl_last = self.wl_list[-1] - pin = self.rbc_inst.get_pin(wl) - pin_last = self.rbc_inst.get_pin(wl_last) + pin = self.replica_cell_inst.get_pin(wl) + pin_last = self.replica_cell_inst.get_pin(wl_last) x_offset = self.short_wordlines(pin, pin_last, "left", True) #correct = vector(0.5*drc("minwidth_metal1"), 0) @@ -315,7 +322,7 @@ class replica_bitline(design.design): # DRAIN ROUTE # Route the drain to the vdd rail drain_offset = self.tx_inst.get_pin("D").center() - self.add_power_pin("vdd", drain_offset, rotate=0) + self.add_power_pin("vdd", drain_offset, vertical=True) # SOURCE ROUTE # Route the drain to the RBL inverter input @@ -325,7 +332,7 @@ class replica_bitline(design.design): # Route the connection of the source route to the RBL bitline (left) # Via will go halfway down from the bitcell - bl_offset = self.rbc_inst.get_pin(self.bl_list[0]).bc() + bl_offset = self.replica_cell_inst.get_pin(self.bl_list[0]).bc() # Route down a pitch so we can use M2 routing bl_down_offset = bl_offset - vector(0, self.m2_pitch) self.add_path("metal2",[source_offset, bl_down_offset, bl_offset]) @@ -344,12 +351,12 @@ class replica_bitline(design.design): def route_vdd(self): """ Route all signals connected to vdd """ - self.copy_layout_pin(self.dc_inst,"vdd") - self.copy_layout_pin(self.rbc_inst,"vdd") + self.copy_layout_pin(self.delay_chain_inst,"vdd") + self.copy_layout_pin(self.replica_cell_inst,"vdd") # Connect the WL and vdd pins directly to the center and right vdd rails # Connect RBL vdd pins to center and right rails - rbl_vdd_pins = self.rbl_inst.get_pins("vdd") + rbl_vdd_pins = self.replica_column_inst.get_pins("vdd") for pin in rbl_vdd_pins: if pin.layer != "metal1": continue @@ -360,11 +367,9 @@ class replica_bitline(design.design): start=start, end=end) self.add_via_center(layers=("metal1", "via1", "metal2"), - offset=start, - rotate=90) + offset=start) self.add_via_center(layers=("metal1", "via1", "metal2"), - offset=end, - rotate=90) + offset=end) # Add via for the inverter pin = self.rbl_inv_inst.get_pin("vdd") @@ -374,38 +379,34 @@ class replica_bitline(design.design): start=start, end=end) self.add_via_center(layers=("metal1", "via1", "metal2"), - offset=start, - rotate=90) + offset=start) self.add_via_center(layers=("metal1", "via1", "metal2"), - offset=end, - rotate=90) + offset=end) # Add via for the RBC - pin = self.rbc_inst.get_pin("vdd") + pin = self.replica_cell_inst.get_pin("vdd") start = pin.lc() end = vector(self.right_vdd_pin.cx(),pin.cy()) self.add_segment_center(layer="metal1", start=start, end=end) self.add_via_center(layers=("metal1", "via1", "metal2"), - offset=end, - rotate=90) + offset=end) # Create the RBL rails too - rbl_pins = self.rbl_inst.get_pins("vdd") + rbl_pins = self.replica_column_inst.get_pins("vdd") for pin in rbl_pins: if pin.layer != "metal1": continue # If above the delay line, route the full width left = vector(self.left_vdd_pin.cx(),pin.cy()) center = vector(self.center_vdd_pin.cx(),pin.cy()) - if pin.cy() > self.dc_inst.uy() + self.m1_pitch: + if pin.cy() > self.delay_chain_inst.uy() + self.m1_pitch: start = left self.add_via_center(layers=("metal1", "via1", "metal2"), - offset=left, - rotate=90) + offset=left) else: start = center end = vector(self.right_vdd_pin.cx()+0.5*self.m1_width,pin.cy()) @@ -425,22 +426,22 @@ class replica_bitline(design.design): # Route the gnd lines from left to right # Add via for the delay chain - left_gnd_start = self.dc_inst.ll().scale(1,0) - vector(2*self.m2_pitch,0) - left_gnd_end = vector(left_gnd_start.x, self.rbl_inst.uy()+self.m2_pitch) + left_gnd_start = self.delay_chain_inst.ll().scale(1,0) - vector(2*self.m2_pitch,0) + left_gnd_end = vector(left_gnd_start.x, self.replica_column_inst.uy()+self.m2_pitch) self.left_gnd_pin=self.add_segment_center(layer="metal2", start=left_gnd_start, end=left_gnd_end) # Gnd line to the left of the replica bitline - center_gnd_start = self.rbc_inst.ll().scale(1,0) - vector(2*self.m2_pitch,0) - center_gnd_end = vector(center_gnd_start.x, self.rbl_inst.uy()+self.m2_pitch) + center_gnd_start = self.replica_cell_inst.ll().scale(1,0) - vector(2*self.m2_pitch,0) + center_gnd_end = vector(center_gnd_start.x, self.replica_column_inst.uy()+self.m2_pitch) self.center_gnd_pin=self.add_segment_center(layer="metal2", start=center_gnd_start, end=center_gnd_end) # Gnd line to the right of the replica bitline - right_gnd_start = self.rbc_inst.lr().scale(1,0) + vector(self.m2_pitch,0) - right_gnd_end = vector(right_gnd_start.x, self.rbl_inst.uy()+self.m2_pitch) + right_gnd_start = self.replica_cell_inst.lr().scale(1,0) + vector(self.m2_pitch,0) + right_gnd_end = vector(right_gnd_start.x, self.replica_column_inst.uy()+self.m2_pitch) self.right_gnd_pin=self.add_segment_center(layer="metal2", start=right_gnd_start, end=right_gnd_end) @@ -450,13 +451,13 @@ class replica_bitline(design.design): # Connect the WL and gnd pins directly to the center and right gnd rails for row in range(self.bitcell_loads): wl = self.wl_list[0]+"_{}".format(row) - pin = self.rbl_inst.get_pin(wl) + pin = self.replica_column_inst.get_pin(wl) if pin.layer != "metal1": continue # If above the delay line, route the full width left = vector(self.left_gnd_pin.cx(),pin.cy()) center = vector(self.center_gnd_pin.cx(),pin.cy()) - if pin.cy() > self.dc_inst.uy() + self.m1_pitch: + if pin.cy() > self.delay_chain_inst.uy() + self.m1_pitch: start = left else: start = center @@ -467,47 +468,41 @@ class replica_bitline(design.design): end=end) if start == left: self.add_via_center(layers=("metal1", "via1", "metal2"), - offset=left, - rotate=90) + offset=left) self.add_via_center(layers=("metal1", "via1", "metal2"), - offset=center, - rotate=90) + offset=center) self.add_via_center(layers=("metal1", "via1", "metal2"), - offset=end, - rotate=90) + offset=end) - rbl_gnd_pins = self.rbl_inst.get_pins("gnd") - # Add L shapes to each vertical gnd rail - for pin in rbl_gnd_pins: - if pin.layer != "metal1": - continue - # If above the delay line, route the full width - left = vector(self.left_gnd_pin.cx(),pin.cy()) - center = vector(self.center_gnd_pin.cx(),pin.cy()) - if pin.cy() > self.dc_inst.uy() + self.m1_pitch: - start = left - else: - start = center - end = vector(self.right_gnd_pin.cx(),pin.cy()) - self.add_segment_center(layer="metal1", - start=start, - end=end) - if start == left: - self.add_via_center(layers=("metal1", "via1", "metal2"), - offset=left, - rotate=90) - self.add_via_center(layers=("metal1", "via1", "metal2"), - offset=center, - rotate=90) - self.add_via_center(layers=("metal1", "via1", "metal2"), - offset=end, - rotate=90) + # rbl_gnd_pins = self.replica_column_inst.get_pins("gnd") + # # Add L shapes to each vertical gnd rail + # for pin in rbl_gnd_pins: + # if pin.layer != "metal1": + # continue + # # If above the delay line, route the full width + # left = vector(self.left_gnd_pin.cx(),pin.cy()) + # center = vector(self.center_gnd_pin.cx(),pin.cy()) + # if pin.cy() > self.delay_chain_inst.uy() + self.m1_pitch: + # start = left + # else: + # start = center + # end = vector(self.right_gnd_pin.cx(),pin.cy()) + # self.add_segment_center(layer="metal1", + # start=start, + # end=end) + # if start == left: + # self.add_via_center(layers=("metal1", "via1", "metal2"), + # offset=left) + # self.add_via_center(layers=("metal1", "via1", "metal2"), + # offset=center) + # self.add_via_center(layers=("metal1", "via1", "metal2"), + # offset=end) # Connect the gnd pins of the delay chain to the left rails - dc_gnd_pins = self.dc_inst.get_pins("gnd") + dc_gnd_pins = self.delay_chain_inst.get_pins("gnd") for pin in dc_gnd_pins: if pin.layer != "metal1": continue @@ -520,12 +515,10 @@ class replica_bitline(design.design): start=start, end=end) self.add_via_center(layers=("metal1", "via1", "metal2"), - offset=start, - rotate=90) + offset=start) # self.add_via_center(layers=("metal1", "via1", "metal2"), - # offset=end, - #rotate=90) + # offset=end) # Add via for the inverter @@ -536,16 +529,14 @@ class replica_bitline(design.design): # start=start, # end=end) # self.add_via_center(layers=("metal1", "via1", "metal2"), - # offset=start, - #rotate=90) + # offset=start) # self.add_via_center(layers=("metal1", "via1", "metal2"), - # offset=end, - #rotate=90) + # offset=end) # Create RBL rails too - rbl_pins = self.rbl_inst.get_pins("gnd") + rbl_pins = self.replica_column_inst.get_pins("gnd") for pin in rbl_pins: if pin.layer != "metal2": continue @@ -560,7 +551,7 @@ class replica_bitline(design.design): def add_layout_pins(self): """ Route the input and output signal """ - en_offset = self.dc_inst.get_pin("in").bc() + en_offset = self.delay_chain_inst.get_pin("in").bc() self.add_layout_pin_segment_center(text="en", layer="metal2", start=en_offset, @@ -587,7 +578,7 @@ class replica_bitline(design.design): height=pin.height(), width=pin.width()) - pin = self.dc_inst.get_pin("out") + pin = self.delay_chain_inst.get_pin("out") self.add_label_pin(text="delayed_en", layer=pin.layer, offset=pin.ll(), diff --git a/compiler/modules/sense_amp.py b/compiler/modules/sense_amp.py index 0c959685..8267f42f 100644 --- a/compiler/modules/sense_amp.py +++ b/compiler/modules/sense_amp.py @@ -1,7 +1,15 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# import design import debug import utils from tech import GDS,layer, parameter,drc +import logical_effort class sense_amp(design.design): """ @@ -31,12 +39,13 @@ class sense_amp(design.design): bitline_pmos_size = 8 #FIXME: This should be set somewhere and referenced. Probably in tech file. return spice["min_tx_drain_c"]*(bitline_pmos_size/parameter["min_tx_size"])#ff - def analytical_delay(self, corner, slew, load=0.0): - from tech import spice - r = spice["min_tx_r"]/(10) - c_para = spice["min_tx_drain_c"] - result = self.cal_delay_with_rc(corner, r = r, c = c_para+load, slew = slew) - return self.return_delay(result.delay, result.slew) + def analytical_delay(self, corner, slew, load): + #Delay of the sense amp will depend on the size of the amp and the output load. + parasitic_delay = 1 + cin = (parameter["sa_inv_pmos_size"] + parameter["sa_inv_nmos_size"])/drc("minwidth_tx") + sa_size = parameter["sa_inv_nmos_size"]/drc("minwidth_tx") + cc_inv_cin = cin + return logical_effort.logical_effort('column_mux', sa_size, cin, load+cc_inv_cin, parasitic_delay, False) def analytical_power(self, corner, load): """Returns dynamic and leakage power. Results in nW""" diff --git a/compiler/modules/sense_amp_array.py b/compiler/modules/sense_amp_array.py index 47969fd1..4dfa03ad 100644 --- a/compiler/modules/sense_amp_array.py +++ b/compiler/modules/sense_amp_array.py @@ -1,9 +1,17 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# import design from tech import drc from vector import vector from sram_factory import factory import debug from globals import OPTS +import logical_effort class sense_amp_array(design.design): """ @@ -136,10 +144,17 @@ class sense_amp_array(design.design): def input_load(self): return self.amp.input_load() - def analytical_delay(self, corner, slew, load=0.0): - return self.amp.analytical_delay(corner, slew=slew, load=load) + def analytical_delay(self, corner, slew, load): + return [self.amp.analytical_delay(corner, slew=slew, load=load)] def get_en_cin(self): """Get the relative capacitance of all the sense amp enable connections in the array""" sense_amp_en_cin = self.amp.get_en_cin() return sense_amp_en_cin * self.word_size + + def get_drain_cin(self): + """Get the relative capacitance of the drain of the PMOS isolation TX""" + from tech import parameter + #Bitcell drain load being used to estimate PMOS drain load + drain_load = logical_effort.convert_farad_to_relative_c(parameter['bitcell_drain_cap']) + return drain_load diff --git a/compiler/modules/single_level_column_mux_array.py b/compiler/modules/single_level_column_mux_array.py index 57d2cd54..435f0cbe 100644 --- a/compiler/modules/single_level_column_mux_array.py +++ b/compiler/modules/single_level_column_mux_array.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# from math import log import design import contact @@ -7,6 +14,7 @@ import math from vector import vector from sram_factory import factory from globals import OPTS +import logical_effort class single_level_column_mux_array(design.design): """ @@ -130,8 +138,7 @@ class single_level_column_mux_array(design.design): self.add_layout_pin(text="sel_{}".format(j), layer="metal1", offset=offset, - width=self.mux.width * self.columns, - height=contact.m1m2.width) + width=self.mux.width * self.columns) def add_vertical_poly_rail(self): """ Connect the poly to the address rails """ @@ -148,82 +155,72 @@ class single_level_column_mux_array(design.design): offset = vector(gate_offset.x,self.get_pin("sel_{}".format(sel_index)).cy()) # Add the poly contact with a shift to account for the rotation self.add_via_center(layers=("metal1", "contact", "poly"), - offset=offset, - rotate=90) + offset=offset) self.add_path("poly", [offset, gate_offset]) def route_bitlines(self): """ Connect the output bit-lines to form the appropriate width mux """ for j in range(self.columns): - bl_offset = self.mux_inst[j].get_pin("bl_out").ll() - br_offset = self.mux_inst[j].get_pin("br_out").ll() + bl_offset = self.mux_inst[j].get_pin("bl_out").bc() + br_offset = self.mux_inst[j].get_pin("br_out").bc() bl_out_offset = bl_offset - vector(0,(self.words_per_row+1)*self.m1_pitch) br_out_offset = br_offset - vector(0,(self.words_per_row+2)*self.m1_pitch) + bl_out_offset_end = bl_out_offset + vector(0,self.route_height) + br_out_offset_end = br_out_offset + vector(0,self.route_height) + if (j % self.words_per_row) == 0: # Create the metal1 to connect the n-way mux output from the pass gate # These will be located below the select lines. Yes, these are M2 width # to ensure vias are enclosed and M1 min width rules. - width = contact.m1m2.width + self.mux.width * (self.words_per_row - 1) - self.add_rect(layer="metal1", - offset=bl_out_offset, - width=width, - height=drc("minwidth_metal2")) - self.add_rect(layer="metal1", - offset=br_out_offset, - width=width, - height=drc("minwidth_metal2")) - + width = self.m2_width + self.mux.width * (self.words_per_row - 1) + self.add_path("metal1", [bl_out_offset, bl_out_offset+vector(width,0)]) + self.add_path("metal1", [br_out_offset, br_out_offset+vector(width,0)]) # Extend the bitline output rails and gnd downward on the first bit of each n-way mux - self.add_layout_pin(text="bl_out_{}".format(int(j/self.words_per_row)), - layer="metal2", - offset=bl_out_offset.scale(1,0), - width=drc('minwidth_metal2'), - height=self.route_height) - self.add_layout_pin(text="br_out_{}".format(int(j/self.words_per_row)), - layer="metal2", - offset=br_out_offset.scale(1,0), - width=drc('minwidth_metal2'), - height=self.route_height) + self.add_layout_pin_segment_center(text="bl_out_{}".format(int(j/self.words_per_row)), + layer="metal2", + start=bl_out_offset, + end=bl_out_offset_end) + self.add_layout_pin_segment_center(text="br_out_{}".format(int(j/self.words_per_row)), + layer="metal2", + start=br_out_offset, + end=br_out_offset_end) + # This via is on the right of the wire - self.add_via(layers=("metal1", "via1", "metal2"), - offset=bl_out_offset + vector(contact.m1m2.height,0), - rotate=90) + self.add_via_center(layers=("metal1", "via1", "metal2"), + offset=bl_out_offset) + # This via is on the left of the wire - self.add_via(layers=("metal1", "via1", "metal2"), - offset= br_out_offset, - rotate=90) + self.add_via_center(layers=("metal1", "via1", "metal2"), + offset=br_out_offset) else: - self.add_rect(layer="metal2", - offset=bl_out_offset, - width=drc('minwidth_metal2'), - height=self.route_height-bl_out_offset.y) + self.add_path("metal2", [ bl_out_offset, bl_out_offset_end]) + self.add_path("metal2", [ br_out_offset, br_out_offset_end]) + # This via is on the right of the wire - self.add_via(layers=("metal1", "via1", "metal2"), - offset=bl_out_offset + vector(contact.m1m2.height,0), - rotate=90) - self.add_rect(layer="metal2", - offset=br_out_offset, - width=drc('minwidth_metal2'), - height=self.route_height-br_out_offset.y) + self.add_via_center(layers=("metal1", "via1", "metal2"), + offset=bl_out_offset) # This via is on the left of the wire - self.add_via(layers=("metal1", "via1", "metal2"), - offset= br_out_offset, - rotate=90) + self.add_via_center(layers=("metal1", "via1", "metal2"), + offset=br_out_offset) - def analytical_delay(self, corner, vdd, slew, load=0.0): - from tech import spice, parameter - proc,vdd,temp = corner - r = spice["min_tx_r"]/(self.mux.ptx_width/parameter["min_tx_size"]) - #Drains of mux transistors make up capacitance. - c_para = spice["min_tx_drain_c"]*(self.mux.ptx_width/parameter["min_tx_size"])*self.words_per_row#ff - volt_swing = spice["v_threshold_typical"]/vdd + + def analytical_delay(self, corner, slew, load): + from tech import parameter + """Returns relative delay that the column mux adds""" + #Single level column mux will add parasitic loads from other mux pass transistors and the sense amp. + drain_load = logical_effort.convert_farad_to_relative_c(parameter['bitcell_drain_cap']) + array_load = drain_load*self.words_per_row + return [self.mux.analytical_delay(corner, slew, load+array_load)] - result = self.cal_delay_with_rc(corner, r = r, c = c_para+load, slew = slew, swing = volt_swing) - return self.return_delay(result.delay, result.slew) - + def get_drain_cin(self): + """Get the relative capacitance of the drain of the NMOS pass TX""" + from tech import parameter + #Bitcell drain load being used to estimate mux NMOS drain load + drain_load = logical_effort.convert_farad_to_relative_c(parameter['bitcell_drain_cap']) + return drain_load diff --git a/compiler/modules/tri_gate.py b/compiler/modules/tri_gate.py index 688b3644..e5951a53 100644 --- a/compiler/modules/tri_gate.py +++ b/compiler/modules/tri_gate.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# import debug import design import utils diff --git a/compiler/modules/tri_gate_array.py b/compiler/modules/tri_gate_array.py index 913c6097..e3eb42cb 100644 --- a/compiler/modules/tri_gate_array.py +++ b/compiler/modules/tri_gate_array.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# import debug from tech import drc import design diff --git a/compiler/modules/wordline_driver.py b/compiler/modules/wordline_driver.py index 6ddba9de..dbef0417 100644 --- a/compiler/modules/wordline_driver.py +++ b/compiler/modules/wordline_driver.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# from tech import drc, parameter import debug import design @@ -81,21 +88,13 @@ class wordline_driver(design.design): (gate_offset, y_dir) = self.get_gate_offset(0, self.inv.height, num) # Route both supplies - for n in ["vdd", "gnd"]: - supply_pin = self.inv2_inst[num].get_pin(n) + for name in ["vdd", "gnd"]: + supply_pin = self.inv2_inst[num].get_pin(name) # Add pins in two locations for xoffset in [a_xoffset, b_xoffset]: pin_pos = vector(xoffset, supply_pin.cy()) - self.add_via_center(layers=("metal1", "via1", "metal2"), - offset=pin_pos, - rotate=90) - self.add_via_center(layers=("metal2", "via2", "metal3"), - offset=pin_pos, - rotate=90) - self.add_layout_pin_rect_center(text=n, - layer="metal3", - offset=pin_pos) + self.add_power_pin(name, pin_pos) @@ -193,13 +192,14 @@ class wordline_driver(design.design): start=input_offset, end=mid_via_offset) self.add_via_center(layers=("metal1", "via1", "metal2"), - offset=mid_via_offset) + offset=mid_via_offset, + directions=("V","V")) # now connect to the nand2 B self.add_path("metal2", [mid_via_offset, b_pos]) self.add_via_center(layers=("metal1", "via1", "metal2"), offset=b_pos - vector(0.5*contact.m1m2.height,0), - rotate=90) + directions=("H","H")) # output each WL on the right diff --git a/compiler/modules/write_driver.py b/compiler/modules/write_driver.py index 34c51245..bbe676c0 100644 --- a/compiler/modules/write_driver.py +++ b/compiler/modules/write_driver.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# import debug import design import utils diff --git a/compiler/modules/write_driver_array.py b/compiler/modules/write_driver_array.py index 3367cc00..27da84b0 100644 --- a/compiler/modules/write_driver_array.py +++ b/compiler/modules/write_driver_array.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# from math import log import design from tech import drc diff --git a/compiler/openram.py b/compiler/openram.py index 555f2c8e..daef3b9c 100755 --- a/compiler/openram.py +++ b/compiler/openram.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ SRAM Compiler diff --git a/compiler/options.py b/compiler/options.py index a6e5726a..b3ac813a 100644 --- a/compiler/options.py +++ b/compiler/options.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# import optparse import getpass import os diff --git a/compiler/pgates/pand2.py b/compiler/pgates/pand2.py index 54787282..add59565 100644 --- a/compiler/pgates/pand2.py +++ b/compiler/pgates/pand2.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# import debug from tech import drc from math import log @@ -11,16 +18,13 @@ class pand2(pgate.pgate): This is a simple buffer used for driving loads. """ def __init__(self, name, size=1, height=None): - self.size = size - - pgate.pgate.__init__(self, name, height) - debug.info(1, "Creating {}".format(self.name)) + debug.info(1, "reating pnand2 {}".format(name)) self.add_comment("size: {}".format(size)) - self.create_netlist() - if not OPTS.netlist_only: - self.create_layout() - + self.size = size + + # Creates the netlist and layout + pgate.pgate.__init__(self, name, height) def create_netlist(self): self.add_pins() @@ -40,6 +44,7 @@ class pand2(pgate.pgate): self.place_insts() self.add_wires() self.add_layout_pins() + self.DRC_LVS() def add_pins(self): self.add_pin("A") @@ -125,3 +130,8 @@ class pand2(pgate.pgate): stage_effort_list.append(stage2) return stage_effort_list + + def get_cin(self): + """Return the relative input capacitance of a single input""" + return self.nand.get_cin() + diff --git a/compiler/pgates/pbuf.py b/compiler/pgates/pbuf.py index 9d73c004..f34a1827 100644 --- a/compiler/pgates/pbuf.py +++ b/compiler/pgates/pbuf.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# import debug from tech import drc from math import log @@ -12,17 +19,15 @@ class pbuf(pgate.pgate): """ def __init__(self, name, size=4, height=None): + debug.info(1, "creating {0} with size of {1}".format(name,size)) + self.add_comment("size: {}".format(size)) + self.stage_effort = 4 self.size = size self.height = height + # Creates the netlist and layout pgate.pgate.__init__(self, name, height) - debug.info(1, "creating {0} with size of {1}".format(self.name,self.size)) - self.add_comment("size: {}".format(size)) - - self.create_netlist() - if not OPTS.netlist_only: - self.create_layout() def create_netlist(self): diff --git a/compiler/pgates/pdriver.py b/compiler/pgates/pdriver.py index daf4d334..39428515 100644 --- a/compiler/pgates/pdriver.py +++ b/compiler/pgates/pdriver.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# import debug import pgate import math @@ -13,27 +20,24 @@ class pdriver(pgate.pgate): """ def __init__(self, name, neg_polarity=False, fanout=0, size_list=None, height=None): + debug.info(1, "creating pdriver {}".format(name)) + self.stage_effort = 3 self.height = height self.neg_polarity = neg_polarity self.size_list = size_list self.fanout = fanout + if size_list == None and self.fanout == 0: + debug.error("Either fanout or size list must be specified.", -1) if self.size_list and self.fanout != 0: debug.error("Cannot specify both size_list and fanout.", -1) if self.size_list and self.neg_polarity: debug.error("Cannot specify both size_list and neg_polarity.", -1) + # Creates the netlist and layout pgate.pgate.__init__(self, name, height) - debug.info(1, "Creating {}".format(self.name)) - self.compute_sizes() - - self.add_comment("sizes: {}".format(str(self.size_list))) - - self.create_netlist() - if not OPTS.netlist_only: - self.create_layout() def compute_sizes(self): # size_list specified @@ -61,6 +65,8 @@ class pdriver(pgate.pgate): def create_netlist(self): + self.compute_sizes() + self.add_comment("sizes: {}".format(str(self.size_list))) self.add_pins() self.add_modules() self.create_insts() @@ -73,7 +79,6 @@ class pdriver(pgate.pgate): self.width = self.inv_inst_list[-1].rx() self.height = self.inv_inst_list[0].height - self.DRC_LVS() def add_pins(self): self.add_pin("A") diff --git a/compiler/pgates/pgate.py b/compiler/pgates/pgate.py index 2f641da9..57b73a21 100644 --- a/compiler/pgates/pgate.py +++ b/compiler/pgates/pgate.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# import contact import design import debug @@ -21,7 +28,20 @@ class pgate(design.design): b = factory.create(module_type="bitcell") self.height = b.height + self.create_netlist() + if not OPTS.netlist_only: + self.create_layout() + self.DRC_LVS() + + def create_netlist(): + """ Pure virtual function """ + debug.error("Must over-ride create_netlist.",-1) + + def create_layout(): + """ Pure virtual function """ + debug.error("Must over-ride create_layout.",-1) + def connect_pin_to_rail(self,inst,pin,supply): """ Connects a ptx pin to a supply rail. """ source_pin = inst.get_pin(pin) @@ -42,7 +62,7 @@ class pgate(design.design): height=height, width=source_pin.width()) - def route_input_gate(self, pmos_inst, nmos_inst, ypos, name, position="left", rotate=90): + def route_input_gate(self, pmos_inst, nmos_inst, ypos, name, position="left", rotate=False): """ Route the input gate to the left side of the cell for access. Position specifies to place the contact the left, center, or right of gate. """ @@ -61,17 +81,21 @@ class pgate(design.design): left_gate_offset = vector(nmos_gate_pin.lx(),ypos) # Center is completely symmetric. - if rotate==90: + if rotate: contact_width = contact.poly.height contact_m1_width = contact.poly.second_layer_height contact_m1_height = contact.poly.second_layer_width + directions = ("H","V") else: contact_width = contact.poly.width contact_m1_width = contact.poly.second_layer_width contact_m1_height = contact.poly.second_layer_height + directions = ("V","H") if position=="center": contact_offset = left_gate_offset + vector(0.5*self.poly_width, 0) + elif position=="farleft": + contact_offset = left_gate_offset - vector(0.5*contact.poly.width, 0) elif position=="left": contact_offset = left_gate_offset - vector(0.5*contact_width - 0.5*self.poly_width, 0) elif position=="right": @@ -79,9 +103,12 @@ class pgate(design.design): else: debug.error("Invalid contact placement option.", -1) - self.add_contact_center(layers=("poly", "contact", "metal1"), - offset=contact_offset, - rotate=rotate) + # Non-preferred direction via + + self.add_via_center(layers=("poly", "contact", "metal1"), + offset=contact_offset, + directions=directions) + # self.add_layout_pin_segment_center(text=name, # layer="metal1", # start=left_gate_offset.scale(0,1), @@ -145,10 +172,11 @@ class pgate(design.design): # Offset by half a contact in x and y contact_offset += vector(0.5*pmos.active_contact.first_layer_width, 0.5*pmos.active_contact.first_layer_height) - self.nwell_contact=self.add_contact_center(layers=layer_stack, - offset=contact_offset, - implant_type="n", - well_type="n") + self.nwell_contact=self.add_via_center(layers=layer_stack, + offset=contact_offset, + directions=("H","V"), + implant_type="n", + well_type="n") self.add_rect_center(layer="metal1", offset=contact_offset + vector(0,0.5*(self.height-contact_offset.y)), width=self.nwell_contact.mod.second_layer_width, @@ -191,10 +219,11 @@ class pgate(design.design): # Offset by half a contact contact_offset += vector(0.5*nmos.active_contact.first_layer_width, 0.5*nmos.active_contact.first_layer_height) - self.pwell_contact=self.add_contact_center(layers=layer_stack, - offset=contact_offset, - implant_type="p", - well_type="p") + self.pwell_contact=self.add_via_center(layers=layer_stack, + offset=contact_offset, + directions=("H","V"), + implant_type="p", + well_type="p") self.add_rect_center(layer="metal1", offset=contact_offset.scale(1,0.5), width=self.pwell_contact.mod.second_layer_width, diff --git a/compiler/pgates/pinv.py b/compiler/pgates/pinv.py index f00e9af7..8f05c2b1 100644 --- a/compiler/pgates/pinv.py +++ b/compiler/pgates/pinv.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# import contact import pgate import debug @@ -20,28 +27,18 @@ class pinv(pgate.pgate): """ def __init__(self, name, size=1, beta=parameter["beta"], height=None, route_output=True): - # We need to keep unique names because outputting to GDSII - # will use the last record with a given name. I.e., you will - # over-write a design in GDS if one has and the other doesn't - # have poly connected, for example. - pgate.pgate.__init__(self, name, height) - debug.info(2, "create pinv structure {0} with size of {1}".format(name, size)) + + debug.info(2, "creating pinv structure {0} with size of {1}".format(name, size)) self.add_comment("size: {}".format(size)) - + self.size = size self.nmos_size = size self.pmos_size = beta*size self.beta = beta self.route_output = False - - self.create_netlist() - if not OPTS.netlist_only: - self.create_layout() - - # for run-time, we won't check every transitor DRC/LVS independently - # but this may be uncommented for debug purposes - #self.DRC_LVS() + # Creates the netlist and layout + pgate.pgate.__init__(self, name, height) def create_netlist(self): """ Calls all functions related to the generation of the netlist """ @@ -58,7 +55,7 @@ class pinv(pgate.pgate): self.add_well_contacts() self.extend_wells(self.well_pos) self.connect_rails() - self.route_input_gate(self.pmos_inst, self.nmos_inst, self.output_pos.y, "A", rotate=0) + self.route_input_gate(self.pmos_inst, self.nmos_inst, self.output_pos.y, "A", position="farleft") self.route_outputs() def add_pins(self): @@ -222,8 +219,8 @@ class pinv(pgate.pgate): pmos_drain_pin = self.pmos_inst.get_pin("D") # Pick point at right most of NMOS and connect down to PMOS - nmos_drain_pos = nmos_drain_pin.lr() - vector(0.5*self.m1_width,0) - pmos_drain_pos = vector(nmos_drain_pos.x, pmos_drain_pin.bc().y) + nmos_drain_pos = nmos_drain_pin.bc() + pmos_drain_pos = vector(nmos_drain_pos.x, pmos_drain_pin.uc().y) self.add_path("metal1",[nmos_drain_pos,pmos_drain_pos]) # Remember the mid for the output diff --git a/compiler/pgates/pinvbuf.py b/compiler/pgates/pinvbuf.py index 06936895..75c64b08 100644 --- a/compiler/pgates/pinvbuf.py +++ b/compiler/pgates/pinvbuf.py @@ -1,18 +1,28 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# import debug -import design +import pgate from tech import drc from math import log from vector import vector from globals import OPTS from sram_factory import factory -class pinvbuf(design.design): +class pinvbuf(pgate.pgate): """ This is a simple inverter/buffer used for driving loads. It is used in the column decoder for 1:2 decoding and as the clock buffer. """ def __init__(self, name, size=4, height=None): + debug.info(1, "creating pinvbuf {}".format(name)) + self.add_comment("size: {}".format(size)) + self.stage_effort = 4 self.row_height = height # FIXME: Change the number of stages to support high drives. @@ -23,13 +33,8 @@ class pinvbuf(design.design): self.size = size self.predriver_size = max(int(self.size/(self.stage_effort/2)),1) - design.design.__init__(self, name) - debug.info(1, "Creating {}".format(self.name)) - self.add_comment("size: {}".format(size)) - - self.create_netlist() - if not OPTS.netlist_only: - self.create_layout() + # Creates the netlist and layout + pgate.pgate.__init__(self, name) def create_netlist(self): @@ -48,7 +53,6 @@ class pinvbuf(design.design): self.offset_all_coordinates() - self.DRC_LVS() def add_pins(self): self.add_pin("A") diff --git a/compiler/pgates/pnand2.py b/compiler/pgates/pnand2.py index 95a9bc28..865e1c60 100644 --- a/compiler/pgates/pnand2.py +++ b/compiler/pgates/pnand2.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# import contact import pgate import debug @@ -14,8 +21,8 @@ class pnand2(pgate.pgate): """ def __init__(self, name, size=1, height=None): """ Creates a cell for a simple 2 input nand """ - pgate.pgate.__init__(self, name, height) - debug.info(2, "create pnand2 structure {0} with size of {1}".format(name, size)) + + debug.info(2, "creating pnand2 structure {0} with size of {1}".format(name, size)) self.add_comment("size: {}".format(size)) self.size = size @@ -28,9 +35,8 @@ class pnand2(pgate.pgate): debug.check(size==1,"Size 1 pnand2 is only supported now.") self.tx_mults = 1 - self.create_netlist() - if not OPTS.netlist_only: - self.create_layout() + # Creates the netlist and layout + pgate.pgate.__init__(self, name, height) def create_netlist(self): @@ -203,13 +209,15 @@ class pnand2(pgate.pgate): mid1_offset = vector(out_offset.x, top_pin_offset.y) mid2_offset = vector(out_offset.x, bottom_pin_offset.y) - self.add_contact_center(layers=("metal1", "via1", "metal2"), - offset=pmos_pin.center()) - self.add_contact_center(layers=("metal1", "via1", "metal2"), - offset=nmos_pin.center()) - self.add_contact_center(layers=("metal1", "via1", "metal2"), - offset=out_offset, - rotate=90) + self.add_via_center(layers=("metal1", "via1", "metal2"), + offset=pmos_pin.center(), + directions=("V","H")) + self.add_via_center(layers=("metal1", "via1", "metal2"), + offset=nmos_pin.center(), + directions=("V","H")) + self.add_via_center(layers=("metal1", "via1", "metal2"), + offset=out_offset) + # PMOS1 to mid-drain to NMOS2 drain self.add_path("metal2",[top_pin_offset, mid1_offset, out_offset, mid2_offset, bottom_pin_offset]) diff --git a/compiler/pgates/pnand3.py b/compiler/pgates/pnand3.py index d0c37b55..6f9d138d 100644 --- a/compiler/pgates/pnand3.py +++ b/compiler/pgates/pnand3.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# import contact import pgate import debug @@ -14,8 +21,8 @@ class pnand3(pgate.pgate): """ def __init__(self, name, size=1, height=None): """ Creates a cell for a simple 3 input nand """ - pgate.pgate.__init__(self, name, height) - debug.info(2, "create pnand3 structure {0} with size of {1}".format(name, size)) + + debug.info(2, "creating pnand3 structure {0} with size of {1}".format(name, size)) self.add_comment("size: {}".format(size)) # We have trouble pitch matching a 3x sizes to the bitcell... @@ -30,9 +37,8 @@ class pnand3(pgate.pgate): debug.check(size==1,"Size 1 pnand3 is only supported now.") self.tx_mults = 1 - self.create_netlist() - if not OPTS.netlist_only: - self.create_layout() + # Creates the netlist and layout + pgate.pgate.__init__(self, name, height) def add_pins(self): @@ -213,12 +219,12 @@ class pnand3(pgate.pgate): nmos3_pin = self.nmos3_inst.get_pin("D") # Go up to metal2 for ease on all output pins - self.add_contact_center(layers=("metal1", "via1", "metal2"), - offset=pmos1_pin.center()) - self.add_contact_center(layers=("metal1", "via1", "metal2"), - offset=pmos3_pin.center()) - self.add_contact_center(layers=("metal1", "via1", "metal2"), - offset=nmos3_pin.center()) + self.add_via_center(layers=("metal1", "via1", "metal2"), + offset=pmos1_pin.center()) + self.add_via_center(layers=("metal1", "via1", "metal2"), + offset=pmos3_pin.center()) + self.add_via_center(layers=("metal1", "via1", "metal2"), + offset=nmos3_pin.center()) # PMOS3 and NMOS3 are drain aligned self.add_path("metal2",[pmos3_pin.bc(), nmos3_pin.uc()]) @@ -227,8 +233,8 @@ class pnand3(pgate.pgate): self.add_path("metal2",[pmos1_pin.bc(), mid_offset, nmos3_pin.uc()]) # This extends the output to the edge of the cell - self.add_contact_center(layers=("metal1", "via1", "metal2"), - offset=mid_offset) + self.add_via_center(layers=("metal1", "via1", "metal2"), + offset=mid_offset) self.add_layout_pin_rect_center(text="Z", layer="metal1", offset=mid_offset, diff --git a/compiler/pgates/pnor2.py b/compiler/pgates/pnor2.py index 8a5c80d4..3cc01f1a 100644 --- a/compiler/pgates/pnor2.py +++ b/compiler/pgates/pnor2.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# import pgate import debug from tech import drc, parameter, spice @@ -13,8 +20,8 @@ class pnor2(pgate.pgate): """ def __init__(self, name, size=1, height=None): """ Creates a cell for a simple 2 input nor """ - pgate.pgate.__init__(self, name, height) - debug.info(2, "create pnor2 structure {0} with size of {1}".format(name, size)) + + debug.info(2, "creating pnor2 structure {0} with size of {1}".format(name, size)) self.add_comment("size: {}".format(size)) self.nmos_size = size @@ -27,9 +34,8 @@ class pnor2(pgate.pgate): debug.check(size==1,"Size 1 pnor2 is only supported now.") self.tx_mults = 1 - self.create_netlist() - self.create_layout() - #self.DRC_LVS() + # Creates the netlist and layout + pgate.pgate.__init__(self, name, height) def add_pins(self): @@ -38,12 +44,11 @@ class pnor2(pgate.pgate): def create_netlist(self): self.add_pins() + self.create_ptx() + self.setup_layout_constants() def create_layout(self): """ Calls all functions related to the generation of the layout """ - - self.create_ptx() - self.setup_layout_constants() self.add_supply_rails() self.add_ptx() self.connect_rails() @@ -184,11 +189,11 @@ class pnor2(pgate.pgate): nmos2_pin = self.nmos2_inst.get_pin("D") # Go up to metal2 for ease on all output pins - self.add_contact_center(layers=("metal1", "via1", "metal2"), - offset=pmos_pin.center()) - m1m2_contact=self.add_contact_center(layers=("metal1", "via1", "metal2"), - offset=nmos_pin.center(), - rotate=90) + self.add_via_center(layers=("metal1", "via1", "metal2"), + offset=pmos_pin.center()) + m1m2_contact=self.add_via_center(layers=("metal1", "via1", "metal2"), + offset=nmos_pin.center()) + mid1_offset = vector(pmos_pin.center().x,nmos2_pin.center().y) mid2_offset = vector(pmos_pin.center().x,self.inputA_yoffset) @@ -198,9 +203,8 @@ class pnor2(pgate.pgate): self.add_path("metal2",[pmos_pin.bc(), mid2_offset, mid3_offset]) self.add_path("metal2",[nmos_pin.rc(), mid1_offset, mid2_offset]) # This extends the output to the edge of the cell - self.add_contact_center(layers=("metal1", "via1", "metal2"), - offset=mid3_offset, - rotate=90) + self.add_via_center(layers=("metal1", "via1", "metal2"), + offset=mid3_offset) self.add_layout_pin_rect_center(text="Z", layer="metal1", offset=mid3_offset, diff --git a/compiler/pgates/precharge.py b/compiler/pgates/precharge.py index cea9c845..61785d9d 100644 --- a/compiler/pgates/precharge.py +++ b/compiler/pgates/precharge.py @@ -1,31 +1,42 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# import contact -import pgate +import design import debug from tech import drc, parameter from vector import vector from globals import OPTS from sram_factory import factory -class precharge(pgate.pgate): +class precharge(design.design): """ Creates a single precharge cell This module implements the precharge bitline cell used in the design. """ def __init__(self, name, size=1, bitcell_bl="bl", bitcell_br="br"): - pgate.pgate.__init__(self, name) - debug.info(2, "create single precharge cell: {0}".format(name)) + + debug.info(2, "creating precharge cell {0}".format(name)) + design.design.__init__(self, name) self.bitcell = factory.create(module_type="bitcell") - self.beta = parameter["beta"] self.ptx_width = self.beta*parameter["min_tx_size"] self.width = self.bitcell.width self.bitcell_bl = bitcell_bl self.bitcell_br = bitcell_br - + + + # Creates the netlist and layout + # Since it has variable height, it is not a pgate. self.create_netlist() - if not OPTS.netlist_only: + if not OPTS.netlist_only: self.create_layout() + self.DRC_LVS() def create_netlist(self): self.add_pins() @@ -40,7 +51,6 @@ class precharge(pgate.pgate): self.route_vdd_rail() self.route_bitlines() self.connect_to_bitlines() - self.DRC_LVS() def add_pins(self): self.add_pin_list(["bl", "br", "en_bar", "vdd"]) @@ -75,7 +85,7 @@ class precharge(pgate.pgate): self.add_path("metal1", [pmos_pin.uc(), pmos_vdd_pos]) # Add vdd pin above the transistor - self.add_power_pin("vdd", pmos_pin.center(), rotate=0) + self.add_power_pin("vdd", pmos_pin.center(), vertical=True) def create_ptx(self): @@ -149,9 +159,8 @@ class precharge(pgate.pgate): # adds the en contact to connect the gates to the en rail on metal1 offset = self.lower_pmos_inst.get_pin("G").ul() + vector(0,0.5*self.poly_space) - self.add_contact_center(layers=("poly", "contact", "metal1"), - offset=offset, - rotate=90) + self.add_via_center(layers=("poly", "contact", "metal1"), + offset=offset) # adds the en rail on metal1 self.add_layout_pin_segment_center(text="en_bar", @@ -168,10 +177,10 @@ class precharge(pgate.pgate): # adds the contact from active to metal1 well_contact_pos = self.upper_pmos1_inst.get_pin("D").center().scale(1,0) \ + vector(0, self.upper_pmos1_inst.uy() + contact.well.height/2 + drc("well_extend_active")) - self.add_contact_center(layers=("active", "contact", "metal1"), - offset=well_contact_pos, - implant_type="n", - well_type="n") + self.add_via_center(layers=("active", "contact", "metal1"), + offset=well_contact_pos, + implant_type="n", + well_type="n") # leave an extra pitch for the height self.height = well_contact_pos.y + contact.well.height + self.m1_pitch @@ -225,16 +234,20 @@ class precharge(pgate.pgate): lower_pin = self.lower_pmos_inst.get_pin("S") # BL goes up to M2 at the transistor - self.bl_contact=self.add_contact_center(layers=stack, - offset=upper_pin.center()) - self.add_contact_center(layers=stack, - offset=lower_pin.center()) + self.bl_contact=self.add_via_center(layers=stack, + offset=upper_pin.center(), + directions=("V","V")) + self.add_via_center(layers=stack, + offset=lower_pin.center(), + directions=("V","V")) # BR routes over on M1 first - self.add_contact_center(layers=stack, - offset = vector(self.br_pin.cx(), upper_pin.cy())) - self.add_contact_center(layers=stack, - offset = vector(self.br_pin.cx(), lower_pin.cy())) + self.add_via_center(layers=stack, + offset = vector(self.br_pin.cx(), upper_pin.cy()), + directions=("V","V")) + self.add_via_center(layers=stack, + offset = vector(self.br_pin.cx(), lower_pin.cy()), + directions=("V","V")) def connect_pmos_m1(self, pmos_pin, bit_pin): """ diff --git a/compiler/pgates/ptristate_inv.py b/compiler/pgates/ptristate_inv.py new file mode 100644 index 00000000..531ce160 --- /dev/null +++ b/compiler/pgates/ptristate_inv.py @@ -0,0 +1,227 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# +import contact +import pgate +import debug +from tech import drc, parameter, spice +from vector import vector +from math import ceil +from globals import OPTS +from utils import round_to_grid +import logical_effort +from sram_factory import factory + +class ptristate_inv(pgate.pgate): + """ + ptristate generates gds of a parametrically sized tristate inverter. + + There is some flexibility in the size, but we do not allow multiple fingers + to fit in the cell height. + + """ + + def __init__(self, name, size=1, height=None): + + debug.info(2, "creating ptristate inv {0} with size of {1}".format(name, size)) + self.add_comment("size: {}".format(size)) + + # We are 2x since there are two series devices + self.size = 2*size + self.nmos_size = size + self.beta = parameter["beta"] + self.pmos_size = self.beta*size + + self.nmos_width = self.nmos_size * drc("minwidth_tx") + self.pmos_width = self.pmos_size * drc("minwidth_tx") + + # Creates the netlist and layout + pgate.pgate.__init__(self, name, height) + + def create_netlist(self): + """ Calls all functions related to the generation of the netlist """ + self.add_pins() + self.add_ptx() + self.create_ptx() + + def create_layout(self): + """ Calls all functions related to the generation of the layout """ + self.setup_layout_constants() + self.route_supply_rails() + self.place_ptx() + self.add_well_contacts() + self.extend_wells(self.well_pos) + self.connect_rails() + self.route_inputs() + self.route_outputs() + + def add_pins(self): + """ Adds pins for spice netlist """ + self.add_pin_list(["in", "out", "en", "en_bar", "vdd", "gnd"]) + + + def setup_layout_constants(self): + """ + Pre-compute some handy layout parameters. + """ + + # Compute the other pmos2 location, but determining offset to overlap the + # source and drain pins + self.overlap_offset = self.pmos.get_pin("D").ll() - self.pmos.get_pin("S").ll() + + # Two PMOS devices and a well contact. Separation between each. + # Enclosure space on the sides. + self.well_width = 2*self.pmos.active_width + drc("well_enclosure_active") + + # Add an extra space because we route the output on the right of the S/D + self.width = self.well_width + 0.5*self.m1_space + # Height is an input parameter, so it is not recomputed. + + # Make sure we can put a well above and below + self.top_bottom_space = max(contact.well.width, contact.well.height) + + + def add_ptx(self): + """ Create the PMOS and NMOS transistors. """ + self.nmos = factory.create(module_type="ptx", + width=self.nmos_width, + mults=1, + tx_type="nmos") + self.add_mod(self.nmos) + + self.pmos = factory.create(module_type="ptx", + width=self.pmos_width, + mults=1, + tx_type="pmos") + + self.add_mod(self.pmos) + + def route_supply_rails(self): + """ Add vdd/gnd rails to the top and bottom. """ + self.add_layout_pin_rect_center(text="gnd", + layer="metal1", + offset=vector(0.5*self.width,0), + width=self.width) + + self.add_layout_pin_rect_center(text="vdd", + layer="metal1", + offset=vector(0.5*self.width,self.height), + width=self.width) + + + def create_ptx(self): + """ + Create the PMOS and NMOS netlist. + """ + + # These are the inverter PMOS/NMOS + self.pmos1_inst=self.add_inst(name="ptri_pmos1", mod=self.pmos) + self.connect_inst(["vdd", "in", "n1", "vdd"]) + self.nmos1_inst=self.add_inst(name="ptri_nmos1", mod=self.nmos) + self.connect_inst(["gnd", "in", "n2", "gnd"]) + + + # These are the tristate PMOS/NMOS + self.pmos2_inst = self.add_inst(name="ptri_pmos2", mod=self.pmos) + self.connect_inst(["out", "en_bar", "n1", "vdd"]) + self.nmos2_inst=self.add_inst(name="ptri_nmos2", mod=self.nmos) + self.connect_inst(["out", "en", "n2", "gnd"]) + + + + def place_ptx(self): + """ + Place PMOS and NMOS to the layout at the upper-most and lowest position + to provide maximum routing in channel + """ + + pmos_yoff = self.height - self.pmos.active_height - self.top_bottom_space - 0.5*contact.well.height + nmos_yoff = self.top_bottom_space + 0.5*contact.well.height + + # Tristate transistors + pmos1_pos = vector(self.pmos.active_offset.x, pmos_yoff) + self.pmos1_inst.place(pmos1_pos) + nmos1_pos = vector(self.pmos.active_offset.x, nmos_yoff) + self.nmos1_inst.place(nmos1_pos) + + # Inverter transistors + self.pmos2_pos = pmos1_pos + self.overlap_offset + self.pmos2_inst.place(self.pmos2_pos) + self.nmos2_pos = nmos1_pos + self.overlap_offset + self.nmos2_inst.place(self.nmos2_pos) + + # Output position will be in between the PMOS and NMOS + self.output_pos = vector(0, 0.5*(pmos_yoff + nmos_yoff + self.nmos.height)) + + # This will help with the wells + self.well_pos = vector(0,self.nmos1_inst.uy()) + + + def route_inputs(self): + """ Route the gates """ + + self.route_input_gate(self.pmos1_inst, self.nmos1_inst, self.output_pos.y, "in", position="farleft") + self.route_single_gate(self.pmos2_inst, "en_bar", position="left") + self.route_single_gate(self.nmos2_inst, "en", position="left") + + + def route_outputs(self): + """ Route the output (drains) together. """ + + nmos_drain_pin = self.nmos2_inst.get_pin("D") + pmos_drain_pin = self.pmos2_inst.get_pin("D") + + nmos_drain_pos = nmos_drain_pin.lr() + pmos_drain_pos = pmos_drain_pin.ur() + + self.add_layout_pin(text="out", + layer="metal1", + offset=nmos_drain_pos, + height=pmos_drain_pos.y-nmos_drain_pos.y) + + + def add_well_contacts(self): + """ Add n/p well taps to the layout and connect to supplies AFTER the wells are created """ + + layer_stack = ("active", "contact", "metal1") + + drain_pos = self.nmos1_inst.get_pin("S").center() + vdd_pos = self.get_pin("vdd").center() + self.nwell_contact=self.add_via_center(layers=layer_stack, + offset=vector(drain_pos.x,vdd_pos.y), + implant_type="n", + well_type="n") + + gnd_pos = self.get_pin("gnd").center() + self.pwell_contact=self.add_via_center(layers=layer_stack, + offset=vector(drain_pos.x,gnd_pos.y), + implant_type="p", + well_type="p") + + + + def connect_rails(self): + """ Connect the nmos and pmos to its respective power rails """ + + self.connect_pin_to_rail(self.nmos1_inst,"S","gnd") + self.connect_pin_to_rail(self.pmos1_inst,"S","vdd") + + + def analytical_delay(self, corner, slew, load=0.0): + from tech import spice + r = spice["min_tx_r"] + c_para = spice["min_tx_drain_c"] + return self.cal_delay_with_rc(corner, r = r, c = c_para+load, slew = slew) + + def analytical_power(self, corner, load): + """Returns dynamic and leakage power. Results in nW""" + #Power in this module currently not defined. Returns 0 nW (leakage and dynamic). + total_power = self.return_power() + return total_power + + def input_load(self): + return 9*spice["min_tx_gate_c"] diff --git a/compiler/pgates/ptx.py b/compiler/pgates/ptx.py index 3a127454..eade6682 100644 --- a/compiler/pgates/ptx.py +++ b/compiler/pgates/ptx.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# import design import debug from tech import drc, spice @@ -28,9 +35,8 @@ class ptx(design.design): name += "_c{}".format(num_contacts) # replace periods with underscore for newer spice compatibility name=name.replace('.','_') - + debug.info(3, "creating ptx {0}".format(name)) design.design.__init__(self, name) - debug.info(3, "create ptx2 structure {0}".format(name)) self.tx_type = tx_type self.mults = mults @@ -39,6 +45,8 @@ class ptx(design.design): self.connect_poly = connect_poly self.num_contacts = num_contacts + # Do NOT create the netlist and layout (not a pgate) + # Since it has variable height, it is not a pgate. self.create_netlist() # We must always create ptx layout for pbitcell # some transistor sizes in other netlist depend on pbitcell @@ -326,11 +334,12 @@ class ptx(design.design): [source_positions,drain_positions] = self.get_contact_positions() for pos in source_positions: - contact=self.add_contact_center(layers=("active", "contact", "metal1"), - offset=pos, - size=(1, self.num_contacts), - implant_type=self.implant_type, - well_type=self.well_type) + contact=self.add_via_center(layers=("active", "contact", "metal1"), + offset=pos, + size=(1, self.num_contacts), + directions=("H","V"), + implant_type=self.implant_type, + well_type=self.well_type) self.add_layout_pin_rect_center(text="S", layer="metal1", offset=pos, @@ -339,11 +348,12 @@ class ptx(design.design): for pos in drain_positions: - contact=self.add_contact_center(layers=("active", "contact", "metal1"), - offset=pos, - size=(1, self.num_contacts), - implant_type=self.implant_type, - well_type=self.well_type) + contact=self.add_via_center(layers=("active", "contact", "metal1"), + offset=pos, + size=(1, self.num_contacts), + directions=("H","V"), + implant_type=self.implant_type, + well_type=self.well_type) self.add_layout_pin_rect_center(text="D", layer="metal1", offset=pos, diff --git a/compiler/pgates/single_level_column_mux.py b/compiler/pgates/single_level_column_mux.py index f03a22e8..caf01862 100644 --- a/compiler/pgates/single_level_column_mux.py +++ b/compiler/pgates/single_level_column_mux.py @@ -1,12 +1,20 @@ -import design +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# +import pgate import debug from tech import drc from vector import vector import contact from globals import OPTS from sram_factory import factory +import logical_effort -class single_level_column_mux(design.design): +class single_level_column_mux(pgate.pgate): """ This module implements the columnmux bitline cell used in the design. Creates a single columnmux cell with the given integer size relative @@ -14,18 +22,14 @@ class single_level_column_mux(design.design): Column-mux transistors driven by the decoder must be sized for optimal speed """ def __init__(self, name, tx_size=8, bitcell_bl="bl", bitcell_br="br"): + + debug.info(2, "creating single column mux cell: {0}".format(name)) self.tx_size = int(tx_size) - - design.design.__init__(self, name) - debug.info(2, "create single column mux cell: {0}".format(name)) - self.bitcell_bl = bitcell_bl self.bitcell_br = bitcell_br - self.create_netlist() - if not OPTS.netlist_only: - self.create_layout() + pgate.pgate.__init__(self, name) def create_netlist(self): self.add_modules() @@ -126,13 +130,18 @@ class single_level_column_mux(design.design): # Add vias to bl, br_out, nmos_upper/S, nmos_lower/D self.add_via_center(layers=("metal1","via1","metal2"), - offset=bl_pin.bc()) + offset=bl_pin.bc(), + directions=("V","V")) self.add_via_center(layers=("metal1","via1","metal2"), - offset=br_out_pin.uc()) + offset=br_out_pin.uc(), + directions=("V","V")) self.add_via_center(layers=("metal1","via1","metal2"), - offset=nmos_upper_s_pin.center()) + offset=nmos_upper_s_pin.center(), + directions=("V","V")) self.add_via_center(layers=("metal1","via1","metal2"), - offset=nmos_lower_d_pin.center()) + offset=nmos_lower_d_pin.center(), + directions=("V","V")) + # bl -> nmos_upper/D on metal1 # bl_out -> nmos_upper/S on metal2 @@ -180,5 +189,9 @@ class single_level_column_mux(design.design): width=self.bitcell.width, height=self.height) - + def analytical_delay(self, corner, slew, load): + """Returns relative delay that the column mux. Difficult to convert to LE model.""" + parasitic_delay = 1 + cin = 2*self.tx_size #This is not CMOS, so using this may be incorrect. + return logical_effort.logical_effort('column_mux', self.tx_size, cin, load, parasitic_delay, False) diff --git a/compiler/router/direction.py b/compiler/router/direction.py index 8a6681a7..7508823d 100644 --- a/compiler/router/direction.py +++ b/compiler/router/direction.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# from enum import Enum from vector3d import vector3d diff --git a/compiler/router/grid.py b/compiler/router/grid.py index 245bcb68..4533b8e7 100644 --- a/compiler/router/grid.py +++ b/compiler/router/grid.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# import numpy as np import string import debug diff --git a/compiler/router/grid_cell.py b/compiler/router/grid_cell.py index cb78116c..d2816c28 100644 --- a/compiler/router/grid_cell.py +++ b/compiler/router/grid_cell.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# class grid_cell: """ A single cell that can be occupied in a given layer, blocked, diff --git a/compiler/router/grid_path.py b/compiler/router/grid_path.py index cbe739ef..f914e477 100644 --- a/compiler/router/grid_path.py +++ b/compiler/router/grid_path.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# import debug from vector3d import vector3d from itertools import tee diff --git a/compiler/router/grid_utils.py b/compiler/router/grid_utils.py index 7ad864aa..6524a9d5 100644 --- a/compiler/router/grid_utils.py +++ b/compiler/router/grid_utils.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ Some utility functions for sets of grid cells. """ diff --git a/compiler/router/pin_group.py b/compiler/router/pin_group.py index 13368d12..bef538e3 100644 --- a/compiler/router/pin_group.py +++ b/compiler/router/pin_group.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# from direction import direction from pin_layout import pin_layout from vector3d import vector3d @@ -25,7 +32,7 @@ class pin_group: # This is a list because we can have a pin group of disconnected sets of pins # and these are represented by separate lists - self.pins = [set(irredundant_pin_set)] + self.pins = set(irredundant_pin_set) self.router = router # These are the corresponding pin grids for each pin group. @@ -55,7 +62,7 @@ class pin_group: total_string += grids_string if self.enclosed: - enlosure_string = "\n enclose={}".format(self.enclosures) + enclosure_string = "\n enclose={}".format(self.enclosures) total_string += enclosure_string total_string += ")" @@ -74,25 +81,6 @@ class pin_group: def is_routed(self): return self.routed - def pins_enclosed(self): - """ - Check if all of the pin shapes are enclosed. - Does not check if the DRC is correct, but just touching. - """ - for pin_list in self.pins: - pin_is_enclosed=False - for pin in pin_list: - if pin_is_enclosed: - break - for encosure in self.enclosures: - if pin.overlaps(enclosure): - pin_is_enclosed=True - break - else: - return False - - return True - def remove_redundant_shapes(self, pin_list): """ Remove any pin layout that is contained within another. @@ -135,7 +123,6 @@ class pin_group: return new_pin_list - # FIXME: This relies on some technology parameters from router which is not clean. def compute_enclosures(self): """ Find the minimum rectangle enclosures of the given tracks. @@ -406,8 +393,8 @@ class pin_group: def enclose_pin_grids(self, ll, dir1=direction.NORTH, dir2=direction.EAST): """ This encloses a single pin component with a rectangle - starting with the seed and expanding right until blocked - and then up until blocked. + starting with the seed and expanding dir1 until blocked + and then dir2 until blocked. dir1 and dir2 should be two orthogonal directions. """ @@ -458,61 +445,86 @@ class pin_group: # Compute the enclosure pin_layout list of the set of tracks self.enclosures = self.compute_enclosures() - for pin_list in self.pins: - for pin in pin_list: + # Find a connector to every pin and add it to the enclosures + for pin in self.pins: - # If it is contained, it won't need a connector - if pin.contained_by_any(self.enclosures): - continue + # If it is contained, it won't need a connector + if pin.contained_by_any(self.enclosures): + continue - # Find a connector in the cardinal directions - # If there is overlap, but it isn't contained, these could all be None - # These could also be none if the pin is diagonal from the enclosure - left_connector = self.find_left_connector(pin, self.enclosures) - right_connector = self.find_right_connector(pin, self.enclosures) - above_connector = self.find_above_connector(pin, self.enclosures) - below_connector = self.find_below_connector(pin, self.enclosures) - connector_list = [left_connector, right_connector, above_connector, below_connector] - filtered_list = list(filter(lambda x: x!=None, connector_list)) - if (len(filtered_list)>0): - import copy - bbox_connector = copy.copy(pin) - bbox_connector.bbox(filtered_list) - self.enclosures.append(bbox_connector) + # Find a connector in the cardinal directions + # If there is overlap, but it isn't contained, these could all be None + # These could also be none if the pin is diagonal from the enclosure + left_connector = self.find_left_connector(pin, self.enclosures) + right_connector = self.find_right_connector(pin, self.enclosures) + above_connector = self.find_above_connector(pin, self.enclosures) + below_connector = self.find_below_connector(pin, self.enclosures) + connector_list = [left_connector, right_connector, above_connector, below_connector] + filtered_list = list(filter(lambda x: x!=None, connector_list)) + if (len(filtered_list)>0): + import copy + bbox_connector = copy.copy(pin) + bbox_connector.bbox(filtered_list) + self.enclosures.append(bbox_connector) # Now, make sure each pin touches an enclosure. If not, add another (diagonal) connector. # This could only happen when there was no enclosure in any cardinal direction from a pin - for pin_list in self.pins: - if not self.overlap_any_shape(pin_list, self.enclosures): - connector = self.find_smallest_connector(pin_list, self.enclosures) - if connector==None: - debug.error("Could not find a connector for {} with {}".format(pin_list, self.enclosures)) - self.router.write_debug_gds("no_connector.gds") - self.enclosures.append(connector) - + if not self.overlap_any_shape(self.pins, self.enclosures): + connector = self.find_smallest_connector(pin_list, self.enclosures) + if connector==None: + debug.error("Could not find a connector for {} with {}".format(pin_list, self.enclosures)) + self.router.write_debug_gds("no_connector.gds") + self.enclosures.append(connector) + + # At this point, the pins are overlapping, but there might be more than one! + overlap_set = set() + for pin in self.pins: + overlap_set.update(self.transitive_overlap(pin, self.enclosures)) + # Use the new enclosures and recompute the grids that correspond to them + if len(overlap_set) len(old_connected_set): + old_connected_set = connected_set + connected_set = set([shape]) + for old_shape in old_connected_set: + for cur_shape in augmented_shape_list: + if old_shape.overlaps(cur_shape): + connected_set.add(cur_shape) + + + # Remove the original shape + connected_set.remove(shape) + + # if len(connected_set) {0}\n {1}".format(combined.pins,combined.grids)) + # new_pin_groups.append(combined) + + # # Add the pin groups that weren't added to the new set + # for index in all_indices: + # new_pin_groups.append(self.pin_groups[pin_name][index]) + + # old_size = len(self.pin_groups[pin_name]) + # # Use the new pin group! + # self.pin_groups[pin_name] = new_pin_groups + # removed_pairs = old_size - len(new_pin_groups) + # debug.info(1, "Combined {0} pin groups for {1}".format(removed_pairs,pin_name)) - # Now reconstruct the new groups - new_pin_groups = [] - for index1,index2_set in adjacent_pins.items(): - # Remove the indices if they are added to the new set - all_indices.discard(index1) - all_indices.difference_update(index2_set) - - # Create the combined group starting with the first item - combined = self.pin_groups[pin_name][index1] - # Add all of the other items that overlapped - for index2 in index2_set: - pg = self.pin_groups[pin_name][index2] - combined.add_group(pg) - debug.info(3,"Combining {0} {1}:".format(pin_name, index2)) - debug.info(3, " {0}\n {1}".format(combined.pins, pg.pins)) - debug.info(3," --> {0}\n {1}".format(combined.pins,combined.grids)) - new_pin_groups.append(combined) - - # Add the pin groups that weren't added to the new set - for index in all_indices: - new_pin_groups.append(self.pin_groups[pin_name][index]) - - old_size = len(self.pin_groups[pin_name]) - # Use the new pin group! - self.pin_groups[pin_name] = new_pin_groups - removed_pairs = old_size - len(new_pin_groups) - debug.info(1, "Combined {0} pin groups for {1}".format(removed_pairs,pin_name)) - - return removed_pairs + # return removed_pairs def separate_adjacent_pins(self, separation): @@ -748,44 +759,10 @@ class router(router_tech): if gid not in group_map: group_map[gid] = pin_group(name=pin_name, pin_set=[], router=self) # We always add it to the first set since they are touching - group_map[gid].pins[0].add(pin) + group_map[gid].pins.add(pin) self.pin_groups[pin_name] = list(group_map.values()) - # This is the old O(n^2) implementation - # def analyze_pins(self, pin_name): - # """ - # Analyze the shapes of a pin and combine them into pin_groups which are connected. - # """ - # debug.info(2,"Analyzing pin groups for {}.".format(pin_name)) - - # pin_set = self.pins[pin_name] - - # # Put each pin in an equivalence class of it's own - # equiv_classes = [set([x]) for x in pin_set] - # def combine_classes(equiv_classes): - # for class1 in equiv_classes: - # for class2 in equiv_classes: - # if class1 == class2: - # continue - # # Compare each pin in each class, - # # and if any overlap, update equiv_classes to include the combined the class - # for p1 in class1: - # for p2 in class2: - # if p1.overlaps(p2): - # combined_class = class1 | class2 - # equiv_classes.remove(class1) - # equiv_classes.remove(class2) - # equiv_classes.append(combined_class) - # return(equiv_classes) - # return(equiv_classes) - - # old_length = math.inf - # while (len(equiv_classes)= 1: debug.info(3,"Via overlap {0} {1}".format(len(overlap),overlap)) connections.update([i1,i2]) @@ -213,7 +222,7 @@ class supply_router(router): ur = grid_utils.get_upper_right(rail) z = ll.z pin = self.compute_pin_enclosure(ll, ur, z, name) - debug.info(2,"Adding supply rail {0} {1}->{2} {3}".format(name,ll,ur,pin)) + debug.info(3,"Adding supply rail {0} {1}->{2} {3}".format(name,ll,ur,pin)) self.cell.add_layout_pin(text=name, layer=pin.layer, offset=pin.ll(), @@ -270,7 +279,8 @@ class supply_router(router): Find a start location, probe in the direction, and see if the rail is big enough to contain a via, and, if so, add it. """ - start_wave = self.find_supply_rail_start(name, seed_wave, direct) + # Sweep to find an initial unblocked valid wave + start_wave = self.rg.find_start_wave(seed_wave, direct) # This means there were no more unblocked grids in the row/col if not start_wave: @@ -284,17 +294,6 @@ class supply_router(router): # as it will be used to find the next start location return wave_path - def find_supply_rail_start(self, name, seed_wave, direct): - """ - This finds the first valid starting location and routes a supply rail - in the given direction. - It returns the space after the end of the rail to seed another call for multiple - supply rails in the same "track" when there is a blockage. - """ - # Sweep to find an initial unblocked valid wave - start_wave = self.rg.find_start_wave(seed_wave, len(seed_wave), direct) - - return start_wave def probe_supply_rail(self, name, start_wave, direct): """ @@ -400,7 +399,10 @@ class supply_router(router): # Actually run the A* router if not self.run_router(detour_scale=5): - self.write_debug_gds() + self.write_debug_gds("debug_route.gds",False) + + #if index==3 and pin_name=="vdd": + # self.write_debug_gds("route.gds",False) def add_supply_rail_target(self, pin_name): diff --git a/compiler/router/tests/01_no_blockages_test.py b/compiler/router/tests/01_no_blockages_test.py old mode 100755 new mode 100644 index 4197f714..4529864a --- a/compiler/router/tests/01_no_blockages_test.py +++ b/compiler/router/tests/01_no_blockages_test.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# #!/usr/bin/env python3 "Run a regresion test the library cells for DRC" diff --git a/compiler/router/tests/02_blockages_test.py b/compiler/router/tests/02_blockages_test.py old mode 100755 new mode 100644 index 6e3bee08..3abe2e7e --- a/compiler/router/tests/02_blockages_test.py +++ b/compiler/router/tests/02_blockages_test.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# #!/usr/bin/env python3 "Run a regresion test the library cells for DRC" diff --git a/compiler/router/tests/03_same_layer_pins_test.py b/compiler/router/tests/03_same_layer_pins_test.py old mode 100755 new mode 100644 index 726cd02b..af3d1ee8 --- a/compiler/router/tests/03_same_layer_pins_test.py +++ b/compiler/router/tests/03_same_layer_pins_test.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# #!/usr/bin/env python3 "Run a regresion test the library cells for DRC" diff --git a/compiler/router/tests/04_diff_layer_pins_test.py b/compiler/router/tests/04_diff_layer_pins_test.py old mode 100755 new mode 100644 index 2882156f..b70cba36 --- a/compiler/router/tests/04_diff_layer_pins_test.py +++ b/compiler/router/tests/04_diff_layer_pins_test.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# #!/usr/bin/env python3 "Run a regresion test the library cells for DRC" diff --git a/compiler/router/tests/05_two_nets_test.py b/compiler/router/tests/05_two_nets_test.py old mode 100755 new mode 100644 index e71920a8..10c157d7 --- a/compiler/router/tests/05_two_nets_test.py +++ b/compiler/router/tests/05_two_nets_test.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# #!/usr/bin/env python3 "Run a regresion test the library cells for DRC" diff --git a/compiler/router/tests/06_pin_location_test.py b/compiler/router/tests/06_pin_location_test.py old mode 100755 new mode 100644 index f469d326..7f75e541 --- a/compiler/router/tests/06_pin_location_test.py +++ b/compiler/router/tests/06_pin_location_test.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# #!/usr/bin/env python3 "Run a regresion test the library cells for DRC" diff --git a/compiler/router/tests/07_big_test.py b/compiler/router/tests/07_big_test.py old mode 100755 new mode 100644 index 8fcf2826..6692cee0 --- a/compiler/router/tests/07_big_test.py +++ b/compiler/router/tests/07_big_test.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# #!/usr/bin/env python3 "Run a regresion test the library cells for DRC" diff --git a/compiler/router/tests/08_expand_region_test.py b/compiler/router/tests/08_expand_region_test.py old mode 100755 new mode 100644 index 3e63bd51..46af863d --- a/compiler/router/tests/08_expand_region_test.py +++ b/compiler/router/tests/08_expand_region_test.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# #!/usr/bin/env python3 "Run a regresion test the library cells for DRC" diff --git a/compiler/router/tests/10_supply_grid_test.py b/compiler/router/tests/10_supply_grid_test.py old mode 100755 new mode 100644 index 7258ab40..4910797a --- a/compiler/router/tests/10_supply_grid_test.py +++ b/compiler/router/tests/10_supply_grid_test.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# #!/usr/bin/env python3 "Run a regresion test the library cells for DRC" diff --git a/compiler/router/tests/config_freepdk45.py b/compiler/router/tests/config_freepdk45.py old mode 100755 new mode 100644 index aaaa4c37..a6eb3bcc --- a/compiler/router/tests/config_freepdk45.py +++ b/compiler/router/tests/config_freepdk45.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# word_size = 1 num_words = 16 diff --git a/compiler/router/tests/config_scn4m_subm.py b/compiler/router/tests/config_scn4m_subm.py old mode 100755 new mode 100644 index e3aa1498..fdf7a2c3 --- a/compiler/router/tests/config_scn4m_subm.py +++ b/compiler/router/tests/config_scn4m_subm.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# word_size = 1 num_words = 16 diff --git a/compiler/router/tests/gds_cell.py b/compiler/router/tests/gds_cell.py index 5c1e0f91..60c0f48e 100644 --- a/compiler/router/tests/gds_cell.py +++ b/compiler/router/tests/gds_cell.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# from design import design class gds_cell(design): """ diff --git a/compiler/router/tests/regress.py b/compiler/router/tests/regress.py old mode 100755 new mode 100644 index b40263c7..8f6c8938 --- a/compiler/router/tests/regress.py +++ b/compiler/router/tests/regress.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# #!/usr/bin/env python3 import re diff --git a/compiler/router/tests/testutils.py b/compiler/router/tests/testutils.py old mode 100755 new mode 100644 index 4bea5d15..447cace6 --- a/compiler/router/tests/testutils.py +++ b/compiler/router/tests/testutils.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# import unittest,warnings import sys,os,glob,copy sys.path.append(os.path.join(sys.path[0],"../..")) diff --git a/compiler/router/vector3d.py b/compiler/router/vector3d.py index 1d0d083e..cc830faf 100644 --- a/compiler/router/vector3d.py +++ b/compiler/router/vector3d.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# import debug import math diff --git a/compiler/sram.py b/compiler/sram.py index d2234d92..d080acbc 100644 --- a/compiler/sram.py +++ b/compiler/sram.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# import sys import datetime import getpass @@ -102,13 +109,6 @@ class sram(): start_time = datetime.datetime.now() from characterizer import lib debug.print_raw("LIB: Characterizing... ") - if OPTS.analytical_delay: - debug.print_raw("Using analytical delay models (no characterization)") - else: - if OPTS.spice_name!="": - debug.print_raw("Performing simulation-based characterization with {}".format(OPTS.spice_name)) - if OPTS.trim_netlist: - debug.print_raw("Trimming netlist to speed up characterization.") lib(out_dir=OPTS.output_path, sram=self.s, sp_file=sp_file) print_time("Characterization", datetime.datetime.now(), start_time) diff --git a/compiler/sram_1bank.py b/compiler/sram_1bank.py index cbfec653..8edc317e 100644 --- a/compiler/sram_1bank.py +++ b/compiler/sram_1bank.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# import sys from tech import drc, spice import debug @@ -200,8 +207,7 @@ class sram_1bank(sram_base): clk_steiner_pos = vector(mid1_pos.x, control_clk_buf_pos.y) self.add_path("metal1", [control_clk_buf_pos, clk_steiner_pos]) self.add_via_center(layers=("metal1","via1","metal2"), - offset=clk_steiner_pos, - rotate=90) + offset=clk_steiner_pos) # Note, the via to the control logic is taken care of above self.add_wire(("metal3","via2","metal2"),[row_addr_clk_pos, mid1_pos, clk_steiner_pos]) @@ -233,8 +239,7 @@ class sram_1bank(sram_base): dest_pin = self.bank_inst.get_pin(signal+"{}".format(port)) self.connect_rail_from_left_m2m3(src_pin, dest_pin) self.add_via_center(layers=("metal1","via1","metal2"), - offset=src_pin.rc(), - rotate=90) + offset=src_pin.rc()) def route_row_addr_dff(self): @@ -250,8 +255,7 @@ class sram_1bank(sram_base): mid_pos = vector(bank_pos.x,flop_pos.y) self.add_wire(("metal3","via2","metal2"),[flop_pos, mid_pos,bank_pos]) self.add_via_center(layers=("metal2","via2","metal3"), - offset=flop_pos, - rotate=90) + offset=flop_pos) def route_col_addr_dff(self): """ Connect the output of the row flops to the bank pins """ diff --git a/compiler/sram_2bank.py b/compiler/sram_2bank.py index daf02563..acf0e1a2 100644 --- a/compiler/sram_2bank.py +++ b/compiler/sram_2bank.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# import sys from tech import drc, spice import debug diff --git a/compiler/sram_base.py b/compiler/sram_base.py index 22f1c354..192bc669 100644 --- a/compiler/sram_base.py +++ b/compiler/sram_base.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# import sys import datetime import getpass @@ -11,6 +18,7 @@ from design import design from verilog import verilog from lef import lef from sram_factory import factory +import logical_effort class sram_base(design, verilog, lef): """ @@ -468,8 +476,7 @@ class sram_base(design, verilog, lef): out_pos = dest_pin.center() self.add_wire(("metal3","via2","metal2"),[in_pos, vector(out_pos.x,in_pos.y),out_pos]) self.add_via_center(layers=("metal2","via2","metal3"), - offset=src_pin.rc(), - rotate=90) + offset=src_pin.rc()) def connect_rail_from_left_m2m1(self, src_pin, dest_pin): @@ -505,10 +512,28 @@ class sram_base(design, verilog, lef): def analytical_delay(self, corner, slew,load): - """ LH and HL are the same in analytical model. """ - return self.bank.analytical_delay(corner,slew,load) + """ Estimates the delay from clk -> DOUT + LH and HL are the same in analytical model. """ + delays = {} + for port in self.all_ports: + if port in self.readonly_ports: + control_logic = self.control_logic_r + elif port in self.readwrite_ports: + control_logic = self.control_logic_rw + else: + continue + clk_to_wlen_delays = control_logic.analytical_delay(corner, slew, load) + wlen_to_dout_delays = self.bank.analytical_delay(corner,slew,load,port) #port should probably be specified... + all_delays = clk_to_wlen_delays+wlen_to_dout_delays + total_delay = logical_effort.calculate_absolute_delay(all_delays) + total_delay = self.apply_corners_analytically(total_delay, corner) + last_slew = .1*all_delays[-1].get_absolute_delay() #slew approximated as 10% of delay + last_slew = self.apply_corners_analytically(last_slew, corner) + delays[port] = self.return_delay(delay=total_delay, slew=last_slew) + + return delays - def determine_wordline_stage_efforts(self, inp_is_rise=True): + def get_wordline_stage_efforts(self, inp_is_rise=True): """Get the all the stage efforts for each stage in the path from clk_buf to a wordline""" stage_effort_list = [] @@ -546,4 +571,12 @@ class sram_base(design, verilog, lef): return self.bank.get_sen_cin() - + def get_dff_clk_buf_cin(self): + """Get the relative capacitance of the clk_buf signal. + Does not get the control logic loading but everything else""" + total_cin = 0 + total_cin += self.row_addr_dff.get_clk_cin() + total_cin += self.data_dff.get_clk_cin() + if self.col_addr_size > 0: + total_cin += self.col_addr_dff.get_clk_cin() + return total_cin \ No newline at end of file diff --git a/compiler/sram_config.py b/compiler/sram_config.py index 5edf9282..671bcf62 100644 --- a/compiler/sram_config.py +++ b/compiler/sram_config.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# import debug from math import log,sqrt,ceil from importlib import reload diff --git a/compiler/sram_factory.py b/compiler/sram_factory.py index 1b4041d4..325261a0 100644 --- a/compiler/sram_factory.py +++ b/compiler/sram_factory.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# import debug from globals import OPTS from importlib import reload @@ -54,12 +61,15 @@ 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(3, "Existing module: type={0} name={1} kwargs={2}".format(module_type, obj_item.name, str(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. @@ -67,7 +77,8 @@ class sram_factory: # Create a unique name and increment the index module_name = "{0}_{1}".format(module_name, self.module_indices[module_type]) self.module_indices[module_type] += 1 - #debug.info(1, "New module: type={0} name={1} kwargs={2}".format(module_type,module_name,str(kwargs))) + + #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)) return obj diff --git a/compiler/tests/00_code_format_check_test.py b/compiler/tests/00_code_format_check_test.py index 98799ee8..373b1516 100755 --- a/compiler/tests/00_code_format_check_test.py +++ b/compiler/tests/00_code_format_check_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# import unittest from testutils import header,openram_test diff --git a/compiler/tests/01_library_drc_test.py b/compiler/tests/01_library_drc_test.py index 1f4aa853..c2052e4e 100755 --- a/compiler/tests/01_library_drc_test.py +++ b/compiler/tests/01_library_drc_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# "Run a regression test the library cells for DRC" import unittest diff --git a/compiler/tests/02_library_lvs_test.py b/compiler/tests/02_library_lvs_test.py index f312c298..6775f41f 100755 --- a/compiler/tests/02_library_lvs_test.py +++ b/compiler/tests/02_library_lvs_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# "Run a regression test the library cells for LVS" import unittest diff --git a/compiler/tests/03_contact_test.py b/compiler/tests/03_contact_test.py index 29d7ca0e..2aa79df6 100755 --- a/compiler/tests/03_contact_test.py +++ b/compiler/tests/03_contact_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# "Run a regression test for DRC on basic contacts of different array sizes" import unittest @@ -7,36 +14,50 @@ import sys,os sys.path.append(os.path.join(sys.path[0],"..")) import globals from globals import OPTS +from sram_factory import factory import debug class contact_test(openram_test): def runTest(self): globals.init_openram("config_{0}".format(OPTS.tech_name)) - import contact - - for layer_stack in [("poly", "contact", "metal1"), ("metal1", "via1", "metal2")]: + for layer_stack in [("metal1", "via1", "metal2"), ("poly", "contact", "metal1")]: stack_name = ":".join(map(str, layer_stack)) # Check single 1 x 1 contact" debug.info(2, "1 x 1 {} test".format(stack_name)) - c = contact.contact(layer_stack, (1, 1)) + c = factory.create(module_type="contact", layer_stack=layer_stack, dimensions=(1, 1)) + self.local_drc_check(c) + + # Check single 1 x 1 contact" + debug.info(2, "1 x 1 {} test".format(stack_name)) + c = factory.create(module_type="contact", layer_stack=layer_stack, dimensions=(1, 1), directions=("H","V")) self.local_drc_check(c) + # Check single x 1 contact" + debug.info(2, "1 x 1 {} test".format(stack_name)) + c = factory.create(module_type="contact", layer_stack=layer_stack, dimensions=(1, 1), directions=("H","H")) + self.local_drc_check(c) + + # Check single 1 x 1 contact" + debug.info(2, "1 x 1 {} test".format(stack_name)) + c = factory.create(module_type="contact", layer_stack=layer_stack, dimensions=(1, 1), directions=("V","V")) + self.local_drc_check(c) + # check vertical array with one in the middle and two ends debug.info(2, "1 x 3 {} test".format(stack_name)) - c = contact.contact(layer_stack, (1, 3)) + c = factory.create(module_type="contact", layer_stack=layer_stack, dimensions=(1, 3)) self.local_drc_check(c) # check horizontal array with one in the middle and two ends debug.info(2, "3 x 1 {} test".format(stack_name)) - c = contact.contact(layer_stack, (3, 1)) + c = factory.create(module_type="contact", layer_stack=layer_stack, dimensions=(3, 1)) self.local_drc_check(c) # check 3x3 array for all possible neighbors debug.info(2, "3 x 3 {} test".format(stack_name)) - c = contact.contact(layer_stack, (3, 3)) + c = factory.create(module_type="contact", layer_stack=layer_stack, dimensions=(3, 3)) self.local_drc_check(c) globals.end_openram() diff --git a/compiler/tests/03_path_test.py b/compiler/tests/03_path_test.py index 78abc9e3..4748e18d 100755 --- a/compiler/tests/03_path_test.py +++ b/compiler/tests/03_path_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# "Run a regression test on a basic path" import unittest diff --git a/compiler/tests/03_ptx_1finger_nmos_test.py b/compiler/tests/03_ptx_1finger_nmos_test.py index a5ea028c..cc6d6ed6 100755 --- a/compiler/tests/03_ptx_1finger_nmos_test.py +++ b/compiler/tests/03_ptx_1finger_nmos_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# "Run a regression test on a basic parameterized transistors" import unittest diff --git a/compiler/tests/03_ptx_1finger_pmos_test.py b/compiler/tests/03_ptx_1finger_pmos_test.py index f1a4de56..cd2128be 100755 --- a/compiler/tests/03_ptx_1finger_pmos_test.py +++ b/compiler/tests/03_ptx_1finger_pmos_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# "Run a regression test on a basic parameterized transistors" import unittest diff --git a/compiler/tests/03_ptx_3finger_nmos_test.py b/compiler/tests/03_ptx_3finger_nmos_test.py index 535560e1..8231f090 100755 --- a/compiler/tests/03_ptx_3finger_nmos_test.py +++ b/compiler/tests/03_ptx_3finger_nmos_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# "Run a regression test on a basic parameterized transistors" import unittest diff --git a/compiler/tests/03_ptx_3finger_pmos_test.py b/compiler/tests/03_ptx_3finger_pmos_test.py index fd2abc0b..16e3730b 100755 --- a/compiler/tests/03_ptx_3finger_pmos_test.py +++ b/compiler/tests/03_ptx_3finger_pmos_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# "Run a regression test on a basic parameterized transistors" import unittest diff --git a/compiler/tests/03_ptx_4finger_nmos_test.py b/compiler/tests/03_ptx_4finger_nmos_test.py index 56102419..c0a54d85 100755 --- a/compiler/tests/03_ptx_4finger_nmos_test.py +++ b/compiler/tests/03_ptx_4finger_nmos_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# "Run a regression test on a basic parameterized transistors" import unittest diff --git a/compiler/tests/03_ptx_4finger_pmos_test.py b/compiler/tests/03_ptx_4finger_pmos_test.py index 4d7181b1..afb874af 100755 --- a/compiler/tests/03_ptx_4finger_pmos_test.py +++ b/compiler/tests/03_ptx_4finger_pmos_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# "Run a regression test on a basic parameterized transistors" import unittest diff --git a/compiler/tests/03_wire_test.py b/compiler/tests/03_wire_test.py index 1cce5f08..3b3388e9 100755 --- a/compiler/tests/03_wire_test.py +++ b/compiler/tests/03_wire_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# "Run a regression test on a basic wire" import unittest diff --git a/compiler/tests/04_pand2_test.py b/compiler/tests/04_pand2_test.py index 8dd900fe..af99f6ec 100755 --- a/compiler/tests/04_pand2_test.py +++ b/compiler/tests/04_pand2_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ Run a regression test on a pand2 cell """ diff --git a/compiler/tests/04_pbitcell_test.py b/compiler/tests/04_pbitcell_test.py index b1edb5d7..e8b7cb55 100755 --- a/compiler/tests/04_pbitcell_test.py +++ b/compiler/tests/04_pbitcell_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ Run regresion tests on a parameterized bitcell """ diff --git a/compiler/tests/04_pbuf_test.py b/compiler/tests/04_pbuf_test.py index 7ee53781..9eeaaeab 100755 --- a/compiler/tests/04_pbuf_test.py +++ b/compiler/tests/04_pbuf_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ Run a regression test on a 2-row buffer cell """ diff --git a/compiler/tests/04_pdriver_test.py b/compiler/tests/04_pdriver_test.py index 65cc3ee3..ecd697c9 100755 --- a/compiler/tests/04_pdriver_test.py +++ b/compiler/tests/04_pdriver_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ Run a regression test on a 2-row buffer cell """ diff --git a/compiler/tests/04_pinv_10x_test.py b/compiler/tests/04_pinv_10x_test.py index d24b3ef4..0548cbf4 100755 --- a/compiler/tests/04_pinv_10x_test.py +++ b/compiler/tests/04_pinv_10x_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ Run regression tests on a parameterized inverter """ diff --git a/compiler/tests/04_pinv_1x_beta_test.py b/compiler/tests/04_pinv_1x_beta_test.py index 0786ed80..1f8aae26 100755 --- a/compiler/tests/04_pinv_1x_beta_test.py +++ b/compiler/tests/04_pinv_1x_beta_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ Run regression tests on a parameterized inverter """ diff --git a/compiler/tests/04_pinv_1x_test.py b/compiler/tests/04_pinv_1x_test.py index a83fc6ee..fd70d8dc 100755 --- a/compiler/tests/04_pinv_1x_test.py +++ b/compiler/tests/04_pinv_1x_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ Run regression tests on a parameterized inverter """ diff --git a/compiler/tests/04_pinv_2x_test.py b/compiler/tests/04_pinv_2x_test.py index 517c5b0a..6b472f9e 100755 --- a/compiler/tests/04_pinv_2x_test.py +++ b/compiler/tests/04_pinv_2x_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ Run regression tests on a parameterized inverter """ diff --git a/compiler/tests/04_pinvbuf_test.py b/compiler/tests/04_pinvbuf_test.py index 2febfab3..ea407d0c 100755 --- a/compiler/tests/04_pinvbuf_test.py +++ b/compiler/tests/04_pinvbuf_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ Run a regression test on a 2-row buffer cell """ diff --git a/compiler/tests/04_pnand2_test.py b/compiler/tests/04_pnand2_test.py index b8e25d52..527c6204 100755 --- a/compiler/tests/04_pnand2_test.py +++ b/compiler/tests/04_pnand2_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ Run regression tests on a parameterized nand 2. This module doesn't generate a multi_finger 2-input nand gate. It generates only a minimum diff --git a/compiler/tests/04_pnand3_test.py b/compiler/tests/04_pnand3_test.py index 9d0d8241..6dba468a 100755 --- a/compiler/tests/04_pnand3_test.py +++ b/compiler/tests/04_pnand3_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ Run regression tests on a parameterized pnand3. This module doesn't generate a multi-finger 3-input nand gate. diff --git a/compiler/tests/04_pnor2_test.py b/compiler/tests/04_pnor2_test.py index bb458b63..8a66324d 100755 --- a/compiler/tests/04_pnor2_test.py +++ b/compiler/tests/04_pnor2_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ Run regression tests on a parameterized nor 2. This module doesn't generate a multi_finger 2-input nor gate. It generates only a minimum diff --git a/compiler/tests/04_precharge_test.py b/compiler/tests/04_precharge_test.py index ccf05090..162f1091 100755 --- a/compiler/tests/04_precharge_test.py +++ b/compiler/tests/04_precharge_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ Run a regression test on a precharge cell """ diff --git a/compiler/tests/04_replica_pbitcell_test.py b/compiler/tests/04_replica_pbitcell_test.py index 7ce1b9cf..1e028e40 100755 --- a/compiler/tests/04_replica_pbitcell_test.py +++ b/compiler/tests/04_replica_pbitcell_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ Run a regression test on a replica pbitcell """ diff --git a/compiler/tests/04_single_level_column_mux_test.py b/compiler/tests/04_single_level_column_mux_test.py index 58d79ca4..151f2797 100755 --- a/compiler/tests/04_single_level_column_mux_test.py +++ b/compiler/tests/04_single_level_column_mux_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ Run a regression test on a wordline_driver array """ diff --git a/compiler/tests/05_bitcell_1rw_1r_array_test.py b/compiler/tests/05_bitcell_1rw_1r_array_test.py index 9ea0cc32..9df2c8c3 100755 --- a/compiler/tests/05_bitcell_1rw_1r_array_test.py +++ b/compiler/tests/05_bitcell_1rw_1r_array_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ Run a regression test on a basic array """ diff --git a/compiler/tests/05_bitcell_array_test.py b/compiler/tests/05_bitcell_array_test.py index 82eaf256..21943a5d 100755 --- a/compiler/tests/05_bitcell_array_test.py +++ b/compiler/tests/05_bitcell_array_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ Run a regression test on a basic array """ diff --git a/compiler/tests/05_pbitcell_array_test.py b/compiler/tests/05_pbitcell_array_test.py index 15040649..45968266 100755 --- a/compiler/tests/05_pbitcell_array_test.py +++ b/compiler/tests/05_pbitcell_array_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ Run a regression test on a basic array """ diff --git a/compiler/tests/06_hierarchical_decoder_test.py b/compiler/tests/06_hierarchical_decoder_test.py index f2277335..bcc22ce8 100755 --- a/compiler/tests/06_hierarchical_decoder_test.py +++ b/compiler/tests/06_hierarchical_decoder_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ Run a regression test on a hierarchical_decoder. """ diff --git a/compiler/tests/06_hierarchical_predecode2x4_test.py b/compiler/tests/06_hierarchical_predecode2x4_test.py index dce5069f..e4687d5e 100755 --- a/compiler/tests/06_hierarchical_predecode2x4_test.py +++ b/compiler/tests/06_hierarchical_predecode2x4_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ Run a regression test on a hierarchical_predecode2x4. """ diff --git a/compiler/tests/06_hierarchical_predecode3x8_test.py b/compiler/tests/06_hierarchical_predecode3x8_test.py index 1710b459..12e87d06 100755 --- a/compiler/tests/06_hierarchical_predecode3x8_test.py +++ b/compiler/tests/06_hierarchical_predecode3x8_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ Run a regression test on a hierarchical_predecode3x8. """ diff --git a/compiler/tests/07_single_level_column_mux_array_test.py b/compiler/tests/07_single_level_column_mux_array_test.py index 1ff0d65b..8da5f252 100755 --- a/compiler/tests/07_single_level_column_mux_array_test.py +++ b/compiler/tests/07_single_level_column_mux_array_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ Run a regression test on a single transistor column_mux. """ diff --git a/compiler/tests/08_precharge_array_test.py b/compiler/tests/08_precharge_array_test.py index eb6d75dd..86f308f4 100755 --- a/compiler/tests/08_precharge_array_test.py +++ b/compiler/tests/08_precharge_array_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ Run a regression test on a precharge array """ diff --git a/compiler/tests/08_wordline_driver_test.py b/compiler/tests/08_wordline_driver_test.py index 12edf32e..585b85cd 100755 --- a/compiler/tests/08_wordline_driver_test.py +++ b/compiler/tests/08_wordline_driver_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ Run a regression test on a wordline_driver array """ diff --git a/compiler/tests/09_sense_amp_array_test.py b/compiler/tests/09_sense_amp_array_test.py index 903e5512..12a20e8f 100755 --- a/compiler/tests/09_sense_amp_array_test.py +++ b/compiler/tests/09_sense_amp_array_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ Run a regression test on a sense amp array """ diff --git a/compiler/tests/10_write_driver_array_test.py b/compiler/tests/10_write_driver_array_test.py index f3ed3ee6..f5d0c23c 100755 --- a/compiler/tests/10_write_driver_array_test.py +++ b/compiler/tests/10_write_driver_array_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ Run a regression test on a write driver array """ diff --git a/compiler/tests/11_dff_array_test.py b/compiler/tests/11_dff_array_test.py index 5e3ce761..fc48adce 100755 --- a/compiler/tests/11_dff_array_test.py +++ b/compiler/tests/11_dff_array_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ Run a regression test on a dff_array. """ diff --git a/compiler/tests/11_dff_buf_array_test.py b/compiler/tests/11_dff_buf_array_test.py index 86d394e6..7d614d1b 100755 --- a/compiler/tests/11_dff_buf_array_test.py +++ b/compiler/tests/11_dff_buf_array_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ Run a regression test on a dff_array. """ diff --git a/compiler/tests/11_dff_buf_test.py b/compiler/tests/11_dff_buf_test.py index 30b56957..afb1f73b 100755 --- a/compiler/tests/11_dff_buf_test.py +++ b/compiler/tests/11_dff_buf_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ Run a regression test on a dff_buf. """ diff --git a/compiler/tests/12_tri_gate_array_test.py b/compiler/tests/12_tri_gate_array_test.py index 04ef1369..203c5f94 100755 --- a/compiler/tests/12_tri_gate_array_test.py +++ b/compiler/tests/12_tri_gate_array_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ Run a regression test on a tri_gate_array. """ diff --git a/compiler/tests/13_delay_chain_test.py b/compiler/tests/13_delay_chain_test.py index 1dbfbc67..498c1005 100755 --- a/compiler/tests/13_delay_chain_test.py +++ b/compiler/tests/13_delay_chain_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ Run a test on a delay chain """ diff --git a/compiler/tests/14_replica_bitline_multiport_test.py b/compiler/tests/14_replica_bitline_multiport_test.py index 3a83d397..947f9c52 100755 --- a/compiler/tests/14_replica_bitline_multiport_test.py +++ b/compiler/tests/14_replica_bitline_multiport_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ Run a test on a multiport replica bitline """ diff --git a/compiler/tests/14_replica_bitline_test.py b/compiler/tests/14_replica_bitline_test.py index 8c1c306c..b5830d63 100755 --- a/compiler/tests/14_replica_bitline_test.py +++ b/compiler/tests/14_replica_bitline_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ Run a test on a replica bitline """ diff --git a/compiler/tests/16_control_logic_test.py b/compiler/tests/16_control_logic_test.py index 2b9a8be2..ed8a0088 100755 --- a/compiler/tests/16_control_logic_test.py +++ b/compiler/tests/16_control_logic_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ Run a regression test on a control_logic """ diff --git a/compiler/tests/19_bank_select_test.py b/compiler/tests/19_bank_select_test.py index 9dcb6039..5ea16052 100755 --- a/compiler/tests/19_bank_select_test.py +++ b/compiler/tests/19_bank_select_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ Run a regression test on various srams """ diff --git a/compiler/tests/19_multi_bank_test.py b/compiler/tests/19_multi_bank_test.py index 57a089aa..3139b4eb 100755 --- a/compiler/tests/19_multi_bank_test.py +++ b/compiler/tests/19_multi_bank_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ Run a regression test on various srams """ diff --git a/compiler/tests/19_pmulti_bank_test.py b/compiler/tests/19_pmulti_bank_test.py index f201c778..f31e2608 100755 --- a/compiler/tests/19_pmulti_bank_test.py +++ b/compiler/tests/19_pmulti_bank_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ Run a regression test on various srams """ diff --git a/compiler/tests/19_psingle_bank_test.py b/compiler/tests/19_psingle_bank_test.py index c36df8ef..22c3da2f 100755 --- a/compiler/tests/19_psingle_bank_test.py +++ b/compiler/tests/19_psingle_bank_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ Run a regression test on various srams """ diff --git a/compiler/tests/19_single_bank_1rw_1r_test.py b/compiler/tests/19_single_bank_1rw_1r_test.py index 96fc2512..fb0e1c66 100755 --- a/compiler/tests/19_single_bank_1rw_1r_test.py +++ b/compiler/tests/19_single_bank_1rw_1r_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ Run a regression test on 1rw 1r sram bank """ diff --git a/compiler/tests/19_single_bank_test.py b/compiler/tests/19_single_bank_test.py index 368a7cad..72e61c0d 100755 --- a/compiler/tests/19_single_bank_test.py +++ b/compiler/tests/19_single_bank_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ Run a regression test on various srams """ diff --git a/compiler/tests/20_psram_1bank_2mux_1rw_1w_test.py b/compiler/tests/20_psram_1bank_2mux_1rw_1w_test.py index 22b878b9..4bdad91f 100755 --- a/compiler/tests/20_psram_1bank_2mux_1rw_1w_test.py +++ b/compiler/tests/20_psram_1bank_2mux_1rw_1w_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ Run a regression test on a 1 bank SRAM """ diff --git a/compiler/tests/20_psram_1bank_2mux_1w_1r_test.py b/compiler/tests/20_psram_1bank_2mux_1w_1r_test.py index 61d636d9..a0b2b242 100755 --- a/compiler/tests/20_psram_1bank_2mux_1w_1r_test.py +++ b/compiler/tests/20_psram_1bank_2mux_1w_1r_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ Run a regression test on a 1 bank SRAM """ diff --git a/compiler/tests/20_psram_1bank_2mux_test.py b/compiler/tests/20_psram_1bank_2mux_test.py index 7c38da90..c718daa3 100755 --- a/compiler/tests/20_psram_1bank_2mux_test.py +++ b/compiler/tests/20_psram_1bank_2mux_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ Run a regression test on a 1 bank SRAM """ diff --git a/compiler/tests/20_psram_1bank_4mux_1rw_1r_test.py b/compiler/tests/20_psram_1bank_4mux_1rw_1r_test.py index f7cb57fc..f415bd77 100755 --- a/compiler/tests/20_psram_1bank_4mux_1rw_1r_test.py +++ b/compiler/tests/20_psram_1bank_4mux_1rw_1r_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ Run a regression test on a 1 bank SRAM """ diff --git a/compiler/tests/20_sram_1bank_2mux_1rw_1r_test.py b/compiler/tests/20_sram_1bank_2mux_1rw_1r_test.py index b13c8020..46725bc5 100755 --- a/compiler/tests/20_sram_1bank_2mux_1rw_1r_test.py +++ b/compiler/tests/20_sram_1bank_2mux_1rw_1r_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ Run a regression test on a 1 bank, 2 port SRAM """ diff --git a/compiler/tests/20_sram_1bank_2mux_1w_1r_test.py b/compiler/tests/20_sram_1bank_2mux_1w_1r_test.py index a0d75054..fec42aeb 100755 --- a/compiler/tests/20_sram_1bank_2mux_1w_1r_test.py +++ b/compiler/tests/20_sram_1bank_2mux_1w_1r_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ Run a regression test on a 1 bank SRAM """ diff --git a/compiler/tests/20_sram_1bank_2mux_test.py b/compiler/tests/20_sram_1bank_2mux_test.py index 7f305c0e..c61ebe4f 100755 --- a/compiler/tests/20_sram_1bank_2mux_test.py +++ b/compiler/tests/20_sram_1bank_2mux_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ Run a regression test on a 1 bank SRAM """ diff --git a/compiler/tests/20_sram_1bank_4mux_test.py b/compiler/tests/20_sram_1bank_4mux_test.py index 96e8cfda..5d10903c 100755 --- a/compiler/tests/20_sram_1bank_4mux_test.py +++ b/compiler/tests/20_sram_1bank_4mux_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ Run a regression test on a 1 bank SRAM """ diff --git a/compiler/tests/20_sram_1bank_8mux_1rw_1r_test.py b/compiler/tests/20_sram_1bank_8mux_1rw_1r_test.py index b2cd395f..3a2c34e6 100755 --- a/compiler/tests/20_sram_1bank_8mux_1rw_1r_test.py +++ b/compiler/tests/20_sram_1bank_8mux_1rw_1r_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ Run a regression test on a 1 bank SRAM """ diff --git a/compiler/tests/20_sram_1bank_8mux_test.py b/compiler/tests/20_sram_1bank_8mux_test.py index f8b43835..94c073f9 100755 --- a/compiler/tests/20_sram_1bank_8mux_test.py +++ b/compiler/tests/20_sram_1bank_8mux_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ Run a regression test on a 1 bank SRAM """ diff --git a/compiler/tests/20_sram_1bank_nomux_1rw_1r_test.py b/compiler/tests/20_sram_1bank_nomux_1rw_1r_test.py index b33ef2c4..2ce13456 100755 --- a/compiler/tests/20_sram_1bank_nomux_1rw_1r_test.py +++ b/compiler/tests/20_sram_1bank_nomux_1rw_1r_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ Run a regression test on a 1 bank, 2 port SRAM """ diff --git a/compiler/tests/20_sram_1bank_nomux_test.py b/compiler/tests/20_sram_1bank_nomux_test.py index 004c7604..272d16ee 100755 --- a/compiler/tests/20_sram_1bank_nomux_test.py +++ b/compiler/tests/20_sram_1bank_nomux_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ Run a regression test on a 1 bank SRAM """ diff --git a/compiler/tests/20_sram_2bank_test.py b/compiler/tests/20_sram_2bank_test.py index b63691ec..b625f9ec 100755 --- a/compiler/tests/20_sram_2bank_test.py +++ b/compiler/tests/20_sram_2bank_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ Run a regression test on a 2 bank SRAM """ diff --git a/compiler/tests/21_hspice_delay_test.py b/compiler/tests/21_hspice_delay_test.py index abe65b02..aa6cbf49 100755 --- a/compiler/tests/21_hspice_delay_test.py +++ b/compiler/tests/21_hspice_delay_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ Run a regression test on various srams """ diff --git a/compiler/tests/21_hspice_setuphold_test.py b/compiler/tests/21_hspice_setuphold_test.py index 11020365..49c0d2cb 100755 --- a/compiler/tests/21_hspice_setuphold_test.py +++ b/compiler/tests/21_hspice_setuphold_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ Run a regression test on various srams """ diff --git a/compiler/tests/28_delay_model_test.py b/compiler/tests/21_model_delay_test.py similarity index 52% rename from compiler/tests/28_delay_model_test.py rename to compiler/tests/21_model_delay_test.py index 95db008b..c54a9118 100755 --- a/compiler/tests/28_delay_model_test.py +++ b/compiler/tests/21_model_delay_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ Run a regression test on various srams """ @@ -12,24 +19,21 @@ from globals import OPTS from sram_factory import factory import debug -class delay_model_test(openram_test): +class model_delay_sram_test(openram_test): def runTest(self): globals.init_openram("config_{0}".format(OPTS.tech_name)) - OPTS.spice_name="hspice" OPTS.analytical_delay = False OPTS.netlist_only = True - OPTS.trim_netlist = False - debug.info(1, "Trimming disabled for this test. Simulation could be slow.") # This is a hack to reload the characterizer __init__ with the spice version from importlib import reload import characterizer reload(characterizer) - - from characterizer import model_check + from characterizer import delay + from sram import sram from sram_config import sram_config - c = sram_config(word_size=4, + c = sram_config(word_size=1, num_words=16, num_banks=1) c.words_per_row=1 @@ -45,15 +49,32 @@ class delay_model_test(openram_test): debug.info(1, "Probe address {0} probe data bit {1}".format(probe_address, probe_data)) corner = (OPTS.process_corners[0], OPTS.supply_voltages[0], OPTS.temperatures[0]) - mc = model_check(s.s, tempspice, corner) + d = delay(s.s, tempspice, corner) import tech loads = [tech.spice["msflop_in_cap"]*4] slews = [tech.spice["rise_time"]*2] - sram_data = mc.analyze(probe_address, probe_data, slews, loads) - #Combine info about port into all data - - #debug.info(1,"Data:\n{}".format(wl_data)) + spice_data, port_data = d.analyze(probe_address, probe_data, slews, loads) + spice_data.update(port_data[0]) + + model_data, port_data = d.analytical_delay(slews, loads) + model_data.update(port_data[0]) + + #Only compare the delays + spice_delays = {key:value for key, value in spice_data.items() if 'delay' in key} + model_delays = {key:value for key, value in model_data.items() if 'delay' in key} + debug.info(1,"Spice Delays={}".format(spice_delays)) + debug.info(1,"Model Delays={}".format(model_delays)) + if OPTS.tech_name == "freepdk45": + error_tolerance = .25 + elif OPTS.tech_name == "scn4m_subm": + error_tolerance = .25 + else: + self.assertTrue(False) # other techs fail + # Check if no too many or too few results + self.assertTrue(len(spice_delays.keys())==len(model_delays.keys())) + self.assertTrue(self.check_golden_data(spice_delays,model_delays,error_tolerance)) + globals.end_openram() # run the test from the command line diff --git a/compiler/tests/21_ngspice_delay_test.py b/compiler/tests/21_ngspice_delay_test.py index c0b2c8fe..c12d3835 100755 --- a/compiler/tests/21_ngspice_delay_test.py +++ b/compiler/tests/21_ngspice_delay_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ Run a regression test on various srams """ diff --git a/compiler/tests/21_ngspice_setuphold_test.py b/compiler/tests/21_ngspice_setuphold_test.py index 774e3e75..abf64d33 100755 --- a/compiler/tests/21_ngspice_setuphold_test.py +++ b/compiler/tests/21_ngspice_setuphold_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ Run a regression test on various srams """ diff --git a/compiler/tests/22_psram_1bank_2mux_func_test.py b/compiler/tests/22_psram_1bank_2mux_func_test.py index 8606fd5f..4a99f009 100755 --- a/compiler/tests/22_psram_1bank_2mux_func_test.py +++ b/compiler/tests/22_psram_1bank_2mux_func_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ Run a regression test on various srams """ diff --git a/compiler/tests/22_psram_1bank_4mux_func_test.py b/compiler/tests/22_psram_1bank_4mux_func_test.py index 45c4676d..9eaa2671 100755 --- a/compiler/tests/22_psram_1bank_4mux_func_test.py +++ b/compiler/tests/22_psram_1bank_4mux_func_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ Run a regression test on various srams """ diff --git a/compiler/tests/22_psram_1bank_8mux_func_test.py b/compiler/tests/22_psram_1bank_8mux_func_test.py index 7bc75e2e..a0d52d1b 100755 --- a/compiler/tests/22_psram_1bank_8mux_func_test.py +++ b/compiler/tests/22_psram_1bank_8mux_func_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ Run a regression test on various srams """ diff --git a/compiler/tests/22_psram_1bank_nomux_func_test.py b/compiler/tests/22_psram_1bank_nomux_func_test.py index 1673c4f7..7b76e0da 100755 --- a/compiler/tests/22_psram_1bank_nomux_func_test.py +++ b/compiler/tests/22_psram_1bank_nomux_func_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ Run a functioal test on 1 bank SRAM """ diff --git a/compiler/tests/22_sram_1bank_2mux_func_test.py b/compiler/tests/22_sram_1bank_2mux_func_test.py index 60e8929d..e5fa9280 100755 --- a/compiler/tests/22_sram_1bank_2mux_func_test.py +++ b/compiler/tests/22_sram_1bank_2mux_func_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ Run a regression test on various srams """ diff --git a/compiler/tests/22_sram_1bank_4mux_func_test.py b/compiler/tests/22_sram_1bank_4mux_func_test.py index b768a7b9..dc06a882 100755 --- a/compiler/tests/22_sram_1bank_4mux_func_test.py +++ b/compiler/tests/22_sram_1bank_4mux_func_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ Run a regression test on various srams """ diff --git a/compiler/tests/22_sram_1bank_8mux_func_test.py b/compiler/tests/22_sram_1bank_8mux_func_test.py index 45aa2bff..ee3449ab 100755 --- a/compiler/tests/22_sram_1bank_8mux_func_test.py +++ b/compiler/tests/22_sram_1bank_8mux_func_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ Run a regression test on various srams """ diff --git a/compiler/tests/22_sram_1bank_nomux_func_test.py b/compiler/tests/22_sram_1bank_nomux_func_test.py index baf10e9e..bc626858 100755 --- a/compiler/tests/22_sram_1bank_nomux_func_test.py +++ b/compiler/tests/22_sram_1bank_nomux_func_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ Run a functioal test on 1 bank SRAM """ diff --git a/compiler/tests/22_sram_1rw_1r_1bank_nomux_func_test.py b/compiler/tests/22_sram_1rw_1r_1bank_nomux_func_test.py index df0ad3a6..0b8bffcc 100755 --- a/compiler/tests/22_sram_1rw_1r_1bank_nomux_func_test.py +++ b/compiler/tests/22_sram_1rw_1r_1bank_nomux_func_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ Run a functioal test on 1 bank SRAM """ diff --git a/compiler/tests/23_lib_sram_model_corners_test.py b/compiler/tests/23_lib_sram_model_corners_test.py index 6cac68b1..85d96a73 100755 --- a/compiler/tests/23_lib_sram_model_corners_test.py +++ b/compiler/tests/23_lib_sram_model_corners_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ Check the .lib file for an SRAM """ diff --git a/compiler/tests/23_lib_sram_model_test.py b/compiler/tests/23_lib_sram_model_test.py index 0b4e1efb..e1727794 100755 --- a/compiler/tests/23_lib_sram_model_test.py +++ b/compiler/tests/23_lib_sram_model_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ Check the .lib file for an SRAM """ diff --git a/compiler/tests/23_lib_sram_prune_test.py b/compiler/tests/23_lib_sram_prune_test.py index 266d3ba3..0d33d1af 100755 --- a/compiler/tests/23_lib_sram_prune_test.py +++ b/compiler/tests/23_lib_sram_prune_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ Check the .lib file for an SRAM with pruning """ diff --git a/compiler/tests/23_lib_sram_test.py b/compiler/tests/23_lib_sram_test.py index a81b1479..6f2bf0b7 100755 --- a/compiler/tests/23_lib_sram_test.py +++ b/compiler/tests/23_lib_sram_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ Check the .lib file for an SRAM """ diff --git a/compiler/tests/24_lef_sram_test.py b/compiler/tests/24_lef_sram_test.py index bd1fdc6a..362495d7 100755 --- a/compiler/tests/24_lef_sram_test.py +++ b/compiler/tests/24_lef_sram_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ Check the LEF file for an SRMA """ diff --git a/compiler/tests/25_verilog_sram_test.py b/compiler/tests/25_verilog_sram_test.py index 63810357..0bbe45b7 100755 --- a/compiler/tests/25_verilog_sram_test.py +++ b/compiler/tests/25_verilog_sram_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ Check the .v file for an SRAM """ diff --git a/compiler/tests/26_pex_test.py b/compiler/tests/26_pex_test.py index cd47a21c..5d26d26e 100755 --- a/compiler/tests/26_pex_test.py +++ b/compiler/tests/26_pex_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ Run a regression test on an extracted SRAM to ensure functionality. """ diff --git a/compiler/tests/27_worst_case_delay_test.py b/compiler/tests/27_worst_case_delay_test.py deleted file mode 100755 index da632862..00000000 --- a/compiler/tests/27_worst_case_delay_test.py +++ /dev/null @@ -1,80 +0,0 @@ -#!/usr/bin/env python3 -""" -Run a regression test on various srams -""" - -import unittest -from testutils import header,openram_test -import sys,os -sys.path.append(os.path.join(sys.path[0],"..")) -import globals -from globals import OPTS -from sram_factory import factory -import debug - -@unittest.skip("SKIPPING 27_worst_case_delay_test") -class worst_case_timing_sram_test(openram_test): - - def runTest(self): - OPTS.tech_name = "freepdk45" - globals.init_openram("config_{0}".format(OPTS.tech_name)) - OPTS.spice_name="hspice" - OPTS.analytical_delay = False - OPTS.netlist_only = True - OPTS.trim_netlist = False - - - # This is a hack to reload the characterizer __init__ with the spice version - from importlib import reload - import characterizer - reload(characterizer) - from characterizer import worst_case - if not OPTS.spice_exe: - debug.error("Could not find {} simulator.".format(OPTS.spice_name),-1) - - word_size, num_words, num_banks = 2, 16, 1 - from sram_config import sram_config - c = sram_config(word_size=word_size, - num_words=num_words, - num_banks=num_banks) - c.words_per_row=1 - c.recompute_sizes() - debug.info(1, "Testing the timing different bitecells inside a {}bit, {} words SRAM with {} bank".format( - word_size, num_words, num_banks)) - s = factory.create(module_type="sram", sram_config=c) - - sp_netlist_file = OPTS.openram_temp + "temp.sp" - s.sp_write(sp_netlist_file) - - if OPTS.use_pex: - gdsname = OPTS.output_path + s.name + ".gds" - s.gds_write(gdsname) - - import verify - reload(verify) - # Output the extracted design if requested - sp_pex_file = OPTS.output_path + s.name + "_pex.sp" - verify.run_pex(s.name, gdsname, sp_netlist_file, output=sp_pex_file) - sp_sim_file = sp_pex_file - debug.info(1, "Performing spice simulations with backannotated spice file.") - else: - sp_sim_file = sp_netlist_file - debug.info(1, "Performing spice simulations with spice netlist.") - - corner = (OPTS.process_corners[0], OPTS.supply_voltages[0], OPTS.temperatures[0]) - wc = worst_case(s.s, sp_sim_file, corner) - import tech - loads = [tech.spice["msflop_in_cap"]*4] - slews = [tech.spice["rise_time"]*2] - probe_address = "1" * s.s.addr_size - probe_data = s.s.word_size - 1 - wc.analyze(probe_address, probe_data, slews, loads) - - globals.end_openram() - -# run the test from the command line -if __name__ == "__main__": - (OPTS, args) = globals.parse_args() - del sys.argv[1:] - header(__file__, OPTS.tech_name) - unittest.main() diff --git a/compiler/tests/30_openram_test.py b/compiler/tests/30_openram_back_end_test.py similarity index 88% rename from compiler/tests/30_openram_test.py rename to compiler/tests/30_openram_back_end_test.py index 2681b351..d5cbe0af 100755 --- a/compiler/tests/30_openram_test.py +++ b/compiler/tests/30_openram_back_end_test.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ This tests the top-level executable. It checks that it generates the appropriate files: .lef, .lib, .sp, .gds, .v. It DOES NOT, however, @@ -20,10 +27,9 @@ class openram_test(openram_test): def runTest(self): OPENRAM_HOME = os.path.abspath(os.environ.get("OPENRAM_HOME")) globals.init_openram("{0}/tests/config_{1}".format(OPENRAM_HOME,OPTS.tech_name)) - - debug.info(1, "Testing top-level openram.py with 2-bit, 16 word SRAM.") + + debug.info(1, "Testing top-level back-end openram.py with 2-bit, 16 word SRAM.") out_file = "testsram" - # make a temp directory for output out_path = "/tmp/testsram_{0}_{1}_{2}/".format(OPTS.tech_name,getpass.getuser(),os.getpid()) # make sure we start without the files existing @@ -41,7 +47,6 @@ class openram_test(openram_test): verbosity = "" for i in range(OPTS.debug_level): verbosity += " -v" - # Always perform code coverage if OPTS.coverage == 0: @@ -49,7 +54,7 @@ class openram_test(openram_test): exe_name = "{0}/openram.py ".format(OPENRAM_HOME) else: exe_name = "coverage run -p {0}/openram.py ".format(OPENRAM_HOME) - config_name = "{0}config_{1}.py".format(OPENRAM_HOME + "/tests/",OPTS.tech_name) + config_name = "{0}config_{1}_back_end.py".format(OPENRAM_HOME + "/tests/",OPTS.tech_name) cmd = "{0} -n -o {1} -p {2} {3} {4} 2>&1 > {5}/output.log".format(exe_name, out_file, out_path, diff --git a/compiler/tests/30_openram_front_end_test.py b/compiler/tests/30_openram_front_end_test.py new file mode 100755 index 00000000..006d1bf3 --- /dev/null +++ b/compiler/tests/30_openram_front_end_test.py @@ -0,0 +1,102 @@ +#!/usr/bin/env python3 +""" +This tests the top-level executable. It checks that it generates the +appropriate files: .lef, .lib, .sp, .gds, .v. It DOES NOT, however, +check that these files are right. +""" + +import unittest +from testutils import header,openram_test +import sys,os,re,shutil +sys.path.append(os.path.join(sys.path[0],"..")) +import globals +from globals import OPTS +from sram_factory import factory +import debug +import getpass + +class openram_test(openram_test): + + def runTest(self): + OPENRAM_HOME = os.path.abspath(os.environ.get("OPENRAM_HOME")) + globals.init_openram("{0}/tests/config_{1}".format(OPENRAM_HOME,OPTS.tech_name)) + + debug.info(1, "Testing top-level front-end openram.py with 2-bit, 16 word SRAM.") + out_file = "testsram" + out_path = "/tmp/testsram_{0}_{1}_{2}".format(OPTS.tech_name,getpass.getuser(),os.getpid()) + + # make sure we start without the files existing + if os.path.exists(out_path): + shutil.rmtree(out_path, ignore_errors=True) + self.assertEqual(os.path.exists(out_path),False) + + try: + os.makedirs(out_path, 0o0750) + except OSError as e: + if e.errno == 17: # errno.EEXIST + os.chmod(out_path, 0o0750) + + # specify the same verbosity for the system call + verbosity = "" + for i in range(OPTS.debug_level): + verbosity += " -v" + + + # Always perform code coverage + if OPTS.coverage == 0: + debug.warning("Failed to find coverage installation. This can be installed with pip3 install coverage") + exe_name = "{0}/openram.py ".format(OPENRAM_HOME) + else: + exe_name = "coverage run -p {0}/openram.py ".format(OPENRAM_HOME) + config_name = "{0}config_{1}_front_end.py".format(OPENRAM_HOME + "/tests/",OPTS.tech_name) + cmd = "{0} -n -o {1} -p {2} {3} {4} 2>&1 > {5}/output.log".format(exe_name, + out_file, + out_path, + verbosity, + config_name, + out_path) + debug.info(1, cmd) + os.system(cmd) + + # assert an error until we actually check a result + for extension in ["v", "lef", "sp"]: + filename = "{0}/{1}.{2}".format(out_path,out_file,extension) + debug.info(1,"Checking for file: " + filename) + self.assertEqual(os.path.exists(filename),True) + # assert an error if we output the incomplete gds! + for extension in ["gds"]: + filename = "{0}/{1}.{2}".format(out_path,out_file,extension) + debug.info(1,"Checking file does NOT exist: " + filename) + self.assertEqual(os.path.exists(filename),False) + + # Make sure there is any .lib file + import glob + files = glob.glob('{0}/*.lib'.format(out_path)) + self.assertTrue(len(files)>0) + + # Make sure there is any .html file + if os.path.exists(out_path): + datasheets = glob.glob('{0}/*html'.format(out_path)) + self.assertTrue(len(datasheets)>0) + + # grep any errors from the output + output_log = open("{0}/output.log".format(out_path),"r") + output = output_log.read() + output_log.close() + self.assertEqual(len(re.findall('ERROR',output)),0) + self.assertEqual(len(re.findall('WARNING',output)),0) + + + # now clean up the directory + if os.path.exists(out_path): + shutil.rmtree(out_path, ignore_errors=True) + self.assertEqual(os.path.exists(out_path),False) + + globals.end_openram() + +# run the test from the command line +if __name__ == "__main__": + (OPTS, args) = globals.parse_args() + del sys.argv[1:] + header(__file__, OPTS.tech_name) + unittest.main() diff --git a/compiler/tests/config_freepdk45.py b/compiler/tests/config_freepdk45.py old mode 100755 new mode 100644 index 7a1da315..5a5b2054 --- a/compiler/tests/config_freepdk45.py +++ b/compiler/tests/config_freepdk45.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# word_size = 1 num_words = 16 diff --git a/compiler/tests/config_freepdk45_back_end.py b/compiler/tests/config_freepdk45_back_end.py new file mode 100644 index 00000000..5fc87ead --- /dev/null +++ b/compiler/tests/config_freepdk45_back_end.py @@ -0,0 +1,20 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# +word_size = 1 +num_words = 16 + +tech_name = "freepdk45" +process_corners = ["TT"] +supply_voltages = [1.0] +temperatures = [25] + +inline_lvsdrc = True +route_supplies = True +check_lvsdrc = True + + diff --git a/compiler/tests/config_freepdk45_front_end.py b/compiler/tests/config_freepdk45_front_end.py old mode 100755 new mode 100644 index 81da24e8..69d58442 --- a/compiler/tests/config_freepdk45_front_end.py +++ b/compiler/tests/config_freepdk45_front_end.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# word_size = 1 num_words = 16 diff --git a/compiler/tests/config_scn4m_subm.py b/compiler/tests/config_scn4m_subm.py old mode 100755 new mode 100644 index adb1c99d..61e5cfe9 --- a/compiler/tests/config_scn4m_subm.py +++ b/compiler/tests/config_scn4m_subm.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# word_size = 1 num_words = 16 diff --git a/compiler/tests/config_scn4m_subm_back_end.py b/compiler/tests/config_scn4m_subm_back_end.py new file mode 100644 index 00000000..d966abfa --- /dev/null +++ b/compiler/tests/config_scn4m_subm_back_end.py @@ -0,0 +1,22 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# +word_size = 1 +num_words = 16 + +tech_name = "scn4m_subm" +process_corners = ["TT"] +supply_voltages = [5.0] +temperatures = [25] + +route_supplies = True +check_lvsdrc = True +inline_lvsdrc = True + +drc_name = "magic" +lvs_name = "netgen" +pex_name = "magic" diff --git a/compiler/tests/config_scn4m_subm_front_end.py b/compiler/tests/config_scn4m_subm_front_end.py old mode 100755 new mode 100644 index e847745b..d0c8de85 --- a/compiler/tests/config_scn4m_subm_front_end.py +++ b/compiler/tests/config_scn4m_subm_front_end.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# word_size = 1 num_words = 16 diff --git a/compiler/tests/regress.py b/compiler/tests/regress.py index d97def2b..c6591cf4 100755 --- a/compiler/tests/regress.py +++ b/compiler/tests/regress.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# import re import unittest diff --git a/compiler/tests/testutils.py b/compiler/tests/testutils.py old mode 100755 new mode 100644 index 799c223e..dfe34361 --- a/compiler/tests/testutils.py +++ b/compiler/tests/testutils.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# import unittest,warnings import sys,os,glob,copy import shutil diff --git a/compiler/verify/__init__.py b/compiler/verify/__init__.py index 1f0ffaab..04fa9746 100644 --- a/compiler/verify/__init__.py +++ b/compiler/verify/__init__.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ This is a module that will import the correct DRC/LVS/PEX module based on what tools are found. It is a layer of indirection diff --git a/compiler/verify/assura.py b/compiler/verify/assura.py index af034730..f7777fdb 100644 --- a/compiler/verify/assura.py +++ b/compiler/verify/assura.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ This is a DRC/LVS interface for Assura. It implements completely two functions: run_drc and run_lvs, that perform these functions in batch diff --git a/compiler/verify/calibre.py b/compiler/verify/calibre.py index 5f8d2c73..509e05fd 100644 --- a/compiler/verify/calibre.py +++ b/compiler/verify/calibre.py @@ -1,82 +1,37 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ This is a DRC/LVS interface for calibre. It implements completely -independently two functions: run_drc and run_lvs, that perform these +independently three functions: run_drc, run_lvs, run_pex, that perform these functions in batch mode and will return true/false if the result passes. All of the setup (the rules, temp dirs, etc.) should be contained in this file. Replacing with another DRC/LVS tool involves rewriting this code to work properly. Porting to a new technology in Calibre means pointing the code to the proper DRC and LVS rule files. -A calibre DRC runset file contains, at the minimum, the following information: - -*drcRulesFile: /mada/software/techfiles/FreePDK45/ncsu_basekit/techfile/calibre/calibreDRC.rul -*drcRunDir: . -*drcLayoutPaths: ./cell_6t.gds -*drcLayoutPrimary: cell_6t -*drcLayoutSystem: GDSII -*drcResultsformat: ASCII -*drcResultsFile: cell_6t.drc.results -*drcSummaryFile: cell_6t.drc.summary -*cmnFDILayerMapFile: ./layer.map -*cmnFDIUseLayerMap: 1 - -This can be executed in "batch" mode with the following command: - -calibre -gui -drc example_drc_runset -batch - -To open the results, you can do this: - -calibredrv cell_6t.gds -Select Verification->Start RVE. -Select the cell_6t.drc.results file. -Click on the errors and they will highlight in the design layout viewer. - -For LVS: - -*lvsRulesFile: /mada/software/techfiles/FreePDK45/ncsu_basekit/techfile/calibre/calibreLVS.rul -*lvsRunDir: . -*lvsLayoutPaths: ./cell_6t.gds -*lvsLayoutPrimary: cell_6t -*lvsSourcePath: ./cell_6t.sp -*lvsSourcePrimary: cell_6t -*lvsSourceSystem: SPICE -*lvsSpiceFile: extracted.sp -*lvsPowerNames: vdd -*lvsGroundNames: vss -*lvsIgnorePorts: 1 -*lvsERCDatabase: cell_6t.erc.results -*lvsERCSummaryFile: cell_6t.erc.summary -*lvsReportFile: cell_6t.lvs.report -*lvsMaskDBFile: cell_6t.maskdb -*cmnFDILayerMapFile: ./layer.map -*cmnFDIUseLayerMap: 1 - -To run and see results: - -calibre -gui -lvs example_lvs_runset -batch -more cell_6t.lvs.report """ import os +import shutil import re import time import debug from globals import OPTS -import subprocess +from run_script import * # Keep track of statistics num_drc_runs = 0 num_lvs_runs = 0 num_pex_runs = 0 -def run_drc(cell_name, gds_name, extract=False, final_verification=False): - """Run DRC check on a given top-level name which is - implemented in gds_name.""" - - global num_drc_runs - num_drc_runs += 1 - +def write_calibre_drc_script(cell_name, extract, final_verification): + """ Write a Calibre runset file and script to run DRC """ # the runset file contains all the options to run calibre from tech import drc drc_rules = drc["drc_rules"] @@ -84,12 +39,12 @@ def run_drc(cell_name, gds_name, extract=False, final_verification=False): drc_runset = { 'drcRulesFile': drc_rules, 'drcRunDir': OPTS.openram_temp, - 'drcLayoutPaths': gds_name, + 'drcLayoutPaths': cell_name + ".gds", 'drcLayoutPrimary': cell_name, 'drcLayoutSystem': 'GDSII', 'drcResultsformat': 'ASCII', - 'drcResultsFile': OPTS.openram_temp + cell_name + ".drc.results", - 'drcSummaryFile': OPTS.openram_temp + cell_name + ".drc.summary", + 'drcResultsFile': cell_name + ".drc.results", + 'drcSummaryFile': cell_name + ".drc.summary", 'cmnFDILayerMapFile': drc["layer_map"], 'cmnFDIUseLayerMap': 1 } @@ -100,26 +55,148 @@ def run_drc(cell_name, gds_name, extract=False, final_verification=False): f.write("*{0}: {1}\n".format(k, drc_runset[k])) f.close() - # run drc - cwd = os.getcwd() - os.chdir(OPTS.openram_temp) - errfile = "{0}{1}.drc.err".format(OPTS.openram_temp, cell_name) - outfile = "{0}{1}.drc.out".format(OPTS.openram_temp, cell_name) + # Create an auxiliary script to run calibre with the runset + run_file = OPTS.openram_temp + "run_drc.sh" + f = open(run_file, "w") + f.write("#!/bin/sh\n") + cmd = "{0} -gui -drc {1}drc_runset -batch".format(OPTS.drc_exe[1], + OPTS.openram_temp) + f.write(cmd) + f.write("\n") + f.close() + os.system("chmod u+x {}".format(run_file)) + return drc_runset - cmd = "{0} -gui -drc {1}drc_runset -batch 2> {2} 1> {3}".format(OPTS.drc_exe[1], - OPTS.openram_temp, - errfile, - outfile) - debug.info(2, cmd) - os.system(cmd) - os.chdir(cwd) +def write_calibre_lvs_script(cell_name, final_verification): + """ Write a Calibre runset file and script to run LVS """ + + from tech import drc + lvs_rules = drc["lvs_rules"] + lvs_runset = { + 'lvsRulesFile': lvs_rules, + 'lvsRunDir': OPTS.openram_temp, + 'lvsLayoutPaths': cell_name + ".gds", + 'lvsLayoutPrimary': cell_name, + 'lvsSourcePath': cell_name + ".sp", + 'lvsSourcePrimary': cell_name, + 'lvsSourceSystem': 'SPICE', + 'lvsSpiceFile': "extracted.sp", + 'lvsPowerNames': 'vdd', + 'lvsGroundNames': 'gnd', + 'lvsIncludeSVRFCmds': 1, + 'lvsIgnorePorts': 1, + 'lvsERCDatabase': cell_name + ".erc.results", + 'lvsERCSummaryFile': cell_name + ".erc.summary", + 'lvsReportFile': cell_name + ".lvs.report", + 'lvsMaskDBFile': cell_name + ".maskdb", + 'cmnFDILayerMapFile': drc["layer_map"], + 'cmnFDIUseLayerMap': 1, + 'cmnTranscriptFile': './lvs.log', + 'cmnTranscriptEchoToFile': 1, + 'lvsRecognizeGates': 'NONE', + } + # FIXME: Remove when vdd/gnd connected + #'cmnVConnectNamesState' : 'ALL', #connects all nets with the same namee + # FIXME: Remove when vdd/gnd connected + #'lvsAbortOnSupplyError' : 0 + + if not final_verification: + lvs_runset['cmnVConnectReport']=1 + lvs_runset['cmnVConnectNamesState']='SOME' + lvs_runset['cmnVConnectNames']='vdd gnd' + else: + lvs_runset['lvsAbortOnSupplyError']=1 + + + + # write the runset file + f = open(OPTS.openram_temp + "lvs_runset", "w") + for k in sorted(iter(lvs_runset.keys())): + f.write("*{0}: {1}\n".format(k, lvs_runset[k])) + f.close() + + # Create an auxiliary script to run calibre with the runset + run_file = OPTS.openram_temp + "run_lvs.sh" + f = open(run_file, "w") + f.write("#!/bin/sh\n") + PDK_DIR=os.environ.get("PDK_DIR") + f.write("export PDK_DIR={}\n".format(PDK_DIR)) + cmd = "{0} -gui -lvs {1}lvs_runset -batch".format(OPTS.lvs_exe[1], + OPTS.openram_temp) + f.write(cmd) + f.write("\n") + f.close() + os.system("chmod u+x {}".format(run_file)) + + return lvs_runset + +def write_calibre_pex_script(cell_name, extract, output, final_verification): + + if output == None: + output = name + ".pex.netlist" + + # check if lvs report has been done + # if not run drc and lvs + if not os.path.isfile(cell_name + ".lvs.report"): + run_drc(cell_name, gds_name) + run_lvs(cell_name, gds_name, sp_name) + + pex_rules = drc["xrc_rules"] + pex_runset = { + 'pexRulesFile': pex_rules, + 'pexRunDir': OPTS.openram_temp, + 'pexLayoutPaths': cell_name + ".gds", + 'pexLayoutPrimary': cell_name, + #'pexSourcePath' : OPTS.openram_temp+"extracted.sp", + 'pexSourcePath': cell_name + ".sp", + 'pexSourcePrimary': cell_name, + 'pexReportFile': cell_name + ".lvs.report", + 'pexPexNetlistFile': cell_name + ".pex.netlist", + 'pexPexReportFile': cell_name + ".pex.report", + 'pexMaskDBFile': cell_name + ".maskdb", + 'cmnFDIDEFLayoutPath': cell_name + ".def", + } + + # write the runset file + f = open(OPTS.openram_temp + "pex_runset", "w") + for k in sorted(iter(pex_runset.keys())): + f.write("*{0}: {1}\n".format(k, pex_runset[k])) + f.close() + + # Create an auxiliary script to run calibre with the runset + run_file = OPTS.openram_temp + "run_pex.sh" + f = open(run_file, "w") + f.write("#!/bin/sh\n") + cmd = "{0} -gui -pex {1}pex_runset -batch".format(OPTS.pex_exe[1], + OPTS.openram_temp) + f.write(cmd) + f.write("\n") + f.close() + os.system("chmod u+x {}".format(run_file)) + + return pex_runset + +def run_drc(cell_name, gds_name, extract=False, final_verification=False): + """Run DRC check on a given top-level name which is + implemented in gds_name.""" + + global num_drc_runs + num_drc_runs += 1 + + # Copy file to local dir if it isn't already + if os.path.dirname(gds_name)!=OPTS.openram_temp.rstrip('/'): + shutil.copy(gds_name, OPTS.openram_temp) + + drc_runset = write_calibre_drc_script(cell_name, extract, final_verification) + + (outfile, errfile, resultsfile) = run_script(cell_name, "drc") # check the result for these lines in the summary: # TOTAL Original Layer Geometries: 106 (157) # TOTAL DRC RuleChecks Executed: 156 # TOTAL DRC Results Generated: 0 (0) try: - f = open(drc_runset['drcSummaryFile'], "r") + f = open(OPTS.openram_temp + drc_runset['drcSummaryFile'], "r") except: debug.error("Unable to retrieve DRC results file. Is calibre set up?",1) results = f.readlines() @@ -152,67 +229,18 @@ def run_lvs(cell_name, gds_name, sp_name, final_verification=False): global num_lvs_runs num_lvs_runs += 1 - from tech import drc - lvs_rules = drc["lvs_rules"] - lvs_runset = { - 'lvsRulesFile': lvs_rules, - 'lvsRunDir': OPTS.openram_temp, - 'lvsLayoutPaths': gds_name, - 'lvsLayoutPrimary': cell_name, - 'lvsSourcePath': sp_name, - 'lvsSourcePrimary': cell_name, - 'lvsSourceSystem': 'SPICE', - 'lvsSpiceFile': OPTS.openram_temp + "extracted.sp", - 'lvsPowerNames': 'vdd', - 'lvsGroundNames': 'gnd', - 'lvsIncludeSVRFCmds': 1, - 'lvsIgnorePorts': 1, - 'lvsERCDatabase': OPTS.openram_temp + cell_name + ".erc.results", - 'lvsERCSummaryFile': OPTS.openram_temp + cell_name + ".erc.summary", - 'lvsReportFile': OPTS.openram_temp + cell_name + ".lvs.report", - 'lvsMaskDBFile': OPTS.openram_temp + cell_name + ".maskdb", - 'cmnFDILayerMapFile': drc["layer_map"], - 'cmnFDIUseLayerMap': 1, - 'cmnTranscriptFile': './lvs.log', - 'cmnTranscriptEchoToFile': 1, - 'lvsRecognizeGates': 'NONE', - } - # FIXME: Remove when vdd/gnd connected - #'cmnVConnectNamesState' : 'ALL', #connects all nets with the same namee - # FIXME: Remove when vdd/gnd connected - #'lvsAbortOnSupplyError' : 0 + lvs_runset = write_calibre_lvs_script(cell_name, final_verification) - if not final_verification: - lvs_runset['cmnVConnectReport']=1 - lvs_runset['cmnVConnectNamesState']='SOME' - lvs_runset['cmnVConnectNames']='vdd gnd' - else: - lvs_runset['lvsAbortOnSupplyError']=1 - + # Copy file to local dir if it isn't already + if os.path.dirname(gds_name)!=OPTS.openram_temp.rstrip('/'): + shutil.copy(gds_name, OPTS.openram_temp) + if os.path.dirname(sp_name)!=OPTS.openram_temp.rstrip('/'): + shutil.copy(sp_name, OPTS.openram_temp) - - # write the runset file - f = open(OPTS.openram_temp + "lvs_runset", "w") - for k in sorted(iter(lvs_runset.keys())): - f.write("*{0}: {1}\n".format(k, lvs_runset[k])) - f.close() - - # run LVS - cwd = os.getcwd() - os.chdir(OPTS.openram_temp) - errfile = "{0}{1}.lvs.err".format(OPTS.openram_temp, cell_name) - outfile = "{0}{1}.lvs.out".format(OPTS.openram_temp, cell_name) - - cmd = "{0} -gui -lvs {1}lvs_runset -batch 2> {2} 1> {3}".format(OPTS.lvs_exe[1], - OPTS.openram_temp, - errfile, - outfile) - debug.info(2, cmd) - os.system(cmd) - os.chdir(cwd) + (outfile, errfile, resultsfile) = run_script(cell_name, "lvs") # check the result for these lines in the summary: - f = open(lvs_runset['lvsReportFile'], "r") + f = open(OPTS.openram_temp + lvs_runset['lvsReportFile'], "r") results = f.readlines() f.close() @@ -235,7 +263,7 @@ def run_lvs(cell_name, gds_name, sp_name, final_verification=False): summary_errors = len(notcompared) + len(incorrect) + len(errors) # also check the extraction summary file - f = open(lvs_runset['lvsReportFile'] + ".ext", "r") + f = open(OPTS.openram_temp + lvs_runset['lvsReportFile'] + ".ext", "r") results = f.readlines() f.close() @@ -288,52 +316,11 @@ def run_pex(cell_name, gds_name, sp_name, output=None, final_verification=False) global num_pex_runs num_pex_runs += 1 - - from tech import drc - if output == None: - output = name + ".pex.netlist" - # check if lvs report has been done - # if not run drc and lvs - if not os.path.isfile(cell_name + ".lvs.report"): - run_drc(cell_name, gds_name) - run_lvs(cell_name, gds_name, sp_name) + write_calibre_pex_script() - pex_rules = drc["xrc_rules"] - pex_runset = { - 'pexRulesFile': pex_rules, - 'pexRunDir': OPTS.openram_temp, - 'pexLayoutPaths': gds_name, - 'pexLayoutPrimary': cell_name, - #'pexSourcePath' : OPTS.openram_temp+"extracted.sp", - 'pexSourcePath': sp_name, - 'pexSourcePrimary': cell_name, - 'pexReportFile': cell_name + ".lvs.report", - 'pexPexNetlistFile': output, - 'pexPexReportFile': cell_name + ".pex.report", - 'pexMaskDBFile': cell_name + ".maskdb", - 'cmnFDIDEFLayoutPath': cell_name + ".def", - } - - # write the runset file - f = open(OPTS.openram_temp + "pex_runset", "w") - for k in sorted(iter(pex_runset.keys())): - f.write("*{0}: {1}\n".format(k, pex_runset[k])) - f.close() - - # run pex - cwd = os.getcwd() - os.chdir(OPTS.openram_temp) - errfile = "{0}{1}.pex.err".format(OPTS.openram_temp, cell_name) - outfile = "{0}{1}.pex.out".format(OPTS.openram_temp, cell_name) - - cmd = "{0} -gui -pex {1}pex_runset -batch 2> {2} 1> {3}".format(OPTS.pex_exe[1], - OPTS.openram_temp, - errfile, - outfile) - debug.info(2, cmd) - os.system(cmd) - os.chdir(cwd) + (outfile, errfile, resultsfile) = run_script(cell_name, "pex") + # also check the output file f = open(outfile, "r") diff --git a/compiler/verify/magic.py b/compiler/verify/magic.py index 5c5a65da..2db87ae2 100644 --- a/compiler/verify/magic.py +++ b/compiler/verify/magic.py @@ -1,7 +1,14 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ This is a DRC/LVS/PEX interface file for magic + netgen. -We include the tech file for SCN3ME_SUBM in the tech directory, +We include the tech file for SCN4M_SUBM in the tech directory, that is included in OpenRAM during DRC. You can use this interactively by appending the magic system path in your .magicrc file @@ -19,14 +26,15 @@ import time import shutil import debug from globals import OPTS -import subprocess +from run_script import * # Keep track of statistics num_drc_runs = 0 num_lvs_runs = 0 num_pex_runs = 0 -def write_magic_script(cell_name, gds_name, extract=False, final_verification=False): + +def write_magic_script(cell_name, extract=False, final_verification=False): """ Write a magic script to perform DRC and optionally extraction. """ global OPTS @@ -37,7 +45,7 @@ def write_magic_script(cell_name, gds_name, extract=False, final_verification=Fa f.write("{} -dnull -noconsole << EOF\n".format(OPTS.drc_exe[1])) f.write("gds polygon subcell true\n") f.write("gds warning default\n") - f.write("gds read {}\n".format(gds_name)) + f.write("gds read {}.gds\n".format(cell_name)) f.write("load {}\n".format(cell_name)) # Flatten the cell to get rid of DRCs spanning multiple layers # (e.g. with routes) @@ -53,6 +61,7 @@ def write_magic_script(cell_name, gds_name, extract=False, final_verification=Fa f.write("drc catchup\n") f.write("drc count total\n") f.write("drc count\n") + f.write("port makeall\n") if not extract: pre = "#" else: @@ -84,15 +93,17 @@ def write_magic_script(cell_name, gds_name, extract=False, final_verification=Fa f.close() os.system("chmod u+x {}".format(run_file)) -def write_netgen_script(cell_name, sp_name): + +def write_netgen_script(cell_name): """ Write a netgen script to perform LVS. """ global OPTS - setup_file = OPTS.openram_tech + "mag_lib/setup.tcl" - if os.path.exists(setup_file): + setup_file = "setup.tcl" + full_setup_file = OPTS.openram_tech + "mag_lib/" + setup_file + if os.path.exists(full_setup_file): # Copy setup.tcl file into temp dir - shutil.copy(setup_file, OPTS.openram_temp) + shutil.copy(full_setup_file, OPTS.openram_temp) else: setup_file = 'nosetup' @@ -101,14 +112,8 @@ def write_netgen_script(cell_name, sp_name): f.write("#!/bin/sh\n") f.write("{} -noconsole << EOF\n".format(OPTS.lvs_exe[1])) f.write("readnet spice {0}.spice\n".format(cell_name)) - f.write("readnet spice {0}\n".format(sp_name)) - # Allow some flexibility in W size because magic will snap to a lambda grid - # This can also cause disconnects unfortunately! - # f.write("property {{{0}{1}.spice nfet}} tolerance {{w 0.1}}\n".format(OPTS.openram_temp, - # cell_name)) - # f.write("property {{{0}{1}.spice pfet}} tolerance {{w 0.1}}\n".format(OPTS.openram_temp, - # cell_name)) - f.write("lvs {0}.spice {{{1} {0}}} {2} {0}.lvs.report\n".format(cell_name, sp_name, setup_file)) + f.write("readnet spice {0}.sp\n".format(cell_name)) + f.write("lvs {{{0}.spice {0}}} {{{0}.sp {0}}} {1} {0}.lvs.report\n".format(cell_name, setup_file)) f.write("quit\n") f.write("EOF\n") f.close() @@ -121,6 +126,10 @@ def run_drc(cell_name, gds_name, extract=True, final_verification=False): global num_drc_runs num_drc_runs += 1 + # Copy file to local dir if it isn't already + if os.path.dirname(gds_name)!=OPTS.openram_temp.rstrip('/'): + shutil.copy(gds_name, OPTS.openram_temp) + # Copy .magicrc file into temp dir magic_file = OPTS.openram_tech + "mag_lib/.magicrc" if os.path.exists(magic_file): @@ -128,20 +137,9 @@ def run_drc(cell_name, gds_name, extract=True, final_verification=False): else: debug.warning("Could not locate .magicrc file: {}".format(magic_file)) - write_magic_script(cell_name, gds_name, extract, final_verification) - - # run drc - cwd = os.getcwd() - os.chdir(OPTS.openram_temp) - errfile = "{0}{1}.drc.err".format(OPTS.openram_temp, cell_name) - outfile = "{0}{1}.drc.summary".format(OPTS.openram_temp, cell_name) + write_magic_script(cell_name, extract, final_verification) - cmd = "{0}run_drc.sh 2> {1} 1> {2}".format(OPTS.openram_temp, - errfile, - outfile) - debug.info(2, cmd) - os.system(cmd) - os.chdir(cwd) + (outfile, errfile, resultsfile) = run_script(cell_name, "drc") # Check the result for these lines in the summary: # Total DRC errors found: 0 @@ -185,23 +183,17 @@ def run_lvs(cell_name, gds_name, sp_name, final_verification=False): global num_lvs_runs num_lvs_runs += 1 - - write_netgen_script(cell_name, sp_name) - - # run LVS - cwd = os.getcwd() - os.chdir(OPTS.openram_temp) - errfile = "{0}{1}.lvs.err".format(OPTS.openram_temp, cell_name) - outfile = "{0}{1}.lvs.out".format(OPTS.openram_temp, cell_name) - resultsfile = "{0}{1}.lvs.report".format(OPTS.openram_temp, cell_name) - cmd = "{0}run_lvs.sh lvs 2> {1} 1> {2}".format(OPTS.openram_temp, - errfile, - outfile) - debug.info(2, cmd) - os.system(cmd) - os.chdir(cwd) + # Copy file to local dir if it isn't already + if os.path.dirname(gds_name)!=OPTS.openram_temp.rstrip('/'): + shutil.copy(gds_name, OPTS.openram_temp) + if os.path.dirname(sp_name)!=OPTS.openram_temp.rstrip('/'): + shutil.copy(sp_name, OPTS.openram_temp) + + write_netgen_script(cell_name) + (outfile, errfile, resultsfile) = run_script(cell_name, "lvs") + total_errors = 0 # check the result for these lines in the summary: diff --git a/compiler/verify/none.py b/compiler/verify/none.py index c69ed93b..68246463 100644 --- a/compiler/verify/none.py +++ b/compiler/verify/none.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ This is a DRC/LVS/PEX interface file the case with no DRC/LVS tools. diff --git a/compiler/verify/run_script.py b/compiler/verify/run_script.py new file mode 100644 index 00000000..71f55074 --- /dev/null +++ b/compiler/verify/run_script.py @@ -0,0 +1,34 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# +""" +Some baseline functions to run scripts. +""" + +import os +import debug +from globals import OPTS + +def run_script(cell_name, script="lvs"): + """ Run script and create output files. """ + + cwd = os.getcwd() + os.chdir(OPTS.openram_temp) + errfile = "{0}{1}.{2}.err".format(OPTS.openram_temp, cell_name, script) + outfile = "{0}{1}.{2}.out".format(OPTS.openram_temp, cell_name, script) + resultsfile = "{0}{1}.{2}.report".format(OPTS.openram_temp, cell_name, script) + + cmd = "{0}run_{1}.sh 2> {2} 1> {3}".format(OPTS.openram_temp, + script, + errfile, + outfile) + debug.info(2, cmd) + os.system(cmd) + os.chdir(cwd) + + return (outfile,errfile,resultsfile) + diff --git a/compiler/view_profile.py b/compiler/view_profile.py index aadcd459..b292dce2 100755 --- a/compiler/view_profile.py +++ b/compiler/view_profile.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# import pstats p = pstats.Stats("profile.dat") p.strip_dirs() diff --git a/technology/freepdk45/__init__.py b/technology/freepdk45/__init__.py index f7f801ea..0ad8d108 100644 --- a/technology/freepdk45/__init__.py +++ b/technology/freepdk45/__init__.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# #!/usr/bin/python """ This type of setup script should be placed in the setup_scripts directory in diff --git a/technology/freepdk45/lib/.cadence/cadence.signature.xml b/technology/freepdk45/lib/.cadence/cadence.signature.xml deleted file mode 100755 index 64bab7f4..00000000 --- a/technology/freepdk45/lib/.cadence/cadence.signature.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - Do not remove or change this .cadence directory signature file. diff --git a/technology/freepdk45/lib/.cadence/dfII/viva/viva.ini b/technology/freepdk45/lib/.cadence/dfII/viva/viva.ini deleted file mode 100755 index dfde08be..00000000 --- a/technology/freepdk45/lib/.cadence/dfII/viva/viva.ini +++ /dev/null @@ -1,43 +0,0 @@ -[browser] -orientation=horizontal -pathlist=/mada/users/cpeters/Working/simulations/latch.run1/si.raw, /mada/users/cpeters/Working/simulations/out_latch.run1/si.raw, /mada/users/cpeters/Working/simulations/ms_ff.run1/si.raw -pos=@Point(1118 92) -size=@Size(214 928) -splitter=@ByteArray(\0\0\0\xff\0\0\0\0\0\0\0\x2\0\0\0\0\0\0\0\xc0\x1\0\0\0\x4\x1\0\0\0\x1) - -[fullCalculator] -_bufferState=@Invalid() -_funcPanelName=undefined -_funcPanelSplitter=@ByteArray(\0\0\0\xff\0\0\0\0\0\0\0\x2\0\0\0\xb3\0\0\x1\xb4\0\0\0\0\x4\x1\0\0\0\x2) -_funcPanelType=FuncListType -_keyPadSplitter=@ByteArray(\0\0\0\xff\0\0\0\0\0\0\0\x2\0\0\x2\xf4\0\0\0\x64\x1\0\0\0\x4\x1\0\0\0\x1) -_resultsDir= -_signalSelectionHistory=@Invalid() -_splitter=@ByteArray(\0\0\0\xff\0\0\0\0\0\0\0\x2\0\0\0\xb3\0\0\0\0\x1\0\0\0\x4\x1\0\0\0\x2) -_testName= -clipSelectionMode=true -defaultCategory=Special Functions -displayContext=true -mathToolBar=false -plotStyle=Append -pos=@Point(582 186) -rpnMode=true -schematicAnalyses="tran,ac,dc,sweptDc,info,noise,rf" -schematicToolBar=true -showKeyPad=true -showStack=false -signalSelection=Off -size=@Size(866 834) -trigToolBar=false -userButton1=user 1, undefined -userButton10=user 1, undefined -userButton11=user 1, undefined -userButton12=user 1, undefined -userButton2=user 2, undefined -userButton3=user 3, undefined -userButton4=user 4, undefined -userButton5=user 5, undefined -userButton6=user 6, undefined -userButton7=user 7, undefined -userButton8=user 8, undefined -userButton9=user 9, undefined diff --git a/technology/freepdk45/lib/.cdsinit b/technology/freepdk45/lib/.cdsinit deleted file mode 100755 index 14e60079..00000000 --- a/technology/freepdk45/lib/.cdsinit +++ /dev/null @@ -1,47 +0,0 @@ - -envSetVal( "graphic" "drfPath" 'string - strcat( getShellEnvVar("PDK_DIR") "/ncsu_basekit/cdssetup/display.drf")) - - -loadi( strcat( getShellEnvVar("PDK_DIR") "/ncsu_basekit/cdssetup/common_bindkeys.il")) -if( getShellEnvVar("MGC_HOME") then - loadi( strcat( getShellEnvVar("MGC_HOME") "/shared/pkgs/icv/tools/queryskl/calibre.OA.skl")) -) ;if -procedure( prependNCSUCDKInstallPath( dir) - strcat( getShellEnvVar("PDK_DIR") "/ncsu_basekit/" dir)) -(envLoadVals -?envFile ( prependNCSUCDKInstallPath "cdssetup/cdsenv") -?tool "layout") - -printf( strcat( -"---------------------------------------------------------------------------\n" -"Welcome to the FreePDK 45nm Free, Open-Source Process Design Kit\n" -"\n" -"This initiative is brought to you by the Semiconductor Research\n" -"Corporation (SRC), the National Science Foundation (NSF), Silicon\n" -"Integration Initiative (Si2), Mentor Graphics, and Synopsys.\n" -"\n" -"This version of the kit was created by Rhett Davis, Paul Franzon,\n" -"Michael Bucher, and Sunil Basavarajaiah of North Carolina State University,\n" -"and James Stine and Ivan Castellanos of Oklahoma State University.\n" -"\n" -"Contributions and modifications to this kit are welcomed and encouraged.\n" -"\n" -"Copyright 2008 North Carolina State University (ncsu_basekit subtree)\n" -" and Oklahoma State University (osu_soc subtree)\n" -"\n" -"Licensed under the Apache License, Version 2.0 (the \"License\");\n" -"you may not use this file except in compliance with the License.\n" -"You may obtain a copy of the License at\n" -"\n" -" http://www.apache.org/licenses/LICENSE-2.0\n" -"\n" -"Unless required by applicable law or agreed to in writing, software\n" -"distributed under the License is distributed on an \"AS IS\" BASIS,\n" -"WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n" -"See the License for the specific language governing permissions and\n" -"limitations under the License.\n" -"---------------------------------------------------------------------------\n" -"\n" -"Done loading FreePDK customizations.\n" -)) diff --git a/technology/freepdk45/lib/.runset.calibre.drc b/technology/freepdk45/lib/.runset.calibre.drc deleted file mode 100755 index 35186ce6..00000000 --- a/technology/freepdk45/lib/.runset.calibre.drc +++ /dev/null @@ -1,2 +0,0 @@ -*drcRulesFile: $PDK_DIR/ncsu_basekit/techfile/calibre/calibreDRC.rul - diff --git a/technology/freepdk45/lib/.runset.calibre.lfd b/technology/freepdk45/lib/.runset.calibre.lfd deleted file mode 100755 index f770b0a1..00000000 --- a/technology/freepdk45/lib/.runset.calibre.lfd +++ /dev/null @@ -1,2 +0,0 @@ -*drcRulesFile: $PDK_DIR/ncsu_basekit/techfile/calibre/calibreLFD.rul - diff --git a/technology/freepdk45/lib/.runset.calibre.lvs b/technology/freepdk45/lib/.runset.calibre.lvs deleted file mode 100755 index aa47aacb..00000000 --- a/technology/freepdk45/lib/.runset.calibre.lvs +++ /dev/null @@ -1,3 +0,0 @@ -*lvsRulesFile: $PDK_DIR/ncsu_basekit/techfile/calibre/calibreLVS.rul - - diff --git a/technology/freepdk45/lib/.runset.calibre.pex b/technology/freepdk45/lib/.runset.calibre.pex deleted file mode 100755 index a1f8b6d9..00000000 --- a/technology/freepdk45/lib/.runset.calibre.pex +++ /dev/null @@ -1,3 +0,0 @@ -*pexRulesFile: $PDK_DIR/ncsu_basekit/techfile/calibre/calibrexRC.rul - - diff --git a/technology/freepdk45/lib/cds.lib b/technology/freepdk45/lib/cds.lib deleted file mode 100644 index e3c63316..00000000 --- a/technology/freepdk45/lib/cds.lib +++ /dev/null @@ -1,8 +0,0 @@ -DEFINE analogLib $CDSHOME/tools/dfII/etc/cdslib/artist/analogLib -DEFINE US_8ths $CDSHOME/tools/dfII/etc/cdslib/sheets/US_8ths -DEFINE basic $CDSHOME/tools/dfII/etc/cdslib/basic -DEFINE cdsDefTechLib $CDSHOME/tools/dfII/etc/cdsDefTechLib -DEFINE NCSU_TechLib_FreePDK45 $PDK_DIR/ncsu_basekit/lib/NCSU_TechLib_FreePDK45 -DEFINE NCSU_Devices_FreePDK45 $PDK_DIR/ncsu_basekit/lib/NCSU_Devices_FreePDK45 -DEFINE sram $OPENRAM_HOME/lib/sram -DEFINE sub_sram $OPENRAM_HOME/lib/sub_sram diff --git a/technology/freepdk45/lib/lib.defs b/technology/freepdk45/lib/lib.defs deleted file mode 100644 index c2a6982c..00000000 --- a/technology/freepdk45/lib/lib.defs +++ /dev/null @@ -1,16 +0,0 @@ -DEFINE analogLib $CDSHOME/tools/dfII/etc/cdslib/artist/analogLib -ASSIGN analogLib libMode shared -DEFINE US_8ths $CDSHOME/tools/dfII/etc/cdslib/sheets/US_8ths -ASSIGN US_8ths libMode shared -DEFINE basic $CDSHOME/tools/dfII/etc/cdslib/basic -ASSIGN basic libMode shared -DEFINE cdsDefTechLib $CDSHOME/tools/dfII/etc/cdsDefTechLib -ASSIGN cdsDefTechLib libMode shared -DEFINE NCSU_TechLib_FreePDK45 $PDK_DIR/ncsu_basekit/lib/NCSU_TechLib_FreePDK45 -ASSIGN NCSU_TechLib_FreePDK45 libMode shared -DEFINE NCSU_Devices_FreePDK45 $PDK_DIR/ncsu_basekit/lib/NCSU_Devices_FreePDK45 -ASSIGN NCSU_Devices_FreePDK45 libMode shared -DEFINE sram $OPENRAM_HOME/lib/sram -ASSIGN sram libMode shared -DEFINE sub_sram $OPENRAM_HOME/lib/sub_sram -ASSIGN sub_sram libMode shared diff --git a/technology/freepdk45/lib/sram/.oalib b/technology/freepdk45/lib/sram/.oalib deleted file mode 100755 index 21ffef89..00000000 --- a/technology/freepdk45/lib/sram/.oalib +++ /dev/null @@ -1,6 +0,0 @@ - - - - - diff --git a/technology/freepdk45/lib/sram/addr_ff/layout/layout.oa b/technology/freepdk45/lib/sram/addr_ff/layout/layout.oa deleted file mode 100755 index 60a18e10..00000000 Binary files a/technology/freepdk45/lib/sram/addr_ff/layout/layout.oa and /dev/null differ diff --git a/technology/freepdk45/lib/sram/addr_ff/layout/master.tag b/technology/freepdk45/lib/sram/addr_ff/layout/master.tag deleted file mode 100755 index 431d8f04..00000000 --- a/technology/freepdk45/lib/sram/addr_ff/layout/master.tag +++ /dev/null @@ -1,2 +0,0 @@ --- Master.tag File, Rev:1.0 -layout.oa diff --git a/technology/freepdk45/lib/sram/addr_ff/schematic/data.dm b/technology/freepdk45/lib/sram/addr_ff/schematic/data.dm deleted file mode 100755 index 11925091..00000000 Binary files a/technology/freepdk45/lib/sram/addr_ff/schematic/data.dm and /dev/null differ diff --git a/technology/freepdk45/lib/sram/addr_ff/schematic/master.tag b/technology/freepdk45/lib/sram/addr_ff/schematic/master.tag deleted file mode 100755 index 26be1bef..00000000 --- a/technology/freepdk45/lib/sram/addr_ff/schematic/master.tag +++ /dev/null @@ -1,2 +0,0 @@ --- Master.tag File, Rev:1.0 -sch.oa diff --git a/technology/freepdk45/lib/sram/addr_ff/schematic/sch.oa b/technology/freepdk45/lib/sram/addr_ff/schematic/sch.oa deleted file mode 100755 index eabefc20..00000000 Binary files a/technology/freepdk45/lib/sram/addr_ff/schematic/sch.oa and /dev/null differ diff --git a/technology/freepdk45/lib/sram/addr_latch/layout/layout.oa b/technology/freepdk45/lib/sram/addr_latch/layout/layout.oa deleted file mode 100755 index 3525ac02..00000000 Binary files a/technology/freepdk45/lib/sram/addr_latch/layout/layout.oa and /dev/null differ diff --git a/technology/freepdk45/lib/sram/addr_latch/layout/master.tag b/technology/freepdk45/lib/sram/addr_latch/layout/master.tag deleted file mode 100755 index 431d8f04..00000000 --- a/technology/freepdk45/lib/sram/addr_latch/layout/master.tag +++ /dev/null @@ -1,2 +0,0 @@ --- Master.tag File, Rev:1.0 -layout.oa diff --git a/technology/freepdk45/lib/sram/addr_latch/schematic/data.dm b/technology/freepdk45/lib/sram/addr_latch/schematic/data.dm deleted file mode 100755 index 6a4c9f97..00000000 Binary files a/technology/freepdk45/lib/sram/addr_latch/schematic/data.dm and /dev/null differ diff --git a/technology/freepdk45/lib/sram/addr_latch/schematic/master.tag b/technology/freepdk45/lib/sram/addr_latch/schematic/master.tag deleted file mode 100755 index 26be1bef..00000000 --- a/technology/freepdk45/lib/sram/addr_latch/schematic/master.tag +++ /dev/null @@ -1,2 +0,0 @@ --- Master.tag File, Rev:1.0 -sch.oa diff --git a/technology/freepdk45/lib/sram/addr_latch/schematic/sch.oa b/technology/freepdk45/lib/sram/addr_latch/schematic/sch.oa deleted file mode 100755 index 74b3999f..00000000 Binary files a/technology/freepdk45/lib/sram/addr_latch/schematic/sch.oa and /dev/null differ diff --git a/technology/freepdk45/lib/sram/array/layout/layout.oa b/technology/freepdk45/lib/sram/array/layout/layout.oa deleted file mode 100755 index 8af1983b..00000000 Binary files a/technology/freepdk45/lib/sram/array/layout/layout.oa and /dev/null differ diff --git a/technology/freepdk45/lib/sram/array/layout/master.tag b/technology/freepdk45/lib/sram/array/layout/master.tag deleted file mode 100755 index 431d8f04..00000000 --- a/technology/freepdk45/lib/sram/array/layout/master.tag +++ /dev/null @@ -1,2 +0,0 @@ --- Master.tag File, Rev:1.0 -layout.oa diff --git a/technology/freepdk45/lib/sram/cdsinfo.tag b/technology/freepdk45/lib/sram/cdsinfo.tag deleted file mode 100644 index a8dcdcb4..00000000 --- a/technology/freepdk45/lib/sram/cdsinfo.tag +++ /dev/null @@ -1,40 +0,0 @@ -# -# This is a cdsinfo.tag file. -# -# See the "Cadence Application Infrastructure Reference Manual" for -# details on the format of this file, its semantics, and its use. -# -# The `#' character denotes a comment. Removing the leading `#' -# character from any of the entries below will activate them. -# -# CDSLIBRARY entry - add this entry if the directory containing -# this cdsinfo.tag file is the root of a Cadence library. -# CDSLIBRARY -# -# CDSLIBCHECK - set this entry to require that libraries have -# a cdsinfo.tag file with a CDSLIBRARY entry. Legal values are -# ON and OFF. By default (OFF), directories named in a cds.lib file -# do not have to have a cdsinfo.tag file with a CDSLIBRARY entry. -# CDSLIBCHECK ON -# -# DMTYPE - set this entry to define the DM system for Cadence's -# Generic DM facility. Values will be shifted to lower case. -# DMTYPE none -# DMTYPE crcs -# DMTYPE tdm -# DMTYPE sync -# -# NAMESPACE - set this entry to define the library namespace according -# to the type of machine on which the data is stored. Legal values are -# `LibraryNT' and -# `LibraryUnix'. -# NAMESPACE LibraryUnix -# -# Other entries may be added for use by specific applications as -# name-value pairs. Application documentation will describe the -# use and behaviour of these entries when appropriate. -# -# Current Settings: -# -CDSLIBRARY -NAMESPACE LibraryUnix diff --git a/technology/freepdk45/lib/sram/cell_10t/layout/layout.oa b/technology/freepdk45/lib/sram/cell_10t/layout/layout.oa deleted file mode 100755 index d19dccf7..00000000 Binary files a/technology/freepdk45/lib/sram/cell_10t/layout/layout.oa and /dev/null differ diff --git a/technology/freepdk45/lib/sram/cell_10t/layout/layout.oa- b/technology/freepdk45/lib/sram/cell_10t/layout/layout.oa- deleted file mode 100755 index 7f81fccb..00000000 Binary files a/technology/freepdk45/lib/sram/cell_10t/layout/layout.oa- and /dev/null differ diff --git a/technology/freepdk45/lib/sram/cell_10t/layout/master.tag b/technology/freepdk45/lib/sram/cell_10t/layout/master.tag deleted file mode 100755 index 431d8f04..00000000 --- a/technology/freepdk45/lib/sram/cell_10t/layout/master.tag +++ /dev/null @@ -1,2 +0,0 @@ --- Master.tag File, Rev:1.0 -layout.oa diff --git a/technology/freepdk45/lib/sram/cell_10t/schematic/data.dm b/technology/freepdk45/lib/sram/cell_10t/schematic/data.dm deleted file mode 100755 index ff96d2ab..00000000 Binary files a/technology/freepdk45/lib/sram/cell_10t/schematic/data.dm and /dev/null differ diff --git a/technology/freepdk45/lib/sram/cell_10t/schematic/master.tag b/technology/freepdk45/lib/sram/cell_10t/schematic/master.tag deleted file mode 100755 index 26be1bef..00000000 --- a/technology/freepdk45/lib/sram/cell_10t/schematic/master.tag +++ /dev/null @@ -1,2 +0,0 @@ --- Master.tag File, Rev:1.0 -sch.oa diff --git a/technology/freepdk45/lib/sram/cell_10t/schematic/sch.oa b/technology/freepdk45/lib/sram/cell_10t/schematic/sch.oa deleted file mode 100755 index 8f2d4cd0..00000000 Binary files a/technology/freepdk45/lib/sram/cell_10t/schematic/sch.oa and /dev/null differ diff --git a/technology/freepdk45/lib/sram/cell_6t/layout/layout.oa b/technology/freepdk45/lib/sram/cell_6t/layout/layout.oa deleted file mode 100755 index 2c763698..00000000 Binary files a/technology/freepdk45/lib/sram/cell_6t/layout/layout.oa and /dev/null differ diff --git a/technology/freepdk45/lib/sram/cell_6t/layout/layout.oa- b/technology/freepdk45/lib/sram/cell_6t/layout/layout.oa- deleted file mode 100755 index 43f013e8..00000000 Binary files a/technology/freepdk45/lib/sram/cell_6t/layout/layout.oa- and /dev/null differ diff --git a/technology/freepdk45/lib/sram/cell_6t/layout/master.tag b/technology/freepdk45/lib/sram/cell_6t/layout/master.tag deleted file mode 100755 index 431d8f04..00000000 --- a/technology/freepdk45/lib/sram/cell_6t/layout/master.tag +++ /dev/null @@ -1,2 +0,0 @@ --- Master.tag File, Rev:1.0 -layout.oa diff --git a/technology/freepdk45/lib/sram/cell_6t/schematic/data.dm b/technology/freepdk45/lib/sram/cell_6t/schematic/data.dm deleted file mode 100755 index c2d60e51..00000000 Binary files a/technology/freepdk45/lib/sram/cell_6t/schematic/data.dm and /dev/null differ diff --git a/technology/freepdk45/lib/sram/cell_6t/schematic/master.tag b/technology/freepdk45/lib/sram/cell_6t/schematic/master.tag deleted file mode 100755 index 26be1bef..00000000 --- a/technology/freepdk45/lib/sram/cell_6t/schematic/master.tag +++ /dev/null @@ -1,2 +0,0 @@ --- Master.tag File, Rev:1.0 -sch.oa diff --git a/technology/freepdk45/lib/sram/cell_6t/schematic/sch.oa b/technology/freepdk45/lib/sram/cell_6t/schematic/sch.oa deleted file mode 100755 index 51940d44..00000000 Binary files a/technology/freepdk45/lib/sram/cell_6t/schematic/sch.oa and /dev/null differ diff --git a/technology/freepdk45/lib/sram/clock_nor/layout/layout.oa b/technology/freepdk45/lib/sram/clock_nor/layout/layout.oa deleted file mode 100755 index 7bf4d583..00000000 Binary files a/technology/freepdk45/lib/sram/clock_nor/layout/layout.oa and /dev/null differ diff --git a/technology/freepdk45/lib/sram/clock_nor/layout/master.tag b/technology/freepdk45/lib/sram/clock_nor/layout/master.tag deleted file mode 100755 index 431d8f04..00000000 --- a/technology/freepdk45/lib/sram/clock_nor/layout/master.tag +++ /dev/null @@ -1,2 +0,0 @@ --- Master.tag File, Rev:1.0 -layout.oa diff --git a/technology/freepdk45/lib/sram/data.dm b/technology/freepdk45/lib/sram/data.dm deleted file mode 100644 index 329ccd3c..00000000 Binary files a/technology/freepdk45/lib/sram/data.dm and /dev/null differ diff --git a/technology/freepdk45/lib/sram/delay_line/layout/layout.oa b/technology/freepdk45/lib/sram/delay_line/layout/layout.oa deleted file mode 100755 index 2a84a075..00000000 Binary files a/technology/freepdk45/lib/sram/delay_line/layout/layout.oa and /dev/null differ diff --git a/technology/freepdk45/lib/sram/delay_line/layout/master.tag b/technology/freepdk45/lib/sram/delay_line/layout/master.tag deleted file mode 100755 index 431d8f04..00000000 --- a/technology/freepdk45/lib/sram/delay_line/layout/master.tag +++ /dev/null @@ -1,2 +0,0 @@ --- Master.tag File, Rev:1.0 -layout.oa diff --git a/technology/freepdk45/lib/sram/dinv/layout/layout.oa b/technology/freepdk45/lib/sram/dinv/layout/layout.oa deleted file mode 100755 index a7735463..00000000 Binary files a/technology/freepdk45/lib/sram/dinv/layout/layout.oa and /dev/null differ diff --git a/technology/freepdk45/lib/sram/dinv/layout/master.tag b/technology/freepdk45/lib/sram/dinv/layout/master.tag deleted file mode 100755 index 431d8f04..00000000 --- a/technology/freepdk45/lib/sram/dinv/layout/master.tag +++ /dev/null @@ -1,2 +0,0 @@ --- Master.tag File, Rev:1.0 -layout.oa diff --git a/technology/freepdk45/lib/sram/dinv_mx/layout/layout.oa b/technology/freepdk45/lib/sram/dinv_mx/layout/layout.oa deleted file mode 100755 index ca7c13d2..00000000 Binary files a/technology/freepdk45/lib/sram/dinv_mx/layout/layout.oa and /dev/null differ diff --git a/technology/freepdk45/lib/sram/dinv_mx/layout/master.tag b/technology/freepdk45/lib/sram/dinv_mx/layout/master.tag deleted file mode 100755 index 431d8f04..00000000 --- a/technology/freepdk45/lib/sram/dinv_mx/layout/master.tag +++ /dev/null @@ -1,2 +0,0 @@ --- Master.tag File, Rev:1.0 -layout.oa diff --git a/technology/freepdk45/lib/sram/inv/layout/layout.oa b/technology/freepdk45/lib/sram/inv/layout/layout.oa deleted file mode 100755 index e98db560..00000000 Binary files a/technology/freepdk45/lib/sram/inv/layout/layout.oa and /dev/null differ diff --git a/technology/freepdk45/lib/sram/inv/layout/master.tag b/technology/freepdk45/lib/sram/inv/layout/master.tag deleted file mode 100755 index 431d8f04..00000000 --- a/technology/freepdk45/lib/sram/inv/layout/master.tag +++ /dev/null @@ -1,2 +0,0 @@ --- Master.tag File, Rev:1.0 -layout.oa diff --git a/technology/freepdk45/lib/sram/inv_clk/layout/layout.oa b/technology/freepdk45/lib/sram/inv_clk/layout/layout.oa deleted file mode 100755 index 20790f89..00000000 Binary files a/technology/freepdk45/lib/sram/inv_clk/layout/layout.oa and /dev/null differ diff --git a/technology/freepdk45/lib/sram/inv_clk/layout/master.tag b/technology/freepdk45/lib/sram/inv_clk/layout/master.tag deleted file mode 100755 index 431d8f04..00000000 --- a/technology/freepdk45/lib/sram/inv_clk/layout/master.tag +++ /dev/null @@ -1,2 +0,0 @@ --- Master.tag File, Rev:1.0 -layout.oa diff --git a/technology/freepdk45/lib/sram/inv_col/layout/layout.oa b/technology/freepdk45/lib/sram/inv_col/layout/layout.oa deleted file mode 100755 index 3335bece..00000000 Binary files a/technology/freepdk45/lib/sram/inv_col/layout/layout.oa and /dev/null differ diff --git a/technology/freepdk45/lib/sram/inv_col/layout/master.tag b/technology/freepdk45/lib/sram/inv_col/layout/master.tag deleted file mode 100755 index 431d8f04..00000000 --- a/technology/freepdk45/lib/sram/inv_col/layout/master.tag +++ /dev/null @@ -1,2 +0,0 @@ --- Master.tag File, Rev:1.0 -layout.oa diff --git a/technology/freepdk45/lib/sram/inv_dec/layout/layout.oa b/technology/freepdk45/lib/sram/inv_dec/layout/layout.oa deleted file mode 100755 index 3ec1f587..00000000 Binary files a/technology/freepdk45/lib/sram/inv_dec/layout/layout.oa and /dev/null differ diff --git a/technology/freepdk45/lib/sram/inv_dec/layout/master.tag b/technology/freepdk45/lib/sram/inv_dec/layout/master.tag deleted file mode 100755 index 431d8f04..00000000 --- a/technology/freepdk45/lib/sram/inv_dec/layout/master.tag +++ /dev/null @@ -1,2 +0,0 @@ --- Master.tag File, Rev:1.0 -layout.oa diff --git a/technology/freepdk45/lib/sram/inv_nor/layout/layout.oa b/technology/freepdk45/lib/sram/inv_nor/layout/layout.oa deleted file mode 100755 index 6c23bc4e..00000000 Binary files a/technology/freepdk45/lib/sram/inv_nor/layout/layout.oa and /dev/null differ diff --git a/technology/freepdk45/lib/sram/inv_nor/layout/master.tag b/technology/freepdk45/lib/sram/inv_nor/layout/master.tag deleted file mode 100755 index 431d8f04..00000000 --- a/technology/freepdk45/lib/sram/inv_nor/layout/master.tag +++ /dev/null @@ -1,2 +0,0 @@ --- Master.tag File, Rev:1.0 -layout.oa diff --git a/technology/freepdk45/lib/sram/mux_a/layout/layout.oa b/technology/freepdk45/lib/sram/mux_a/layout/layout.oa deleted file mode 100755 index 16e1369b..00000000 Binary files a/technology/freepdk45/lib/sram/mux_a/layout/layout.oa and /dev/null differ diff --git a/technology/freepdk45/lib/sram/mux_a/layout/master.tag b/technology/freepdk45/lib/sram/mux_a/layout/master.tag deleted file mode 100755 index 431d8f04..00000000 --- a/technology/freepdk45/lib/sram/mux_a/layout/master.tag +++ /dev/null @@ -1,2 +0,0 @@ --- Master.tag File, Rev:1.0 -layout.oa diff --git a/technology/freepdk45/lib/sram/mux_abar/layout/layout.oa b/technology/freepdk45/lib/sram/mux_abar/layout/layout.oa deleted file mode 100755 index 126897ec..00000000 Binary files a/technology/freepdk45/lib/sram/mux_abar/layout/layout.oa and /dev/null differ diff --git a/technology/freepdk45/lib/sram/mux_abar/layout/master.tag b/technology/freepdk45/lib/sram/mux_abar/layout/master.tag deleted file mode 100755 index 431d8f04..00000000 --- a/technology/freepdk45/lib/sram/mux_abar/layout/master.tag +++ /dev/null @@ -1,2 +0,0 @@ --- Master.tag File, Rev:1.0 -layout.oa diff --git a/technology/freepdk45/lib/sram/nor_1/layout/layout.oa b/technology/freepdk45/lib/sram/nor_1/layout/layout.oa deleted file mode 100755 index b0d79792..00000000 Binary files a/technology/freepdk45/lib/sram/nor_1/layout/layout.oa and /dev/null differ diff --git a/technology/freepdk45/lib/sram/nor_1/layout/master.tag b/technology/freepdk45/lib/sram/nor_1/layout/master.tag deleted file mode 100755 index 431d8f04..00000000 --- a/technology/freepdk45/lib/sram/nor_1/layout/master.tag +++ /dev/null @@ -1,2 +0,0 @@ --- Master.tag File, Rev:1.0 -layout.oa diff --git a/technology/freepdk45/lib/sram/nor_1_mx/layout/layout.oa b/technology/freepdk45/lib/sram/nor_1_mx/layout/layout.oa deleted file mode 100755 index 82764ea0..00000000 Binary files a/technology/freepdk45/lib/sram/nor_1_mx/layout/layout.oa and /dev/null differ diff --git a/technology/freepdk45/lib/sram/nor_1_mx/layout/master.tag b/technology/freepdk45/lib/sram/nor_1_mx/layout/master.tag deleted file mode 100755 index 431d8f04..00000000 --- a/technology/freepdk45/lib/sram/nor_1_mx/layout/master.tag +++ /dev/null @@ -1,2 +0,0 @@ --- Master.tag File, Rev:1.0 -layout.oa diff --git a/technology/freepdk45/lib/sram/ntap/layout/layout.oa b/technology/freepdk45/lib/sram/ntap/layout/layout.oa deleted file mode 100755 index aa2cdc19..00000000 Binary files a/technology/freepdk45/lib/sram/ntap/layout/layout.oa and /dev/null differ diff --git a/technology/freepdk45/lib/sram/ntap/layout/master.tag b/technology/freepdk45/lib/sram/ntap/layout/master.tag deleted file mode 100755 index 431d8f04..00000000 --- a/technology/freepdk45/lib/sram/ntap/layout/master.tag +++ /dev/null @@ -1,2 +0,0 @@ --- Master.tag File, Rev:1.0 -layout.oa diff --git a/technology/freepdk45/lib/sram/out_inv_16/layout/layout.oa b/technology/freepdk45/lib/sram/out_inv_16/layout/layout.oa deleted file mode 100755 index 00d0b24e..00000000 Binary files a/technology/freepdk45/lib/sram/out_inv_16/layout/layout.oa and /dev/null differ diff --git a/technology/freepdk45/lib/sram/out_inv_16/layout/layout.oa- b/technology/freepdk45/lib/sram/out_inv_16/layout/layout.oa- deleted file mode 100755 index 211c52e7..00000000 Binary files a/technology/freepdk45/lib/sram/out_inv_16/layout/layout.oa- and /dev/null differ diff --git a/technology/freepdk45/lib/sram/out_inv_16/layout/master.tag b/technology/freepdk45/lib/sram/out_inv_16/layout/master.tag deleted file mode 100755 index 431d8f04..00000000 --- a/technology/freepdk45/lib/sram/out_inv_16/layout/master.tag +++ /dev/null @@ -1,2 +0,0 @@ --- Master.tag File, Rev:1.0 -layout.oa diff --git a/technology/freepdk45/lib/sram/out_inv_2/layout/layout.oa b/technology/freepdk45/lib/sram/out_inv_2/layout/layout.oa deleted file mode 100755 index c1480a3c..00000000 Binary files a/technology/freepdk45/lib/sram/out_inv_2/layout/layout.oa and /dev/null differ diff --git a/technology/freepdk45/lib/sram/out_inv_2/layout/layout.oa- b/technology/freepdk45/lib/sram/out_inv_2/layout/layout.oa- deleted file mode 100755 index 94f550c6..00000000 Binary files a/technology/freepdk45/lib/sram/out_inv_2/layout/layout.oa- and /dev/null differ diff --git a/technology/freepdk45/lib/sram/out_inv_2/layout/master.tag b/technology/freepdk45/lib/sram/out_inv_2/layout/master.tag deleted file mode 100755 index 431d8f04..00000000 --- a/technology/freepdk45/lib/sram/out_inv_2/layout/master.tag +++ /dev/null @@ -1,2 +0,0 @@ --- Master.tag File, Rev:1.0 -layout.oa diff --git a/technology/freepdk45/lib/sram/out_inv_2/schematic/data.dm b/technology/freepdk45/lib/sram/out_inv_2/schematic/data.dm deleted file mode 100755 index 7cfdc2da..00000000 Binary files a/technology/freepdk45/lib/sram/out_inv_2/schematic/data.dm and /dev/null differ diff --git a/technology/freepdk45/lib/sram/out_inv_2/schematic/master.tag b/technology/freepdk45/lib/sram/out_inv_2/schematic/master.tag deleted file mode 100755 index 26be1bef..00000000 --- a/technology/freepdk45/lib/sram/out_inv_2/schematic/master.tag +++ /dev/null @@ -1,2 +0,0 @@ --- Master.tag File, Rev:1.0 -sch.oa diff --git a/technology/freepdk45/lib/sram/out_inv_2/schematic/sch.oa b/technology/freepdk45/lib/sram/out_inv_2/schematic/sch.oa deleted file mode 100755 index 1f45ca4a..00000000 Binary files a/technology/freepdk45/lib/sram/out_inv_2/schematic/sch.oa and /dev/null differ diff --git a/technology/freepdk45/lib/sram/out_inv_4/layout/layout.oa b/technology/freepdk45/lib/sram/out_inv_4/layout/layout.oa deleted file mode 100755 index e0690088..00000000 Binary files a/technology/freepdk45/lib/sram/out_inv_4/layout/layout.oa and /dev/null differ diff --git a/technology/freepdk45/lib/sram/out_inv_4/layout/layout.oa- b/technology/freepdk45/lib/sram/out_inv_4/layout/layout.oa- deleted file mode 100755 index e0690088..00000000 Binary files a/technology/freepdk45/lib/sram/out_inv_4/layout/layout.oa- and /dev/null differ diff --git a/technology/freepdk45/lib/sram/out_inv_4/layout/master.tag b/technology/freepdk45/lib/sram/out_inv_4/layout/master.tag deleted file mode 100755 index 431d8f04..00000000 --- a/technology/freepdk45/lib/sram/out_inv_4/layout/master.tag +++ /dev/null @@ -1,2 +0,0 @@ --- Master.tag File, Rev:1.0 -layout.oa diff --git a/technology/freepdk45/lib/sram/output_latch/layout/layout.oa b/technology/freepdk45/lib/sram/output_latch/layout/layout.oa deleted file mode 100755 index ff29df6d..00000000 Binary files a/technology/freepdk45/lib/sram/output_latch/layout/layout.oa and /dev/null differ diff --git a/technology/freepdk45/lib/sram/output_latch/layout/layout.oa- b/technology/freepdk45/lib/sram/output_latch/layout/layout.oa- deleted file mode 100755 index 6b39e820..00000000 Binary files a/technology/freepdk45/lib/sram/output_latch/layout/layout.oa- and /dev/null differ diff --git a/technology/freepdk45/lib/sram/output_latch/layout/master.tag b/technology/freepdk45/lib/sram/output_latch/layout/master.tag deleted file mode 100755 index 431d8f04..00000000 --- a/technology/freepdk45/lib/sram/output_latch/layout/master.tag +++ /dev/null @@ -1,2 +0,0 @@ --- Master.tag File, Rev:1.0 -layout.oa diff --git a/technology/freepdk45/lib/sram/precharge/layout/layout.oa b/technology/freepdk45/lib/sram/precharge/layout/layout.oa deleted file mode 100755 index 8e1768fc..00000000 Binary files a/technology/freepdk45/lib/sram/precharge/layout/layout.oa and /dev/null differ diff --git a/technology/freepdk45/lib/sram/precharge/layout/master.tag b/technology/freepdk45/lib/sram/precharge/layout/master.tag deleted file mode 100755 index 431d8f04..00000000 --- a/technology/freepdk45/lib/sram/precharge/layout/master.tag +++ /dev/null @@ -1,2 +0,0 @@ --- Master.tag File, Rev:1.0 -layout.oa diff --git a/technology/freepdk45/lib/sram/ptap/layout/layout.oa b/technology/freepdk45/lib/sram/ptap/layout/layout.oa deleted file mode 100755 index f55a28cd..00000000 Binary files a/technology/freepdk45/lib/sram/ptap/layout/layout.oa and /dev/null differ diff --git a/technology/freepdk45/lib/sram/ptap/layout/master.tag b/technology/freepdk45/lib/sram/ptap/layout/master.tag deleted file mode 100755 index 431d8f04..00000000 --- a/technology/freepdk45/lib/sram/ptap/layout/master.tag +++ /dev/null @@ -1,2 +0,0 @@ --- Master.tag File, Rev:1.0 -layout.oa diff --git a/technology/freepdk45/lib/sram/sense_amp/layout.oa.backup b/technology/freepdk45/lib/sram/sense_amp/layout.oa.backup deleted file mode 100755 index 99f09b81..00000000 Binary files a/technology/freepdk45/lib/sram/sense_amp/layout.oa.backup and /dev/null differ diff --git a/technology/freepdk45/lib/sram/sense_amp/layout/layout.oa b/technology/freepdk45/lib/sram/sense_amp/layout/layout.oa deleted file mode 100755 index 33c3ce0e..00000000 Binary files a/technology/freepdk45/lib/sram/sense_amp/layout/layout.oa and /dev/null differ diff --git a/technology/freepdk45/lib/sram/sense_amp/layout/layout.oa- b/technology/freepdk45/lib/sram/sense_amp/layout/layout.oa- deleted file mode 100755 index b69654d6..00000000 Binary files a/technology/freepdk45/lib/sram/sense_amp/layout/layout.oa- and /dev/null differ diff --git a/technology/freepdk45/lib/sram/sense_amp/layout/master.tag b/technology/freepdk45/lib/sram/sense_amp/layout/master.tag deleted file mode 100755 index 431d8f04..00000000 --- a/technology/freepdk45/lib/sram/sense_amp/layout/master.tag +++ /dev/null @@ -1,2 +0,0 @@ --- Master.tag File, Rev:1.0 -layout.oa diff --git a/technology/freepdk45/lib/sram/tgate/layout/layout.oa b/technology/freepdk45/lib/sram/tgate/layout/layout.oa deleted file mode 100755 index df7fd9be..00000000 Binary files a/technology/freepdk45/lib/sram/tgate/layout/layout.oa and /dev/null differ diff --git a/technology/freepdk45/lib/sram/tgate/layout/layout.oa- b/technology/freepdk45/lib/sram/tgate/layout/layout.oa- deleted file mode 100755 index df7fd9be..00000000 Binary files a/technology/freepdk45/lib/sram/tgate/layout/layout.oa- and /dev/null differ diff --git a/technology/freepdk45/lib/sram/tgate/layout/master.tag b/technology/freepdk45/lib/sram/tgate/layout/master.tag deleted file mode 100755 index 431d8f04..00000000 --- a/technology/freepdk45/lib/sram/tgate/layout/master.tag +++ /dev/null @@ -1,2 +0,0 @@ --- Master.tag File, Rev:1.0 -layout.oa diff --git a/technology/freepdk45/lib/sram/write_driver/layout/layout.oa b/technology/freepdk45/lib/sram/write_driver/layout/layout.oa deleted file mode 100755 index 79c3ed15..00000000 Binary files a/technology/freepdk45/lib/sram/write_driver/layout/layout.oa and /dev/null differ diff --git a/technology/freepdk45/lib/sram/write_driver/layout/layout.oa- b/technology/freepdk45/lib/sram/write_driver/layout/layout.oa- deleted file mode 100755 index e5f3cdf7..00000000 Binary files a/technology/freepdk45/lib/sram/write_driver/layout/layout.oa- and /dev/null differ diff --git a/technology/freepdk45/lib/sram/write_driver/layout/master.tag b/technology/freepdk45/lib/sram/write_driver/layout/master.tag deleted file mode 100755 index 431d8f04..00000000 --- a/technology/freepdk45/lib/sram/write_driver/layout/master.tag +++ /dev/null @@ -1,2 +0,0 @@ --- Master.tag File, Rev:1.0 -layout.oa diff --git a/technology/freepdk45/lib/stream_all_gds.sh b/technology/freepdk45/lib/stream_all_gds.sh deleted file mode 100644 index 8a2c1048..00000000 --- a/technology/freepdk45/lib/stream_all_gds.sh +++ /dev/null @@ -1,8 +0,0 @@ - -for i in addr_ff clock_nor dinv inv_clk inv_nor nor_1 out_inv_16 output_latch sense_amp addr_latch cell_10t dinv_mx inv_col mux_a nor_1_mx out_inv_2 precharge tgate cell_6t inv inv_dec mux_abar out_inv_4 write_driver -do - echo $i - strmout -layerMap ../sram_lib/layers.map -library sram -topCell $i -view layout -strmFile ../sram_lib/$i.gds -done - - diff --git a/technology/freepdk45/tech/__init__.py b/technology/freepdk45/tech/__init__.py index 2573d2c2..a516facc 100644 --- a/technology/freepdk45/tech/__init__.py +++ b/technology/freepdk45/tech/__init__.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ Import tech specific modules. """ diff --git a/technology/freepdk45/tech/tech.py b/technology/freepdk45/tech/tech.py index 760d2a5a..12c314cf 100644 --- a/technology/freepdk45/tech/tech.py +++ b/technology/freepdk45/tech/tech.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# import os from design_rules import * @@ -7,7 +14,16 @@ File containing the process technology parameters for FreePDK 45nm. #GDS file info GDS = {} -# gds units +# gds units +# From http://www.cnf.cornell.edu/cnf_spie9.html: "The first +#is the size of a database unit in user units. The second is the size +#of a database unit in meters. For example, if your library was +#created with the default units (user unit = 1 m and 1000 database +#units per user unit), then the first number would be 0.001 and the +#second number would be 10-9. Typically, the first number is less than +#1, since you use more than 1 database unit per user unit. To +#calculate the size of a user unit in meters, divide the second number +#by the first." GDS["unit"] = (0.0005,1e-9) # default label zoom GDS["zoom"] = 0.05 @@ -336,6 +352,8 @@ spice["nand3_transition_prob"] = .1094 # Transition probability of 3-input na spice["nor2_transition_prob"] = .1875 # Transition probability of 2-input nor. #Parameters related to sense amp enable timing and delay chain/RBL sizing +parameter['le_tau'] = 2.25 #In pico-seconds. +parameter['cap_relative_per_ff'] = 7.5 #Units of Relative Capacitance/ Femto-Farad parameter["static_delay_stages"] = 4 parameter["static_fanout_per_stage"] = 3 parameter["static_fanout_list"] = parameter["static_delay_stages"]*[parameter["static_fanout_per_stage"]] @@ -344,7 +362,10 @@ parameter["6tcell_wl_cin"] = 3 #relative capacitance parameter["min_inv_para_delay"] = 2.4 #Tau delay units parameter["sa_en_pmos_size"] = .72 #micro-meters parameter["sa_en_nmos_size"] = .27 #micro-meters +parameter["sa_inv_pmos_size"] = .54 #micro-meters +parameter["sa_inv_nmos_size"] = .27 #micro-meters parameter["rbl_height_percentage"] = .5 #Height of RBL compared to bitcell array +parameter['bitcell_drain_cap'] = 0.1 #In Femto-Farad, approximation of drain capacitance ################################################### ##END Spice Simulation Parameters diff --git a/technology/freepdk45/tf/display.drf b/technology/freepdk45/tf/display.drf index 7923ae62..86c87a30 100644 --- a/technology/freepdk45/tf/display.drf +++ b/technology/freepdk45/tf/display.drf @@ -1097,7 +1097,7 @@ drDefinePacket( ( display metal1Pin X solid blue blue ) ( display metal1Lbl blank solid blue blue ) ( display metal1Bnd blank solid blue blue ) - ( display contact X solid black lime ) + ( display contact solid solid green green ) ( display contactNe blank solid brown brown ) ( display contactPin X solid black black ) ( display contactLbl blank solid black black ) diff --git a/technology/scn4m_subm/__init__.py b/technology/scn4m_subm/__init__.py index d8474497..e54e3e33 100644 --- a/technology/scn4m_subm/__init__.py +++ b/technology/scn4m_subm/__init__.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# #!/usr/bin/python """ This type of setup script should be placed in the setup_scripts directory in the trunk diff --git a/technology/scn4m_subm/gds_lib/write_driver.gds b/technology/scn4m_subm/gds_lib/write_driver.gds index 44dabaf1..1f9274ac 100644 Binary files a/technology/scn4m_subm/gds_lib/write_driver.gds and b/technology/scn4m_subm/gds_lib/write_driver.gds differ diff --git a/technology/scn4m_subm/mag_lib/setup.tcl b/technology/scn4m_subm/mag_lib/setup.tcl index 084428b5..01639fe2 100644 --- a/technology/scn4m_subm/mag_lib/setup.tcl +++ b/technology/scn4m_subm/mag_lib/setup.tcl @@ -6,10 +6,10 @@ equate class {-circuit1 pfet} {-circuit2 p} # or the banks won't pass flatten class {-circuit1 bitcell_array_0} flatten class {-circuit1 bitcell_array_1} -flatten class {-circuit1 precharge_array_0} -flatten class {-circuit1 precharge_array_1} -flatten class {-circuit1 precharge_array_2} -flatten class {-circuit1 precharge_array_3} +#flatten class {-circuit1 precharge_array_0} +#flatten class {-circuit1 precharge_array_1} +#flatten class {-circuit1 precharge_array_2} +#flatten class {-circuit1 precharge_array_3} property {-circuit1 nfet} remove as ad ps pd property {-circuit1 pfet} remove as ad ps pd property {-circuit2 n} remove as ad ps pd diff --git a/technology/scn4m_subm/mag_lib/write_driver.mag b/technology/scn4m_subm/mag_lib/write_driver.mag index ab2014aa..9144f9d2 100644 --- a/technology/scn4m_subm/mag_lib/write_driver.mag +++ b/technology/scn4m_subm/mag_lib/write_driver.mag @@ -1,16 +1,16 @@ magic tech scmos -timestamp 1536089714 +timestamp 1556015973 << nwell >> rect -3 101 37 138 rect -3 0 37 51 << pwell >> -rect -3 138 37 202 +rect -3 138 37 203 rect -3 51 37 101 << ntransistor >> -rect 9 177 11 189 -rect 17 177 19 189 -rect 15 162 27 164 +rect 9 178 11 190 +rect 17 178 19 190 +rect 15 163 27 165 rect 9 144 11 148 rect 17 144 19 148 rect 10 82 12 89 @@ -27,14 +27,14 @@ rect 8 38 10 45 rect 16 38 18 45 rect 24 38 26 45 << ndiffusion >> -rect 8 177 9 189 -rect 11 177 12 189 -rect 16 177 17 189 -rect 19 177 20 189 -rect 15 164 27 165 -rect 15 161 27 162 -rect 12 157 15 160 -rect 12 156 16 157 +rect 8 178 9 190 +rect 11 178 12 190 +rect 16 178 17 190 +rect 19 178 20 190 +rect 15 165 27 166 +rect 15 162 27 163 +rect 12 158 15 161 +rect 12 156 16 158 rect 8 144 9 148 rect 11 144 12 148 rect 16 144 17 148 @@ -43,7 +43,7 @@ rect 9 82 10 89 rect 12 82 13 89 rect 17 82 18 89 rect 20 82 21 89 -rect 25 82 26 86 +rect 25 82 26 89 rect 7 57 8 64 rect 10 57 11 64 rect 15 57 16 64 @@ -68,11 +68,11 @@ rect 23 38 24 45 rect 26 38 27 45 rect 3 35 7 38 << ndcontact >> -rect 4 177 8 189 -rect 12 177 16 189 -rect 20 177 24 189 -rect 15 165 27 169 -rect 15 157 27 161 +rect 4 178 8 190 +rect 12 178 16 190 +rect 20 178 24 190 +rect 15 166 27 170 +rect 15 158 27 162 rect 4 144 8 148 rect 12 144 16 148 rect 20 144 24 148 @@ -96,21 +96,21 @@ rect 19 38 23 45 rect 27 38 31 45 << psubstratepcontact >> rect 12 152 16 156 -rect 26 82 30 86 +rect 26 82 30 89 << nsubstratencontact >> rect 12 118 16 122 rect 3 31 7 35 << polysilicon >> -rect 9 194 30 196 -rect 9 189 11 194 -rect 17 189 19 191 -rect 28 185 30 194 -rect 9 175 11 177 -rect 17 172 19 177 -rect 6 170 19 172 -rect 6 167 8 170 -rect 13 162 15 164 -rect 27 162 33 164 +rect 9 195 30 197 +rect 9 190 11 195 +rect 17 190 19 192 +rect 28 186 30 195 +rect 9 176 11 178 +rect 17 173 19 178 +rect 6 171 19 173 +rect 6 168 8 171 +rect 13 163 15 165 +rect 27 163 33 165 rect 9 148 11 150 rect 17 148 19 150 rect 9 132 11 144 @@ -136,7 +136,7 @@ rect 2 71 3 75 rect 11 71 13 79 rect 18 79 20 82 rect 18 77 23 79 -rect 31 71 33 162 +rect 31 71 33 163 rect 11 69 33 71 rect 11 67 13 69 rect 8 65 13 67 @@ -153,26 +153,27 @@ rect 8 28 10 38 rect 16 14 18 38 rect 24 36 26 38 << polycontact >> -rect 28 181 32 185 -rect 4 163 8 167 +rect 28 182 32 186 +rect 4 164 8 168 rect 23 96 27 100 rect 3 71 7 75 rect 23 75 27 79 rect 7 24 11 28 rect 15 10 19 14 << metal1 >> -rect 5 192 10 196 -rect 5 189 8 192 -rect 32 181 33 185 -rect 13 169 16 177 -rect 13 165 15 169 -rect 4 148 8 163 -rect 12 157 15 161 -rect 12 156 16 157 +rect 5 193 10 197 +rect 5 190 8 193 +rect 32 182 33 186 +rect 13 170 16 178 +rect 13 166 15 170 +rect 4 148 8 164 +rect 12 158 15 162 +rect 12 156 16 158 +rect 23 157 27 158 rect 12 148 16 152 rect 4 132 8 144 rect 20 142 24 144 -rect 30 142 33 181 +rect 30 142 33 182 rect 20 138 33 142 rect 20 132 24 138 rect 12 122 16 125 @@ -196,29 +197,30 @@ rect 7 31 19 35 rect 0 24 7 28 rect 11 24 36 28 << m2contact >> -rect 10 192 14 196 -rect 20 189 24 193 +rect 10 193 14 197 +rect 20 190 24 194 rect 23 153 27 157 rect 16 118 20 122 -rect 26 86 30 90 +rect 26 89 30 90 +rect 26 86 30 89 rect 19 64 23 68 rect 19 31 23 35 rect 15 6 19 10 << metal2 >> -rect 10 196 14 202 -rect 20 193 24 202 -rect 20 177 24 189 +rect 10 197 14 203 +rect 20 194 24 203 +rect 20 178 24 190 rect 15 0 19 6 << bb >> -rect 0 0 34 202 +rect 0 0 34 203 << labels >> rlabel metal2 15 1 15 1 1 din rlabel metal1 2 25 2 25 3 en -rlabel metal2 12 200 12 200 5 bl -rlabel metal2 22 200 22 200 5 br rlabel m2contact 21 66 21 66 1 gnd rlabel m2contact 28 88 28 88 1 gnd rlabel m2contact 21 33 21 33 1 vdd rlabel m2contact 18 120 18 120 1 vdd rlabel m2contact 25 155 25 155 1 gnd +rlabel metal2 12 201 12 201 5 bl +rlabel metal2 22 201 22 201 5 br << end >> diff --git a/technology/scn4m_subm/tech/SCN4M_SUBM.20.tech b/technology/scn4m_subm/tech/SCN4M_SUBM.20.tech index f39aa84f..deaae865 100644 --- a/technology/scn4m_subm/tech/SCN4M_SUBM.20.tech +++ b/technology/scn4m_subm/tech/SCN4M_SUBM.20.tech @@ -636,8 +636,8 @@ style lambda=0.20(p) #CRE/CRM layer CRM rm1,prm1,rm2,prm2,rm3,prm3,rm4,prm4 #CRE/CRM calma 70 0 - layer CX comment - labels comment + layer CX comment,bb + labels comment,bb calma 63 0 layer XP pad,xp @@ -1075,8 +1075,8 @@ style lambda=0.20(cp) #CRE/CRM layer CRM rm1,prm1,rm2,prm2,rm3,prm3,rm4,prm4 #CRE/CRM calma 70 0 - layer CX comment - labels comment + layer CX comment,bb + labels comment,bb calma 63 0 layer XP pad,xp @@ -1412,8 +1412,8 @@ style lambda=0.20(c) #CRE/CRM layer CRM rm1,prm1,rm2,prm2,rm3,prm3,rm4,prm4 #CRE/CRM calma 70 0 - layer CX comment - labels comment + layer CX comment,bb + labels comment,bb calma 63 0 layer XP pad,xp @@ -1749,8 +1749,8 @@ style lambda=0.20() #CRE/CRM layer CRM rm1,prm1,rm2,prm2,rm3,prm3,rm4,prm4 #CRE/CRM calma 70 0 - layer CX comment - labels comment + layer CX comment,bb + labels comment,bb calma 63 0 layer XP pad,xp diff --git a/technology/scn4m_subm/tech/__init__.py b/technology/scn4m_subm/tech/__init__.py old mode 100755 new mode 100644 index 2573d2c2..a516facc --- a/technology/scn4m_subm/tech/__init__.py +++ b/technology/scn4m_subm/tech/__init__.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# """ Import tech specific modules. """ diff --git a/technology/scn4m_subm/tech/tech.py b/technology/scn4m_subm/tech/tech.py old mode 100755 new mode 100644 index 78222fd6..15278c7b --- a/technology/scn4m_subm/tech/tech.py +++ b/technology/scn4m_subm/tech/tech.py @@ -1,3 +1,10 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 2016-2019 Regents of the University of California and The Board +#of Regents for the Oklahoma Agricultural and Mechanical College +#(acting for and on behalf of Oklahoma State University) +#All rights reserved. +# import os from design_rules import * @@ -8,6 +15,15 @@ File containing the process technology parameters for SCMOS 3me, subm, 180nm. #GDS file info GDS={} # gds units +# From http://www.cnf.cornell.edu/cnf_spie9.html: "The first +#is the size of a database unit in user units. The second is the size +#of a database unit in meters. For example, if your library was +#created with the default units (user unit = 1 m and 1000 database +#units per user unit), then the first number would be 0.001 and the +#second number would be 10-9. Typically, the first number is less than +#1, since you use more than 1 database unit per user unit. To +#calculate the size of a user unit in meters, divide the second number +#by the first." GDS["unit"]=(0.001,1e-6) # default label zoom GDS["zoom"] = 0.5 @@ -302,15 +318,20 @@ spice["nand3_transition_prob"] = .1094 # Transition probability of 3-input na spice["nor2_transition_prob"] = .1875 # Transition probability of 2-input nor. #Logical Effort relative values for the Handmade cells +parameter['le_tau'] = 23 #In pico-seconds. +parameter["min_inv_para_delay"] = .73 #In relative delay units +parameter['cap_relative_per_ff'] = .91 #Units of Relative Capacitance/ Femto-Farad parameter["static_delay_stages"] = 4 parameter["static_fanout_per_stage"] = 3 parameter["static_fanout_list"] = parameter["static_delay_stages"]*[parameter["static_fanout_per_stage"]] -parameter["dff_clk_cin"] = 27.5 -parameter["6tcell_wl_cin"] = 2 -parameter["min_inv_para_delay"] = .5 +parameter["dff_clk_cin"] = 27.5 #In relative capacitance units +parameter["6tcell_wl_cin"] = 2 #In relative capacitance units parameter["sa_en_pmos_size"] = 24*_lambda_ parameter["sa_en_nmos_size"] = 9*_lambda_ +parameter["sa_inv_pmos_size"] = 18*_lambda_ +parameter["sa_inv_nmos_size"] = 9*_lambda_ parameter["rbl_height_percentage"] = .5 #Height of RBL compared to bitcell array +parameter['bitcell_drain_cap'] = 0.2 #In Femto-Farad, approximation of drain capacitance ################################################### ##END Spice Simulation Parameters