added gds support
This commit is contained in:
parent
2cea2debdb
commit
223e5ab623
63
rect2lef.py
63
rect2lef.py
@ -3,6 +3,12 @@
|
|||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
hasGDSTK = True
|
||||||
|
try:
|
||||||
|
import gdstk
|
||||||
|
except ImportError:
|
||||||
|
hasGDSTK = False
|
||||||
|
|
||||||
def stripComments(line):
|
def stripComments(line):
|
||||||
escape = False
|
escape = False
|
||||||
inString = False
|
inString = False
|
||||||
@ -136,6 +142,39 @@ def writeLayerMap(path, conf):
|
|||||||
if "prb" in name.lower():
|
if "prb" in name.lower():
|
||||||
print(f"DIEAREA ALL {layer[1]} {layer[2]}", file=fptr)
|
print(f"DIEAREA ALL {layer[1]} {layer[2]}", file=fptr)
|
||||||
|
|
||||||
|
def writeGDS(path, conf, cell):
|
||||||
|
if not hasGDSTK:
|
||||||
|
print("gdstk not found, skipping gds export")
|
||||||
|
return
|
||||||
|
|
||||||
|
scale = conf["general"]["scale"]
|
||||||
|
numMetals = conf["general"]["metals"]
|
||||||
|
layers = {layer: (major, minor) for layer, major, minor in zip(conf["gds"]["layers"], conf["gds"]["major"], conf["gds"]["minor"])}
|
||||||
|
|
||||||
|
lib = gdstk.Library()
|
||||||
|
gdsCell = lib.new_cell(cell.name)
|
||||||
|
|
||||||
|
bndry = None
|
||||||
|
for layer, idx in layers.items():
|
||||||
|
if layer.startswith("prb"):
|
||||||
|
bndry = idx
|
||||||
|
break
|
||||||
|
if bndry:
|
||||||
|
gdsCell.add(gdstk.rectangle((cell.bbox[0]*scale, cell.bbox[1]*scale), (cell.bbox[2]*scale, cell.bbox[3]*scale), layer=bndry[0], datatype=bndry[1]))
|
||||||
|
for rect in cell.rects:
|
||||||
|
gds = queryGDS(conf, rect.layer)
|
||||||
|
labelWritten = False
|
||||||
|
for layerName, bloat in gds:
|
||||||
|
name, purpose = layerName.rsplit(".", 1)
|
||||||
|
if layerName in layers:
|
||||||
|
idx = layers[layerName]
|
||||||
|
gdsCell.add(gdstk.rectangle(((rect.bounds[0]-bloat)*scale, (rect.bounds[1]-bloat)*scale), ((rect.bounds[2]+bloat)*scale, (rect.bounds[3]+bloat)*scale), layer=idx[0], datatype=idx[1]))
|
||||||
|
if rect.label and rect.label != "#" and not labelWritten:
|
||||||
|
gdsCell.add(gdstk.Label(rect.label, ((rect.bounds[0] + rect.bounds[2])*scale/2, (rect.bounds[1] + rect.bounds[3])*scale/2), layer=idx[0], texttype=idx[1]))
|
||||||
|
labelWritten = True
|
||||||
|
|
||||||
|
lib.write_gds(path)
|
||||||
|
|
||||||
def writeLEF(path, conf, cell):
|
def writeLEF(path, conf, cell):
|
||||||
scale = conf["general"]["scale"]
|
scale = conf["general"]["scale"]
|
||||||
numMetals = conf["general"]["metals"]
|
numMetals = conf["general"]["metals"]
|
||||||
@ -205,22 +244,28 @@ def writeLEF(path, conf, cell):
|
|||||||
print("", file=fptr)
|
print("", file=fptr)
|
||||||
|
|
||||||
def print_help():
|
def print_help():
|
||||||
print("Usage: rect2lef.py [options] <input.rect> <output.lef> [output.layermap]")
|
print("Usage: rect2lef.py [options] <input.rect>")
|
||||||
print("\t-T<tech>\tidentify the technology used for this translation.")
|
print("\t-T<tech>\tidentify the technology used for this translation.")
|
||||||
|
print("\t-lm\temit the layermap")
|
||||||
|
print("\t-gds\twrite the gds.")
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
if len(sys.argv) <= 2 or sys.argv[1] == '--help' or sys.argv[1] == '-h':
|
if len(sys.argv) <= 2 or sys.argv[1] == '--help' or sys.argv[1] == '-h':
|
||||||
print_help()
|
print_help()
|
||||||
else:
|
else:
|
||||||
rectPath = None
|
rectPath = None
|
||||||
lefPath = None
|
doLM = False
|
||||||
lmPath = None
|
doGDS = False
|
||||||
techName = "sky130"
|
techName = "sky130"
|
||||||
actHome = os.environ.get('ACT_HOME', "/opt/cad")
|
actHome = os.environ.get('ACT_HOME', "/opt/cad")
|
||||||
for arg in sys.argv[1:]:
|
for arg in sys.argv[1:]:
|
||||||
if arg[0] == '-':
|
if arg[0] == '-':
|
||||||
if arg[1] == 'T':
|
if arg[1] == 'T':
|
||||||
techName = arg[2:]
|
techName = arg[2:]
|
||||||
|
elif arg == "-lm":
|
||||||
|
doLM = True
|
||||||
|
elif arg == "-gds":
|
||||||
|
doGDS = True
|
||||||
else:
|
else:
|
||||||
print(f"error: unrecognized option '{arg}'")
|
print(f"error: unrecognized option '{arg}'")
|
||||||
print("")
|
print("")
|
||||||
@ -228,14 +273,12 @@ if __name__ == "__main__":
|
|||||||
sys.exit()
|
sys.exit()
|
||||||
elif not rectPath:
|
elif not rectPath:
|
||||||
rectPath = arg
|
rectPath = arg
|
||||||
elif not lefPath:
|
|
||||||
lefPath = arg
|
|
||||||
elif not lmPath:
|
|
||||||
lmPath = arg
|
|
||||||
|
|
||||||
conf = loadActConf(actHome + "/conf/" + techName + "/layout.conf")
|
conf = loadActConf(actHome + "/conf/" + techName + "/layout.conf")
|
||||||
if rectPath and lefPath:
|
if rectPath:
|
||||||
cell = readCell(rectPath)
|
cell = readCell(rectPath)
|
||||||
writeLEF(cell.name + ".lef", conf, cell)
|
writeLEF(cell.name + ".lef", conf, cell)
|
||||||
if lmPath:
|
if doLM:
|
||||||
writeLayerMap(lmPath, conf)
|
writeLayerMap("layermap.txt", conf)
|
||||||
|
if doGDS:
|
||||||
|
writeGDS(cell.name + ".gds", conf, cell)
|
||||||
|
Loading…
Reference in New Issue
Block a user