Update router to work with pin_layout structure.

This commit is contained in:
Matt Guthaus 2018-08-22 11:37:24 -07:00
parent ea52af3747
commit 2ae1e0234d
50 changed files with 493 additions and 641 deletions

View File

@ -55,9 +55,12 @@ class geometry:
self.compute_boundary(self.offset,self.mirror,self.rotate)
def compute_boundary(self,offset=vector(0,0),mirror="",rotate=0):
""" Transform with offset, mirror and rotation to get the absolute pin location.
We must then re-find the ll and ur. The master is the cell instance. """
"""
Transform with offset, mirror and rotation to get the absolute pin location.
We must then re-find the ll and ur. The master is the cell instance.
"""
(ll,ur) = [vector(0,0),vector(self.width,self.height)]
if mirror=="MX":
ll=ll.scale(1,-1)
ur=ur.scale(1,-1)

View File

@ -16,8 +16,14 @@ class hierarchy_design(hierarchy_spice.spice, hierarchy_layout.layout):
def __init__(self, name):
self.gds_file = OPTS.openram_tech + "gds_lib/" + name + ".gds"
self.sp_file = OPTS.openram_tech + "sp_lib/" + name + ".sp"
try:
self.gds_file
except AttributeError:
self.gds_file = OPTS.openram_tech + "gds_lib/" + name + ".gds"
try:
self.sp_file
except AttributeError:
self.sp_file = OPTS.openram_tech + "sp_lib/" + name + ".sp"
self.name = name
hierarchy_layout.layout.__init__(self, name)

View File

@ -322,7 +322,7 @@ class layout(lef.lef):
position_list=coordinates,
width=width)
def add_route(self, design, layers, coordinates):
def add_route(self, layers, coordinates):
"""Connects a routing path on given layer,coordinates,width. The
layers are the (horizontal, via, vertical). add_wire assumes
preferred direction routing whereas this includes layers in

View File

@ -117,7 +117,7 @@ class spice(verilog.verilog):
def sp_read(self):
"""Reads the sp file (and parse the pins) from the library
Otherwise, initialize it to null for dynamic generation"""
if os.path.isfile(self.sp_file):
if self.sp_file and os.path.isfile(self.sp_file):
debug.info(3, "opening {0}".format(self.sp_file))
f = open(self.sp_file)
self.spice = f.readlines()

View File

@ -1,11 +1,12 @@
from tech import drc
import debug
from design import design
from contact import contact
from itertools import tee
from vector import vector
from vector3d import vector3d
class route():
class route(design):
"""
Object route (used by the router module)
Add a route of minimium metal width between a set of points.
@ -14,10 +15,13 @@ class route():
The points are the center of the wire.
This can have non-preferred direction routing.
"""
unique_route_id = 0
def __init__(self, obj, layer_stack, path):
name = "route_{0}".format(route.unique_route_id)
route.unique_route_id += 1
design.design.__init__(self, name)
design.__init__(self, name)
debug.info(3, "create route obj {0}".format(name))
self.obj = obj
@ -52,7 +56,7 @@ class route():
next(b, None)
return zip(a, b)
plist = pairwise(self.path)
plist = list(pairwise(self.path))
for p0,p1 in plist:
if p0.z != p1.z: # via
# offset if not rotated
@ -67,6 +71,13 @@ class route():
self.draw_corner_wire(p1)
# draw the point to point wire
self.draw_wire(p0,p1)
# Draw the layers on the ends of the wires to ensure full width
# connections
self.draw_corner_wire(plist[0][0])
self.draw_corner_wire(plist[-1][1])
@ -99,10 +110,10 @@ class route():
height = end.y - start.y
width = layer_width
deisgn.add_rect(layer=layer_name,
offset=offset,
width=width,
height=height)
self.obj.add_rect(layer=layer_name,
offset=vector(offset.x,offset.y),
width=width,
height=height)
def draw_corner_wire(self, p0):

View File

@ -37,12 +37,6 @@ def pin_center(boundary):
"""
return [0.5 * (boundary[0] + boundary[2]), 0.5 * (boundary[1] + boundary[3])]
def pin_rect(boundary):
"""
This returns a LL,UR point pair.
"""
return [vector(boundary[0],boundary[1]),vector(boundary[2],boundary[3])]
def auto_measure_libcell(pin_list, name, units, layer):
"""
Open a GDS file and find the pins in pin_list as text on a given layer.
@ -66,15 +60,14 @@ def auto_measure_libcell(pin_list, name, units, layer):
def get_libcell_size(name, units, layer):
def get_gds_size(name, gds_filename, units, layer):
"""
Open a GDS file and return the library cell size from either the
Open a GDS file and return the size from either the
bounding box or a border layer.
"""
cell_gds = OPTS.openram_tech + "gds_lib/" + str(name) + ".gds"
cell_vlsi = gdsMill.VlsiLayout(units=units)
reader = gdsMill.Gds2reader(cell_vlsi)
reader.loadFromFile(cell_gds)
reader.loadFromFile(gds_filename)
cell = {}
measure_result = cell_vlsi.getLayoutBorder(layer)
@ -83,16 +76,23 @@ def get_libcell_size(name, units, layer):
# returns width,height
return measure_result
def get_libcell_size(name, units, layer):
"""
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))
def get_libcell_pins(pin_list, name, units, layer):
def get_gds_pins(pin_list, name, gds_filename, units, layer):
"""
Open a GDS file and find the pins in pin_list as text on a given layer.
Return these as a rectangle layer pair for each pin.
"""
cell_gds = OPTS.openram_tech + "gds_lib/" + str(name) + ".gds"
cell_vlsi = gdsMill.VlsiLayout(units=units)
reader = gdsMill.Gds2reader(cell_vlsi)
reader.loadFromFile(cell_gds)
reader.loadFromFile(gds_filename)
cell = {}
for pin in pin_list:
@ -100,11 +100,19 @@ def get_libcell_pins(pin_list, name, units, layer):
label_list=cell_vlsi.getPinShapeByLabel(str(pin))
for label in label_list:
(name,layer,boundary)=label
rect = pin_rect(boundary)
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)].append(pin_layout(pin, rect, layer))
return cell
def get_libcell_pins(pin_list, name, units, layer):
"""
Open a GDS file and find the pins in pin_list as text on a given layer.
Return these as a rectangle layer pair for each pin.
"""
cell_gds = OPTS.openram_tech + "gds_lib/" + str(name) + ".gds"
return(get_gds_pins(pin_list, name, cell_gds, units, layer))

View File

