Merge branch 'dev' of github.com:VLSIDA/PrivateRAM into pex_fix_v2

This commit is contained in:
Bin Wu 2019-06-25 11:28:04 -07:00
commit 9ef2616d41
3 changed files with 91 additions and 51 deletions

View File

@ -165,7 +165,7 @@ class instance(geometry):
debug.info(4, "creating instance: " + self.name)
def get_blockages(self, layer, top=False):
""" Retrieve rectangular blockages of all modules in this instance.
""" Retrieve blockages of all modules in this instance.
Apply the transform of the instance placement to give absolute blockages."""
angle = math.radians(float(self.rotate))
mirr = 1
@ -186,11 +186,11 @@ class instance(geometry):
new_blockages = []
if self.mod.is_library_cell:
# Writes library cell blockages as shapes instead of a large metal blockage
blockages = []
blockages = self.mod.gds.getBlockages(layer)
for b in blockages:
new_blockages.append(self.transform_coords(b,self.offset, mirr, angle))
print(new_blockages)
else:
blockages = self.mod.get_blockages(layer)
for b in blockages:

View File

@ -12,6 +12,7 @@ import math
import debug
import datetime
from collections import defaultdict
import pdb
class lef:
"""
@ -84,7 +85,7 @@ class lef:
pin_list = self.get_pins(name)
for pin in pin_list:
self.lef.write("{0}LAYER {1} ;\n".format(self.indent,pin.layer))
self.lef_write_rect(pin.rect)
self.lef_write_shape(pin.rect)
# End the PORT
self.indent = self.indent[:-3]
@ -100,15 +101,29 @@ class lef:
for layer in self.lef_layers:
self.lef.write("{0}LAYER {1} ;\n".format(self.indent,layer))
self.indent += " "
# pdb.set_trace()
blockages = self.get_blockages(layer,True)
for b in blockages:
self.lef_write_rect(b)
# if len(b) > 2:
# print(b)
self.lef_write_shape(b)
self.indent = self.indent[:-3]
self.lef.write("{0}END\n".format(self.indent))
def lef_write_rect(self, rect):
""" Write a LEF rectangle """
self.lef.write("{0}RECT ".format(self.indent))
for item in rect:
self.lef.write(" {0} {1}".format(round(item[0],self.round_grid), round(item[1],self.round_grid)))
self.lef.write(" ;\n")
def lef_write_shape(self, rect):
if len(rect) == 2:
""" Write a LEF rectangle """
self.lef.write("{0}RECT ".format(self.indent))
for item in rect:
# print(rect)
self.lef.write(" {0} {1}".format(round(item[0],self.round_grid), round(item[1],self.round_grid)))
self.lef.write(" ;\n")
else:
""" Write a LEF polygon """
self.lef.write("{0}POLYGON ".format(self.indent))
for item in rect:
self.lef.write(" {0} {1}".format(round(item[0],self.round_grid), round(item[1],self.round_grid)))
# for i in range(0,len(rect)):
# self.lef.write(" {0} {1}".format(round(rect[i][0],self.round_grid), round(rect[i][1],self.round_grid)))
self.lef.write(" ;\n")

View File

