Merged and fixed conflicts with dev

This commit is contained in:
Hunter Nichols 2019-06-25 16:55:50 -07:00
commit 4e08e2da87
311 changed files with 14271 additions and 1503 deletions

View File

@ -8,7 +8,7 @@
import hierarchy_design import hierarchy_design
import debug import debug
import utils import utils
from tech import drc from tech import drc,layer
from vector import vector from vector import vector
@ -196,5 +196,8 @@ active = factory.create(module_type="contact", layer_stack=("active", "contact",
poly = factory.create(module_type="contact", layer_stack=("poly", "contact", "metal1"), directions=("V","H")) 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")) 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")) m2m3 = factory.create(module_type="contact", layer_stack=("metal2", "via2", "metal3"), directions=("V","H"))
if "metal4" in layer.keys():
m3m4 = factory.create(module_type="contact", layer_stack=("metal3", "via3", "metal4"), directions=("H","V")) m3m4 = factory.create(module_type="contact", layer_stack=("metal3", "via3", "metal4"), directions=("H","V"))
else:
m3m4 = None

View File

@ -26,14 +26,17 @@ class design(hierarchy_design):
self.setup_drc_constants() self.setup_drc_constants()
self.setup_multiport_constants() self.setup_multiport_constants()
from tech import layer
self.m1_pitch = max(contact.m1m2.width,contact.m1m2.height) + max(self.m1_space, self.m2_space) self.m1_pitch = max(contact.m1m2.width,contact.m1m2.height) + max(self.m1_space, self.m2_space)
self.m2_pitch = max(contact.m2m3.width,contact.m2m3.height) + max(self.m2_space, self.m3_space) self.m2_pitch = max(contact.m2m3.width,contact.m2m3.height) + max(self.m2_space, self.m3_space)
if contact.m3m4: if "metal4" in layer:
self.m3_pitch = max(contact.m3m4.width,contact.m3m4.height) + max(self.m3_space, self.m4_space) self.m3_pitch = max(contact.m3m4.width,contact.m3m4.height) + max(self.m3_space, self.m4_space)
else:
self.m3_pitch = self.m2_pitch
def setup_drc_constants(self): def setup_drc_constants(self):
""" These are some DRC constants used in many places in the compiler.""" """ These are some DRC constants used in many places in the compiler."""
from tech import drc from tech import drc,layer
self.well_width = drc("minwidth_well") self.well_width = drc("minwidth_well")
self.poly_width = drc("minwidth_poly") self.poly_width = drc("minwidth_poly")
self.poly_space = drc("poly_to_poly") self.poly_space = drc("poly_to_poly")
@ -43,7 +46,7 @@ class design(hierarchy_design):
self.m2_space = drc("metal2_to_metal2") self.m2_space = drc("metal2_to_metal2")
self.m3_width = drc("minwidth_metal3") self.m3_width = drc("minwidth_metal3")
self.m3_space = drc("metal3_to_metal3") self.m3_space = drc("metal3_to_metal3")
if contact.m3m4: if "metal4" in layer:
self.m4_width = drc("minwidth_metal4") self.m4_width = drc("minwidth_metal4")
self.m4_space = drc("metal4_to_metal4") self.m4_space = drc("metal4_to_metal4")
self.active_width = drc("minwidth_active") self.active_width = drc("minwidth_active")

View File

@ -165,7 +165,7 @@ class instance(geometry):
debug.info(4, "creating instance: " + self.name) debug.info(4, "creating instance: " + self.name)
def get_blockages(self, layer, top=False): 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.""" Apply the transform of the instance placement to give absolute blockages."""
angle = math.radians(float(self.rotate)) angle = math.radians(float(self.rotate))
mirr = 1 mirr = 1
@ -184,21 +184,20 @@ class instance(geometry):
mirr = 1 mirr = 1
angle += math.radians(180.0) angle += math.radians(180.0)
if self.mod.is_library_cell:
# For lib cells, block the whole thing except on metal3
# since they shouldn't use metal3
if layer==tech.layer["metal1"] or layer==tech.layer["metal2"]:
return [self.transform_coords(self.mod.get_boundary(), self.offset, mirr, angle)]
else:
return []
else:
blockages = self.mod.get_blockages(layer)
new_blockages = [] 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))
else:
blockages = self.mod.get_blockages(layer)
for b in blockages: for b in blockages:
new_blockages.append(self.transform_coords(b,self.offset, mirr, angle)) new_blockages.append(self.transform_coords(b,self.offset, mirr, angle))
return new_blockages return new_blockages
def gds_write_file(self, new_layout): def gds_write_file(self, new_layout):
"""Recursively writes all the sub-modules in this instance""" """Recursively writes all the sub-modules in this instance"""
debug.info(4, "writing instance: " + self.name) debug.info(4, "writing instance: " + self.name)

View File

@ -880,6 +880,13 @@ class layout():
""" """
self.create_channel_route(netlist, offset, layer_stack, pitch, vertical=False) self.create_channel_route(netlist, offset, layer_stack, pitch, vertical=False)
def add_boundary(self):
""" Add boundary for debugging dimensions """
self.add_rect(layer="boundary",
offset=vector(0,0),
height=self.height,
width=self.width)
def add_enclosure(self, insts, layer="nwell"): def add_enclosure(self, insts, layer="nwell"):
""" Add a layer that surrounds the given instances. Useful """ Add a layer that surrounds the given instances. Useful
for creating wells, for example. Doesn't check for minimum widths or for creating wells, for example. Doesn't check for minimum widths or

View File

@ -12,6 +12,7 @@ import math
import debug import debug
import datetime import datetime
from collections import defaultdict from collections import defaultdict
import pdb
class lef: class lef:
""" """
@ -21,9 +22,11 @@ class lef:
""" """
def __init__(self,layers): def __init__(self,layers):
# LEF db units per micron # LEF db units per micron
self.lef_units = 1000 self.lef_units = 2000
# These are the layers of the obstructions # These are the layers of the obstructions
self.lef_layers = layers self.lef_layers = layers
# Round to ensure float values are divisible by 0.0025 (the manufacturing grid)
self.round_grid = 4;
def lef_write(self, lef_name): def lef_write(self, lef_name):
"""Write the entire lef of the object to the file.""" """Write the entire lef of the object to the file."""
@ -49,24 +52,13 @@ class lef:
self.lef.write(" DATABASE MICRONS {0} ;\n".format(self.lef_units)) self.lef.write(" DATABASE MICRONS {0} ;\n".format(self.lef_units))
self.lef.write("END UNITS\n") self.lef.write("END UNITS\n")
self.lef.write("SITE MacroSite\n")
self.indent += " "
self.lef.write("{0}CLASS Core ;\n".format(self.indent))
self.lef.write("{0}SIZE {1} by {2} ;\n".format(self.indent,
self.lef_units*self.width,
self.lef_units*self.height))
self.indent = self.indent[:-3]
self.lef.write("END MacroSite\n")
self.lef.write("{0}MACRO {1}\n".format(self.indent,self.name)) self.lef.write("{0}MACRO {1}\n".format(self.indent,self.name))
self.indent += " " self.indent += " "
self.lef.write("{0}CLASS BLOCK ;\n".format(self.indent)) self.lef.write("{0}CLASS BLOCK ;\n".format(self.indent))
self.lef.write("{0}SIZE {1} BY {2} ;\n" .format(self.indent, self.lef.write("{0}SIZE {1} BY {2} ;\n" .format(self.indent,
self.lef_units*self.width, round(self.width,self.round_grid),
self.lef_units*self.height)) round(self.height,self.round_grid)))
self.lef.write("{0}SYMMETRY X Y R90 ;\n".format(self.indent)) self.lef.write("{0}SYMMETRY X Y R90 ;\n".format(self.indent))
self.lef.write("{0}SITE MacroSite ;\n".format(self.indent))
def lef_write_footer(self): def lef_write_footer(self):
self.lef.write("{0}END {1}\n".format(self.indent,self.name)) self.lef.write("{0}END {1}\n".format(self.indent,self.name))
@ -93,7 +85,7 @@ class lef:
pin_list = self.get_pins(name) pin_list = self.get_pins(name)
for pin in pin_list: for pin in pin_list:
self.lef.write("{0}LAYER {1} ;\n".format(self.indent,pin.layer)) 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 # End the PORT
self.indent = self.indent[:-3] self.indent = self.indent[:-3]
@ -109,15 +101,29 @@ class lef:
for layer in self.lef_layers: for layer in self.lef_layers:
self.lef.write("{0}LAYER {1} ;\n".format(self.indent,layer)) self.lef.write("{0}LAYER {1} ;\n".format(self.indent,layer))
self.indent += " " self.indent += " "
# pdb.set_trace()
blockages = self.get_blockages(layer,True) blockages = self.get_blockages(layer,True)
for b in blockages: 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.indent = self.indent[:-3]
self.lef.write("{0}END\n".format(self.indent)) self.lef.write("{0}END\n".format(self.indent))
def lef_write_rect(self, rect): def lef_write_shape(self, rect):
if len(rect) == 2:
""" Write a LEF rectangle """ """ Write a LEF rectangle """
self.lef.write("{0}RECT ".format(self.indent)) self.lef.write("{0}RECT ".format(self.indent))
for item in rect: for item in rect:
self.lef.write(" {0} {1}".format(self.lef_units*item[0], self.lef_units*item[1])) # print(rect)
self.lef.write(" {0} {1}".format(round(item[0],self.round_grid), round(item[1],self.round_grid)))
self.lef.write(" ;\n") 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

