Merge remote-tracking branch 'private/dev' into dev

This commit is contained in:
mrg 2020-12-08 10:50:02 -08:00
commit ebe19abf60
13 changed files with 119 additions and 48 deletions

View File

@ -976,7 +976,7 @@ class layout():
(horizontal_layer, via_layer, vertical_layer) = layer_stack (horizontal_layer, via_layer, vertical_layer) = layer_stack
if horizontal: if horizontal:
route_layer = vertical_layer route_layer = vertical_layer
bys_layer = horizontal_layer bus_layer = horizontal_layer
else: else:
route_layer = horizontal_layer route_layer = horizontal_layer
bus_layer = vertical_layer bus_layer = vertical_layer

View File

@ -379,6 +379,14 @@ class pin_layout:
except ImportError: except ImportError:
label_purpose = purpose label_purpose = purpose
newLayout.addBox(layerNumber=layer_num,
purposeNumber=purpose,
offsetInMicrons=self.ll(),
width=self.width(),
height=self.height(),
center=False)
# Draw a second pin shape too
if pin_purpose != purpose:
newLayout.addBox(layerNumber=layer_num, newLayout.addBox(layerNumber=layer_num,
purposeNumber=pin_purpose, purposeNumber=pin_purpose,
offsetInMicrons=self.ll(), offsetInMicrons=self.ll(),

View File

@ -0,0 +1,22 @@
# See LICENSE for licensing information.
#
# Copyright (c) 2016-2019 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University)
# All rights reserved.
#
import debug
from tech import cell_properties as props
import bitcell_base
class col_cap_bitcell_1port(bitcell_base.bitcell_base):
"""
Column end cap cell.
"""
def __init__(self, name="col_cap_bitcell_1port"):
bitcell_base.bitcell_base.__init__(self, name, prop=props.col_cap_1port)
debug.info(2, "Create col_cap bitcell 1 port object")
self.no_instances = True

View File

@ -0,0 +1,22 @@
# See LICENSE for licensing information.
#
# Copyright (c) 2016-2019 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University)
# All rights reserved.
#
import debug
from tech import cell_properties as props
import bitcell_base
class row_cap_bitcell_1port(bitcell_base.bitcell_base):
"""
Row end cap cell.
"""
def __init__(self, name="row_cap_bitcell_1port"):
bitcell_base.bitcell_base.__init__(self, name, prop=props.row_cap_1port)
debug.info(2, "Create row_cap bitcell 1 port object")
self.no_instances = True

View File

@ -79,7 +79,8 @@ class Gds2reader:
recordLength = struct.unpack(">h",recordLengthAscii) #gives us a tuple with a short int inside recordLength = struct.unpack(">h",recordLengthAscii) #gives us a tuple with a short int inside
offset_int = int(recordLength[0]) # extract length offset_int = int(recordLength[0]) # extract length
offset += offset_int # count offset offset += offset_int # count offset
#print(offset) #print out the record numbers for de-bugging if(self.debugToTerminal==1):
print("Offset: " + str(offset)) #print out the record numbers for de-bugging
record = self.fileHandle.read(recordLength[0]-2) #read the rest of it (first 2 bytes were already read) record = self.fileHandle.read(recordLength[0]-2) #read the rest of it (first 2 bytes were already read)
return record return record
@ -176,7 +177,7 @@ class Gds2reader:
def readBoundary(self): def readBoundary(self):
##reads in a boundary type structure = a filled polygon ##reads in a boundary type structure = a filled polygon
if(self.debugToTerminal==1): if(self.debugToTerminal==1):
print("\t\t\tBeginBoundary") print("\t\tBeginBoundary")
thisBoundary=GdsBoundary() thisBoundary=GdsBoundary()
while 1: while 1:
record = self.readNextRecord() record = self.readNextRecord()
@ -214,13 +215,13 @@ class Gds2reader:
print("\t\t\tXY Point: "+str(x)+","+str(y)) print("\t\t\tXY Point: "+str(x)+","+str(y))
elif(idBits==b'\x11\x00'): #End Of Element elif(idBits==b'\x11\x00'): #End Of Element
if(self.debugToTerminal==1): if(self.debugToTerminal==1):
print("\t\t\tEndBoundary") print("\t\tEndBoundary")
break; break;
return thisBoundary return thisBoundary
def readPath(self): #reads in a path structure def readPath(self): #reads in a path structure
if(self.debugToTerminal==1): if(self.debugToTerminal==1):
print("\t\t\tBeginPath") print("\t\tBeginPath")
thisPath=GdsPath() thisPath=GdsPath()
while 1: while 1:
@ -274,7 +275,7 @@ class Gds2reader:
print("\t\t\tXY Point: "+str(x)+","+str(y)) print("\t\t\tXY Point: "+str(x)+","+str(y))
elif(idBits==b'\x11\x00'): #End Of Element elif(idBits==b'\x11\x00'): #End Of Element
if(self.debugToTerminal==1): if(self.debugToTerminal==1):
print("\t\t\tEndPath") print("\t\tEndPath")
break; break;
return thisPath return thisPath

View File

@ -362,16 +362,8 @@ def end_openram():
verify.print_pex_stats() verify.print_pex_stats()
def cleanup_paths(): def purge_temp():
""" """ Remove the temp directory. """
We should clean up the temp directory after execution.
"""
global OPTS
if OPTS.keep_temp:
debug.info(0,
"Preserving temp directory: {}".format(OPTS.openram_temp))
return
elif os.path.exists(OPTS.openram_temp):
debug.info(1, debug.info(1,
"Purging temp directory: {}".format(OPTS.openram_temp)) "Purging temp directory: {}".format(OPTS.openram_temp))
# This annoyingly means you have to re-cd into # This annoyingly means you have to re-cd into
@ -385,6 +377,19 @@ def cleanup_paths():
shutil.rmtree(i) shutil.rmtree(i)
def cleanup_paths():
"""
We should clean up the temp directory after execution.
"""
global OPTS
if OPTS.keep_temp:
debug.info(0,
"Preserving temp directory: {}".format(OPTS.openram_temp))
return
elif os.path.exists(OPTS.openram_temp):
purge_temp()
def setup_paths(): def setup_paths():
""" Set up the non-tech related paths. """ """ Set up the non-tech related paths. """
debug.info(2, "Setting up paths...") debug.info(2, "Setting up paths...")
@ -435,7 +440,9 @@ def find_exe(check_exe):
def init_paths(): def init_paths():
""" Create the temp and output directory if it doesn't exist """ """ Create the temp and output directory if it doesn't exist """
if os.path.exists(OPTS.openram_temp):
purge_temp()
else:
# make the directory if it doesn't exist # make the directory if it doesn't exist
try: try:
debug.info(1, debug.info(1,

View File

@ -100,7 +100,7 @@ class col_cap_array(bitcell_base_array):
inst = self.cell_inst[row, col] inst = self.cell_inst[row, col]
for pin_name in ["vdd", "gnd"]: for pin_name in ["vdd", "gnd"]:
for pin in inst.get_pins(pin_name): for pin in inst.get_pins(pin_name):
self.add_power_pin(name=pin.name, self.add_power_pin(name=pin_name,
loc=pin.center(), loc=pin.center(),
start_layer=pin.layer) start_layer=pin.layer)

View File

@ -390,20 +390,19 @@ class replica_bitcell_array(bitcell_base_array):
# These grow up, away from the array # These grow up, away from the array
for bit in range(self.rbl[1]): for bit in range(self.rbl[1]):
dummy_offset = self.bitcell_offset.scale(0, bit + bit % 2) + self.bitcell_array_inst.ul() dummy_offset = self.bitcell_offset.scale(0, bit + bit % 2) + self.bitcell_array_inst.ul()
import pdb; pdb.set_trace()
self.dummy_row_replica_insts[self.rbl[0] + bit].place(offset=dummy_offset, self.dummy_row_replica_insts[self.rbl[0] + bit].place(offset=dummy_offset,
mirror="MX" if bit % 2 else "R0") mirror="MX" if (self.row_size + bit) % 2 else "R0")
def add_end_caps(self): def add_end_caps(self):
""" Add dummy cells or end caps around the array """ """ Add dummy cells or end caps around the array """
# FIXME: These depend on the array size itself # Far top dummy row (first row above array is NOT flipped if even number of rows)
# Far top dummy row (first row above array is NOT flipped) flip_dummy = (self.row_size + self.rbl[1]) % 2
flip_dummy = self.rbl[1] % 2
dummy_row_offset = self.bitcell_offset.scale(0, self.rbl[1] + flip_dummy) + self.bitcell_array_inst.ul() dummy_row_offset = self.bitcell_offset.scale(0, self.rbl[1] + flip_dummy) + self.bitcell_array_inst.ul()
self.dummy_row_insts[1].place(offset=dummy_row_offset, self.dummy_row_insts[1].place(offset=dummy_row_offset,
mirror="MX" if flip_dummy else "R0") mirror="MX" if flip_dummy else "R0")
# FIXME: These depend on the array size itself
# Far bottom dummy row (first row below array IS flipped) # Far bottom dummy row (first row below array IS flipped)
flip_dummy = (self.rbl[0] + 1) % 2 flip_dummy = (self.rbl[0] + 1) % 2
dummy_row_offset = self.bitcell_offset.scale(0, -self.rbl[0] - 1 + flip_dummy) + self.unused_offset dummy_row_offset = self.bitcell_offset.scale(0, -self.rbl[0] - 1 + flip_dummy) + self.unused_offset
@ -422,9 +421,8 @@ class replica_bitcell_array(bitcell_base_array):
def add_layout_pins(self): def add_layout_pins(self):
""" Add the layout pins """ """ Add the layout pins """
#All wordlines # All wordlines
#Main array wl and bl/br # Main array wl and bl/br
for pin_name in self.all_wordline_names: for pin_name in self.all_wordline_names:
pin_list = self.bitcell_array_inst.get_pins(pin_name) pin_list = self.bitcell_array_inst.get_pins(pin_name)
for pin in pin_list: for pin in pin_list:

View File

@ -113,7 +113,7 @@ class row_cap_array(bitcell_base_array):
inst = self.cell_inst[row, col] inst = self.cell_inst[row, col]
for pin_name in ["vdd", "gnd"]: for pin_name in ["vdd", "gnd"]:
for pin in inst.get_pins(pin_name): for pin in inst.get_pins(pin_name):
self.add_power_pin(name=pin.name, self.add_power_pin(name=pin_name,
loc=pin.center(), loc=pin.center(),
start_layer=pin.layer) start_layer=pin.layer)

14
compiler/printGDS.py Executable file
View File

@ -0,0 +1,14 @@
#!/usr/bin/env python3
import sys
from gdsMill import gdsMill
if len(sys.argv) < 2:
print("Usage: {0} file.gds".format(sys.argv[0]))
sys.exit(1)
gds_file = sys.argv[1]
arrayCellLayout = gdsMill.VlsiLayout()
reader = gdsMill.Gds2reader(arrayCellLayout,debugToTerminal = 1)
reader.loadFromFile(gds_file)

View File

@ -25,7 +25,7 @@ class replica_bitcell_array_test(openram_test):
factory.reset() factory.reset()
debug.info(2, "Testing 4x4 array for bitcell") debug.info(2, "Testing 4x4 array for bitcell")
a = factory.create(module_type="replica_bitcell_array", cols=4, rows=4, rbl=[1, 0]) a = factory.create(module_type="replica_bitcell_array", cols=7, rows=5, rbl=[1, 0])
self.local_check(a) self.local_check(a)
globals.end_openram() globals.end_openram()

View File

@ -104,9 +104,9 @@ def write_lvs_script(cell_name, gds_name, sp_name, final_verification=False, out
'lvsRecognizeGates': 'NONE', 'lvsRecognizeGates': 'NONE',
} }
# FIXME: Remove when vdd/gnd connected # FIXME: Remove when vdd/gnd connected
#'cmnVConnectNamesState' : 'ALL', #connects all nets with the same namee # 'cmnVConnectNamesState' : 'ALL', #connects all nets with the same namee
# FIXME: Remove when vdd/gnd connected # FIXME: Remove when vdd/gnd connected
#'lvsAbortOnSupplyError' : 0 # 'lvsAbortOnSupplyError' : 0
if not final_verification or not OPTS.route_supplies: if not final_verification or not OPTS.route_supplies:
lvs_runset['cmnVConnectReport']=1 lvs_runset['cmnVConnectReport']=1
@ -115,8 +115,6 @@ def write_lvs_script(cell_name, gds_name, sp_name, final_verification=False, out
else: else:
lvs_runset['lvsAbortOnSupplyError']=1 lvs_runset['lvsAbortOnSupplyError']=1
# write the runset file # write the runset file
f = open(output_path + "lvs_runset", "w") f = open(output_path + "lvs_runset", "w")
for k in sorted(iter(lvs_runset.keys())): for k in sorted(iter(lvs_runset.keys())):

View File

@ -89,6 +89,7 @@ def write_drc_script(cell_name, gds_name, extract, final_verification, output_pa
f.write("gds warning default\n") f.write("gds warning default\n")
f.write("gds flatten true\n") f.write("gds flatten true\n")
f.write("gds readonly true\n") f.write("gds readonly true\n")
f.write("gds ordering true\n")
f.write("gds read {}\n".format(gds_name)) f.write("gds read {}\n".format(gds_name))
f.write('puts "Finished reading gds {}"\n'.format(gds_name)) f.write('puts "Finished reading gds {}"\n'.format(gds_name))
f.write("load {}\n".format(cell_name)) f.write("load {}\n".format(cell_name))
@ -218,7 +219,7 @@ def write_lvs_script(cell_name, gds_name, sp_name, final_verification=False, out
f = open(run_file, "w") f = open(run_file, "w")
f.write("#!/bin/sh\n") f.write("#!/bin/sh\n")
f.write('export OPENRAM_TECH="{}"\n'.format(os.environ['OPENRAM_TECH'])) f.write('export OPENRAM_TECH="{}"\n'.format(os.environ['OPENRAM_TECH']))
f.write('echo "$(date): Starting LVS using Magic {}"\n'.format(OPTS.drc_exe[1])) f.write('echo "$(date): Starting LVS using Netgen {}"\n'.format(OPTS.lvs_exe[1]))
f.write("{} -noconsole << EOF\n".format(OPTS.lvs_exe[1])) f.write("{} -noconsole << EOF\n".format(OPTS.lvs_exe[1]))
# f.write("readnet spice {0}.spice\n".format(cell_name)) # f.write("readnet spice {0}.spice\n".format(cell_name))
# f.write("readnet spice {0}\n".format(sp_name)) # f.write("readnet spice {0}\n".format(sp_name))
@ -226,7 +227,7 @@ def write_lvs_script(cell_name, gds_name, sp_name, final_verification=False, out
f.write("quit\n") f.write("quit\n")
f.write("EOF\n") f.write("EOF\n")
f.write("magic_retcode=$?\n") f.write("magic_retcode=$?\n")
f.write('echo "$(date): Finished ($magic_retcode) LVS using Magic {}"\n'.format(OPTS.drc_exe[1])) f.write('echo "$(date): Finished ($magic_retcode) LVS using Netgen {}"\n'.format(OPTS.lvs_exe[1]))
f.write("exit $magic_retcode\n") f.write("exit $magic_retcode\n")
f.close() f.close()
os.system("chmod u+x {}".format(run_file)) os.system("chmod u+x {}".format(run_file))