@ -3,7 +3,6 @@ from datetime import *
#from mpmath import matrix
#from numpy import matrix
from vector import vector
from pin_layout import pin_layout
import numpy as np
#import gdsPrimitives
import debug
@ -727,12 +726,26 @@ class VlsiLayout:
self.pins[label_text] = []
self.pins[label_text].append(pin_shapes)
def getBlockages(self,layer):
"""
Return all blockages on a given layer in [llx, lly, urx, ury] format and
user units.
"""
blockages = []
shapes = self.getAllShapes(layer)
for boundary in shapes:
vectors = []
for i in range(0,len(boundary),2):
vectors.append(vector(boundary[i],boundary[i+1]))
blockages.append(vectors)
return blockages
def getAllShapes(self,layer):
"""
Return all shapes on a given layer in [llx, lly, urx, ury] format and
user units.
Return all shapes on a given layer in [llx, lly, urx, ury] format and user units for rectangles
and [coordinate 1, coordinate 2,...] format and user units for polygons.
"""
boundaries = set()
for TreeUnit in self.xyTree:
@ -742,55 +755,67 @@ class VlsiLayout:
# Convert to user units
user_boundaries = []
for boundary in boundaries:
user_boundaries.append([boundary[0]*self.units[0],boundary[1]*self.units[0],
boundary[2]*self.units[0],boundary[3]*self.units[0]])
boundaries_list = []
for i in range(0,len(boundary)):
boundaries_list.append(boundary[i]*self.units[0])
user_boundaries.append(boundaries_list)
return user_boundaries
def getBlockages(self,layer):
blockages = []
shapes = self.getAllShapes(layer)
for boundary in shapes:
ll = vector(boundary[0],boundary[1])
ur = vector(boundary[2],boundary[3])
rect = [ll,ur]
new_pin = rect
blockages.append(new_pin)
return blockages
def getShapesInStructure(self,layer,structure):
"""
Go through all the shapes in a structure and return the list of shapes in
the form [llx, lly, urx, ury]
the form [llx, lly, urx, ury] for rectangles and [coordinate 1, coordinate 2,...] for polygons.
"""
(structureName,structureOrigin,structureuVector,structurevVector)=structure
#print(structureName,"u",structureuVector.transpose(),"v",structurevVector.transpose(),"o",structureOrigin.transpose())
boundaries = []
for boundary in self.structures[str(structureName)].boundaries:
# FIXME: Right now, this only supports rectangular shapes!
# We should trigger an error but some FreePDK45 library cells contain paths.
# These get saved fine, but we cannot parse them as blockages...
#debug.check(len(boundary.coordinates)==5,"Non-rectangular shapes are not supported.")
if len(boundary.coordinates)!=5:
continue
if layer==boundary.drawingLayer:
left_bottom=boundary.coordinates[0]
right_top=boundary.coordinates[2]
# Rectangle is [leftx, bottomy, rightx, topy].
boundaryRect=[left_bottom[0],left_bottom[1],right_top[0],right_top[1]]
# perform the rotation
boundaryRect=self.transformRectangle(boundaryRect,structureuVector,structurevVector)
# add the offset and make it a tuple
boundaryRect=(boundaryRect[0]+structureOrigin[0].item(),boundaryRect[1]+structureOrigin[1].item(),
boundaryRect[2]+structureOrigin[0].item(),boundaryRect[3]+structureOrigin[1].item())
boundaries.append(boundaryRect)
if len(boundary.coordinates)!=5:
# if shape is a polygon (used in DFF)
boundaryPolygon = []
# Polygon is a list of coordinates going ccw
for coord in range(0,len(boundary.coordinates)):
boundaryPolygon.append(boundary.coordinates[coord][0])
boundaryPolygon.append(boundary.coordinates[coord][1])
# perform the rotation
boundaryPolygon=self.transformPolygon(boundaryPolygon,structureuVector,structurevVector)
# add the offset
polygon = []
for i in range(0,len(boundaryPolygon),2):
polygon.append(boundaryPolygon[i]+structureOrigin[0].item())
polygon.append(boundaryPolygon[i+1]+structureOrigin[1].item())
# make it a tuple
polygon = tuple(polygon)
boundaries.append(polygon)
else:
# else shape is a rectangle
left_bottom=boundary.coordinates[0]
right_top=boundary.coordinates[2]
# Rectangle is [leftx, bottomy, rightx, topy].
boundaryRect=[left_bottom[0],left_bottom[1],right_top[0],right_top[1]]
# perform the rotation
boundaryRect=self.transformRectangle(boundaryRect,structureuVector,structurevVector)
# add the offset and make it a tuple
boundaryRect=(boundaryRect[0]+structureOrigin[0].item(),boundaryRect[1]+structureOrigin[1].item(),
boundaryRect[2]+structureOrigin[0].item(),boundaryRect[3]+structureOrigin[1].item())
boundaries.append(boundaryRect)
return boundaries
def transformPolygon(self,originalPolygon,uVector,vVector):
"""
Transforms the coordinates of a polygon in space.
"""
polygon = []
newPolygon = []
for i in range(0,len(originalPolygon),2):
polygon.append(self.transformCoordinate([originalPolygon[i],originalPolygon[i+1]],uVector,vVector))
newPolygon.append(polygon[int(i/2)][0])
newPolygon.append(polygon[int(i/2)][1])
return newPolygon
def transformRectangle(self,originalRectangle,uVector,vVector):
"""
Transforms the four coordinates of a rectangle in space
@ -814,7 +839,7 @@ class VlsiLayout:
"""
Rotate a coordinate in space.
"""
# MRG: 9/3/18 Incorrect matrixi multiplication!
# MRG: 9/3/18 Incorrect matrix multiplication!
# This is fixed to be:
# |u[0] v[0]| |x| |x'|
# |u[1] v[1]|x|y|=|y'|