@ -36,6 +36,7 @@ class pbitcell(design.design):
self.create_netlist() self.create_netlist()
# We must always create the bitcell layout because some transistor sizes in the other netlists depend on it # We must always create the bitcell layout because some transistor sizes in the other netlists depend on it
self.create_layout() self.create_layout()
self.add_boundary()
def create_netlist(self): def create_netlist(self):
self.add_pins() self.add_pins()
@ -79,9 +80,7 @@ class pbitcell(design.design):
# in netlist_only mode, calling offset_all_coordinates or translate_all will not be possible # in netlist_only mode, calling offset_all_coordinates or translate_all will not be possible
# this function is not needed to calculate the dimensions of pbitcell in netlist_only mode though # this function is not needed to calculate the dimensions of pbitcell in netlist_only mode though
if not OPTS.netlist_only: if not OPTS.netlist_only:
self.offset_all_coordinates() self.translate_all(vector(self.leftmost_xpos, self.botmost_ypos))
gnd_overlap = vector(0, 0.5*contact.well.width)
self.translate_all(gnd_overlap)
def add_pins(self): def add_pins(self):
@ -143,7 +142,8 @@ class pbitcell(design.design):
def add_modules(self): def add_modules(self):
""" Determine size of transistors and add ptx modules """ """ Determine size of transistors and add ptx modules """
# if there are any read/write ports, then the inverter nmos is sized based the number of read/write ports # if there are any read/write ports,
# then the inverter nmos is sized based the number of read/write ports
if(self.num_rw_ports > 0): if(self.num_rw_ports > 0):
inverter_nmos_width = self.num_rw_ports*parameter["6T_inv_nmos_size"] inverter_nmos_width = self.num_rw_ports*parameter["6T_inv_nmos_size"]
inverter_pmos_width = parameter["6T_inv_pmos_size"] inverter_pmos_width = parameter["6T_inv_pmos_size"]
@ -151,7 +151,8 @@ class pbitcell(design.design):
write_nmos_width = parameter["6T_access_size"] write_nmos_width = parameter["6T_access_size"]
read_nmos_width = 2*parameter["6T_inv_pmos_size"] read_nmos_width = 2*parameter["6T_inv_pmos_size"]
# if there are no read/write ports, then the inverter nmos is statically sized for the dual port case # if there are no read/write ports,
# then the inverter nmos is statically sized for the dual port case
else: else:
inverter_nmos_width = 2*parameter["6T_inv_pmos_size"] inverter_nmos_width = 2*parameter["6T_inv_pmos_size"]
inverter_pmos_width = parameter["6T_inv_pmos_size"] inverter_pmos_width = parameter["6T_inv_pmos_size"]
@ -185,14 +186,21 @@ class pbitcell(design.design):
def calculate_spacing(self): def calculate_spacing(self):
""" Calculate transistor spacings """ """ Calculate transistor spacings """
# calculate metal contact extensions over transistor active # calculate metal contact extensions over transistor active
readwrite_nmos_contact_extension = 0.5*(self.readwrite_nmos.active_contact.height - self.readwrite_nmos.active_height) readwrite_nmos_contact_extension = 0.5*(self.readwrite_nmos.active_contact.height \
write_nmos_contact_extension = 0.5*(self.write_nmos.active_contact.height - self.write_nmos.active_height) - self.readwrite_nmos.active_height)
read_nmos_contact_extension = 0.5*(self.read_nmos.active_contact.height - self.read_nmos.active_height) write_nmos_contact_extension = 0.5*(self.write_nmos.active_contact.height \
max_contact_extension = max(readwrite_nmos_contact_extension, write_nmos_contact_extension, read_nmos_contact_extension) - self.write_nmos.active_height)
read_nmos_contact_extension = 0.5*(self.read_nmos.active_contact.height \
- self.read_nmos.active_height)
max_contact_extension = max(readwrite_nmos_contact_extension,
write_nmos_contact_extension,
read_nmos_contact_extension)
# y-offset for the access transistor's gate contact # y-offset for the access transistor's gate contact
self.gate_contact_yoffset = max_contact_extension + self.m2_space + 0.5*max(contact.poly.height, contact.m1m2.height) self.gate_contact_yoffset = max_contact_extension + self.m2_space \
+ 0.5*max(contact.poly.height, contact.m1m2.height)
# y-position of access transistors # y-position of access transistors
self.port_ypos = self.m1_space + 0.5*contact.m1m2.height + self.gate_contact_yoffset self.port_ypos = self.m1_space + 0.5*contact.m1m2.height + self.gate_contact_yoffset
@ -201,8 +209,10 @@ class pbitcell(design.design):
self.inverter_nmos_ypos = self.port_ypos self.inverter_nmos_ypos = self.port_ypos
# spacing between ports (same for read/write and write ports) # spacing between ports (same for read/write and write ports)
self.bitline_offset = -0.5*self.readwrite_nmos.active_width + 0.5*contact.m1m2.height + self.m2_space + self.m2_width self.bitline_offset = -0.5*self.readwrite_nmos.active_width + 0.5*contact.m1m2.height \
m2_constraint = self.bitline_offset + self.m2_space + 0.5*contact.m1m2.height - 0.5*self.readwrite_nmos.active_width + self.m2_space + self.m2_width
m2_constraint = self.bitline_offset + self.m2_space + 0.5*contact.m1m2.height \
- 0.5*self.readwrite_nmos.active_width
self.write_port_spacing = max(self.active_space, self.m1_space, m2_constraint) self.write_port_spacing = max(self.active_space, self.m1_space, m2_constraint)
self.read_port_spacing = self.bitline_offset + self.m2_space self.read_port_spacing = self.bitline_offset + self.m2_space
@ -224,11 +234,11 @@ class pbitcell(design.design):
+ 1.5*contact.poly.width + 1.5*contact.poly.width
# spacing between wordlines (and gnd) # spacing between wordlines (and gnd)
self.rowline_spacing = self.m1_space + contact.m1m2.width self.m1_offset = -0.5*self.m1_width
self.rowline_offset = -0.5*self.m1_width
# spacing for vdd # spacing for vdd
implant_constraint = max(inverter_pmos_contact_extension, 0) + 2*self.implant_enclose_active + 0.5*(contact.well.width - self.m1_width) implant_constraint = max(inverter_pmos_contact_extension, 0) + 2*self.implant_enclose_active \
+ 0.5*(contact.well.width - self.m1_width)
metal1_constraint = max(inverter_pmos_contact_extension, 0) + self.m1_space metal1_constraint = max(inverter_pmos_contact_extension, 0) + self.m1_space
self.vdd_offset = max(implant_constraint, metal1_constraint) + 0.5*self.m1_width self.vdd_offset = max(implant_constraint, metal1_constraint) + 0.5*self.m1_width
@ -238,8 +248,10 @@ class pbitcell(design.design):
def calculate_postions(self): def calculate_postions(self):
""" Calculate positions that describe the edges and dimensions of the cell """ """ Calculate positions that describe the edges and dimensions of the cell """
self.botmost_ypos = -0.5*self.m1_width - self.total_ports*self.rowline_spacing self.botmost_ypos = self.m1_offset - self.total_ports*self.m1_pitch
self.topmost_ypos = self.inverter_nmos_ypos + self.inverter_nmos.active_height + self.inverter_gap + self.inverter_pmos.active_height + self.vdd_offset self.topmost_ypos = self.inverter_nmos_ypos + self.inverter_nmos.active_height \
+ self.inverter_gap + self.inverter_pmos.active_height \
+ self.vdd_offset
self.leftmost_xpos = -0.5*self.inverter_to_inverter_spacing - self.inverter_nmos.active_width \ self.leftmost_xpos = -0.5*self.inverter_to_inverter_spacing - self.inverter_nmos.active_width \
- self.num_rw_ports*(self.readwrite_nmos.active_width + self.write_port_spacing) \ - self.num_rw_ports*(self.readwrite_nmos.active_width + self.write_port_spacing) \
@ -249,9 +261,9 @@ class pbitcell(design.design):
self.width = -2*self.leftmost_xpos self.width = -2*self.leftmost_xpos
self.height = self.topmost_ypos - self.botmost_ypos self.height = self.topmost_ypos - self.botmost_ypos
self.center_ypos = 0.5*(self.topmost_ypos + self.botmost_ypos) self.center_ypos = 0.5*(self.topmost_ypos + self.botmost_ypos)
def create_storage(self): def create_storage(self):
""" """
Creates the crossed coupled inverters that act as storage for the bitcell. Creates the crossed coupled inverters that act as storage for the bitcell.
@ -309,13 +321,15 @@ class pbitcell(design.design):
width=contact.active.second_layer_width) width=contact.active.second_layer_width)
# add contacts to connect gate poly to drain/source metal1 (to connect Q to Q_bar) # 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) 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_via_center(layers=("poly", "contact", "metal1"), self.add_via_center(layers=("poly", "contact", "metal1"),
offset=contact_offset_left, offset=contact_offset_left,
directions=("H","H")) 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) 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_via_center(layers=("poly", "contact", "metal1"), self.add_via_center(layers=("poly", "contact", "metal1"),
offset=contact_offset_right, offset=contact_offset_right,
directions=("H","H")) directions=("H","H"))
@ -330,21 +344,21 @@ class pbitcell(design.design):
def route_rails(self): def route_rails(self):
""" Adds gnd and vdd rails and connects them to the inverters """ """ Adds gnd and vdd rails and connects them to the inverters """
# Add rails for vdd and gnd # Add rails for vdd and gnd
gnd_ypos = self.rowline_offset - self.total_ports*self.rowline_spacing gnd_ypos = self.m1_offset - self.total_ports*self.m1_pitch
self.gnd_position = vector(0, gnd_ypos) self.gnd_position = vector(0, gnd_ypos)
self.add_rect_center(layer="metal1", self.add_rect_center(layer="metal1",
offset=self.gnd_position, offset=self.gnd_position,
width=self.width, width=self.width)
height=self.m1_width)
self.add_power_pin("gnd", vector(0,gnd_ypos)) self.add_power_pin("gnd", vector(0,gnd_ypos))
vdd_ypos = self.inverter_nmos_ypos + self.inverter_nmos.active_height + self.inverter_gap + self.inverter_pmos.active_height + self.vdd_offset vdd_ypos = self.inverter_nmos_ypos + self.inverter_nmos.active_height \
+ self.inverter_gap + self.inverter_pmos.active_height \
+ self.vdd_offset
self.vdd_position = vector(0, vdd_ypos) self.vdd_position = vector(0, vdd_ypos)
self.add_rect_center(layer="metal1", self.add_rect_center(layer="metal1",
offset=self.vdd_position, offset=self.vdd_position,
width=self.width, width=self.width)
height=self.m1_width)
self.add_power_pin("vdd", vector(0,vdd_ypos)) self.add_power_pin("vdd", vector(0,vdd_ypos))
def create_readwrite_ports(self): def create_readwrite_ports(self):
@ -395,13 +409,12 @@ class pbitcell(design.design):
self.readwrite_nmos_right[k].place(offset=[right_readwrite_transistor_xpos, self.port_ypos]) self.readwrite_nmos_right[k].place(offset=[right_readwrite_transistor_xpos, self.port_ypos])
# add pin for RWWL # add pin for RWWL
rwwl_ypos = self.rowline_offset - k*self.rowline_spacing rwwl_ypos = self.m1_offset - k*self.m1_pitch
self.rwwl_positions[k] = vector(0, rwwl_ypos) self.rwwl_positions[k] = vector(0, rwwl_ypos)
self.add_layout_pin_rect_center(text=self.rw_wl_names[k], self.add_layout_pin_rect_center(text=self.rw_wl_names[k],
layer="metal1", layer="metal1",
offset=self.rwwl_positions[k], offset=self.rwwl_positions[k],
width=self.width, width=self.width)
height=self.m1_width)
# add pins for RWBL and RWBR # add pins for RWBL and RWBR
rwbl_xpos = left_readwrite_transistor_xpos - self.bitline_offset + 0.5*self.m2_width rwbl_xpos = left_readwrite_transistor_xpos - self.bitline_offset + 0.5*self.m2_width
@ -411,7 +424,8 @@ class pbitcell(design.design):
offset=self.rwbl_positions[k], offset=self.rwbl_positions[k],
height=self.height) height=self.height)
rwbr_xpos = right_readwrite_transistor_xpos + self.readwrite_nmos.active_width + self.bitline_offset - 0.5*self.m2_width rwbr_xpos = right_readwrite_transistor_xpos + self.readwrite_nmos.active_width \
+ self.bitline_offset - 0.5*self.m2_width
self.rwbr_positions[k] = vector(rwbr_xpos, self.center_ypos) self.rwbr_positions[k] = vector(rwbr_xpos, self.center_ypos)
self.add_layout_pin_rect_center(text=self.rw_br_names[k], self.add_layout_pin_rect_center(text=self.rw_br_names[k],
layer="metal2", layer="metal2",
@ -470,13 +484,13 @@ class pbitcell(design.design):
self.write_nmos_right[k].place(offset=[right_write_transistor_xpos, self.port_ypos]) self.write_nmos_right[k].place(offset=[right_write_transistor_xpos, self.port_ypos])
# add pin for WWL # add pin for WWL
wwl_ypos = rwwl_ypos = self.rowline_offset - self.num_rw_ports*self.rowline_spacing - k*self.rowline_spacing wwl_ypos = rwwl_ypos = self.m1_offset - self.num_rw_ports*self.m1_pitch \
- k*self.m1_pitch
self.wwl_positions[k] = vector(0, wwl_ypos) self.wwl_positions[k] = vector(0, wwl_ypos)
self.add_layout_pin_rect_center(text=self.w_wl_names[k], self.add_layout_pin_rect_center(text=self.w_wl_names[k],
layer="metal1", layer="metal1",
offset=self.wwl_positions[k], offset=self.wwl_positions[k],
width=self.width, width=self.width)
height=self.m1_width)
# add pins for WBL and WBR # add pins for WBL and WBR
wbl_xpos = left_write_transistor_xpos - self.bitline_offset + 0.5*self.m2_width wbl_xpos = left_write_transistor_xpos - self.bitline_offset + 0.5*self.m2_width
@ -486,7 +500,8 @@ class pbitcell(design.design):
offset=self.wbl_positions[k], offset=self.wbl_positions[k],
height=self.height) height=self.height)
wbr_xpos = right_write_transistor_xpos + self.write_nmos.active_width + self.bitline_offset - 0.5*self.m2_width wbr_xpos = right_write_transistor_xpos + self.write_nmos.active_width + self.bitline_offset \
- 0.5*self.m2_width
self.wbr_positions[k] = vector(wbr_xpos, self.center_ypos) self.wbr_positions[k] = vector(wbr_xpos, self.center_ypos)
self.add_layout_pin_rect_center(text=self.w_br_names[k], self.add_layout_pin_rect_center(text=self.w_br_names[k],
layer="metal2", layer="metal2",
@ -567,13 +582,13 @@ class pbitcell(design.design):
self.read_nmos_right[k].place(offset=[right_read_transistor_xpos+overlap_offset, self.port_ypos]) self.read_nmos_right[k].place(offset=[right_read_transistor_xpos+overlap_offset, self.port_ypos])
# add pin for RWL # add pin for RWL
rwl_ypos = rwwl_ypos = self.rowline_offset - self.num_rw_ports*self.rowline_spacing - self.num_w_ports*self.rowline_spacing - k*self.rowline_spacing rwl_ypos = rwwl_ypos = self.m1_offset - self.num_rw_ports*self.m1_pitch \
- self.num_w_ports*self.m1_pitch - k*self.m1_pitch
self.rwl_positions[k] = vector(0, rwl_ypos) self.rwl_positions[k] = vector(0, rwl_ypos)
self.add_layout_pin_rect_center(text=self.r_wl_names[k], self.add_layout_pin_rect_center(text=self.r_wl_names[k],
layer="metal1", layer="metal1",
offset=self.rwl_positions[k], offset=self.rwl_positions[k],
width=self.width, width=self.width)
height=self.m1_width)
# add pins for RBL and RBR # add pins for RBL and RBR
rbl_xpos = left_read_transistor_xpos - self.bitline_offset + 0.5*self.m2_width rbl_xpos = left_read_transistor_xpos - self.bitline_offset + 0.5*self.m2_width
@ -583,7 +598,8 @@ class pbitcell(design.design):
offset=self.rbl_positions[k], offset=self.rbl_positions[k],
height=self.height) height=self.height)
rbr_xpos = right_read_transistor_xpos + self.read_port_width + self.bitline_offset - 0.5*self.m2_width rbr_xpos = right_read_transistor_xpos + self.read_port_width + self.bitline_offset \
- 0.5*self.m2_width
self.rbr_positions[k] = vector(rbr_xpos, self.center_ypos) self.rbr_positions[k] = vector(rbr_xpos, self.center_ypos)
self.add_layout_pin_rect_center(text=self.r_br_names[k], self.add_layout_pin_rect_center(text=self.r_br_names[k],
layer="metal2", layer="metal2",
@ -741,12 +757,14 @@ class pbitcell(design.design):
def route_read_access(self): def route_read_access(self):
""" Routes read access transistors to the storage component of the bitcell """ """ Routes read access transistors to the storage component of the bitcell """
# add poly to metal1 contacts for gates of the inverters # add poly to metal1 contacts for gates of the inverters
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) 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"), self.add_via_center(layers=("poly", "contact", "metal1"),
offset=left_storage_contact, offset=left_storage_contact,
directions=("H","H")) directions=("H","H"))
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) 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"), self.add_via_center(layers=("poly", "contact", "metal1"),
offset=right_storage_contact, offset=right_storage_contact,
directions=("H","H")) directions=("H","H"))

View File