@ -583,6 +583,7 @@ class VlsiLayout:
print("Done\n\n")
def getLayoutBorder(self,borderlayer):
cellSizeMicron=None
for boundary in self.structures[self.rootStructureName].boundaries:
if boundary.drawingLayer==borderlayer:
if self.debug:
@ -722,7 +723,8 @@ class VlsiLayout:
def getAllPinShapesByDBLocLayer(self, coordinate, layer):
"""
Return ALL the enclosing rectangles on the same layer
at the given coordinate. Coordinates should be in DB units.
at the given coordinate. Input coordinates should be in DB units.
Returns user unit shapes.
"""
pin_boundaries=self.getAllPinShapesInStructureList(coordinate, layer)
@ -732,8 +734,7 @@ class VlsiLayout:
new_boundaries.append([pin_boundary[0]*self.units[0],pin_boundary[1]*self.units[0],
pin_boundary[2]*self.units[0],pin_boundary[3]*self.units[0]])
# Make a name if we don't have the pin name
return ["p"+str(coordinate)+"_"+str(layer), layer, new_boundaries]
return new_boundaries
def getPinShapeByLabel(self,label_name):
"""
@ -758,7 +759,7 @@ class VlsiLayout:
shape_list=[]
for label in label_list:
(label_coordinate,label_layer)=label
shape_list.append(self.getAllPinShapesByDBLocLayer(label_coordinate, label_layer))
shape_list.extend(self.getAllPinShapesByDBLocLayer(label_coordinate, label_layer))
return shape_list
def getAllPinShapesInStructureList(self,coordinates,layer):

View File

@ -6,11 +6,7 @@ from vector3d import vector3d
from cell import cell
import os
try:
import Queue as Q # ver. < 3.0
except ImportError:
import queue as Q
from heapq import heappush,heappop
class grid:
"""A two layer routing map. Each cell can be blocked in the vertical
@ -36,7 +32,7 @@ class grid:
self.map={}
# priority queue for the maze routing
self.q = Q.PriorityQueue()
self.q = []
def set_blocked(self,n):
self.add_map(n)
@ -66,30 +62,34 @@ class grid:
self.target=[]
# clear the queue
while (not self.q.empty()):
self.q.get(False)
while len(self.q)>0:
heappop(self.q)
self.counter = 0
def add_blockage_shape(self,ll,ur,z):
debug.info(3,"Adding blockage ll={0} ur={1} z={2}".format(str(ll),str(ur),z))
block_list = []
for x in range(int(ll[0]),int(ur[0])+1):
for y in range(int(ll[1]),int(ur[1])+1):
n = vector3d(x,y,z)
self.set_blocked(n)
block_list.append(vector3d(x,y,z))
self.add_blockage(block_list)
def add_blockage(self,block_list):
debug.info(3,"Adding blockage list={0}".format(str(block_list)))
debug.info(2,"Adding blockage list={0}".format(str(block_list)))
for n in block_list:
self.set_blocked(n)
def add_source(self,track_list):
debug.info(3,"Adding source list={0}".format(str(track_list)))
debug.info(2,"Adding source list={0}".format(str(track_list)))
for n in track_list:
if not self.is_blocked(n):
debug.info(3,"Adding source ={0}".format(str(n)))
self.set_source(n)
def add_target(self,track_list):
debug.info(3,"Adding target list={0}".format(str(track_list)))
debug.info(2,"Adding target list={0}".format(str(track_list)))
for n in track_list:
if not self.is_blocked(n):
self.set_target(n)
@ -120,8 +120,8 @@ class grid:
cost_bound = detour_scale*self.cost_to_target(self.source[0])*self.PREFERRED_COST
# Make sure the queue is empty if we run another route
while not self.q.empty():
self.q.get()
while len(self.q)>0:
heappop(self.q)
# Put the source items into the queue
self.init_queue()
@ -129,10 +129,10 @@ class grid:
cheapest_cost = None
# Keep expanding and adding to the priority queue until we are done
while not self.q.empty():
while len(self.q)>0:
# should we keep the path in the queue as well or just the final node?
(cost,path) = self.q.get()
debug.info(2,"Queue size: size=" + str(self.q.qsize()) + " " + str(cost))
(cost,count,path) = heappop(self.q)
debug.info(2,"Queue size: size=" + str(len(self.q)) + " " + str(cost))
debug.info(3,"Expanding: cost=" + str(cost) + " " + str(path))
# expand the last element
@ -158,7 +158,8 @@ class grid:
self.map[n].min_cost = predicted_cost
debug.info(3,"Enqueuing: cost=" + str(current_cost) + "+" + str(target_cost) + " " + str(newpath))
# add the cost to get to this point if we haven't reached it yet
self.q.put((predicted_cost,newpath))
heappush(self.q,(predicted_cost,self.counter,newpath))
self.counter += 1
debug.warning("Unable to route path. Expand the detour_scale to allow detours.")
return (None,None)
@ -227,11 +228,16 @@ class grid:
# uniquify the source (and target while we are at it)
self.source = list(set(self.source))
self.target = list(set(self.target))
# Counter is used to not require data comparison in Python 3.x
# Items will be returned in order they are added during cost ties
self.counter = 0
for s in self.source:
cost = self.cost_to_target(s)
debug.info(4,"Init: cost=" + str(cost) + " " + str([s]))
self.q.put((cost,[s]))
debug.info(1,"Init: cost=" + str(cost) + " " + str([s]))
heappush(self.q,(cost,self.counter,[s]))
self.counter+=1
def hpwl(self, src, dest):
"""

View File

@ -4,6 +4,7 @@ from contact import contact
import math
import debug
import grid
from pin_layout import pin_layout
from vector import vector
from vector3d import vector3d
from globals import OPTS
@ -24,13 +25,11 @@ class router:
self.reader.loadFromFile(gds_name)
self.top_name = self.layout.rootStructureName
self.source_pin_shapes = []
self.source_pin_zindex = None
self.target_pin_shapes = []
self.target_pin_zindex = None
self.source_pins = []
self.target_pins = []
# the list of all blockage shapes
self.blockages = []
# all thepaths we've routed so far (to supplement the blockages)
# all the paths we've routed so far (to supplement the blockages)
self.paths = []
# The boundary will determine the limits to the size of the routing grid
@ -94,20 +93,18 @@ class router:
Pin can either be a label or a location,layer pair: [[x,y],layer].
"""
if type(pin)==str:
(pin_name,pin_layer,pin_shapes) = self.layout.getAllPinShapesByLabel(str(pin))
else:
(pin_name,pin_layer,pin_shapes) = self.layout.getAllPinShapesByLocLayer(pin[0],pin[1])
label_list=self.layout.getPinShapeByLabel(str(pin))
pin_list = []
for label in label_list:
(name,layer,boundary)=label
rect = [vector(boundary[0],boundary[1]),vector(boundary[2],boundary[3])]
# this is a list because other cells/designs may have must-connect pins
pin_list.append(pin_layout(pin, rect, layer))
debug.check(len(pin_list)>0,"Did not find any pin shapes for {0}.".format(str(pin)))
return pin_list
new_pin_shapes = []
for pin_shape in pin_shapes:
debug.info(2,"Find pin {0} layer {1} shape {2}".format(pin_name,str(pin_layer),str(pin_shape)))
# repack the shape as a pair of vectors rather than four values
new_pin_shapes.append([vector(pin_shape[0],pin_shape[1]),vector(pin_shape[2],pin_shape[3])])
debug.check(len(new_pin_shapes)>0,"Did not find any pin shapes for {0}.".format(str(pin)))
return (pin_layer,new_pin_shapes)
def find_blockages(self):
"""
@ -126,17 +123,14 @@ class router:
Convert the routed path to blockages.
Keep the other blockages unchanged.
"""
self.source_pin = None
self.source_pin_shapes = []
self.source_pin_zindex = None
self.target_pin = None
self.target_pin_shapes = []
self.target_pin_zindex = None
# DO NOT clear the blockages as these don't change
self.source_pin_name = None
self.source_pins = []
self.target_pin_name = None
self.target_pins = [] # DO NOT clear the blockages as these don't change
self.rg.reinit()
def route(self, cell, layers, src, dest, detour_scale=2):
def route(self, cell, layers, src, dest, detour_scale=5):
"""
Route a single source-destination net and return
the simplified rectilinear path. Cost factor is how sub-optimal to explore for a feasible route.
@ -186,7 +180,7 @@ class router:
return False
def write_debug_gds(self,):
def write_debug_gds(self):
"""
Write out a GDS file with the routing grid and search information annotated on it.
"""
@ -195,7 +189,7 @@ class router:
if OPTS.debug_level==0: return
self.add_router_info()
debug.error("Writing debug_route.gds from {0} to {1}".format(self.source_pin,self.target_pin))
debug.error("Writing debug_route.gds from {0} to {1}".format(self.source_pin_name,self.target_pin_name))
self.cell.gds_write("debug_route.gds")
def add_router_info(self):
@ -204,7 +198,7 @@ class router:
the boundary layer for debugging purposes. This can only be
called once or the labels will overlap.
"""
debug.info(0,"Adding router info for {0} to {1}".format(self.source_pin,self.target_pin))
debug.info(0,"Adding router info for {0} to {1}".format(self.source_pin_name,self.target_pin_name))
grid_keys=self.rg.map.keys()
partial_track=vector(0,self.track_width/6.0)
for g in grid_keys:
@ -237,7 +231,8 @@ class router:
offset=type_off)
self.cell.add_label(text="{0},{1}".format(g[0],g[1]),
layer="text",
offset=shape[0])
offset=shape[0],
zoom=0.05)
def add_route(self,path):
"""
@ -255,7 +250,7 @@ class router:
if False or path==None:
self.write_debug_gds()
if 'Xout_4_1' in [self.source_pin, self.target_pin]:
if 'Xout_4_1' in [self.source_pin_name, self.target_pin_name]:
self.write_debug_gds()
@ -263,12 +258,6 @@ class router:
#debug.info(1,str(self.path))
contracted_path = self.contract_path(path)
debug.info(1,str(contracted_path))
# Make sure there's a pin enclosure on the source and dest
add_src_via = contracted_path[0].z!=self.source_pin_zindex
self.add_grid_pin(contracted_path[0],add_src_via)
add_tgt_via = contracted_path[-1].z!=self.target_pin_zindex
self.add_grid_pin(contracted_path[-1],add_tgt_via)
# convert the path back to absolute units from tracks
abs_path = map(self.convert_point_to_units,contracted_path)
@ -382,14 +371,12 @@ class router:
self.rg.set_blocked(grid)
def get_source(self,pin):
def get_source(self,pin_name):
"""
Gets the source pin shapes only. Doesn't add to grid.
"""
self.source_pin = pin
(self.source_pin_layer,self.source_pin_shapes) = self.find_pin(pin)
zindex = 0 if self.source_pin_layer==self.horiz_layer_number else 1
self.source_pin_zindex = zindex
self.source_pin_name = pin_name
self.source_pins = self.find_pin(pin_name)
def add_source(self):
"""
@ -398,10 +385,11 @@ class router:
"""
found_pin = False
for shape in self.source_pin_shapes:
(pin_in_tracks,blockage_in_tracks)=self.convert_pin_to_tracks(shape,self.source_pin_zindex,self.source_pin)
if (len(pin_in_tracks)>0): found_pin=True
debug.info(1,"Set source: " + str(self.source_pin) + " " + str(pin_in_tracks) + " z=" + str(self.source_pin_zindex))
for pin in self.source_pins:
(pin_in_tracks,blockage_in_tracks)=self.convert_pin_to_tracks(pin)
if (len(pin_in_tracks)>0):
found_pin=True
debug.info(1,"Set source: " + str(self.source_pin_name) + " " + str(pin_in_tracks))
self.rg.add_source(pin_in_tracks)
self.rg.add_blockage(blockage_in_tracks)
@ -409,14 +397,12 @@ class router:
self.write_debug_gds()
debug.check(found_pin,"Unable to find source pin on grid.")
def get_target(self,pin):
def get_target(self,pin_name):
"""
Gets the target pin shapes only. Doesn't add to grid.
"""
self.target_pin = pin
(self.target_pin_layer,self.target_pin_shapes) = self.find_pin(pin)
zindex = 0 if self.target_pin_layer==self.horiz_layer_number else 1
self.target_pin_zindex = zindex
self.target_pin_name = pin_name
self.target_pins = self.find_pin(pin_name)
def add_target(self):
"""
@ -424,10 +410,11 @@ class router:
pin can be a location or a label.
"""
found_pin=False
for shape in self.target_pin_shapes:
(pin_in_tracks,blockage_in_tracks)=self.convert_pin_to_tracks(shape,self.target_pin_zindex,self.target_pin)
if (len(pin_in_tracks)>0): found_pin=True
debug.info(1,"Set target: " + str(self.target_pin) + " " + str(pin_in_tracks) + " z=" + str(self.target_pin_zindex))
for pin in self.target_pins:
(pin_in_tracks,blockage_in_tracks)=self.convert_pin_to_tracks(pin)
if (len(pin_in_tracks)>0):
found_pin=True
debug.info(1,"Set target: " + str(self.target_pin_name) + " " + str(pin_in_tracks))
self.rg.add_target(pin_in_tracks)
self.rg.add_blockage(blockage_in_tracks)
@ -438,15 +425,15 @@ class router:
def add_blockages(self):
""" Add the blockages except the pin shapes """
for blockage in self.blockages:
(shape,zlayer) = blockage
is_nonpin_blockage = True
# Skip source pin shapes
if zlayer==self.source_pin_zindex and shape in self.source_pin_shapes:
continue
# Skip target pin shapes
if zlayer==self.target_pin_zindex and shape in self.target_pin_shapes:
continue
[ll,ur]=self.convert_blockage_to_tracks(shape)
self.rg.add_blockage_shape(ll,ur,zlayer)
for pin in self.source_pins + self.target_pins:
if blockage.overlaps(pin):
break
else:
[ll,ur]=self.convert_blockage_to_tracks(blockage.rect)
zlayer = 0 if blockage.layer_num==self.horiz_layer_number else 1
self.rg.add_blockage_shape(ll,ur,zlayer)
def get_blockages(self, sref, mirr = 1, angle = math.radians(float(0)), xyShift = (0, 0)):
@ -461,8 +448,8 @@ class router:
# only consider the two layers that we are routing on
if boundary.drawingLayer in [self.vert_layer_number,self.horiz_layer_number]:
zlayer = 0 if boundary.drawingLayer==self.horiz_layer_number else 1
self.blockages.append((shape,zlayer))
# store the blockages as pin layouts so they are easy to compare etc.
self.blockages.append(pin_layout("blockage",shape,boundary.drawingLayer))
# recurse given the mirror, angle, etc.
@ -507,13 +494,13 @@ class router:
#debug.info(1,"Converted [ {0} , {1} ]".format(ll,ur))
return [ll,ur]
def convert_pin_to_tracks(self,shape,zindex,pin):
def convert_pin_to_tracks(self, pin):
"""
Convert a rectangular pin shape into a list of track locations,layers.
If no on-grid pins are found, it searches for the nearest off-grid pin(s).
If a pin has insufficent overlap, it returns the blockage list to avoid it.
"""
[ll,ur] = shape
[ll,ur] = pin.rect
ll = snap_to_grid(ll)
ur = snap_to_grid(ur)
@ -524,6 +511,7 @@ class router:
ur=ur.scale(self.track_factor).ceil()
# width depends on which layer it is
zindex = 0 if pin.layer_num==self.horiz_layer_number else 1
if zindex==0:
width = self.horiz_layer_width
else:
@ -539,12 +527,12 @@ class router:
# if dimension of overlap is greater than min width in any dimension,
# it will be an on-grid pin
rect = self.convert_track_to_pin(vector3d(x,y,zindex))
max_overlap=max(self.compute_overlap(shape,rect))
max_overlap=max(self.compute_overlap(pin.rect,rect))
# however, if there is not enough overlap, then if there is any overlap at all,
# we need to block it to prevent routes coming in on that grid
full_rect = self.convert_full_track_to_shape(vector3d(x,y,zindex))
full_overlap=max(self.compute_overlap(shape,full_rect))
full_overlap=max(self.compute_overlap(pin.rect,full_rect))
#debug.info(1,"Check overlap: {0} {1} max={2}".format(shape,rect,max_overlap))
if max_overlap >= width:
@ -552,7 +540,7 @@ class router:
elif full_overlap>0:
block_list.append(vector3d(x,y,zindex))
else:
debug.info(1,"No overlap: {0} {1} max={2}".format(shape,rect,max_overlap))
debug.info(4,"No overlap: {0} {1} max={2}".format(pin.rect,rect,max_overlap))
#debug.warning("Off-grid pin for {0}.".format(str(pin)))
#debug.info(1,"Converted [ {0} , {1} ]".format(ll,ur))

View File

@ -0,0 +1,55 @@
#!/usr/bin/env python3
"Run a regresion test the library cells for DRC"
import unittest
from testutils import header,openram_test
import sys,os
sys.path.append(os.path.join(sys.path[0],"../.."))
sys.path.append(os.path.join(sys.path[0],".."))
import globals
import debug
OPTS = globals.OPTS
class no_blockages_test(openram_test):
"""
Simplest two pin route test with no blockages.
"""
def runTest(self):
globals.init_openram("config_{0}".format(OPTS.tech_name))
from gds_cell import gds_cell
from design import design
from router import router
class routing(design, openram_test):
"""
A generic GDS design that we can route on.
"""
def __init__(self, name):
design.__init__(self, "top")
# Instantiate a GDS cell with the design
gds_file = "{0}/{1}.gds".format(os.path.dirname(os.path.realpath(__file__)),name)
cell = gds_cell(name, gds_file)
self.add_inst(name=name,
mod=cell,
offset=[0,0])
self.connect_inst([])
r=router(gds_file)
layer_stack =("metal1","via1","metal2")
self.assertTrue(r.route(self,layer_stack,src="A",dest="B"))
r=routing("01_no_blockages_test_{0}".format(OPTS.tech_name))
self.local_drc_check(r)
# fails if there are any DRC errors on any cells
globals.end_openram()
# instantiate a copy of the class to actually run the test
if __name__ == "__main__":
(OPTS, args) = globals.parse_args()
del sys.argv[1:]
header(__file__, OPTS.tech_name)
unittest.main()

View File

@ -0,0 +1,59 @@
#!/usr/bin/env python3
"Run a regresion test the library cells for DRC"
import unittest
from testutils import header,openram_test
import sys,os
sys.path.append(os.path.join(sys.path[0],"../.."))
sys.path.append(os.path.join(sys.path[0],".."))
import globals
import debug
OPTS = globals.OPTS
class blockages_test(openram_test):
"""
Simple two pin route test with multilayer blockages.
"""
def runTest(self):
globals.init_openram("config_{0}".format(OPTS.tech_name))
from gds_cell import gds_cell
from design import design
from router import router
class routing(design, openram_test):
"""
A generic GDS design that we can route on.
"""
def __init__(self, name):
design.__init__(self, "top")
# Instantiate a GDS cell with the design
gds_file = "{0}/{1}.gds".format(os.path.dirname(os.path.realpath(__file__)),name)
cell = gds_cell(name, gds_file)
self.add_inst(name=name,
mod=cell,
offset=[0,0])
self.connect_inst([])
r=router(gds_file)
layer_stack =("metal1","via1","metal2")
self.assertTrue(r.route(self,layer_stack,src="A",dest="B"))
r=routing("02_blockages_test_{0}".format(OPTS.tech_name))
self.local_drc_check(r)
# fails if there are any DRC errors on any cells
globals.end_openram()
# instantiate a copy of the class to actually run the test
if __name__ == "__main__":
(OPTS, args) = globals.parse_args()
del sys.argv[1:]
header(__file__, OPTS.tech_name)
unittest.main()

View File

@ -0,0 +1,54 @@
#!/usr/bin/env python3
"Run a regresion test the library cells for DRC"
import unittest
from testutils import header,openram_test
import sys,os
sys.path.append(os.path.join(sys.path[0],"../.."))
sys.path.append(os.path.join(sys.path[0],".."))
import globals
import debug
OPTS = globals.OPTS
class same_layer_pins_test(openram_test):
"""
Checks two pins on the same layer with positive and negative coordinates.
"""
def runTest(self):
globals.init_openram("config_{0}".format(OPTS.tech_name))
from gds_cell import gds_cell
from design import design
from router import router
class routing(design, openram_test):
"""
A generic GDS design that we can route on.
"""
def __init__(self, name):
design.__init__(self, "top")
# Instantiate a GDS cell with the design
gds_file = "{0}/{1}.gds".format(os.path.dirname(os.path.realpath(__file__)),name)
cell = gds_cell(name, gds_file)
self.add_inst(name=name,
mod=cell,
offset=[0,0])
self.connect_inst([])
r=router(gds_file)
layer_stack =("metal1","via1","metal2")
self.assertTrue(r.route(self,layer_stack,src="A",dest="B"))
r = routing("03_same_layer_pins_test_{0}".format(OPTS.tech_name))
self.local_drc_check(r)
# fails if there are any DRC errors on any cells
globals.end_openram()
# instantiate a copy of the class to actually run the test
if __name__ == "__main__":
(OPTS, args) = globals.parse_args()
del sys.argv[1:]
header(__file__, OPTS.tech_name)
unittest.main()

View File

@ -0,0 +1,56 @@
#!/usr/bin/env python3
"Run a regresion test the library cells for DRC"
import unittest
from testutils import header,openram_test
import sys,os
sys.path.append(os.path.join(sys.path[0],"../.."))
sys.path.append(os.path.join(sys.path[0],".."))
import globals
import debug
OPTS = globals.OPTS
class diff_layer_pins_test(openram_test):
"""
Two pin route test with pins on different layers and blockages.
Pins are smaller than grid size.
"""
def runTest(self):
globals.init_openram("config_{0}".format(OPTS.tech_name))
from gds_cell import gds_cell
from design import design
from router import router
class routing(design, openram_test):
"""
A generic GDS design that we can route on.
"""
def __init__(self, name):
design.__init__(self, "top")
# Instantiate a GDS cell with the design
gds_file = "{0}/{1}.gds".format(os.path.dirname(os.path.realpath(__file__)),name)
cell = gds_cell(name, gds_file)
self.add_inst(name=name,
mod=cell,
offset=[0,0])
self.connect_inst([])
r=router(gds_file)
layer_stack =("metal1","via1","metal2")
self.assertTrue(r.route(self,layer_stack,src="A",dest="B"))
r = routing("04_diff_layer_pins_test_{0}".format(OPTS.tech_name))
self.local_drc_check(r)
# fails if there are any DRC errors on any cells
globals.end_openram()
# instantiate a copy of the class to actually run the test
if __name__ == "__main__":
(OPTS, args) = globals.parse_args()
del sys.argv[1:]
header(__file__, OPTS.tech_name)
unittest.main()

View File

@ -0,0 +1,58 @@
#!/usr/bin/env python3
"Run a regresion test the library cells for DRC"
import unittest
from testutils import header,openram_test
import sys,os
sys.path.append(os.path.join(sys.path[0],"../.."))
sys.path.append(os.path.join(sys.path[0],".."))
import globals
import debug
OPTS = globals.OPTS
class two_nets_test(openram_test):
"""
Route two nets in the same GDS file. The routes will interact,
so they must block eachother.
"""
def runTest(self):
globals.init_openram("config_{0}".format(OPTS.tech_name))
from gds_cell import gds_cell
from design import design
from router import router
class routing(design, openram_test):
"""
A generic GDS design that we can route on.
"""
def __init__(self, name):
design.__init__(self, "top")
# Instantiate a GDS cell with the design
gds_file = "{0}/{1}.gds".format(os.path.dirname(os.path.realpath(__file__)),name)
cell = gds_cell(name, gds_file)
self.add_inst(name=name,
mod=cell,
offset=[0,0])
self.connect_inst([])
r=router(gds_file)
layer_stack =("metal1","via1","metal2")
self.assertTrue(r.route(self,layer_stack,src="A",dest="B"))
self.assertTrue(r.route(self,layer_stack,src="C",dest="D"))
r = routing("05_two_nets_test_{0}".format(OPTS.tech_name))
self.local_drc_check(r)
# fails if there are any DRC errors on any cells
globals.end_openram()
# instantiate a copy of the class to actually run the test
if __name__ == "__main__":
(OPTS, args) = globals.parse_args()
del sys.argv[1:]
header(__file__, OPTS.tech_name)
unittest.main()

View File

@ -1,57 +1,43 @@
#!/usr/bin/env python2.7
#!/usr/bin/env python3
"Run a regresion test the library cells for DRC"
import unittest
from testutils import header
from testutils import header,openram_test
import sys,os
sys.path.append(os.path.join(sys.path[0],"../.."))
sys.path.append(os.path.join(sys.path[0],".."))
import globals
import debug
import calibre
OPTS = globals.OPTS
class pin_location_test(unittest.TestCase):
class pin_location_test(openram_test):
"""
Simplest two pin route test with no blockages using the pin locations instead of labels.
"""
def runTest(self):
globals.init_openram("config_{0}".format(OPTS.tech_name))
from gds_cell import gds_cell
from design import design
from router import router
import design
import router
class gdscell(design.design):
class routing(design, openram_test):
"""
A generic GDS design that we can route on.
"""
def __init__(self, name):
#design.design.__init__(self, name)
debug.info(2, "Create {0} object".format(name))
self.name = name
self.gds_file = "{0}/{1}.gds".format(os.path.dirname(os.path.realpath(__file__)),name)
self.sp_file = "{0}/{1}.sp".format(os.path.dirname(os.path.realpath(__file__)),name)
design.hierarchy_layout.layout.__init__(self, name)
design.hierarchy_spice.spice.__init__(self, name)
class routing(design.design,unittest.TestCase):
"""
A generic GDS design that we can route on.
"""
def __init__(self, name):
design.design.__init__(self, name)
debug.info(2, "Create {0} object".format(name))
design.__init__(self, "top")
cell = gdscell(name)
# Instantiate a GDS cell with the design
gds_file = "{0}/{1}.gds".format(os.path.dirname(os.path.realpath(__file__)),name)
cell = gds_cell(name, gds_file)
self.add_inst(name=name,
mod=cell,
offset=[0,0])
self.connect_inst([])
self.gdsname = "{0}/{1}.gds".format(os.path.dirname(os.path.realpath(__file__)),name)
r=router.router(self.gdsname)
r=router(gds_file)
layer_stack =("metal1","via1","metal2")
# these are user coordinates and layers
src_pin = [[0.52, 4.099],11]
@ -62,21 +48,12 @@ class pin_location_test(unittest.TestCase):
# This only works for freepdk45 since the coordinates are hard coded
if OPTS.tech_name == "freepdk45":
r = routing("06_pin_location_test_{0}".format(OPTS.tech_name))
self.local_check(r)
self.local_drc_check(r)
else:
debug.warning("This test does not support technology {0}".format(OPTS.tech_name))
# fails if there are any DRC errors on any cells
globals.end_openram()
def local_check(self, r):
tempgds = OPTS.openram_temp + "temp.gds"
r.gds_write(tempgds)
self.assertFalse(calibre.run_drc(r.name, tempgds))
os.remove(tempgds)

View File

@ -1,58 +1,44 @@
#!/usr/bin/env python2.7
#!/usr/bin/env python3
"Run a regresion test the library cells for DRC"
import unittest
from testutils import header
from testutils import header,openram_test
import sys,os
sys.path.append(os.path.join(sys.path[0],"../.."))
sys.path.append(os.path.join(sys.path[0],".."))
import globals
import debug
import calibre
OPTS = globals.OPTS
class big_test(unittest.TestCase):
class big_test(openram_test):
"""
Simplest two pin route test with no blockages using the pin locations instead of labels.
"""
def runTest(self):
globals.init_openram("config_{0}".format(OPTS.tech_name))
from gds_cell import gds_cell
from design import design
from router import router
import design
import router
class gdscell(design.design):
class routing(design, openram_test):
"""
A generic GDS design that we can route on.
"""
def __init__(self, name):
#design.design.__init__(self, name)
debug.info(2, "Create {0} object".format(name))
self.name = name
self.gds_file = "{0}/{1}.gds".format(os.path.dirname(os.path.realpath(__file__)),name)
self.sp_file = "{0}/{1}.sp".format(os.path.dirname(os.path.realpath(__file__)),name)
design.hierarchy_layout.layout.__init__(self, name)
design.hierarchy_spice.spice.__init__(self, name)
class routing(design.design,unittest.TestCase):
"""
A generic GDS design that we can route on.
"""
def __init__(self, name):
design.design.__init__(self, name)
debug.info(2, "Create {0} object".format(name))
design.__init__(self, "top")
cell = gdscell(name)
# Instantiate a GDS cell with the design
gds_file = "{0}/{1}.gds".format(os.path.dirname(os.path.realpath(__file__)),name)
cell = gds_cell(name, gds_file)
self.add_inst(name=name,
mod=cell,
offset=[0,0])
self.connect_inst([])
self.gdsname = "{0}/{1}.gds".format(os.path.dirname(os.path.realpath(__file__)),name)
r=router.router(self.gdsname)
layer_stack =("metal3","via2","metal2")
r=router(gds_file)
layer_stack =("metal1","via1","metal2")
connections=[('out_0_2', 'a_0_0'),
('out_0_3', 'b_0_0'),
('out_0_0', 'a_0_1'),
@ -80,21 +66,12 @@ class big_test(unittest.TestCase):
# This test only runs on scn3me_subm tech
if OPTS.tech_name=="scn3me_subm":
r = routing("07_big_test_{0}".format(OPTS.tech_name))
self.local_check(r)
self.local_drc_check(r)
else:
debug.warning("This test does not support technology {0}".format(OPTS.tech_name))
# fails if there are any DRC errors on any cells
globals.end_openram()
def local_check(self, r):
tempgds = OPTS.openram_temp + "temp.gds"
r.gds_write(tempgds)
self.assertFalse(calibre.run_drc(r.name, tempgds))
os.remove(tempgds)

View File

@ -1,57 +1,43 @@
#!/usr/bin/env python2.7
#!/usr/bin/env python3
"Run a regresion test the library cells for DRC"
import unittest
from testutils import header
from testutils import header,openram_test
import sys,os
sys.path.append(os.path.join(sys.path[0],"../.."))
sys.path.append(os.path.join(sys.path[0],".."))
import globals
import debug
import calibre
OPTS = globals.OPTS
class expand_region_test(unittest.TestCase):
class expand_region_test(openram_test):
"""
Test an infeasible route followed by a feasible route with an expanded region.
"""
def runTest(self):
globals.init_openram("config_{0}".format(OPTS.tech_name))
from gds_cell import gds_cell
from design import design
from router import router
import design
import router
class gdscell(design.design):
class routing(design, openram_test):
"""
A generic GDS design that we can route on.
"""
def __init__(self, name):
#design.design.__init__(self, name)
debug.info(2, "Create {0} object".format(name))
self.name = name
self.gds_file = "{0}/{1}.gds".format(os.path.dirname(os.path.realpath(__file__)),name)
self.sp_file = "{0}/{1}.sp".format(os.path.dirname(os.path.realpath(__file__)),name)
design.hierarchy_layout.layout.__init__(self, name)
design.hierarchy_spice.spice.__init__(self, name)
class routing(design.design,unittest.TestCase):
"""
A generic GDS design that we can route on.
"""
def __init__(self, name):
design.design.__init__(self, name)
debug.info(2, "Create {0} object".format(name))
design.__init__(self, "top")
cell = gdscell(name)
# Instantiate a GDS cell with the design
gds_file = "{0}/{1}.gds".format(os.path.dirname(os.path.realpath(__file__)),name)
cell = gds_cell(name, gds_file)
self.add_inst(name=name,
mod=cell,
offset=[0,0])
self.connect_inst([])
self.gdsname = "{0}/{1}.gds".format(os.path.dirname(os.path.realpath(__file__)),name)
r=router.router(self.gdsname)
r=router(gds_file)
layer_stack =("metal1","via1","metal2")
# This should be infeasible because it is blocked without a detour.
self.assertFalse(r.route(self,layer_stack,src="A",dest="B",detour_scale=1))
@ -59,22 +45,12 @@ class expand_region_test(unittest.TestCase):
self.assertTrue(r.route(self,layer_stack,src="A",dest="B",detour_scale=3))
r = routing("08_expand_region_test_{0}".format(OPTS.tech_name))
self.local_check(r)
self.local_drc_check(r)
# fails if there are any DRC errors on any cells
globals.end_openram()
def local_check(self, r):
tempgds = OPTS.openram_temp + "temp.gds"
r.gds_write(tempgds)
self.assertFalse(calibre.run_drc(r.name, tempgds))
os.remove(tempgds)
# instantiate a copy of the class to actually run the test
if __name__ == "__main__":
(OPTS, args) = globals.parse_args()

View File

@ -0,0 +1,16 @@
from design import design
class gds_cell(design):
"""
A generic GDS design.
"""
def __init__(self, name, gds_file):
self.name = name
self.gds_file = gds_file
self.sp_file = None
design.__init__(self, name)
# The dimensions will not be defined, so do this...
self.width=0
self.height=0

View File

@ -1,6 +1,6 @@
import unittest,warnings
import sys,os,glob,copy
sys.path.append(os.path.join(sys.path[0],".."))
sys.path.append(os.path.join(sys.path[0],"../.."))
from globals import OPTS
import debug
@ -19,7 +19,8 @@ class openram_test(unittest.TestCase):
if result != 0:
self.fail("DRC failed: {}".format(w.name))
self.cleanup()
if OPTS.purge_temp:
self.cleanup()
def local_check(self, a, final_verification=False):

View File

@ -86,6 +86,10 @@ def write_magic_script(cell_name, gds_name, extract=False):
f.write("gds warning default\n")
f.write("gds read {}\n".format(gds_name))
f.write("load {}\n".format(cell_name))
# Flatten the cell to get rid of DRCs spanning multiple layers
# (e.g. with routes)
f.write("flatten {}_new\n".format(cell_name))
f.write("load {}_new\n".format(cell_name))
f.write("writeall force\n")
f.write("drc check\n")
f.write("drc catchup\n")

View File

@ -1,81 +0,0 @@
#!/usr/bin/env python2.7
"Run a regresion test the library cells for DRC"
import unittest
from testutils import header
import sys,os
sys.path.append(os.path.join(sys.path[0],"../.."))
sys.path.append(os.path.join(sys.path[0],".."))
import globals
import debug
OPTS = globals.OPTS
class no_blockages_test(unittest.TestCase):
"""
Simplest two pin route test with no blockages.
"""
def runTest(self):
globals.init_openram("config_{0}".format(OPTS.tech_name))
global verify
import verify
import design
import router
class gdscell(design.design):
"""
A generic GDS design that we can route on.
"""
def __init__(self, name):
#design.design.__init__(self, name)
debug.info(2, "Create {0} object".format(name))
self.name = name
self.gds_file = "{0}/{1}.gds".format(os.path.dirname(os.path.realpath(__file__)),name)
self.sp_file = "{0}/{1}.sp".format(os.path.dirname(os.path.realpath(__file__)),name)
design.hierarchy_layout.layout.__init__(self, name)
design.hierarchy_spice.spice.__init__(self, name)
class routing(design.design,unittest.TestCase):
"""
A generic GDS design that we can route on.
"""
def __init__(self, name):
design.design.__init__(self, name)
debug.info(2, "Create {0} object".format(name))
cell = gdscell(name)
self.add_inst(name=name,
mod=cell,
offset=[0,0])
self.connect_inst([])
self.gdsname = "{0}/{1}.gds".format(os.path.dirname(os.path.realpath(__file__)),name)
r=router.router(self.gdsname)
layer_stack =("metal1","via1","metal2")
self.assertTrue(r.route(self,layer_stack,src="A",dest="B"))
r = routing("01_no_blockages_test_{0}".format(OPTS.tech_name))
self.local_check(r)
# fails if there are any DRC errors on any cells
globals.end_openram()
def local_check(self, r):
tempgds = OPTS.openram_temp + "temp.gds"
r.gds_write(tempgds)
self.assertFalse(calibre.run_drc(r.name, tempgds))
os.remove(tempgds)
# instantiate a copy of the class to actually run the test
if __name__ == "__main__":
(OPTS, args) = globals.parse_args()
del sys.argv[1:]
header(__file__, OPTS.tech_name)
unittest.main()

View File

@ -1,80 +0,0 @@
#!/usr/bin/env python2.7
"Run a regresion test the library cells for DRC"
import unittest
from testutils import header
import sys,os
sys.path.append(os.path.join(sys.path[0],"../.."))
sys.path.append(os.path.join(sys.path[0],".."))
import globals
import debug
import calibre
OPTS = globals.OPTS
class blockages_test(unittest.TestCase):
"""
Simple two pin route test with multilayer blockages.
"""
def runTest(self):
globals.init_openram("config_{0}".format(OPTS.tech_name))
import design
import router
class gdscell(design.design):
"""
A generic GDS design that we can route on.
"""
def __init__(self, name):
#design.design.__init__(self, name)
debug.info(2, "Create {0} object".format(name))
self.name = name
self.gds_file = "{0}/{1}.gds".format(os.path.dirname(os.path.realpath(__file__)),name)
self.sp_file = "{0}/{1}.sp".format(os.path.dirname(os.path.realpath(__file__)),name)
design.hierarchy_layout.layout.__init__(self, name)
design.hierarchy_spice.spice.__init__(self, name)
class routing(design.design,unittest.TestCase):
"""
A generic GDS design that we can route on.
"""
def __init__(self, name):
design.design.__init__(self, name)
debug.info(2, "Create {0} object".format(name))
cell = gdscell(name)
self.add_inst(name=name,
mod=cell,
offset=[0,0])
self.connect_inst([])
self.gdsname = "{0}/{1}.gds".format(os.path.dirname(os.path.realpath(__file__)),name)
r=router.router(self.gdsname)
layer_stack =("metal1","via1","metal2")
self.assertTrue(r.route(self,layer_stack,src="A",dest="B"))
r = routing("02_blockages_test_{0}".format(OPTS.tech_name))
self.local_check(r)
# fails if there are any DRC errors on any cells
globals.end_openram()
def local_check(self, r):
tempgds = OPTS.openram_temp + "temp.gds"
r.gds_write(tempgds)
self.assertFalse(calibre.run_drc(r.name, tempgds))
os.remove(tempgds)
# instantiate a copy of the class to actually run the test
if __name__ == "__main__":
(OPTS, args) = globals.parse_args()
del sys.argv[1:]
header(__file__, OPTS.tech_name)
unittest.main()

View File

@ -1,80 +0,0 @@
#!/usr/bin/env python2.7
"Run a regresion test the library cells for DRC"
import unittest
from testutils import header
import sys,os
sys.path.append(os.path.join(sys.path[0],"../.."))
sys.path.append(os.path.join(sys.path[0],".."))
import globals
import debug
import calibre
OPTS = globals.OPTS
class same_layer_pins_test(unittest.TestCase):
"""
Checks two pins on the same layer with positive and negative coordinates.
"""
def runTest(self):
globals.init_openram("config_{0}".format(OPTS.tech_name))
import design
import router
class gdscell(design.design):
"""
A generic GDS design that we can route on.
"""
def __init__(self, name):
#design.design.__init__(self, name)
debug.info(2, "Create {0} object".format(name))
self.name = name
self.gds_file = "{0}/{1}.gds".format(os.path.dirname(os.path.realpath(__file__)),name)
self.sp_file = "{0}/{1}.sp".format(os.path.dirname(os.path.realpath(__file__)),name)
design.hierarchy_layout.layout.__init__(self, name)
design.hierarchy_spice.spice.__init__(self, name)
class routing(design.design,unittest.TestCase):
"""
A generic GDS design that we can route on.
"""
def __init__(self, name):
design.design.__init__(self, name)
debug.info(2, "Create {0} object".format(name))
cell = gdscell(name)
self.add_inst(name=name,
mod=cell,
offset=[0,0])
self.connect_inst([])
self.gdsname = "{0}/{1}.gds".format(os.path.dirname(os.path.realpath(__file__)),name)
r=router.router(self.gdsname)
layer_stack =("metal1","via1","metal2")
self.assertTrue(r.route(self,layer_stack,src="A",dest="B"))
r = routing("03_same_layer_pins_test_{0}".format(OPTS.tech_name))
self.local_check(r)
# fails if there are any DRC errors on any cells
globals.end_openram()
def local_check(self, r):
tempgds = OPTS.openram_temp + "temp.gds"
r.gds_write(tempgds)
self.assertFalse(calibre.run_drc(r.name, tempgds))
os.remove(tempgds)
# instantiate a copy of the class to actually run the test
if __name__ == "__main__":
(OPTS, args) = globals.parse_args()
del sys.argv[1:]
header(__file__, OPTS.tech_name)
unittest.main()

View File

@ -1,81 +0,0 @@
#!/usr/bin/env python2.7
"Run a regresion test the library cells for DRC"
import unittest
from testutils import header
import sys,os
sys.path.append(os.path.join(sys.path[0],"../.."))
sys.path.append(os.path.join(sys.path[0],".."))
import globals
import debug
import calibre
OPTS = globals.OPTS
class diff_layer_pins_test(unittest.TestCase):
"""
Two pin route test with pins on different layers and blockages.
Pins are smaller than grid size.
"""
def runTest(self):
globals.init_openram("config_{0}".format(OPTS.tech_name))
import design
import router
class gdscell(design.design):
"""
A generic GDS design that we can route on.
"""
def __init__(self, name):
#design.design.__init__(self, name)
debug.info(2, "Create {0} object".format(name))
self.name = name
self.gds_file = "{0}/{1}.gds".format(os.path.dirname(os.path.realpath(__file__)),name)
self.sp_file = "{0}/{1}.sp".format(os.path.dirname(os.path.realpath(__file__)),name)
design.hierarchy_layout.layout.__init__(self, name)
design.hierarchy_spice.spice.__init__(self, name)
class routing(design.design,unittest.TestCase):
"""
A generic GDS design that we can route on.
"""
def __init__(self, name):
design.design.__init__(self, name)
debug.info(2, "Create {0} object".format(name))
cell = gdscell(name)
self.add_inst(name=name,
mod=cell,
offset=[0,0])
self.connect_inst([])
self.gdsname = "{0}/{1}.gds".format(os.path.dirname(os.path.realpath(__file__)),name)
r=router.router(self.gdsname)
layer_stack =("metal1","via1","metal2")
self.assertTrue(r.route(self,layer_stack,src="A",dest="B"))
r = routing("04_diff_layer_pins_test_{0}".format(OPTS.tech_name))
self.local_check(r)
# fails if there are any DRC errors on any cells
globals.end_openram()
def local_check(self, r):
tempgds = OPTS.openram_temp + "temp.gds"
r.gds_write(tempgds)
self.assertFalse(calibre.run_drc(r.name, tempgds))
os.remove(tempgds)
# instantiate a copy of the class to actually run the test
if __name__ == "__main__":
(OPTS, args) = globals.parse_args()
del sys.argv[1:]
header(__file__, OPTS.tech_name)
unittest.main()

View File

@ -1,82 +0,0 @@
#!/usr/bin/env python2.7
"Run a regresion test the library cells for DRC"
import unittest
from testutils import header
import sys,os
sys.path.append(os.path.join(sys.path[0],"../.."))
sys.path.append(os.path.join(sys.path[0],".."))
import globals
import debug
import calibre
OPTS = globals.OPTS
class two_nets_test(unittest.TestCase):
"""
Route two nets in the same GDS file. The routes will interact,
so they must block eachother.
"""
def runTest(self):
globals.init_openram("config_{0}".format(OPTS.tech_name))
import design
import router
class gdscell(design.design):
"""
A generic GDS design that we can route on.
"""
def __init__(self, name):
#design.design.__init__(self, name)
debug.info(2, "Create {0} object".format(name))
self.name = name
self.gds_file = "{0}/{1}.gds".format(os.path.dirname(os.path.realpath(__file__)),name)
self.sp_file = "{0}/{1}.sp".format(os.path.dirname(os.path.realpath(__file__)),name)
design.hierarchy_layout.layout.__init__(self, name)
design.hierarchy_spice.spice.__init__(self, name)
class routing(design.design,unittest.TestCase):
"""
A generic GDS design that we can route on.
"""
def __init__(self, name):
design.design.__init__(self, name)
debug.info(2, "Create {0} object".format(name))
cell = gdscell(name)
self.add_inst(name=name,
mod=cell,
offset=[0,0])
self.connect_inst([])
self.gdsname = "{0}/{1}.gds".format(os.path.dirname(os.path.realpath(__file__)),name)
r=router.router(self.gdsname)
layer_stack =("metal1","via1","metal2")
self.assertTrue(r.route(self,layer_stack,src="A",dest="B"))
self.assertTrue(r.route(self,layer_stack,src="C",dest="D"))
r = routing("05_two_nets_test_{0}".format(OPTS.tech_name))
self.local_check(r)
# fails if there are any DRC errors on any cells
globals.end_openram()
def local_check(self, r):
tempgds = OPTS.openram_temp + "temp.gds"
r.gds_write(tempgds)
self.assertFalse(calibre.run_drc(r.name, tempgds))
os.remove(tempgds)
# instantiate a copy of the class to actually run the test
if __name__ == "__main__":
(OPTS, args) = globals.parse_args()
del sys.argv[1:]
header(__file__, OPTS.tech_name)
unittest.main()