mirror of
https://github.com/VLSIDA/OpenRAM.git
synced 2026-09-05 01:01:33 +02:00
Add separate layer and purpose pairs to tech layers.
This commit is contained in:
@@ -266,11 +266,12 @@ class instance(geometry):
|
||||
class path(geometry):
|
||||
"""Represents a Path"""
|
||||
|
||||
def __init__(self, layerNumber, coordinates, path_width):
|
||||
def __init__(self, lpp, coordinates, path_width):
|
||||
"""Initializes a path for the specified layer"""
|
||||
geometry.__init__(self)
|
||||
self.name = "path"
|
||||
self.layerNumber = layerNumber
|
||||
self.layerNumber = lpp[0]
|
||||
self.layerPurpose = lpp[1]
|
||||
self.coordinates = map(lambda x: [x[0], x[1]], coordinates)
|
||||
self.coordinates = vector(self.coordinates).snap_to_grid()
|
||||
self.path_width = path_width
|
||||
@@ -283,7 +284,7 @@ class path(geometry):
|
||||
"""Writes the path to GDS"""
|
||||
debug.info(4, "writing path (" + str(self.layerNumber) + "): " + self.coordinates)
|
||||
new_layout.addPath(layerNumber=self.layerNumber,
|
||||
purposeNumber=0,
|
||||
purposeNumber=self.layerPurpose,
|
||||
coordinates=self.coordinates,
|
||||
width=self.path_width)
|
||||
|
||||
@@ -303,12 +304,13 @@ class path(geometry):
|
||||
class label(geometry):
|
||||
"""Represents a text label"""
|
||||
|
||||
def __init__(self, text, layerNumber, offset, zoom=-1):
|
||||
def __init__(self, text, lpp, offset, zoom=-1):
|
||||
"""Initializes a text label for specified layer"""
|
||||
geometry.__init__(self)
|
||||
self.name = "label"
|
||||
self.text = text
|
||||
self.layerNumber = layerNumber
|
||||
self.layerNumber = lpp[0]
|
||||
self.layerPurpose = lpp[1]
|
||||
self.offset = vector(offset).snap_to_grid()
|
||||
|
||||
if zoom<0:
|
||||
@@ -325,7 +327,7 @@ class label(geometry):
|
||||
debug.info(4, "writing label (" + str(self.layerNumber) + "): " + self.text)
|
||||
new_layout.addText(text=self.text,
|
||||
layerNumber=self.layerNumber,
|
||||
purposeNumber=0,
|
||||
purposeNumber=self.layerPurpose,
|
||||
offsetInMicrons=self.offset,
|
||||
magnification=self.zoom,
|
||||
rotate=None)
|
||||
@@ -346,11 +348,12 @@ class label(geometry):
|
||||
class rectangle(geometry):
|
||||
"""Represents a rectangular shape"""
|
||||
|
||||
def __init__(self, layerNumber, offset, width, height):
|
||||
def __init__(self, lpp, offset, width, height):
|
||||
"""Initializes a rectangular shape for specified layer"""
|
||||
geometry.__init__(self)
|
||||
self.name = "rect"
|
||||
self.layerNumber = layerNumber
|
||||
self.layerNumber = lpp[0]
|
||||
self.layerPurpose = lpp[1]
|
||||
self.offset = vector(offset).snap_to_grid()
|
||||
self.size = vector(width, height).snap_to_grid()
|
||||
self.width = round_to_grid(self.size.x)
|
||||
@@ -374,7 +377,7 @@ class rectangle(geometry):
|
||||
debug.info(4, "writing rectangle (" + str(self.layerNumber) + "):"
|
||||
+ str(self.width) + "x" + str(self.height) + " @ " + str(self.offset))
|
||||
new_layout.addBox(layerNumber=self.layerNumber,
|
||||
purposeNumber=0,
|
||||
purposeNumber=self.layerPurpose,
|
||||
offsetInMicrons=self.offset,
|
||||
width=self.width,
|
||||
height=self.height,
|
||||
|
||||
@@ -150,9 +150,9 @@ class layout():
|
||||
if not height:
|
||||
height=drc["minwidth_{}".format(layer)]
|
||||
# negative layers indicate "unused" layers in a given technology
|
||||
layer_num = techlayer[layer]
|
||||
if layer_num >= 0:
|
||||
self.objs.append(geometry.rectangle(layer_num, offset, width, height))
|
||||
lpp = techlayer[layer]
|
||||
if lpp[0] >= 0:
|
||||
self.objs.append(geometry.rectangle(lpp, offset, width, height))
|
||||
return self.objs[-1]
|
||||
return None
|
||||
|
||||
@@ -165,10 +165,10 @@ class layout():
|
||||
if not height:
|
||||
height=drc["minwidth_{}".format(layer)]
|
||||
# negative layers indicate "unused" layers in a given technology
|
||||
layer_num = techlayer[layer]
|
||||
lpp = techlayer[layer]
|
||||
corrected_offset = offset - vector(0.5*width,0.5*height)
|
||||
if layer_num >= 0:
|
||||
self.objs.append(geometry.rectangle(layer_num, corrected_offset, width, height))
|
||||
if lpp[0] >= 0:
|
||||
self.objs.append(geometry.rectangle(lpp, corrected_offset, width, height))
|
||||
return self.objs[-1]
|
||||
return None
|
||||
|
||||
@@ -334,9 +334,9 @@ class layout():
|
||||
"""Adds a text label on the given layer,offset, and zoom level"""
|
||||
# negative layers indicate "unused" layers in a given technology
|
||||
debug.info(5,"add label " + str(text) + " " + layer + " " + str(offset))
|
||||
layer_num = techlayer[layer]
|
||||
if layer_num >= 0:
|
||||
self.objs.append(geometry.label(text, layer_num, offset, zoom))
|
||||
lpp = techlayer[layer]
|
||||
if lpp[0] >= 0:
|
||||
self.objs.append(geometry.label(text, lpp, offset, zoom))
|
||||
return self.objs[-1]
|
||||
return None
|
||||
|
||||
@@ -347,9 +347,9 @@ class layout():
|
||||
import wire_path
|
||||
# NOTE: (UNTESTED) add_path(...) is currently not used
|
||||
# negative layers indicate "unused" layers in a given technology
|
||||
#layer_num = techlayer[layer]
|
||||
#if layer_num >= 0:
|
||||
# self.objs.append(geometry.path(layer_num, coordinates, width))
|
||||
#lpp = techlayer[layer]
|
||||
#if lpp[0] >= 0:
|
||||
# self.objs.append(geometry.path(lpp, coordinates, width))
|
||||
|
||||
wire_path.wire_path(obj=self,
|
||||
layer=layer,
|
||||
@@ -539,7 +539,7 @@ class layout():
|
||||
Do not write the pins since they aren't obstructions.
|
||||
"""
|
||||
if type(layer)==str:
|
||||
layer_num = techlayer[layer]
|
||||
layer_num = techlayer[layer][0]
|
||||
else:
|
||||
layer_num = layer
|
||||
|
||||
|
||||
+18
-10
@@ -17,7 +17,7 @@ class pin_layout:
|
||||
single shape.
|
||||
"""
|
||||
|
||||
def __init__(self, name, rect, layer_name_num):
|
||||
def __init__(self, name, rect, layer_name_pp):
|
||||
self.name = name
|
||||
# repack the rect as a vector, just in case
|
||||
if type(rect[0])==vector:
|
||||
@@ -30,12 +30,19 @@ class pin_layout:
|
||||
debug.check(self.width()>0,"Zero width pin.")
|
||||
debug.check(self.height()>0,"Zero height pin.")
|
||||
|
||||
# if it's a layer number look up the layer name. this assumes a unique layer number.
|
||||
if type(layer_name_num)==int:
|
||||
self.layer = list(layer.keys())[list(layer.values()).index(layer_name_num)]
|
||||
# if it's a string, use the name
|
||||
if type(layer_name_pp)==str:
|
||||
self.layer=layer_name_pp
|
||||
# else it is required to be a lpp
|
||||
else:
|
||||
self.layer=layer_name_num
|
||||
self.layer_num = layer[self.layer]
|
||||
for (layer_name, lpp) in layer.items():
|
||||
if layer_name_pp[0]==lpp[0] and (layer_name_pp[1]==None or layer_name_pp[1]==lpp[1]):
|
||||
self.layer=layer_name
|
||||
break
|
||||
else:
|
||||
debug.error("Couldn't find layer {}".format(layer_name_pp),-1)
|
||||
|
||||
self.lpp = layer[self.layer]
|
||||
|
||||
def __str__(self):
|
||||
""" override print function output """
|
||||
@@ -310,8 +317,9 @@ class pin_layout:
|
||||
"""Writes the pin shape and label to GDS"""
|
||||
debug.info(4, "writing pin (" + str(self.layer) + "):"
|
||||
+ str(self.width()) + "x" + str(self.height()) + " @ " + str(self.ll()))
|
||||
newLayout.addBox(layerNumber=layer[self.layer],
|
||||
purposeNumber=0,
|
||||
(layer_num,purpose) = layer[self.layer]
|
||||
newLayout.addBox(layerNumber=layer_num,
|
||||
purposeNumber=purpose,
|
||||
offsetInMicrons=self.ll(),
|
||||
width=self.width(),
|
||||
height=self.height(),
|
||||
@@ -319,8 +327,8 @@ class pin_layout:
|
||||
# Add the tet in the middle of the pin.
|
||||
# This fixes some pin label offsetting when GDS gets imported into Magic.
|
||||
newLayout.addText(text=self.name,
|
||||
layerNumber=layer[self.layer],
|
||||
purposeNumber=0,
|
||||
layerNumber=layer_num,
|
||||
purposeNumber=purpose,
|
||||
offsetInMicrons=self.center(),
|
||||
magnification=GDS["zoom"],
|
||||
rotate=None)
|
||||
|
||||
@@ -45,7 +45,7 @@ def pin_center(boundary):
|
||||
"""
|
||||
return [0.5 * (boundary[0] + boundary[2]), 0.5 * (boundary[1] + boundary[3])]
|
||||
|
||||
def auto_measure_libcell(pin_list, name, units, layer):
|
||||
def auto_measure_libcell(pin_list, name, units, lpp):
|
||||
"""
|
||||
Open a GDS file and find the pins in pin_list as text on a given layer.
|
||||
Return these as a set of properties including the cell width/height too.
|
||||
@@ -56,19 +56,19 @@ def auto_measure_libcell(pin_list, name, units, layer):
|
||||
reader.loadFromFile(cell_gds)
|
||||
|
||||
cell = {}
|
||||
measure_result = cell_vlsi.getLayoutBorder(layer)
|
||||
measure_result = cell_vlsi.getLayoutBorder(lpp[0])
|
||||
if measure_result == None:
|
||||
measure_result = cell_vlsi.measureSize(name)
|
||||
[cell["width"], cell["height"]] = measure_result
|
||||
|
||||
for pin in pin_list:
|
||||
(name,layer,boundary)=cell_vlsi.getPinShapeByLabel(str(pin))
|
||||
(name,lpp,boundary)=cell_vlsi.getPinShapeByLabel(str(pin))
|
||||
cell[str(pin)] = pin_center(boundary)
|
||||
return cell
|
||||
|
||||
|
||||
|
||||
def get_gds_size(name, gds_filename, units, layer):
|
||||
def get_gds_size(name, gds_filename, units, lpp):
|
||||
"""
|
||||
Open a GDS file and return the size from either the
|
||||
bounding box or a border layer.
|
||||
@@ -79,20 +79,20 @@ def get_gds_size(name, gds_filename, units, layer):
|
||||
reader.loadFromFile(gds_filename)
|
||||
|
||||
cell = {}
|
||||
measure_result = cell_vlsi.getLayoutBorder(layer)
|
||||
measure_result = cell_vlsi.getLayoutBorder(lpp)
|
||||
if measure_result == None:
|
||||
debug.info(2,"Layout border failed. Trying to measure size for {}".format(name))
|
||||
measure_result = cell_vlsi.measureSize(name)
|
||||
# returns width,height
|
||||
return measure_result
|
||||
|
||||
def get_libcell_size(name, units, layer):
|
||||
def get_libcell_size(name, units, lpp):
|
||||
"""
|
||||
Open a GDS file and return the library cell size from either the
|
||||
bounding box or a border layer.
|
||||
"""
|
||||
cell_gds = OPTS.openram_tech + "gds_lib/" + str(name) + ".gds"
|
||||
return(get_gds_size(name, cell_gds, units, layer))
|
||||
return(get_gds_size(name, cell_gds, units, lpp))
|
||||
|
||||
|
||||
def get_gds_pins(pin_names, name, gds_filename, units):
|
||||
@@ -109,10 +109,10 @@ def get_gds_pins(pin_names, name, gds_filename, units):
|
||||
cell[str(pin_name)]=[]
|
||||
pin_list=cell_vlsi.getPinShape(str(pin_name))
|
||||
for pin_shape in pin_list:
|
||||
(layer,boundary)=pin_shape
|
||||
(lpp,boundary)=pin_shape
|
||||
rect=[vector(boundary[0],boundary[1]),vector(boundary[2],boundary[3])]
|
||||
# this is a list because other cells/designs may have must-connect pins
|
||||
cell[str(pin_name)].append(pin_layout(pin_name, rect, layer))
|
||||
cell[str(pin_name)].append(pin_layout(pin_name, rect, lpp))
|
||||
return cell
|
||||
|
||||
def get_libcell_pins(pin_list, name, units):
|
||||
|
||||
Reference in New Issue
Block a user