@ -0,0 +1,248 @@
# 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
import math
from .stimuli import *
from .trim_spice import *
from .charutils import *
import utils
from globals import OPTS
from .delay import delay
class bitline_delay(delay):
"""Functions to test for the worst case delay in a target SRAM
The current worst case determines a feasible period for the SRAM then tests
several bits and record the delay and differences between the bits.
"""
def __init__(self, sram, spfile, corner):
delay.__init__(self,sram,spfile,corner)
self.period = tech.spice["feasible_period"]
self.is_bitline_measure = True
def create_signal_names(self):
delay.create_signal_names(self)
self.bl_signal_names = ["Xsram.Xbank0.bl", "Xsram.Xbank0.br"]
self.sen_name = "Xsram.s_en"
def create_measurement_names(self):
"""Create measurement names. The names themselves currently define the type of measurement"""
#Altering the names will crash the characterizer. TODO: object orientated approach to the measurements.
self.bl_volt_meas_names = ["volt_bl", "volt_br"]
self.bl_delay_meas_names = ["delay_bl", "delay_br"] #only used in SPICE simulation
self.bl_delay_result_name = "delay_bl_vth" #Used in the return value
def set_probe(self,probe_address, probe_data):
""" Probe address and data can be set separately to utilize other
functions in this characterizer besides analyze."""
delay.set_probe(self,probe_address, probe_data)
self.bitline_column = self.get_data_bit_column_number(probe_address, probe_data)
def write_delay_measures(self):
"""
Write the measure statements to quantify the bitline voltage at sense amp enable 50%.
"""
self.sf.write("\n* Measure statements for delay and power\n")
# Output some comments to aid where cycles start and
for comment in self.cycle_comments:
self.sf.write("* {}\n".format(comment))
for read_port in self.targ_read_ports:
self.write_bitline_voltage_measures(read_port)
self.write_bitline_delay_measures(read_port)
def write_bitline_voltage_measures(self, port):
"""
Add measurments to capture the bitline voltages at 50% Sense amp enable
"""
debug.info(2, "Measuring bitline column={}, port={}".format(self.bitline_column,port))
if len(self.all_ports) == 1: #special naming case for single port sram bitlines
bitline_port = ""
else:
bitline_port = str(port)
sen_port_name = "{}{}".format(self.sen_name,port)
for (measure_name, bl_signal_name) in zip(self.bl_volt_meas_names, self.bl_signal_names):
bl_port_name = "{}{}_{}".format(bl_signal_name, bitline_port, self.bitline_column)
measure_port_name = "{}{}".format(measure_name,port)
self.stim.gen_meas_find_voltage(measure_port_name, sen_port_name, bl_port_name, .5, "RISE", self.cycle_times[self.measure_cycles[port]["read0"]])
def write_bitline_delay_measures(self, port):
"""
Write the measure statements to quantify the delay and power results for a read port.
"""
# add measure statements for delays/slews
for (measure_name, bl_signal_name) in zip(self.bl_delay_meas_names, self.bl_signal_names):
meas_values = self.get_delay_meas_values(measure_name, bl_signal_name, port)
self.stim.gen_meas_delay(*meas_values)
def get_delay_meas_values(self, delay_name, bitline_name, port):
"""Get the values needed to generate a Spice measurement statement based on the name of the measurement."""
if len(self.all_ports) == 1: #special naming case for single port sram bitlines
bitline_port = ""
else:
bitline_port = str(port)
meas_name="{0}{1}".format(delay_name, port)
targ_name = "{0}{1}_{2}".format(bitline_name,bitline_port,self.bitline_column)
half_vdd = 0.5 * self.vdd_voltage
trig_val = half_vdd
targ_val = self.vdd_voltage-tech.spice["v_threshold_typical"]
trig_name = "clk{0}".format(port)
trig_dir="FALL"
targ_dir="FALL"
#Half period added to delay measurement to negative clock edge
trig_td = targ_td = self.cycle_times[self.measure_cycles[port]["read0"]] + self.period/2
return (meas_name,trig_name,targ_name,trig_val,targ_val,trig_dir,targ_dir,trig_td,targ_td)
def gen_test_cycles_one_port(self, read_port, write_port):
"""Sets a list of key time-points [ns] of the waveform (each rising edge)
of the cycles to do a timing evaluation of a single port """
# Create the inverse address for a scratch address
inverse_address = self.calculate_inverse_address()
# For now, ignore data patterns and write ones or zeros
data_ones = "1"*self.word_size
data_zeros = "0"*self.word_size
if self.t_current == 0:
self.add_noop_all_ports("Idle cycle (no positive clock edge)",
inverse_address, data_zeros)
self.add_write("W data 1 address {}".format(inverse_address),
inverse_address,data_ones,write_port)
self.add_write("W data 0 address {} to write value".format(self.probe_address),
self.probe_address,data_zeros,write_port)
self.measure_cycles[write_port]["write0"] = len(self.cycle_times)-1
# This also ensures we will have a H->L transition on the next read
self.add_read("R data 1 address {} to set DOUT caps".format(inverse_address),
inverse_address,data_zeros,read_port)
self.measure_cycles[read_port]["read1"] = len(self.cycle_times)-1
self.add_read("R data 0 address {} to check W0 worked".format(self.probe_address),
self.probe_address,data_zeros,read_port)
self.measure_cycles[read_port]["read0"] = len(self.cycle_times)-1
def get_data_bit_column_number(self, probe_address, probe_data):
"""Calculates bitline column number of data bit under test using bit position and mux size"""
if self.sram.col_addr_size>0:
col_address = int(probe_address[0:self.sram.col_addr_size],2)
else:
col_address = 0
bl_column = int(self.sram.words_per_row*probe_data + col_address)
return bl_column
def run_delay_simulation(self):
"""
This tries to simulate a period and checks if the result works. If
so, it returns True and the delays, slews, and powers. It
works on the trimmed netlist by default, so powers do not
include leakage of all cells.
"""
#Sanity Check
debug.check(self.period > 0, "Target simulation period non-positive")
result = [{} for i in self.all_ports]
# Checking from not data_value to data_value
self.write_delay_stimulus()
self.stim.run_sim() #running sim prodoces spice output file.
for port in self.targ_read_ports:
#Parse and check the voltage measurements
bl_volt_meas_dict = {}
for mname in self.bl_volt_meas_names:
mname_port = "{}{}".format(mname,port)
volt_meas_val = parse_spice_list("timing", mname_port)
if type(volt_meas_val)!=float:
debug.error("Failed to Parse Bitline Voltage:\n\t\t{0}={1}".format(mname,volt_meas_val),1)
bl_volt_meas_dict[mname] = volt_meas_val
result[port].update(bl_volt_meas_dict)
#Parse and check the delay measurements. Intended that one measurement will fail, save the delay that did not fail.
bl_delay_meas_dict = {}
values_added = 0 #For error checking
for mname in self.bl_delay_meas_names: #Parse
mname_port = "{}{}".format(mname,port)
delay_meas_val = parse_spice_list("timing", mname_port)
if type(delay_meas_val)==float: #Only add if value is float, do not error.
bl_delay_meas_dict[self.bl_delay_result_name] = delay_meas_val * 1e9 #convert to ns
values_added+=1
debug.check(values_added>0, "Bitline delay measurements failed in SPICE simulation.")
debug.check(values_added<2, "Both bitlines experienced a Vth drop, check simulation results.")
result[port].update(bl_delay_meas_dict)
# The delay is from the negative edge for our SRAM
return (True,result)
def check_bitline_all_results(self, results):
"""Checks the bitline values measured for each tested port"""
for port in self.targ_read_ports:
self.check_bitline_port_results(results[port])
def check_bitline_port_results(self, port_results):
"""Performs three different checks for the bitline values: functionality, bitline swing from vdd, and differential bit swing"""
bl_volt, br_volt = port_results["volt_bl"], port_results["volt_br"]
self.check_functionality(bl_volt,br_volt)
self.check_swing_from_vdd(bl_volt,br_volt)
self.check_differential_swing(bl_volt,br_volt)
def check_functionality(self, bl_volt, br_volt):
"""Checks whether the read failed or not. Measured values are hardcoded with the intention of reading a 0."""
if bl_volt > br_volt:
debug.error("Read failure. Value 1 was read instead of 0.",1)
def check_swing_from_vdd(self, bl_volt, br_volt):
"""Checks difference on discharging bitline from VDD to see if it is within margin of the RBL height parameter."""
if bl_volt < br_volt:
discharge_volt = bl_volt
else:
discharge_volt = br_volt
desired_bl_volt = tech.parameter["rbl_height_percentage"]*self.vdd_voltage
debug.info(1, "Active bitline={:.3f}v, Desired bitline={:.3f}v".format(discharge_volt,desired_bl_volt))
vdd_error_margin = .2 #20% of vdd margin for bitline, a little high for now.
if abs(discharge_volt - desired_bl_volt) > vdd_error_margin*self.vdd_voltage:
debug.warning("Bitline voltage is not within {}% Vdd margin. Delay chain/RBL could need resizing.".format(vdd_error_margin*100))
def check_differential_swing(self, bl_volt, br_volt):
"""This check looks at the difference between the bitline voltages. This needs to be large enough to prevent
sensing errors."""
bitline_swing = abs(bl_volt-br_volt)
debug.info(1,"Bitline swing={:.3f}v".format(bitline_swing))
vdd_error_margin = .2 #20% of vdd margin for bitline, a little high for now.
if bitline_swing < vdd_error_margin*self.vdd_voltage:
debug.warning("Bitline swing less than {}% Vdd margin. Sensing errors more likely to occur.".format(vdd_error_margin))
def analyze(self, probe_address, probe_data, slews, loads):
"""Measures the bitline swing of the differential bitlines (bl/br) at 50% s_en """
self.set_probe(probe_address, probe_data)
self.load=max(loads)
self.slew=max(slews)
read_port = self.read_ports[0] #only test the first read port
bitline_swings = {}
self.targ_read_ports = [read_port]
self.targ_write_ports = [self.write_ports[0]]
debug.info(1,"Bitline swing test: corner {}".format(self.corner))
(success, results)=self.run_delay_simulation()
debug.check(success, "Bitline Failed: period {}".format(self.period))
debug.info(1,"Bitline values (voltages/delays):\n\t {}".format(results[read_port]))
self.check_bitline_all_results(results)
return results

View File

@ -148,9 +148,9 @@ class lib:
self.lib.write(" area : {};\n\n".format(self.sram.width * self.sram.height)) self.lib.write(" area : {};\n\n".format(self.sram.width * self.sram.height))
#Build string of all control signals. #Build string of all control signals.
control_str = 'CSb0' #assume at least 1 port control_str = 'csb0' #assume at least 1 port
for i in range(1, self.total_port_num): for i in range(1, self.total_port_num):
control_str += ' & CSb{0}'.format(i) control_str += ' & csb{0}'.format(i)
# Leakage is included in dynamic when macro is enabled # Leakage is included in dynamic when macro is enabled
self.lib.write(" leakage_power () {\n") self.lib.write(" leakage_power () {\n")
@ -161,13 +161,17 @@ class lib:
def write_units(self): def write_units(self):
""" Adds default units for time, voltage, current,...""" """ Adds default units for time, voltage, current,...
Valid values are 1mV, 10mV, 100mV, and 1V.
For time: Valid values are 1ps, 10ps, 100ps, and 1ns.
For power: Valid values are 1mW, 100uW (for 100mW), 10uW (for 10mW),
1uW (for 1mW), 100nW, 10nW, 1nW, 100pW, 10pW, and 1pW.
"""
self.lib.write(" time_unit : \"1ns\" ;\n") self.lib.write(" time_unit : \"1ns\" ;\n")
self.lib.write(" voltage_unit : \"1v\" ;\n") self.lib.write(" voltage_unit : \"1V\" ;\n")
self.lib.write(" current_unit : \"1mA\" ;\n") self.lib.write(" current_unit : \"1mA\" ;\n")
self.lib.write(" resistance_unit : \"1kohm\" ;\n") self.lib.write(" resistance_unit : \"1kohm\" ;\n")
self.lib.write(" capacitive_load_unit(1 ,fF) ;\n") self.lib.write(" capacitive_load_unit(1, pF) ;\n")
self.lib.write(" leakage_power_unit : \"1mW\" ;\n") self.lib.write(" leakage_power_unit : \"1mW\" ;\n")
self.lib.write(" pulling_resistance_unit :\"1kohm\" ;\n") self.lib.write(" pulling_resistance_unit :\"1kohm\" ;\n")
self.lib.write(" operating_conditions(OC){\n") self.lib.write(" operating_conditions(OC){\n")
@ -239,7 +243,9 @@ class lib:
self.lib.write(" variable_1 : input_net_transition;\n") self.lib.write(" variable_1 : input_net_transition;\n")
self.lib.write(" variable_2 : total_output_net_capacitance;\n") self.lib.write(" variable_2 : total_output_net_capacitance;\n")
self.write_index(1,self.slews) self.write_index(1,self.slews)
self.write_index(2,self.loads) # Dividing by 1000 to all cap values since output of .sp is in fF,
# and it needs to be in pF for Innovus.
self.write_index(2,self.loads/1000)
self.lib.write(" }\n\n") self.lib.write(" }\n\n")
CONS = ["CONSTRAINT_TABLE"] CONS = ["CONSTRAINT_TABLE"]
@ -327,8 +333,8 @@ class lib:
self.lib.write(" bus_type : DATA; \n") self.lib.write(" bus_type : DATA; \n")
self.lib.write(" direction : output; \n") self.lib.write(" direction : output; \n")
# This is conservative, but limit to range that we characterized. # This is conservative, but limit to range that we characterized.
self.lib.write(" max_capacitance : {0}; \n".format(max(self.loads))) self.lib.write(" max_capacitance : {0}; \n".format(max(self.loads)/1000))
self.lib.write(" min_capacitance : {0}; \n".format(min(self.loads))) self.lib.write(" min_capacitance : {0}; \n".format(min(self.loads)/1000))
self.lib.write(" memory_read(){ \n") self.lib.write(" memory_read(){ \n")
self.lib.write(" address : ADDR{0}; \n".format(read_port)) self.lib.write(" address : ADDR{0}; \n".format(read_port))
self.lib.write(" }\n") self.lib.write(" }\n")
@ -362,7 +368,7 @@ class lib:
self.lib.write(" bus_type : DATA; \n") self.lib.write(" bus_type : DATA; \n")
self.lib.write(" direction : input; \n") self.lib.write(" direction : input; \n")
# This is conservative, but limit to range that we characterized. # This is conservative, but limit to range that we characterized.
self.lib.write(" capacitance : {0}; \n".format(tech.spice["dff_in_cap"])) self.lib.write(" capacitance : {0}; \n".format(tech.spice["dff_in_cap"]/1000))
self.lib.write(" memory_write(){ \n") self.lib.write(" memory_write(){ \n")
self.lib.write(" address : ADDR{0}; \n".format(write_port)) self.lib.write(" address : ADDR{0}; \n".format(write_port))
self.lib.write(" clocked_on : clk{0}; \n".format(write_port)) self.lib.write(" clocked_on : clk{0}; \n".format(write_port))
@ -385,7 +391,7 @@ class lib:
self.lib.write(" bus(ADDR{0}){{\n".format(port)) self.lib.write(" bus(ADDR{0}){{\n".format(port))
self.lib.write(" bus_type : ADDR; \n") self.lib.write(" bus_type : ADDR; \n")
self.lib.write(" direction : input; \n") self.lib.write(" direction : input; \n")
self.lib.write(" capacitance : {0}; \n".format(tech.spice["dff_in_cap"])) self.lib.write(" capacitance : {0}; \n".format(tech.spice["dff_in_cap"]/1000))
self.lib.write(" max_transition : {0};\n".format(self.slews[-1])) self.lib.write(" max_transition : {0};\n".format(self.slews[-1]))
self.lib.write(" pin(ADDR{0}[{1}:0])".format(port,self.sram.addr_size-1)) self.lib.write(" pin(ADDR{0}[{1}:0])".format(port,self.sram.addr_size-1))
self.lib.write("{\n") self.lib.write("{\n")
@ -398,15 +404,15 @@ class lib:
def write_control_pins(self, port): def write_control_pins(self, port):
""" Adds control pins timing results.""" """ Adds control pins timing results."""
#The control pins are still to be determined. This is a placeholder for what could be. #The control pins are still to be determined. This is a placeholder for what could be.
ctrl_pin_names = ["CSb{0}".format(port)] ctrl_pin_names = ["csb{0}".format(port)]
if port in self.readwrite_ports: if port in self.readwrite_ports:
ctrl_pin_names.append("WEb{0}".format(port)) ctrl_pin_names.append("web{0}".format(port))
for i in ctrl_pin_names: for i in ctrl_pin_names:
self.lib.write(" pin({0})".format(i)) self.lib.write(" pin({0})".format(i))
self.lib.write("{\n") self.lib.write("{\n")
self.lib.write(" direction : input; \n") self.lib.write(" direction : input; \n")
self.lib.write(" capacitance : {0}; \n".format(tech.spice["dff_in_cap"])) self.lib.write(" capacitance : {0}; \n".format(tech.spice["dff_in_cap"]/1000))
self.write_FF_setuphold(port) self.write_FF_setuphold(port)
self.lib.write(" }\n\n") self.lib.write(" }\n\n")
@ -417,7 +423,7 @@ class lib:
self.lib.write(" clock : true;\n") self.lib.write(" clock : true;\n")
self.lib.write(" direction : input; \n") self.lib.write(" direction : input; \n")
# FIXME: This depends on the clock buffer size in the control logic # FIXME: This depends on the clock buffer size in the control logic
self.lib.write(" capacitance : {0}; \n".format(tech.spice["dff_in_cap"])) self.lib.write(" capacitance : {0}; \n".format(tech.spice["dff_in_cap"]/1000))
self.add_clk_control_power(port) self.add_clk_control_power(port)
@ -452,10 +458,10 @@ class lib:
if port in self.write_ports: if port in self.write_ports:
if port in self.read_ports: if port in self.read_ports:
web_name = " & !WEb{0}".format(port) web_name = " & !web{0}".format(port)
avg_write_power = np.mean(self.char_port_results[port]["write1_power"] + self.char_port_results[port]["write0_power"]) avg_write_power = np.mean(self.char_port_results[port]["write1_power"] + self.char_port_results[port]["write0_power"])
self.lib.write(" internal_power(){\n") self.lib.write(" internal_power(){\n")
self.lib.write(" when : \"!CSb{0} & clk{0}{1}\"; \n".format(port, web_name)) self.lib.write(" when : \"!csb{0} & clk{0}{1}\"; \n".format(port, web_name))
self.lib.write(" rise_power(scalar){\n") self.lib.write(" rise_power(scalar){\n")
self.lib.write(" values(\"{0}\");\n".format(avg_write_power/2.0)) self.lib.write(" values(\"{0}\");\n".format(avg_write_power/2.0))
self.lib.write(" }\n") self.lib.write(" }\n")
@ -466,10 +472,10 @@ class lib:
if port in self.read_ports: if port in self.read_ports:
if port in self.write_ports: if port in self.write_ports:
web_name = " & WEb{0}".format(port) web_name = " & web{0}".format(port)
avg_read_power = np.mean(self.char_port_results[port]["read1_power"] + self.char_port_results[port]["read0_power"]) avg_read_power = np.mean(self.char_port_results[port]["read1_power"] + self.char_port_results[port]["read0_power"])
self.lib.write(" internal_power(){\n") self.lib.write(" internal_power(){\n")
self.lib.write(" when : \"!CSb{0} & !clk{0}{1}\"; \n".format(port, web_name)) self.lib.write(" when : \"!csb{0} & !clk{0}{1}\"; \n".format(port, web_name))
self.lib.write(" rise_power(scalar){\n") self.lib.write(" rise_power(scalar){\n")
self.lib.write(" values(\"{0}\");\n".format(avg_read_power/2.0)) self.lib.write(" values(\"{0}\");\n".format(avg_read_power/2.0))
self.lib.write(" }\n") self.lib.write(" }\n")
@ -480,7 +486,7 @@ class lib:
# Have 0 internal power when disabled, this will be represented as leakage power. # Have 0 internal power when disabled, this will be represented as leakage power.
self.lib.write(" internal_power(){\n") self.lib.write(" internal_power(){\n")
self.lib.write(" when : \"CSb{0}\"; \n".format(port)) self.lib.write(" when : \"csb{0}\"; \n".format(port))
self.lib.write(" rise_power(scalar){\n") self.lib.write(" rise_power(scalar){\n")
self.lib.write(" values(\"0\");\n") self.lib.write(" values(\"0\");\n")
self.lib.write(" }\n") self.lib.write(" }\n")
@ -610,9 +616,9 @@ class lib:
)) ))
for port in self.all_ports: for port in self.all_ports:
#CSb timings #csb timings
datasheet.write("{0},{1},{2},{3},{4},{5},{6},{7},{8},".format( datasheet.write("{0},{1},{2},{3},{4},{5},{6},{7},{8},".format(
"CSb{0}".format(port), "csb{0}".format(port),
min(list(map(round_time,self.times["setup_times_LH"]))), min(list(map(round_time,self.times["setup_times_LH"]))),
max(list(map(round_time,self.times["setup_times_LH"]))), max(list(map(round_time,self.times["setup_times_LH"]))),
@ -649,9 +655,9 @@ class lib:
for port in self.all_ports: for port in self.all_ports:
if port in self.readwrite_ports: if port in self.readwrite_ports:
#WEb timings #web timings
datasheet.write("{0},{1},{2},{3},{4},{5},{6},{7},{8},".format( datasheet.write("{0},{1},{2},{3},{4},{5},{6},{7},{8},".format(
"WEb{0}".format(port), "web{0}".format(port),
min(list(map(round_time,self.times["setup_times_LH"]))), min(list(map(round_time,self.times["setup_times_LH"]))),
max(list(map(round_time,self.times["setup_times_LH"]))), max(list(map(round_time,self.times["setup_times_LH"]))),
@ -673,8 +679,8 @@ class lib:
# write dynamic power usage # write dynamic power usage
if port in self.read_ports: if port in self.read_ports:
web_name = " & !WEb{0}".format(port) web_name = " & !web{0}".format(port)
name = "!CSb{0} & clk{0}{1}".format(port, web_name) name = "!csb{0} & clk{0}{1}".format(port, web_name)
read_write = 'Read' read_write = 'Read'
datasheet.write("{0},{1},{2},{3},".format( datasheet.write("{0},{1},{2},{3},".format(
@ -686,8 +692,8 @@ class lib:
)) ))
if port in self.write_ports: if port in self.write_ports:
web_name = " & WEb{0}".format(port) web_name = " & web{0}".format(port)
name = "!CSb{0} & !clk{0}{1}".format(port, web_name) name = "!csb{0} & !clk{0}{1}".format(port, web_name)
read_write = 'Write' read_write = 'Write'
datasheet.write("{0},{1},{2},{3},".format( datasheet.write("{0},{1},{2},{3},".format(
@ -699,9 +705,9 @@ class lib:
)) ))
# write leakage power # write leakage power
control_str = 'CSb0' control_str = 'csb0'
for i in range(1, self.total_port_num): for i in range(1, self.total_port_num):
control_str += ' & CSb{0}'.format(i) control_str += ' & csb{0}'.format(i)
datasheet.write("{0},{1},{2},".format('leak', control_str, self.char_sram_results["leakage_power"])) datasheet.write("{0},{1},{2},".format('leak', control_str, self.char_sram_results["leakage_power"]))

View File

@ -45,3 +45,4 @@ class design_rules():

View File

@ -2,6 +2,7 @@ from .gdsPrimitives import *
from datetime import * from datetime import *
#from mpmath import matrix #from mpmath import matrix
#from numpy import matrix #from numpy import matrix
from vector import vector
import numpy as np import numpy as np
#import gdsPrimitives #import gdsPrimitives
import debug import debug
@ -726,11 +727,25 @@ class VlsiLayout:
self.pins[label_text].append(pin_shapes) 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): def getAllShapes(self,layer):
""" """
Return all gshapes on a given layer in [llx, lly, urx, ury] format and Return all shapes on a given layer in [llx, lly, urx, ury] format and user units for rectangles
user units. and [coordinate 1, coordinate 2,...] format and user units for polygons.
""" """
boundaries = set() boundaries = set()
for TreeUnit in self.xyTree: for TreeUnit in self.xyTree:
@ -740,29 +755,42 @@ class VlsiLayout:
# Convert to user units # Convert to user units
user_boundaries = [] user_boundaries = []
for boundary in boundaries: for boundary in boundaries:
user_boundaries.append([boundary[0]*self.units[0],boundary[1]*self.units[0], boundaries_list = []
boundary[2]*self.units[0],boundary[3]*self.units[0]]) for i in range(0,len(boundary)):
boundaries_list.append(boundary[i]*self.units[0])
user_boundaries.append(boundaries_list)
return user_boundaries return user_boundaries
def getShapesInStructure(self,layer,structure): def getShapesInStructure(self,layer,structure):
""" """
Go through all the shapes in a structure and return the list of shapes in 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 (structureName,structureOrigin,structureuVector,structurevVector)=structure
#print(structureName,"u",structureuVector.transpose(),"v",structurevVector.transpose(),"o",structureOrigin.transpose()) #print(structureName,"u",structureuVector.transpose(),"v",structurevVector.transpose(),"o",structureOrigin.transpose())
boundaries = [] boundaries = []
for boundary in self.structures[str(structureName)].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: if layer==boundary.drawingLayer:
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] left_bottom=boundary.coordinates[0]
right_top=boundary.coordinates[2] right_top=boundary.coordinates[2]
# Rectangle is [leftx, bottomy, rightx, topy]. # Rectangle is [leftx, bottomy, rightx, topy].
@ -773,9 +801,21 @@ class VlsiLayout:
boundaryRect=(boundaryRect[0]+structureOrigin[0].item(),boundaryRect[1]+structureOrigin[1].item(), boundaryRect=(boundaryRect[0]+structureOrigin[0].item(),boundaryRect[1]+structureOrigin[1].item(),
boundaryRect[2]+structureOrigin[0].item(),boundaryRect[3]+structureOrigin[1].item()) boundaryRect[2]+structureOrigin[0].item(),boundaryRect[3]+structureOrigin[1].item())
boundaries.append(boundaryRect) boundaries.append(boundaryRect)
return boundaries 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): def transformRectangle(self,originalRectangle,uVector,vVector):
""" """
Transforms the four coordinates of a rectangle in space Transforms the four coordinates of a rectangle in space
@ -799,7 +839,7 @@ class VlsiLayout:
""" """
Rotate a coordinate in space. Rotate a coordinate in space.
""" """
# MRG: 9/3/18 Incorrect matrixi multiplication! # MRG: 9/3/18 Incorrect matrix multiplication!
# This is fixed to be: # This is fixed to be:
# |u[0] v[0]| |x| |x'| # |u[0] v[0]| |x| |x'|
# |u[1] v[1]|x|y|=|y'| # |u[1] v[1]|x|y|=|y'|

View File

@ -47,6 +47,7 @@ class bank(design.design):
if not OPTS.netlist_only: if not OPTS.netlist_only:
debug.check(len(self.all_ports)<=2,"Bank layout cannot handle more than two ports.") debug.check(len(self.all_ports)<=2,"Bank layout cannot handle more than two ports.")
self.create_layout() self.create_layout()
self.add_boundary()
def create_netlist(self): def create_netlist(self):

View File

@ -42,6 +42,7 @@ class bank_select(design.design):
self.place_instances() self.place_instances()
self.route_instances() self.route_instances()
self.add_boundary()
self.DRC_LVS() self.DRC_LVS()

View File

@ -69,6 +69,8 @@ class bitcell_array(design.design):
self.add_layout_pins() self.add_layout_pins()
self.add_boundary()
self.DRC_LVS() self.DRC_LVS()
def add_pins(self): def add_pins(self):

View File

@ -67,6 +67,7 @@ class control_logic(design.design):
self.place_instances() self.place_instances()
self.route_all() self.route_all()
#self.add_lvs_correspondence_points() #self.add_lvs_correspondence_points()
self.add_boundary()
self.DRC_LVS() self.DRC_LVS()

View File

@ -52,6 +52,7 @@ class delay_chain(design.design):
self.place_inverters() self.place_inverters()
self.route_inverters() self.route_inverters()
self.add_layout_pins() self.add_layout_pins()
self.add_boundary()
self.DRC_LVS() self.DRC_LVS()
def add_pins(self): def add_pins(self):

View File

@ -44,6 +44,7 @@ class dff_array(design.design):
self.place_dff_array() self.place_dff_array()
self.add_layout_pins() self.add_layout_pins()
self.add_boundary()
self.DRC_LVS() self.DRC_LVS()
def add_modules(self): def add_modules(self):

View File

@ -55,6 +55,7 @@ class dff_buf(design.design):
self.place_instances() self.place_instances()
self.route_wires() self.route_wires()
self.add_layout_pins() self.add_layout_pins()
self.add_boundary()
self.DRC_LVS() self.DRC_LVS()
def add_modules(self): def add_modules(self):

View File

@ -49,6 +49,7 @@ class dff_buf_array(design.design):
self.height = self.rows * self.dff.height self.height = self.rows * self.dff.height
self.place_dff_array() self.place_dff_array()
self.add_layout_pins() self.add_layout_pins()
self.add_boundary()
self.DRC_LVS() self.DRC_LVS()
def add_pins(self): def add_pins(self):

View File

@ -53,6 +53,7 @@ class dff_inv(design.design):
self.add_wires() self.add_wires()
self.add_layout_pins() self.add_layout_pins()
self.add_boundary()
self.DRC_LVS() self.DRC_LVS()
def add_pins(self): def add_pins(self):

View File

@ -49,6 +49,7 @@ class dff_inv_array(design.design):
self.place_dff_array() self.place_dff_array()
self.add_layout_pins() self.add_layout_pins()
self.add_boundary()
self.DRC_LVS() self.DRC_LVS()
def add_modules(self): def add_modules(self):

View File

@ -54,6 +54,7 @@ class hierarchical_decoder(design.design):
self.route_predecode_rails() self.route_predecode_rails()
self.route_vdd_gnd() self.route_vdd_gnd()
self.offset_all_coordinates() self.offset_all_coordinates()
self.add_boundary()
self.DRC_LVS() self.DRC_LVS()
def add_modules(self): def add_modules(self):

View File

@ -47,6 +47,7 @@ class hierarchical_predecode2x4(hierarchical_predecode):
self.place_output_inverters() self.place_output_inverters()
self.place_nand_array() self.place_nand_array()
self.route() self.route()
self.add_boundary()
self.DRC_LVS() self.DRC_LVS()
def get_nand_input_line_combination(self): def get_nand_input_line_combination(self):

View File

@ -52,6 +52,7 @@ class hierarchical_predecode3x8(hierarchical_predecode):
self.place_output_inverters() self.place_output_inverters()
self.place_nand_array() self.place_nand_array()
self.route() self.route()
self.add_boundary()
self.DRC_LVS() self.DRC_LVS()
def get_nand_input_line_combination(self): def get_nand_input_line_combination(self):

View File

@ -51,6 +51,7 @@ class precharge_array(design.design):
self.place_insts() self.place_insts()
self.add_layout_pins() self.add_layout_pins()
self.add_boundary()
self.DRC_LVS() self.DRC_LVS()
def add_modules(self): def add_modules(self):

View File

@ -51,6 +51,7 @@ class replica_bitline(design.design):
self.width = self.replica_column_inst.rx() - self.delay_chain_inst.lx() + self.m2_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.height = max(self.replica_column_inst.uy(), self.delay_chain_inst.uy()) + self.m3_pitch
self.add_boundary()
self.DRC_LVS() self.DRC_LVS()
def add_pins(self): def add_pins(self):

View File

@ -50,6 +50,7 @@ class sense_amp_array(design.design):
self.place_sense_amp_array() self.place_sense_amp_array()
self.add_layout_pins() self.add_layout_pins()
self.route_rails() self.route_rails()
self.add_boundary()
self.DRC_LVS() self.DRC_LVS()
def add_pins(self): def add_pins(self):

View File

@ -52,6 +52,7 @@ class single_level_column_mux_array(design.design):
self.add_layout_pins() self.add_layout_pins()
self.add_enclosure(self.mux_inst, "pwell") self.add_enclosure(self.mux_inst, "pwell")
self.add_boundary()
self.DRC_LVS() self.DRC_LVS()
def add_pins(self): def add_pins(self):

View File

@ -41,6 +41,7 @@ class tri_gate_array(design.design):
self.place_array() self.place_array()
self.add_layout_pins() self.add_layout_pins()
self.add_boundary()
self.DRC_LVS() self.DRC_LVS()
def add_modules(self): def add_modules(self):

View File

@ -44,6 +44,7 @@ class wordline_driver(design.design):
self.route_layout() self.route_layout()
self.route_vdd_gnd() self.route_vdd_gnd()
self.offset_all_coordinates() self.offset_all_coordinates()
self.add_boundary()
self.DRC_LVS() self.DRC_LVS()
def add_pins(self): def add_pins(self):

View File

@ -50,6 +50,7 @@ class write_driver_array(design.design):
self.place_write_array() self.place_write_array()
self.add_layout_pins() self.add_layout_pins()
self.add_boundary()
self.DRC_LVS() self.DRC_LVS()
def add_pins(self): def add_pins(self):

View File

@ -31,14 +31,15 @@ class pgate(design.design):
self.create_netlist() self.create_netlist()
if not OPTS.netlist_only: if not OPTS.netlist_only:
self.create_layout() self.create_layout()
self.add_boundary()
self.DRC_LVS() self.DRC_LVS()
def create_netlist(): def create_netlist(self):
""" Pure virtual function """ """ Pure virtual function """
debug.error("Must over-ride create_netlist.",-1) debug.error("Must over-ride create_netlist.",-1)
def create_layout(): def create_layout(self):
""" Pure virtual function """ """ Pure virtual function """
debug.error("Must over-ride create_layout.",-1) debug.error("Must over-ride create_layout.",-1)

View File

@ -50,7 +50,7 @@ class grid:
self.add_map(vector3d(x,y,1)) self.add_map(vector3d(x,y,1))
def set_blocked(self,n,value=True): def set_blocked(self,n,value=True):
if isinstance(n, (list,tuple,set,frozenset)): if not isinstance(n, vector3d):
for item in n: for item in n:
self.set_blocked(item,value) self.set_blocked(item,value)
else: else:
@ -58,7 +58,7 @@ class grid:
self.map[n].blocked=value self.map[n].blocked=value
def is_blocked(self,n): def is_blocked(self,n):
if isinstance(n, (list,tuple,set,frozenset)): if not isinstance(n, vector3d):
for item in n: for item in n:
if self.is_blocked(item): if self.is_blocked(item):
return True return True
@ -82,7 +82,7 @@ class grid:
self.map[k].blocked=False self.map[k].blocked=False
def set_source(self,n,value=True): def set_source(self,n,value=True):
if isinstance(n, (list,tuple,set,frozenset)): if not isinstance(n, vector3d):
for item in n: for item in n:
self.set_source(item,value) self.set_source(item,value)
else: else:
@ -91,7 +91,7 @@ class grid:
self.source.add(n) self.source.add(n)
def set_target(self,n,value=True): def set_target(self,n,value=True):
if isinstance(n, (list,tuple,set,frozenset)): if not isinstance(n, vector3d):
for item in n: for item in n:
self.set_target(item,value) self.set_target(item,value)
else: else:
@ -125,7 +125,7 @@ class grid:
""" """
Add a point to the map if it doesn't exist. Add a point to the map if it doesn't exist.
""" """
if isinstance(n, (list,tuple,set,frozenset)): if not isinstance(n, vector3d):
for item in n: for item in n:
self.add_map(item) self.add_map(item)
else: else:

View File

@ -36,16 +36,21 @@ class grid_cell:
def get_type(self): def get_type(self):
type_string = ""
if self.blocked: if self.blocked:
return "X" type_string += "X"
if self.source: if self.source:
return "S" type_string += "S"
if self.target: if self.target:
return "T" type_string += "T"
if self.path: if self.path:
return "P" type_string += "P"
if type_string != "":
return type_string
return None return None

View File

@ -668,7 +668,10 @@ class router(router_tech):
track. track.
""" """
# to scale coordinates to tracks # to scale coordinates to tracks
try:
x = track[0]*self.track_width - 0.5*self.track_width x = track[0]*self.track_width - 0.5*self.track_width
except TypeError:
print(track[0],type(track[0]),self.track_width,type(self.track_width))
y = track[1]*self.track_width - 0.5*self.track_width y = track[1]*self.track_width - 0.5*self.track_width
# offset lowest corner object to to (-track halo,-track halo) # offset lowest corner object to to (-track halo,-track halo)
ll = snap_to_grid(vector(x,y)) ll = snap_to_grid(vector(x,y))
@ -832,13 +835,22 @@ class router(router_tech):
This will mark only the pin tracks from the indexed pin component as a target. This will mark only the pin tracks from the indexed pin component as a target.
It also unsets it as a blockage. It also unsets it as a blockage.
""" """
debug.check(index<self.num_pin_grids(pin_name),"Pin component index too large.") debug.check(index<self.num_pin_components(pin_name),"Pin component index too large.")
pin_in_tracks = self.pin_groups[pin_name][index].grids pin_in_tracks = self.pin_groups[pin_name][index].grids
debug.info(2,"Set target: " + str(pin_name) + " " + str(pin_in_tracks)) debug.info(2,"Set target: " + str(pin_name) + " " + str(pin_in_tracks))
self.rg.add_target(pin_in_tracks) self.rg.add_target(pin_in_tracks)
def add_pin_component_target_except(self, pin_name, index):
"""
This will mark the grids for all *other* pin components as a target.
Marking as source or target also clears blockage status.
"""
for i in range(self.num_pin_components(pin_name)):
if i != index:
self.add_pin_component_target(pin_name, i)
def set_component_blockages(self, pin_name, value=True): def set_component_blockages(self, pin_name, value=True):
""" """
Block all of the pin components. Block all of the pin components.
@ -885,9 +897,14 @@ class router(router_tech):
# This assumes 1-track wide again # This assumes 1-track wide again
abs_path = [self.convert_point_to_units(x[0]) for x in path] abs_path = [self.convert_point_to_units(x[0]) for x in path]
# Otherwise, add the route which includes enclosures # Otherwise, add the route which includes enclosures
if len(self.layers)>1:
self.cell.add_route(layers=self.layers, self.cell.add_route(layers=self.layers,
coordinates=abs_path, coordinates=abs_path,
layer_widths=self.layer_widths) layer_widths=self.layer_widths)
else:
self.cell.add_path(layer=self.layers[0],
coordinates=abs_path,
width=self.layer_widths[0])
def add_single_enclosure(self, track): def add_single_enclosure(self, track):
""" """
@ -956,11 +973,18 @@ class router(router_tech):
""" """
This assumes the blockages, source, and target are all set up. This assumes the blockages, source, and target are all set up.
""" """
# Double check source and taget are not same node, if so, we are done!
for k,v in self.rg.map.items():
if v.source and v.target:
debug.error("Grid cell is source and target! {}".format(k))
return False
# returns the path in tracks # returns the path in tracks
(path,cost) = self.rg.route(detour_scale) (path,cost) = self.rg.route(detour_scale)
if path: if path:
debug.info(2,"Found path: cost={0} ".format(cost)) debug.info(1,"Found path: cost={0} ".format(cost))
debug.info(3,str(path)) debug.info(1,str(path))
self.paths.append(path) self.paths.append(path)
self.add_route(path) self.add_route(path)
@ -1002,6 +1026,7 @@ class router(router_tech):
Write out a GDS file with the routing grid and search information annotated on it. Write out a GDS file with the routing grid and search information annotated on it.
""" """
debug.info(0,"Writing annotated router gds file to {}".format(gds_name)) debug.info(0,"Writing annotated router gds file to {}".format(gds_name))
self.del_router_info()
self.add_router_info() self.add_router_info()
self.cell.gds_write(gds_name) self.cell.gds_write(gds_name)
@ -1053,6 +1078,15 @@ class router(router_tech):
offset=shape[0], offset=shape[0],
zoom=0.05) zoom=0.05)
def del_router_info(self):
"""
Erase all of the comments on the current level.
"""
debug.info(0,"Erasing router info")
layer_num = techlayer["text"]
self.cell.objs = [x for x in self.cell.objs if x.layerNumber != layer_num]
def add_router_info(self): def add_router_info(self):
""" """
Write the routing grid and router cost, blockage, pins on Write the routing grid and router cost, blockage, pins on

View File

@ -25,15 +25,24 @@ class router_tech:
self.layers = layers self.layers = layers
self.rail_track_width = rail_track_width self.rail_track_width = rail_track_width
if len(self.layers)==1:
self.horiz_layer_name = self.vert_layer_name = self.layers[0]
self.horiz_layer_number = self.vert_layer_number = layer[self.layers[0]]
(self.vert_layer_minwidth, self.vert_layer_spacing) = self.get_supply_layer_width_space(1)
(self.horiz_layer_minwidth, self.horiz_layer_spacing) = self.get_supply_layer_width_space(0)
self.horiz_track_width = self.horiz_layer_minwidth + self.horiz_layer_spacing
self.vert_track_width = self.vert_layer_minwidth + self.vert_layer_spacing
else:
(self.horiz_layer_name, self.via_layer_name, self.vert_layer_name) = self.layers (self.horiz_layer_name, self.via_layer_name, self.vert_layer_name) = self.layers
# This is the minimum routed track spacing
via_connect = contact(self.layers, (1, 1)) via_connect = contact(self.layers, (1, 1))
max_via_size = max(via_connect.width,via_connect.height) max_via_size = max(via_connect.width,via_connect.height)
self.horiz_layer_number = layer[self.horiz_layer_name] self.horiz_layer_number = layer[self.horiz_layer_name]
self.vert_layer_number = layer[self.vert_layer_name] self.vert_layer_number = layer[self.vert_layer_name]
if self.rail_track_width>1:
(self.vert_layer_minwidth, self.vert_layer_spacing) = self.get_supply_layer_width_space(1) (self.vert_layer_minwidth, self.vert_layer_spacing) = self.get_supply_layer_width_space(1)
(self.horiz_layer_minwidth, self.horiz_layer_spacing) = self.get_supply_layer_width_space(0) (self.horiz_layer_minwidth, self.horiz_layer_spacing) = self.get_supply_layer_width_space(0)
@ -44,13 +53,6 @@ class router_tech:
self.horiz_track_width = self.horiz_layer_minwidth + self.horiz_layer_spacing self.horiz_track_width = self.horiz_layer_minwidth + self.horiz_layer_spacing
self.vert_track_width = self.vert_layer_minwidth + self.vert_layer_spacing self.vert_track_width = self.vert_layer_minwidth + self.vert_layer_spacing
else:
(self.vert_layer_minwidth, self.vert_layer_spacing) = self.get_layer_width_space(1)
(self.horiz_layer_minwidth, self.horiz_layer_spacing) = self.get_layer_width_space(0)
self.horiz_track_width = max_via_size + self.horiz_layer_spacing
self.vert_track_width = max_via_size + self.vert_layer_spacing
# We'll keep horizontal and vertical tracks the same for simplicity. # We'll keep horizontal and vertical tracks the same for simplicity.
self.track_width = max(self.horiz_track_width,self.vert_track_width) self.track_width = max(self.horiz_track_width,self.vert_track_width)
debug.info(1,"Track width: {:.3f}".format(self.track_width)) debug.info(1,"Track width: {:.3f}".format(self.track_width))
@ -80,24 +82,6 @@ class router_tech:
else: else:
debug.error("Invalid zindex {}".format(zindex),-1) debug.error("Invalid zindex {}".format(zindex),-1)
def get_layer_width_space(self, zindex, width=0, length=0):
"""
Return the width and spacing of a given layer
and wire of a given width and length.
"""
if zindex==1:
layer_name = self.vert_layer_name
elif zindex==0:
layer_name = self.horiz_layer_name
else:
debug.error("Invalid zindex for track", -1)
min_width = drc("minwidth_{0}".format(layer_name), width, length)
min_spacing = drc(str(layer_name)+"_to_"+str(layer_name), width, length)
return (min_width,min_spacing)
def get_supply_layer_width_space(self, zindex): def get_supply_layer_width_space(self, zindex):
""" """
These are the width and spacing of a supply layer given a supply rail These are the width and spacing of a supply layer given a supply rail

View File

@ -20,7 +20,7 @@ from datetime import datetime
import grid import grid
import grid_utils import grid_utils
class supply_router(router): class supply_grid_router(router):
""" """
A router class to read an obstruction map from a gds and A router class to read an obstruction map from a gds and
routes a grid to connect the supply on the two layers. routes a grid to connect the supply on the two layers.

View File

@ -0,0 +1,193 @@
# 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 math
import debug
from globals import OPTS,print_time
from contact import contact
from pin_group import pin_group
from pin_layout import pin_layout
from vector3d import vector3d
from router import router
from direction import direction
from datetime import datetime
import grid
import grid_utils
class supply_tree_router(router):
"""
A router class to read an obstruction map from a gds and
routes a grid to connect the supply on the two layers.
"""
def __init__(self, layers, design, gds_filename=None):
"""
This will route on layers in design. It will get the blockages from
either the gds file name or the design itself (by saving to a gds file).
"""
# Power rail width in minimum wire widths
self.rail_track_width = 3
router.__init__(self, layers, design, gds_filename, self.rail_track_width)
def create_routing_grid(self):
"""
Create a sprase routing grid with A* expansion functions.
"""
size = self.ur - self.ll
debug.info(1,"Size: {0} x {1}".format(size.x,size.y))
import supply_grid
self.rg = supply_grid.supply_grid(self.ll, self.ur, self.track_width)
def route(self, vdd_name="vdd", gnd_name="gnd"):
"""
Route the two nets in a single layer)
"""
debug.info(1,"Running supply router on {0} and {1}...".format(vdd_name, gnd_name))
self.vdd_name = vdd_name
self.gnd_name = gnd_name
# Clear the pins if we have previously routed
if (hasattr(self,'rg')):
self.clear_pins()
else:
# Creat a routing grid over the entire area
# FIXME: This could be created only over the routing region,
# but this is simplest for now.
self.create_routing_grid()
# Get the pin shapes
start_time = datetime.now()
self.find_pins_and_blockages([self.vdd_name, self.gnd_name])
print_time("Finding pins and blockages",datetime.now(), start_time, 3)
# Add the supply rails in a mesh network and connect H/V with vias
start_time = datetime.now()
# Block everything
self.prepare_blockages(self.gnd_name)
self.prepare_blockages(self.vdd_name)
# Route the supply pins to the supply rails
# Route vdd first since we want it to be shorter
start_time = datetime.now()
self.route_pins(vdd_name)
self.route_pins(gnd_name)
print_time("Maze routing supplies",datetime.now(), start_time, 3)
#self.write_debug_gds("final.gds",False)
# Did we route everything??
if not self.check_all_routed(vdd_name):
return False
if not self.check_all_routed(gnd_name):
return False
return True
def check_all_routed(self, pin_name):
"""
Check that all pin groups are routed.
"""
for pg in self.pin_groups[pin_name]:
if not pg.is_routed():
return False
def prepare_blockages(self, pin_name):
"""
Reset and add all of the blockages in the design.
Names is a list of pins to add as a blockage.
"""
debug.info(3,"Preparing blockages.")
# Start fresh. Not the best for run-time, but simpler.
self.clear_blockages()
# This adds the initial blockges of the design
#print("BLOCKING:",self.blocked_grids)
self.set_blockages(self.blocked_grids,True)
# Block all of the pin components (some will be unblocked if they're a source/target)
# Also block the previous routes
for name in self.pin_groups:
blockage_grids = {y for x in self.pin_groups[name] for y in x.grids}
self.set_blockages(blockage_grids,True)
blockage_grids = {y for x in self.pin_groups[name] for y in x.blockages}
self.set_blockages(blockage_grids,True)
# FIXME: These duplicate a bit of work
# These are the paths that have already been routed.
self.set_blockages(self.path_blockages)
# Don't mark the other components as targets since we want to route
# directly to a rail, but unblock all the source components so we can
# route over them
blockage_grids = {y for x in self.pin_groups[pin_name] for y in x.grids}
self.set_blockages(blockage_grids,False)
def route_pins(self, pin_name):
"""
This will route each of the remaining pin components to the other pins.
After it is done, the cells are added to the pin blockage list.
"""
remaining_components = sum(not x.is_routed() for x in self.pin_groups[pin_name])
debug.info(1,"Maze routing {0} with {1} pin components to connect.".format(pin_name,
remaining_components))
for index,pg in enumerate(self.pin_groups[pin_name]):
if pg.is_routed():
continue
debug.info(1,"Routing component {0} {1}".format(pin_name, index))
# Clear everything in the routing grid.
self.rg.reinit()
# This is inefficient since it is non-incremental, but it was
# easier to debug.
self.prepare_blockages(pin_name)
# Add the single component of the pin as the source
# which unmarks it as a blockage too
self.add_pin_component_source(pin_name,index)
# Marks all pin components except index as target
self.add_pin_component_target_except(pin_name,index)
# Add the prevous paths as a target too
self.add_path_target(self.paths)
print("SOURCE: ")
for k,v in self.rg.map.items():
if v.source:
print(k)
print("TARGET: ")
for k,v in self.rg.map.items():
if v.target:
print(k)
import pdb; pdb.set_trace()
if index==1:
self.write_debug_gds("debug{}.gds".format(pin_name),False)
# Actually run the A* router
if not self.run_router(detour_scale=5):
self.write_debug_gds("debug_route.gds",True)
#if index==3 and pin_name=="vdd":
# self.write_debug_gds("route.gds",False)

View File

@ -129,22 +129,30 @@ class sram_base(design, verilog, lef):
def route_supplies(self): def route_supplies(self):
""" Route the supply grid and connect the pins to them. """ """ Route the supply grid and connect the pins to them. """
# Do not route the power supply # Copy the pins to the top level
if not OPTS.route_supplies: # This will either be used to route or left unconnected.
return
for inst in self.insts: for inst in self.insts:
self.copy_power_pins(inst,"vdd") self.copy_power_pins(inst,"vdd")
self.copy_power_pins(inst,"gnd") self.copy_power_pins(inst,"gnd")
from supply_router import supply_router as router import tech
layer_stack =("metal3","via3","metal4") if not OPTS.route_supplies:
rtr=router(layer_stack, self) # Do not route the power supply (leave as must-connect pins)
return
elif "metal4" in tech.layer:
# Route a M3/M4 grid
from supply_grid_router import supply_grid_router as router
rtr=router(("metal3","via3","metal4"), self)
elif "metal3" in tech.layer:
from supply_tree_router import supply_tree_router as router
rtr=router(("metal3",), self)
rtr.route() rtr.route()
def compute_bus_sizes(self): def compute_bus_sizes(self):
""" Compute the independent bus widths shared between two and four bank SRAMs """ """ Compute the independent bus widths shared between two and four bank SRAMs """

View File

@ -7,8 +7,6 @@
# #
import debug import debug
from globals import OPTS from globals import OPTS
from importlib import reload
class sram_factory: class sram_factory:
""" """
@ -52,7 +50,8 @@ class sram_factory:
try: try:
mod = self.modules[module_type] mod = self.modules[module_type]
except KeyError: except KeyError:
c = reload(__import__(module_type)) import importlib
c = importlib.reload(__import__(module_type))
mod = getattr(c, module_type) mod = getattr(c, module_type)
self.modules[module_type] = mod self.modules[module_type] = mod
self.module_indices[module_type] = 0 self.module_indices[module_type] = 0

View File

@ -8,9 +8,9 @@
# #
import unittest import unittest
from testutils import header,openram_test from testutils import *
import sys,os,re import sys,os,re
sys.path.append(os.path.join(sys.path[0],"..")) sys.path.append(os.getenv("OPENRAM_HOME"))
import globals import globals
import debug import debug
@ -51,7 +51,7 @@ def setup_files(path):
files = [] files = []
for (dir, _, current_files) in os.walk(path): for (dir, _, current_files) in os.walk(path):
for f in current_files: for f in current_files:
files.append(os.path.join(dir, f)) files.append(os.getenv("OPENRAM_HOME"))
nametest = re.compile("\.py$", re.IGNORECASE) nametest = re.compile("\.py$", re.IGNORECASE)
select_files = list(filter(nametest.search, files)) select_files = list(filter(nametest.search, files))
return select_files return select_files
@ -122,4 +122,4 @@ if __name__ == "__main__":
(OPTS, args) = globals.parse_args() (OPTS, args) = globals.parse_args()
del sys.argv[1:] del sys.argv[1:]
header(__file__, OPTS.tech_name) header(__file__, OPTS.tech_name)
unittest.main() unittest.main(testRunner=debugTestRunner())

View File

@ -9,9 +9,9 @@
"Run a regression test the library cells for DRC" "Run a regression test the library cells for DRC"
import unittest import unittest
from testutils import header,openram_test from testutils import *
import sys,os,re import sys,os,re
#sys.path.append(os.path.join(sys.path[0],"..")) #sys.path.append(os.getenv("OPENRAM_HOME"))
import globals import globals
from globals import OPTS from globals import OPTS
import debug import debug
@ -51,5 +51,5 @@ if __name__ == "__main__":
(OPTS, args) = globals.parse_args() (OPTS, args) = globals.parse_args()
del sys.argv[1:] del sys.argv[1:]
header(__file__, OPTS.tech_name) header(__file__, OPTS.tech_name)
unittest.main() unittest.main(testRunner=debugTestRunner())

View File

@ -9,9 +9,9 @@
"Run a regression test the library cells for LVS" "Run a regression test the library cells for LVS"
import unittest import unittest
from testutils import header,openram_test from testutils import *
import sys,os,re import sys,os,re
sys.path.append(os.path.join(sys.path[0],"..")) sys.path.append(os.getenv("OPENRAM_HOME"))
import globals import globals
from globals import OPTS from globals import OPTS
import debug import debug
@ -74,4 +74,4 @@ if __name__ == "__main__":
(OPTS, args) = globals.parse_args() (OPTS, args) = globals.parse_args()
del sys.argv[1:] del sys.argv[1:]
header(__file__, OPTS.tech_name) header(__file__, OPTS.tech_name)
unittest.main() unittest.main(testRunner=debugTestRunner())

View File

@ -9,9 +9,9 @@
"Run a regression test for DRC on basic contacts of different array sizes" "Run a regression test for DRC on basic contacts of different array sizes"
import unittest import unittest
from testutils import header,openram_test from testutils import *
import sys,os import sys,os
sys.path.append(os.path.join(sys.path[0],"..")) sys.path.append(os.getenv("OPENRAM_HOME"))
import globals import globals
from globals import OPTS from globals import OPTS
from sram_factory import factory from sram_factory import factory
@ -69,4 +69,4 @@ if __name__ == "__main__":
(OPTS, args) = globals.parse_args() (OPTS, args) = globals.parse_args()
del sys.argv[1:] del sys.argv[1:]
header(__file__, OPTS.tech_name) header(__file__, OPTS.tech_name)
unittest.main() unittest.main(testRunner=debugTestRunner())

View File

@ -9,9 +9,9 @@
"Run a regression test on a basic path" "Run a regression test on a basic path"
import unittest import unittest
from testutils import header,openram_test from testutils import *
import sys,os import sys,os
sys.path.append(os.path.join(sys.path[0],"..")) sys.path.append(os.getenv("OPENRAM_HOME"))
import globals import globals
from globals import OPTS from globals import OPTS
import debug import debug
@ -96,4 +96,4 @@ if __name__ == "__main__":
(OPTS, args) = globals.parse_args() (OPTS, args) = globals.parse_args()
del sys.argv[1:] del sys.argv[1:]
header(__file__, OPTS.tech_name) header(__file__, OPTS.tech_name)
unittest.main() unittest.main(testRunner=debugTestRunner())

View File

@ -9,9 +9,9 @@
"Run a regression test on a basic parameterized transistors" "Run a regression test on a basic parameterized transistors"
import unittest import unittest
from testutils import header,openram_test from testutils import *
import sys,os import sys,os
sys.path.append(os.path.join(sys.path[0],"..")) sys.path.append(os.getenv("OPENRAM_HOME"))
import globals import globals
from globals import OPTS from globals import OPTS
from sram_factory import factory from sram_factory import factory
@ -38,4 +38,4 @@ if __name__ == "__main__":
(OPTS, args) = globals.parse_args() (OPTS, args) = globals.parse_args()
del sys.argv[1:] del sys.argv[1:]
header(__file__, OPTS.tech_name) header(__file__, OPTS.tech_name)
unittest.main() unittest.main(testRunner=debugTestRunner())

View File

@ -9,9 +9,9 @@
"Run a regression test on a basic parameterized transistors" "Run a regression test on a basic parameterized transistors"
import unittest import unittest
from testutils import header,openram_test from testutils import *
import sys,os import sys,os
sys.path.append(os.path.join(sys.path[0],"..")) sys.path.append(os.getenv("OPENRAM_HOME"))
import globals import globals
from globals import OPTS from globals import OPTS
from sram_factory import factory from sram_factory import factory
@ -38,4 +38,4 @@ if __name__ == "__main__":
(OPTS, args) = globals.parse_args() (OPTS, args) = globals.parse_args()
del sys.argv[1:] del sys.argv[1:]
header(__file__, OPTS.tech_name) header(__file__, OPTS.tech_name)
unittest.main() unittest.main(testRunner=debugTestRunner())

View File

@ -9,9 +9,9 @@
"Run a regression test on a basic parameterized transistors" "Run a regression test on a basic parameterized transistors"
import unittest import unittest
from testutils import header,openram_test from testutils import *
import sys,os import sys,os
sys.path.append(os.path.join(sys.path[0],"..")) sys.path.append(os.getenv("OPENRAM_HOME"))
import globals import globals
from globals import OPTS from globals import OPTS
from sram_factory import factory from sram_factory import factory
@ -40,4 +40,4 @@ if __name__ == "__main__":
(OPTS, args) = globals.parse_args() (OPTS, args) = globals.parse_args()
del sys.argv[1:] del sys.argv[1:]
header(__file__, OPTS.tech_name) header(__file__, OPTS.tech_name)
unittest.main() unittest.main(testRunner=debugTestRunner())

View File

@ -9,9 +9,9 @@
"Run a regression test on a basic parameterized transistors" "Run a regression test on a basic parameterized transistors"
import unittest import unittest
from testutils import header,openram_test from testutils import *
import sys,os import sys,os
sys.path.append(os.path.join(sys.path[0],"..")) sys.path.append(os.getenv("OPENRAM_HOME"))
import globals import globals
from globals import OPTS from globals import OPTS
from sram_factory import factory from sram_factory import factory
@ -40,4 +40,4 @@ if __name__ == "__main__":
(OPTS, args) = globals.parse_args() (OPTS, args) = globals.parse_args()
del sys.argv[1:] del sys.argv[1:]
header(__file__, OPTS.tech_name) header(__file__, OPTS.tech_name)
unittest.main() unittest.main(testRunner=debugTestRunner())

View File

@ -9,9 +9,9 @@
"Run a regression test on a basic parameterized transistors" "Run a regression test on a basic parameterized transistors"
import unittest import unittest
from testutils import header,openram_test from testutils import *
import sys,os import sys,os
sys.path.append(os.path.join(sys.path[0],"..")) sys.path.append(os.getenv("OPENRAM_HOME"))
import globals import globals
from globals import OPTS from globals import OPTS
from sram_factory import factory from sram_factory import factory
@ -40,4 +40,4 @@ if __name__ == "__main__":
(OPTS, args) = globals.parse_args() (OPTS, args) = globals.parse_args()
del sys.argv[1:] del sys.argv[1:]
header(__file__, OPTS.tech_name) header(__file__, OPTS.tech_name)
unittest.main() unittest.main(testRunner=debugTestRunner())

View File

@ -9,9 +9,9 @@
"Run a regression test on a basic parameterized transistors" "Run a regression test on a basic parameterized transistors"
import unittest import unittest
from testutils import header,openram_test from testutils import *
import sys,os import sys,os
sys.path.append(os.path.join(sys.path[0],"..")) sys.path.append(os.getenv("OPENRAM_HOME"))
import globals import globals
from globals import OPTS from globals import OPTS
from sram_factory import factory from sram_factory import factory
@ -40,4 +40,4 @@ if __name__ == "__main__":
(OPTS, args) = globals.parse_args() (OPTS, args) = globals.parse_args()
del sys.argv[1:] del sys.argv[1:]
header(__file__, OPTS.tech_name) header(__file__, OPTS.tech_name)
unittest.main() unittest.main(testRunner=debugTestRunner())

View File

@ -9,9 +9,9 @@
"Run a regression test on a basic wire" "Run a regression test on a basic wire"
import unittest import unittest
from testutils import header,openram_test from testutils import *
import sys,os import sys,os
sys.path.append(os.path.join(sys.path[0],"..")) sys.path.append(os.getenv("OPENRAM_HOME"))
import globals import globals
from globals import OPTS from globals import OPTS
import debug import debug
@ -133,4 +133,4 @@ if __name__ == "__main__":
(OPTS, args) = globals.parse_args() (OPTS, args) = globals.parse_args()
del sys.argv[1:] del sys.argv[1:]
header(__file__, OPTS.tech_name) header(__file__, OPTS.tech_name)
unittest.main() unittest.main(testRunner=debugTestRunner())

View File

@ -11,9 +11,9 @@ Run a regression test on a pand2 cell
""" """
import unittest import unittest
from testutils import header,openram_test from testutils import *
import sys,os import sys,os
sys.path.append(os.path.join(sys.path[0],"..")) sys.path.append(os.getenv("OPENRAM_HOME"))
import globals import globals
from globals import OPTS from globals import OPTS
from sram_factory import factory from sram_factory import factory
@ -39,4 +39,4 @@ if __name__ == "__main__":
(OPTS, args) = globals.parse_args() (OPTS, args) = globals.parse_args()
del sys.argv[1:] del sys.argv[1:]
header(__file__, OPTS.tech_name) header(__file__, OPTS.tech_name)
unittest.main() unittest.main(testRunner=debugTestRunner())

View File

@ -11,9 +11,9 @@ Run regresion tests on a parameterized bitcell
""" """
import unittest import unittest
from testutils import header,openram_test from testutils import *
import sys,os import sys,os
sys.path.append(os.path.join(sys.path[0],"..")) sys.path.append(os.getenv("OPENRAM_HOME"))
import globals import globals
from globals import OPTS from globals import OPTS
import debug import debug
@ -114,4 +114,4 @@ if __name__ == "__main__":
(OPTS, args) = globals.parse_args() (OPTS, args) = globals.parse_args()
del sys.argv[1:] del sys.argv[1:]
header(__file__, OPTS.tech_name) header(__file__, OPTS.tech_name)
unittest.main() unittest.main(testRunner=debugTestRunner())

View File

@ -11,9 +11,9 @@ Run a regression test on a 2-row buffer cell
""" """
import unittest import unittest
from testutils import header,openram_test from testutils import *
import sys,os import sys,os
sys.path.append(os.path.join(sys.path[0],"..")) sys.path.append(os.getenv("OPENRAM_HOME"))
import globals import globals
from globals import OPTS from globals import OPTS
from sram_factory import factory from sram_factory import factory
@ -35,4 +35,4 @@ if __name__ == "__main__":
(OPTS, args) = globals.parse_args() (OPTS, args) = globals.parse_args()
del sys.argv[1:] del sys.argv[1:]
header(__file__, OPTS.tech_name) header(__file__, OPTS.tech_name)
unittest.main() unittest.main(testRunner=debugTestRunner())

View File

@ -11,9 +11,9 @@ Run a regression test on a 2-row buffer cell
""" """
import unittest import unittest
from testutils import header,openram_test from testutils import *
import sys,os import sys,os
sys.path.append(os.path.join(sys.path[0],"..")) sys.path.append(os.getenv("OPENRAM_HOME"))
import globals import globals
from globals import OPTS from globals import OPTS
from sram_factory import factory from sram_factory import factory
@ -51,4 +51,4 @@ if __name__ == "__main__":
(OPTS, args) = globals.parse_args() (OPTS, args) = globals.parse_args()
del sys.argv[1:] del sys.argv[1:]
header(__file__, OPTS.tech_name) header(__file__, OPTS.tech_name)
unittest.main() unittest.main(testRunner=debugTestRunner())

View File

@ -11,9 +11,9 @@ Run regression tests on a parameterized inverter
""" """
import unittest import unittest
from testutils import header,openram_test from testutils import *
import sys,os import sys,os
sys.path.append(os.path.join(sys.path[0],"..")) sys.path.append(os.getenv("OPENRAM_HOME"))
import globals import globals
from globals import OPTS from globals import OPTS
from sram_factory import factory from sram_factory import factory
@ -36,4 +36,4 @@ if __name__ == "__main__":
(OPTS, args) = globals.parse_args() (OPTS, args) = globals.parse_args()
del sys.argv[1:] del sys.argv[1:]
header(__file__, OPTS.tech_name) header(__file__, OPTS.tech_name)
unittest.main() unittest.main(testRunner=debugTestRunner())

View File

@ -11,9 +11,9 @@ Run regression tests on a parameterized inverter
""" """
import unittest import unittest
from testutils import header,openram_test from testutils import *
import sys,os import sys,os
sys.path.append(os.path.join(sys.path[0],"..")) sys.path.append(os.getenv("OPENRAM_HOME"))
import globals import globals
from globals import OPTS from globals import OPTS
from sram_factory import factory from sram_factory import factory
@ -35,4 +35,4 @@ if __name__ == "__main__":
(OPTS, args) = globals.parse_args() (OPTS, args) = globals.parse_args()
del sys.argv[1:] del sys.argv[1:]
header(__file__, OPTS.tech_name) header(__file__, OPTS.tech_name)
unittest.main() unittest.main(testRunner=debugTestRunner())

View File

@ -10,9 +10,9 @@
Run regression tests on a parameterized inverter Run regression tests on a parameterized inverter
""" """
import unittest import unittest
from testutils import header,openram_test from testutils import *
import sys,os import sys,os
sys.path.append(os.path.join(sys.path[0],"..")) sys.path.append(os.getenv("OPENRAM_HOME"))
import globals import globals
from globals import OPTS from globals import OPTS
from sram_factory import factory from sram_factory import factory
@ -34,4 +34,4 @@ if __name__ == "__main__":
(OPTS, args) = globals.parse_args() (OPTS, args) = globals.parse_args()
del sys.argv[1:] del sys.argv[1:]
header(__file__, OPTS.tech_name) header(__file__, OPTS.tech_name)
unittest.main() unittest.main(testRunner=debugTestRunner())

View File

@ -11,9 +11,9 @@ Run regression tests on a parameterized inverter
""" """
import unittest import unittest
from testutils import header,openram_test from testutils import *
import sys,os import sys,os
sys.path.append(os.path.join(sys.path[0],"..")) sys.path.append(os.getenv("OPENRAM_HOME"))
import globals import globals
from globals import OPTS from globals import OPTS
from sram_factory import factory from sram_factory import factory
@ -36,4 +36,4 @@ if __name__ == "__main__":
(OPTS, args) = globals.parse_args() (OPTS, args) = globals.parse_args()
del sys.argv[1:] del sys.argv[1:]
header(__file__, OPTS.tech_name) header(__file__, OPTS.tech_name)
unittest.main() unittest.main(testRunner=debugTestRunner())

View File

@ -11,9 +11,9 @@ Run a regression test on a 2-row buffer cell
""" """
import unittest import unittest
from testutils import header,openram_test from testutils import *
import sys,os import sys,os
sys.path.append(os.path.join(sys.path[0],"..")) sys.path.append(os.getenv("OPENRAM_HOME"))
import globals import globals
from globals import OPTS from globals import OPTS
from sram_factory import factory from sram_factory import factory
@ -35,4 +35,4 @@ if __name__ == "__main__":
(OPTS, args) = globals.parse_args() (OPTS, args) = globals.parse_args()
del sys.argv[1:] del sys.argv[1:]
header(__file__, OPTS.tech_name) header(__file__, OPTS.tech_name)
unittest.main() unittest.main(testRunner=debugTestRunner())

View File

@ -13,9 +13,9 @@ size 2-input nand gate.
""" """
import unittest import unittest
from testutils import header,openram_test from testutils import *
import sys,os import sys,os
sys.path.append(os.path.join(sys.path[0],"..")) sys.path.append(os.getenv("OPENRAM_HOME"))
import globals import globals
from globals import OPTS from globals import OPTS
from sram_factory import factory from sram_factory import factory
@ -38,4 +38,4 @@ if __name__ == "__main__":
(OPTS, args) = globals.parse_args() (OPTS, args) = globals.parse_args()
del sys.argv[1:] del sys.argv[1:]
header(__file__, OPTS.tech_name) header(__file__, OPTS.tech_name)
unittest.main() unittest.main(testRunner=debugTestRunner())

View File

@ -13,9 +13,9 @@ It generates only a minimum size 3-input nand gate.
""" """
import unittest import unittest
from testutils import header,openram_test from testutils import *
import sys,os import sys,os
sys.path.append(os.path.join(sys.path[0],"..")) sys.path.append(os.getenv("OPENRAM_HOME"))
import globals import globals
from globals import OPTS from globals import OPTS
from sram_factory import factory from sram_factory import factory
@ -38,4 +38,4 @@ if __name__ == "__main__":
(OPTS, args) = globals.parse_args() (OPTS, args) = globals.parse_args()
del sys.argv[1:] del sys.argv[1:]
header(__file__, OPTS.tech_name) header(__file__, OPTS.tech_name)
unittest.main() unittest.main(testRunner=debugTestRunner())

View File

@ -13,9 +13,9 @@ size 2-input nor gate.
""" """
import unittest import unittest
from testutils import header,openram_test from testutils import *
import sys,os import sys,os
sys.path.append(os.path.join(sys.path[0],"..")) sys.path.append(os.getenv("OPENRAM_HOME"))
import globals import globals
from globals import OPTS from globals import OPTS
from sram_factory import factory from sram_factory import factory
@ -37,4 +37,4 @@ if __name__ == "__main__":
(OPTS, args) = globals.parse_args() (OPTS, args) = globals.parse_args()
del sys.argv[1:] del sys.argv[1:]
header(__file__, OPTS.tech_name) header(__file__, OPTS.tech_name)
unittest.main() unittest.main(testRunner=debugTestRunner())

View File

@ -11,9 +11,9 @@ Run a regression test on a precharge cell
""" """
import unittest import unittest
from testutils import header,openram_test from testutils import *
import sys,os import sys,os
sys.path.append(os.path.join(sys.path[0],"..")) sys.path.append(os.getenv("OPENRAM_HOME"))
import globals import globals
from globals import OPTS from globals import OPTS
from sram_factory import factory from sram_factory import factory
@ -57,4 +57,4 @@ if __name__ == "__main__":
(OPTS, args) = globals.parse_args() (OPTS, args) = globals.parse_args()
del sys.argv[1:] del sys.argv[1:]
header(__file__, OPTS.tech_name) header(__file__, OPTS.tech_name)
unittest.main() unittest.main(testRunner=debugTestRunner())

View File

@ -11,9 +11,9 @@ Run a regression test on a replica pbitcell
""" """
import unittest import unittest
from testutils import header,openram_test from testutils import *
import sys,os import sys,os
sys.path.append(os.path.join(sys.path[0],"..")) sys.path.append(os.getenv("OPENRAM_HOME"))
import globals import globals
from globals import OPTS from globals import OPTS
from sram_factory import factory from sram_factory import factory
@ -51,4 +51,4 @@ if __name__ == "__main__":
(OPTS, args) = globals.parse_args() (OPTS, args) = globals.parse_args()
del sys.argv[1:] del sys.argv[1:]
header(__file__, OPTS.tech_name) header(__file__, OPTS.tech_name)
unittest.main() unittest.main(testRunner=debugTestRunner())

View File

@ -11,9 +11,9 @@ Run a regression test on a wordline_driver array
""" """
import unittest import unittest
from testutils import header,openram_test from testutils import *
import sys,os import sys,os
sys.path.append(os.path.join(sys.path[0],"..")) sys.path.append(os.getenv("OPENRAM_HOME"))
import globals import globals
from globals import OPTS from globals import OPTS
from sram_factory import factory from sram_factory import factory
@ -54,4 +54,4 @@ if __name__ == "__main__":
(OPTS, args) = globals.parse_args() (OPTS, args) = globals.parse_args()
del sys.argv[1:] del sys.argv[1:]
header(__file__, OPTS.tech_name) header(__file__, OPTS.tech_name)
unittest.main() unittest.main(testRunner=debugTestRunner())

View File

@ -11,9 +11,9 @@ Run a regression test on a basic array
""" """
import unittest import unittest
from testutils import header,openram_test from testutils import *
import sys,os import sys,os
sys.path.append(os.path.join(sys.path[0],"..")) sys.path.append(os.getenv("OPENRAM_HOME"))
import globals import globals
from globals import OPTS from globals import OPTS
from sram_factory import factory from sram_factory import factory
@ -41,4 +41,4 @@ if __name__ == "__main__":
(OPTS, args) = globals.parse_args() (OPTS, args) = globals.parse_args()
del sys.argv[1:] del sys.argv[1:]
header(__file__, OPTS.tech_name) header(__file__, OPTS.tech_name)
unittest.main() unittest.main(testRunner=debugTestRunner())

View File

@ -11,9 +11,9 @@ Run a regression test on a basic array
""" """
import unittest import unittest
from testutils import header,openram_test from testutils import *
import sys,os import sys,os
sys.path.append(os.path.join(sys.path[0],"..")) sys.path.append(os.getenv("OPENRAM_HOME"))
import globals import globals
from globals import OPTS from globals import OPTS
from sram_factory import factory from sram_factory import factory
@ -37,4 +37,4 @@ if __name__ == "__main__":
(OPTS, args) = globals.parse_args() (OPTS, args) = globals.parse_args()
del sys.argv[1:] del sys.argv[1:]
header(__file__, OPTS.tech_name) header(__file__, OPTS.tech_name)
unittest.main() unittest.main(testRunner=debugTestRunner())

View File

@ -11,9 +11,9 @@ Run a regression test on a basic array
""" """
import unittest import unittest
from testutils import header,openram_test from testutils import *
import sys,os import sys,os
sys.path.append(os.path.join(sys.path[0],"..")) sys.path.append(os.getenv("OPENRAM_HOME"))
import globals import globals
from globals import OPTS from globals import OPTS
from sram_factory import factory from sram_factory import factory
@ -56,4 +56,4 @@ if __name__ == "__main__":
(OPTS, args) = globals.parse_args() (OPTS, args) = globals.parse_args()
del sys.argv[1:] del sys.argv[1:]
header(__file__, OPTS.tech_name) header(__file__, OPTS.tech_name)
unittest.main() unittest.main(testRunner=debugTestRunner())

View File

@ -11,9 +11,9 @@ Run a regression test on a hierarchical_decoder.
""" """
import unittest import unittest
from testutils import header,openram_test from testutils import *
import sys,os import sys,os
sys.path.append(os.path.join(sys.path[0],"..")) sys.path.append(os.getenv("OPENRAM_HOME"))
import globals import globals
from globals import OPTS from globals import OPTS
from sram_factory import factory from sram_factory import factory
@ -80,4 +80,4 @@ if __name__ == "__main__":
(OPTS, args) = globals.parse_args() (OPTS, args) = globals.parse_args()
del sys.argv[1:] del sys.argv[1:]
header(__file__, OPTS.tech_name) header(__file__, OPTS.tech_name)
unittest.main() unittest.main(testRunner=debugTestRunner())

View File

@ -11,9 +11,9 @@ Run a regression test on a hierarchical_predecode2x4.
""" """
import unittest import unittest
from testutils import header,openram_test from testutils import *
import sys,os import sys,os
sys.path.append(os.path.join(sys.path[0],"..")) sys.path.append(os.getenv("OPENRAM_HOME"))
import globals import globals
from globals import OPTS from globals import OPTS
from sram_factory import factory from sram_factory import factory
@ -46,4 +46,4 @@ if __name__ == "__main__":
(OPTS, args) = globals.parse_args() (OPTS, args) = globals.parse_args()
del sys.argv[1:] del sys.argv[1:]
header(__file__, OPTS.tech_name) header(__file__, OPTS.tech_name)
unittest.main() unittest.main(testRunner=debugTestRunner())

View File

@ -11,9 +11,9 @@ Run a regression test on a hierarchical_predecode3x8.
""" """
import unittest import unittest
from testutils import header,openram_test from testutils import *
import sys,os import sys,os
sys.path.append(os.path.join(sys.path[0],"..")) sys.path.append(os.getenv("OPENRAM_HOME"))
import globals import globals
from globals import OPTS from globals import OPTS
from sram_factory import factory from sram_factory import factory
@ -46,4 +46,4 @@ if __name__ == "__main__":
(OPTS, args) = globals.parse_args() (OPTS, args) = globals.parse_args()
del sys.argv[1:] del sys.argv[1:]
header(__file__, OPTS.tech_name) header(__file__, OPTS.tech_name)
unittest.main() unittest.main(testRunner=debugTestRunner())

View File

@ -10,9 +10,9 @@
Run a regression test on a single transistor column_mux. Run a regression test on a single transistor column_mux.
""" """
from testutils import header,openram_test,unittest from testutils import *
import sys,os import sys,os
sys.path.append(os.path.join(sys.path[0],"..")) sys.path.append(os.getenv("OPENRAM_HOME"))
import globals import globals
from globals import OPTS from globals import OPTS
from sram_factory import factory from sram_factory import factory
@ -68,4 +68,4 @@ if __name__ == "__main__":
(OPTS, args) = globals.parse_args() (OPTS, args) = globals.parse_args()
del sys.argv[1:] del sys.argv[1:]
header(__file__, OPTS.tech_name) header(__file__, OPTS.tech_name)
unittest.main() unittest.main(testRunner=debugTestRunner())

View File

@ -11,9 +11,9 @@ Run a regression test on a precharge array
""" """
import unittest import unittest
from testutils import header,openram_test from testutils import *
import sys,os import sys,os
sys.path.append(os.path.join(sys.path[0],"..")) sys.path.append(os.getenv("OPENRAM_HOME"))
import globals import globals
from globals import OPTS from globals import OPTS
from sram_factory import factory from sram_factory import factory
@ -55,4 +55,4 @@ if __name__ == "__main__":
(OPTS, args) = globals.parse_args() (OPTS, args) = globals.parse_args()
del sys.argv[1:] del sys.argv[1:]
header(__file__, OPTS.tech_name) header(__file__, OPTS.tech_name)
unittest.main() unittest.main(testRunner=debugTestRunner())

View File

@ -11,9 +11,9 @@ Run a regression test on a wordline_driver array
""" """
import unittest import unittest
from testutils import header,openram_test from testutils import *
import sys,os import sys,os
sys.path.append(os.path.join(sys.path[0],"..")) sys.path.append(os.getenv("OPENRAM_HOME"))
import globals import globals
from globals import OPTS from globals import OPTS
from sram_factory import factory from sram_factory import factory
@ -49,4 +49,4 @@ if __name__ == "__main__":
(OPTS, args) = globals.parse_args() (OPTS, args) = globals.parse_args()
del sys.argv[1:] del sys.argv[1:]
header(__file__, OPTS.tech_name) header(__file__, OPTS.tech_name)
unittest.main() unittest.main(testRunner=debugTestRunner())

View File

@ -11,9 +11,9 @@ Run a regression test on a sense amp array
""" """
import unittest import unittest
from testutils import header,openram_test from testutils import *
import sys,os import sys,os
sys.path.append(os.path.join(sys.path[0],"..")) sys.path.append(os.getenv("OPENRAM_HOME"))
import globals import globals
from globals import OPTS from globals import OPTS
from sram_factory import factory from sram_factory import factory
@ -55,4 +55,4 @@ if __name__ == "__main__":
(OPTS, args) = globals.parse_args() (OPTS, args) = globals.parse_args()
del sys.argv[1:] del sys.argv[1:]
header(__file__, OPTS.tech_name) header(__file__, OPTS.tech_name)
unittest.main() unittest.main(testRunner=debugTestRunner())

View File

@ -11,9 +11,9 @@ Run a regression test on a write driver array
""" """
import unittest import unittest
from testutils import header,openram_test from testutils import *
import sys,os import sys,os
sys.path.append(os.path.join(sys.path[0],"..")) sys.path.append(os.getenv("OPENRAM_HOME"))
import globals import globals
from globals import OPTS from globals import OPTS
from sram_factory import factory from sram_factory import factory
@ -55,4 +55,4 @@ if __name__ == "__main__":
(OPTS, args) = globals.parse_args() (OPTS, args) = globals.parse_args()
del sys.argv[1:] del sys.argv[1:]
header(__file__, OPTS.tech_name) header(__file__, OPTS.tech_name)
unittest.main() unittest.main(testRunner=debugTestRunner())

View File

@ -11,9 +11,9 @@ Run a regression test on a dff_array.
""" """
import unittest import unittest
from testutils import header,openram_test from testutils import *
import sys,os import sys,os
sys.path.append(os.path.join(sys.path[0],"..")) sys.path.append(os.getenv("OPENRAM_HOME"))
import globals import globals
from globals import OPTS from globals import OPTS
from sram_factory import factory from sram_factory import factory
@ -43,4 +43,4 @@ if __name__ == "__main__":
(OPTS, args) = globals.parse_args() (OPTS, args) = globals.parse_args()
del sys.argv[1:] del sys.argv[1:]
header(__file__, OPTS.tech_name) header(__file__, OPTS.tech_name)
unittest.main() unittest.main(testRunner=debugTestRunner())

View File

@ -11,9 +11,9 @@ Run a regression test on a dff_array.
""" """
import unittest import unittest
from testutils import header,openram_test from testutils import *
import sys,os import sys,os
sys.path.append(os.path.join(sys.path[0],"..")) sys.path.append(os.getenv("OPENRAM_HOME"))
import globals import globals
from globals import OPTS from globals import OPTS
from sram_factory import factory from sram_factory import factory
@ -43,4 +43,4 @@ if __name__ == "__main__":
(OPTS, args) = globals.parse_args() (OPTS, args) = globals.parse_args()
del sys.argv[1:] del sys.argv[1:]
header(__file__, OPTS.tech_name) header(__file__, OPTS.tech_name)
unittest.main() unittest.main(testRunner=debugTestRunner())

View File

@ -11,9 +11,9 @@ Run a regression test on a dff_buf.
""" """
import unittest import unittest
from testutils import header,openram_test from testutils import *
import sys,os import sys,os
sys.path.append(os.path.join(sys.path[0],"..")) sys.path.append(os.getenv("OPENRAM_HOME"))
import globals import globals
from globals import OPTS from globals import OPTS
from sram_factory import factory from sram_factory import factory
@ -35,4 +35,4 @@ if __name__ == "__main__":
(OPTS, args) = globals.parse_args() (OPTS, args) = globals.parse_args()
del sys.argv[1:] del sys.argv[1:]
header(__file__, OPTS.tech_name) header(__file__, OPTS.tech_name)
unittest.main() unittest.main(testRunner=debugTestRunner())

View File

@ -11,9 +11,9 @@ Run a regression test on a tri_gate_array.
""" """
import unittest import unittest
from testutils import header,openram_test from testutils import *
import sys,os import sys,os
sys.path.append(os.path.join(sys.path[0],"..")) sys.path.append(os.getenv("OPENRAM_HOME"))
import globals import globals
from globals import OPTS from globals import OPTS
from sram_factory import factory from sram_factory import factory
@ -39,4 +39,4 @@ if __name__ == "__main__":
(OPTS, args) = globals.parse_args() (OPTS, args) = globals.parse_args()
del sys.argv[1:] del sys.argv[1:]
header(__file__, OPTS.tech_name) header(__file__, OPTS.tech_name)
unittest.main() unittest.main(testRunner=debugTestRunner())

View File

@ -11,9 +11,9 @@ Run a test on a delay chain
""" """
import unittest import unittest
from testutils import header,openram_test from testutils import *
import sys,os import sys,os
sys.path.append(os.path.join(sys.path[0],"..")) sys.path.append(os.getenv("OPENRAM_HOME"))
import globals import globals
from globals import OPTS from globals import OPTS
from sram_factory import factory from sram_factory import factory
@ -35,4 +35,4 @@ if __name__ == "__main__":
(OPTS, args) = globals.parse_args() (OPTS, args) = globals.parse_args()
del sys.argv[1:] del sys.argv[1:]
header(__file__, OPTS.tech_name) header(__file__, OPTS.tech_name)
unittest.main() unittest.main(testRunner=debugTestRunner())

View File

@ -11,9 +11,9 @@ Run a test on a multiport replica bitline
""" """
import unittest import unittest
from testutils import header,openram_test from testutils import *
import sys,os import sys,os
sys.path.append(os.path.join(sys.path[0],"..")) sys.path.append(os.getenv("OPENRAM_HOME"))
import globals import globals
from globals import OPTS from globals import OPTS
from sram_factory import factory from sram_factory import factory
@ -67,4 +67,4 @@ if __name__ == "__main__":
(OPTS, args) = globals.parse_args() (OPTS, args) = globals.parse_args()
del sys.argv[1:] del sys.argv[1:]
header(__file__, OPTS.tech_name) header(__file__, OPTS.tech_name)
unittest.main() unittest.main(testRunner=debugTestRunner())

View File

@ -11,9 +11,9 @@ Run a test on a replica bitline
""" """
import unittest import unittest
from testutils import header,openram_test from testutils import *
import sys,os import sys,os
sys.path.append(os.path.join(sys.path[0],"..")) sys.path.append(os.getenv("OPENRAM_HOME"))
import globals import globals
from globals import OPTS from globals import OPTS
from sram_factory import factory from sram_factory import factory
@ -45,4 +45,4 @@ if __name__ == "__main__":
(OPTS, args) = globals.parse_args() (OPTS, args) = globals.parse_args()
del sys.argv[1:] del sys.argv[1:]
header(__file__, OPTS.tech_name) header(__file__, OPTS.tech_name)
unittest.main() unittest.main(testRunner=debugTestRunner())

View File

@ -11,9 +11,9 @@ Run a regression test on a control_logic
""" """
import unittest import unittest
from testutils import header,openram_test from testutils import *
import sys,os import sys,os
sys.path.append(os.path.join(sys.path[0],"..")) sys.path.append(os.getenv("OPENRAM_HOME"))
import globals import globals
from globals import OPTS from globals import OPTS
from sram_factory import factory from sram_factory import factory
@ -36,4 +36,4 @@ if __name__ == "__main__":
(OPTS, args) = globals.parse_args() (OPTS, args) = globals.parse_args()
del sys.argv[1:] del sys.argv[1:]
header(__file__, OPTS.tech_name) header(__file__, OPTS.tech_name)
unittest.main() unittest.main(testRunner=debugTestRunner())

View File

@ -11,9 +11,9 @@ Run a regression test on various srams
""" """
import unittest import unittest
from testutils import header,openram_test from testutils import *
import sys,os import sys,os
sys.path.append(os.path.join(sys.path[0],"..")) sys.path.append(os.getenv("OPENRAM_HOME"))
import globals import globals
from globals import OPTS from globals import OPTS
from sram_factory import factory from sram_factory import factory
@ -52,4 +52,4 @@ if __name__ == "__main__":
(OPTS, args) = globals.parse_args() (OPTS, args) = globals.parse_args()
del sys.argv[1:] del sys.argv[1:]
header(__file__, OPTS.tech_name) header(__file__, OPTS.tech_name)
unittest.main() unittest.main(testRunner=debugTestRunner())

View File

@ -11,9 +11,9 @@ Run a regression test on various srams
""" """
import unittest import unittest
from testutils import header,openram_test from testutils import *
import sys,os import sys,os
sys.path.append(os.path.join(sys.path[0],"..")) sys.path.append(os.getenv("OPENRAM_HOME"))
import globals import globals
from globals import OPTS from globals import OPTS
from sram_factory import factory from sram_factory import factory
@ -69,4 +69,4 @@ if __name__ == "__main__":
(OPTS, args) = globals.parse_args() (OPTS, args) = globals.parse_args()
del sys.argv[1:] del sys.argv[1:]
header(__file__, OPTS.tech_name) header(__file__, OPTS.tech_name)
unittest.main() unittest.main(testRunner=debugTestRunner())

View File

@ -11,9 +11,9 @@ Run a regression test on various srams
""" """
import unittest import unittest
from testutils import header,openram_test from testutils import *
import sys,os import sys,os
sys.path.append(os.path.join(sys.path[0],"..")) sys.path.append(os.getenv("OPENRAM_HOME"))
import globals import globals
from globals import OPTS from globals import OPTS
from sram_factory import factory from sram_factory import factory
@ -74,4 +74,4 @@ if __name__ == "__main__":
(OPTS, args) = globals.parse_args() (OPTS, args) = globals.parse_args()
del sys.argv[1:] del sys.argv[1:]
header(__file__, OPTS.tech_name) header(__file__, OPTS.tech_name)
unittest.main() unittest.main(testRunner=debugTestRunner())

View File

@ -11,9 +11,9 @@ Run a regression test on various srams
""" """
import unittest import unittest
from testutils import header,openram_test from testutils import *
import sys,os import sys,os
sys.path.append(os.path.join(sys.path[0],"..")) sys.path.append(os.getenv("OPENRAM_HOME"))
import globals import globals
from globals import OPTS from globals import OPTS
from sram_factory import factory from sram_factory import factory
@ -161,4 +161,4 @@ if __name__ == "__main__":
(OPTS, args) = globals.parse_args() (OPTS, args) = globals.parse_args()
del sys.argv[1:] del sys.argv[1:]
header(__file__, OPTS.tech_name) header(__file__, OPTS.tech_name)
unittest.main() unittest.main(testRunner=debugTestRunner())

View File

@ -11,9 +11,9 @@ Run a regression test on 1rw 1r sram bank
""" """
import unittest import unittest
from testutils import header,openram_test from testutils import *
import sys,os import sys,os
sys.path.append(os.path.join(sys.path[0],"..")) sys.path.append(os.getenv("OPENRAM_HOME"))
import globals import globals
from globals import OPTS from globals import OPTS
from sram_factory import factory from sram_factory import factory
@ -72,4 +72,4 @@ if __name__ == "__main__":
(OPTS, args) = globals.parse_args() (OPTS, args) = globals.parse_args()
del sys.argv[1:] del sys.argv[1:]
header(__file__, OPTS.tech_name) header(__file__, OPTS.tech_name)
unittest.main() unittest.main(testRunner=debugTestRunner())

View File

@ -11,9 +11,9 @@ Run a regression test on various srams
""" """
import unittest import unittest
from testutils import header,openram_test from testutils import *
import sys,os import sys,os
sys.path.append(os.path.join(sys.path[0],"..")) sys.path.append(os.getenv("OPENRAM_HOME"))
import globals import globals
from globals import OPTS from globals import OPTS
from sram_factory import factory from sram_factory import factory
@ -67,4 +67,4 @@ if __name__ == "__main__":
(OPTS, args) = globals.parse_args() (OPTS, args) = globals.parse_args()
del sys.argv[1:] del sys.argv[1:]
header(__file__, OPTS.tech_name) header(__file__, OPTS.tech_name)
unittest.main() unittest.main(testRunner=debugTestRunner())

View File

@ -11,9 +11,9 @@ Run a regression test on a 1 bank SRAM
""" """
import unittest import unittest
from testutils import header,openram_test from testutils import *
import sys,os import sys,os
sys.path.append(os.path.join(sys.path[0],"..")) sys.path.append(os.getenv("OPENRAM_HOME"))
import globals import globals
from globals import OPTS from globals import OPTS
from sram_factory import factory from sram_factory import factory
@ -57,4 +57,4 @@ if __name__ == "__main__":
(OPTS, args) = globals.parse_args() (OPTS, args) = globals.parse_args()
del sys.argv[1:] del sys.argv[1:]
header(__file__, OPTS.tech_name) header(__file__, OPTS.tech_name)
unittest.main() unittest.main(testRunner=debugTestRunner())

View File

@ -11,9 +11,9 @@ Run a regression test on a 1 bank SRAM
""" """
import unittest import unittest
from testutils import header,openram_test from testutils import *
import sys,os import sys,os
sys.path.append(os.path.join(sys.path[0],"..")) sys.path.append(os.getenv("OPENRAM_HOME"))
import globals import globals
from globals import OPTS from globals import OPTS
from sram_factory import factory from sram_factory import factory
@ -55,4 +55,4 @@ if __name__ == "__main__":
(OPTS, args) = globals.parse_args() (OPTS, args) = globals.parse_args()
del sys.argv[1:] del sys.argv[1:]
header(__file__, OPTS.tech_name) header(__file__, OPTS.tech_name)
unittest.main() unittest.main(testRunner=debugTestRunner())

View File

@ -11,9 +11,9 @@ Run a regression test on a 1 bank SRAM
""" """
import unittest import unittest
from testutils import header,openram_test from testutils import *
import sys,os import sys,os
sys.path.append(os.path.join(sys.path[0],"..")) sys.path.append(os.getenv("OPENRAM_HOME"))
import globals import globals
from globals import OPTS from globals import OPTS
from sram_factory import factory from sram_factory import factory
@ -58,4 +58,4 @@ if __name__ == "__main__":
(OPTS, args) = globals.parse_args() (OPTS, args) = globals.parse_args()
del sys.argv[1:] del sys.argv[1:]
header(__file__, OPTS.tech_name) header(__file__, OPTS.tech_name)
unittest.main() unittest.main(testRunner=debugTestRunner())

View File

@ -11,9 +11,9 @@ Run a regression test on a 1 bank SRAM
""" """
import unittest import unittest
from testutils import header,openram_test from testutils import *
import sys,os import sys,os
sys.path.append(os.path.join(sys.path[0],"..")) sys.path.append(os.getenv("OPENRAM_HOME"))
import globals import globals
from globals import OPTS from globals import OPTS
from sram_factory import factory from sram_factory import factory
@ -56,4 +56,4 @@ if __name__ == "__main__":
(OPTS, args) = globals.parse_args() (OPTS, args) = globals.parse_args()
del sys.argv[1:] del sys.argv[1:]
header(__file__, OPTS.tech_name) header(__file__, OPTS.tech_name)
unittest.main() unittest.main(testRunner=debugTestRunner())

View File

@ -11,9 +11,9 @@ Run a regression test on a 1 bank, 2 port SRAM
""" """
import unittest import unittest
from testutils import header,openram_test from testutils import *
import sys,os import sys,os
sys.path.append(os.path.join(sys.path[0],"..")) sys.path.append(os.getenv("OPENRAM_HOME"))
import globals import globals
from globals import OPTS from globals import OPTS
from sram_factory import factory from sram_factory import factory
@ -56,4 +56,4 @@ if __name__ == "__main__":
(OPTS, args) = globals.parse_args() (OPTS, args) = globals.parse_args()
del sys.argv[1:] del sys.argv[1:]
header(__file__, OPTS.tech_name) header(__file__, OPTS.tech_name)
unittest.main() unittest.main(testRunner=debugTestRunner())

Some files were not shown because too many files have changed in this diff Show More