Commit f81b3b98 by sakundu

Added Blockage option in protobuf netlist and RePlAce Flow

Signed-off-by: sakundu <sakundu@ucsd.edu>
parent c94d0e7f
import odb
import os
import datetime
import math
from math import gcd
class BookshelfToOdb:
def __init__(
self,
opendbpy,
opendb,
cellPadding,
modeFormat,
plFile,
nodeMapFile,
netMapFile):
self.odbpy = opendbpy
self.odb = opendb
self.year = datetime.datetime.now().year
self.month = datetime.datetime.now().strftime("%b")
self.day = datetime.datetime.now().day
self.user = 'Seungwon Kim at University of California, San Diego (sek006@ucsd.edu)'
self.modeFormat = modeFormat
self.plFile = plFile
self.nodeMapFile = nodeMapFile
self.netMapFile = netMapFile
self.chip = self.odb.getChip()
self.block = self.chip.getBlock()
self.siteWidth = self.block.getRows()[0].getSite().getWidth()
self.siteHeight = self.block.getRows()[0].getSite().getHeight()
print("siteWidth: %s" % self.siteWidth)
print("siteHeight: %s" % self.siteHeight)
print("GCD: %s" % gcd(self.siteWidth, self.siteHeight))
#self.scaleFactor = self.targetScale / self.siteHeight
self.scaleFactor = 1 / gcd(self.siteWidth, self.siteHeight)
self.targetScale = self.scaleFactor * self.siteHeight
print("Target siteHeight Scale: %s" % self.targetScale)
print(
"Scale Factor (Target siteHeight Scale / siteHeight): %s" %
self.scaleFactor)
def UpdatePl(self, dictNode):
with open(self.plFile, 'r') as inFile:
for line in inFile:
if len(line) < 3:
continue
if line.strip().startswith("UCLA"):
continue
if line.strip().startswith("#"):
continue
elif ':' not in line:
continue
elif self.modeFormat == 'ISPD11' and line.split()[-1] == '/FIXED':
# Fixed insts.
# It has defined in the original ODB, so don't need to
# update.
continue
elif (self.modeFormat == 'ISPD11' and line.split()[-1] == '/FIXED_NI') or (self.modeFormat != 'ISPD11' and line.split()[-1] == '/FIXED'):
# Fixed insts + boundary terminals
instMappedName = line.split()[0]
instLlx = float(line.split()[1])
instLly = float(line.split()[2])
instOrigName = dictNode[instMappedName]
#print(instOrigName, instMappedName)
# print(self.block.findBTerm(instOrigName))
bTerm = self.block.findBTerm(instOrigName)
if bTerm is not None:
bPins = bTerm.getBPins()
for bPin in bPins:
boxes = bPin.getBoxes()
# TODO: do not support multiple boxes
assert(len(boxes) == 1)
for box in boxes:
bTermWidth = int(box.xMax() - box.xMin())
bTermHeight = int(box.yMax() - box.yMin())
#print(bTermWidth, bTermHeight)
layerBPin = box.getTechLayer()
bPin.destroy(bPin)
bPin.create(bTerm)
bPinLlx = int(instLlx / self.scaleFactor)
bPinLly = int(instLly / self.scaleFactor)
bPinUrx = int(
instLlx / self.scaleFactor) + int(bTermWidth)
bPinUry = int(
instLly / self.scaleFactor) + int(bTermHeight)
box.create(
bPin, layerBPin, bPinLlx, bPinLly, bPinUrx, bPinUry)
# print(bPinLlx,bPinLly,bPinUrx,bPinUry)
bPin.setPlacementStatus('PLACED')
# TODO: Snapping to on-track?
continue
else:
instMappedName = line.split()[0]
instLlx = float(line.split()[1])
instLly = float(line.split()[2])
instOrigName = dictNode[instMappedName]
#print(instOrigName, instMappedName)
# print(self.block.findInst(instOrigName))
instOrig = self.block.findInst(instOrigName)
instOrigWidth = instOrig.getMaster().getWidth()
instOrigHeight = instOrig.getMaster().getHeight()
instOrigLlx = int(instLlx / self.scaleFactor)
instOrigLly = int(instLly / self.scaleFactor)
instOrig.setLocation(instOrigLlx, instOrigLly)
instOrig.setPlacementStatus('PLACED')
# TODO: Snapping to on-track?
def DecodeMap(self):
dictNode = dict()
with open(self.nodeMapFile, 'r') as inFile:
for line in inFile:
origName = line.split()[0]
mappedName = line.split()[1]
dictNode[mappedName] = origName
return dictNode
def UpdateOdb(self):
dictNode = self.DecodeMap()
self.UpdatePl(dictNode)
os.path.exists
dbName = './output/%s_pad%s_%s/%s_pad%s_%s_mapped.odb' % (
odbName, cellPadding, modeFormat, odbName, cellPadding, modeFormat)
defName = './output/%s_pad%s_%s/%s_mapped.def' % (
odbName, cellPadding, modeFormat, odbName)
if os.path.exists(dbName):
os.remove(dbName)
if os.path.exists(defName):
os.remove(defName)
odb.write_db(
self.odb,
'./%s_pad%s_%s/%s_pad%s_%s_mapped.odb' %
(odbName,
cellPadding,
modeFormat,
odbName,
cellPadding,
modeFormat))
odb.write_def(
self.block,
'./%s_pad%s_%s/%s_mapped.def' %
(odbName,
cellPadding,
modeFormat,
odbName))
if __name__ == "__main__":
################ Settings #################
odbPath = './odbFiles'
# The number of sites for cell padding (+left, +right)
cellPaddings = [0, 1, 2, 3, 4]
# Format list of Bookshelf to be created.
modeFormats = ['ISPD04', 'ISPD11']
# OpenDB list for Bookshelf generation
odbList = [
'sky130hd_ISPD2006_adaptec1',
]
###########################################
for modeFormat in modeFormats:
for cellPadding in cellPaddings:
for odbName in odbList:
plFile = './output/%s_pad%s_%s/%s_pad%s_%s_mapped.ntup.pl' % (
odbName, cellPadding, modeFormat, odbName, cellPadding, modeFormat)
nodeMapFile = './output/%s_pad%s_%s/%s_pad%s_%s_mapped.nodemap' % (
odbName, cellPadding, modeFormat, odbName, cellPadding, modeFormat)
netMapFile = './output/%s_pad%s_%s/%s_pad%s_%s_mapped.netmap' % (
odbName, cellPadding, modeFormat, odbName, cellPadding, modeFormat)
db = odb.dbDatabase.create()
print(odb)
odb.read_db(db, '%s/%s.odb' % (odbPath, odbName))
bs = BookshelfToOdb(
opendbpy=odb,
opendb=db,
cellPadding=cellPadding,
modeFormat=modeFormat,
plFile=plFile,
nodeMapFile=nodeMapFile,
netMapFile=netMapFile)
bs.UpdateOdb()
#import opendbpy as odb
import odb
import os
import datetime
import math
import namemap
from math import gcd
# import namemap
class OdbToBookshelf:
......@@ -126,7 +125,7 @@ class OdbToBookshelf:
def WriteNodes(self, bsName):
print("Writing .nodes")
f = open('./output/%s/%s.nodes' % (bsName, bsName), 'w')
f.write('UCSD nodes 1.0\n')
f.write('UCLA nodes 1.0\n')
f.write(
'# Created : %s %s %s\n' %
(self.month, self.day, self.year))
......@@ -214,7 +213,7 @@ class OdbToBookshelf:
def WriteRoute(self, bsName):
print("Writing .route")
f = open('./output/%s/%s.route' % (bsName, bsName), 'w')
f.write('UCSD route 1.0\n')
f.write('UCLA route 1.0\n')
f.write(
'# Created : %s %s %s\n' %
(self.month, self.day, self.year))
......@@ -435,7 +434,7 @@ class OdbToBookshelf:
def WriteWts(self, bsName):
print("Writing .wts")
f = open('./output/%s/%s.wts' % (bsName, bsName), 'w')
f.write('UCSD wts 1.0\n')
f.write('UCLA wts 1.0\n')
f.write(
'# Created : %s %s %s\n' %
(self.month, self.day, self.year))
......@@ -445,7 +444,7 @@ class OdbToBookshelf:
def WriteNets(self, bsName):
print("Writing .nets")
f = open('./output/%s/%s.nets' % (bsName, bsName), 'w')
f.write('UCSD nets 1.0\n')
f.write('UCLA nets 1.0\n')
f.write(
'# Created : %s %s %s\n' %
(self.month, self.day, self.year))
......@@ -531,29 +530,15 @@ class OdbToBookshelf:
#
# "getGeomShape().getPoints()" --> a, b, c, d, a
#
#tx = 0
#ty = 0
# t = odb.dbTransform(instOrient, instOrig)
# Calculate center of pin
# for pp in box.getGeomShape().getPoints()[:-1]:
# t.apply(pp)
# tx = tx + float(pp.getX())
# ty = ty + float(pp.getY())
# #print("tx, ty = %s %s"%(pp.getX()/1000,pp.getY()/1000))
# tt = tt + 1
rr = odb.Rect(box.xMin(), box.yMin(), box.xMax(), box.yMax())
# Calculate center of pin
for pp in rr.getPoints():
t.apply(pp)
# print('Hi ',type(pp), type(box))
# print('Here ', box.xMin(), box.yMin(), box.xMax(), box.yMax())
#
# print(pp)
# # box.getBox(pp)
# print(type(pp))
# t.apply(pp)
tt += 1
tx += pp.getX()
ty += pp.getY()
tx += float(pp.getX())
ty += float(pp.getY())
iPinXCen = float(tx) / float(tt)
iPinYCen = float(ty) / float(tt)
......@@ -575,7 +560,7 @@ class OdbToBookshelf:
def WritePl(self, bsName):
print("Writing .pl")
f = open('./output/%s/%s.pl' % (bsName, bsName), 'w')
f.write('UCSD pl 1.0\n')
f.write('UCLA pl 1.0\n')
f.write(
'# Created : %s %s %s\n' %
(self.month, self.day, self.year))
......@@ -637,7 +622,7 @@ class OdbToBookshelf:
def WriteScl(self, bsName):
print("Writing .scl")
f = open('./output/%s/%s.scl' % (bsName, bsName), 'w')
f.write('UCSD scl 1.0\n')
f.write('UCLA scl 1.0\n')
f.write(
'# Created : %s %s %s\n' %
(self.month, self.day, self.year))
......@@ -731,7 +716,7 @@ class OdbToBookshelf:
def WriteShapes(self, bsName):
print("Writing .shapes")
f = open('./output/%s/%s.shapes' % (bsName, bsName), 'w')
f.write('UCSD shapes 1.0\n')
f.write('UCLA shapes 1.0\n')
f.write(
'# Created : %s %s %s\n' %
(self.month, self.day, self.year))
......@@ -808,11 +793,11 @@ class OdbToBookshelf:
self.show(bsName)
# convert for mapping
# self.convert(bsName)
self.convert(bsName)
def convert(self, bsName):
os.chdir('output/%s' % bsName)
# namemap.main('%s.aux' % bsName)
namemap.main('%s.aux' % bsName)
os.chdir('../../')
def show(self, bsName):
......
'''
This script generates OpenDB database from LEF/DEF
'''
import odb
import sys
import os
import re
design = sys.argv[1]
def_file = sys.argv[2]
output_dir = sys.argv[3]
work_dir = re.search(r'(/\S+/MacroPlacement)', os.getcwd()).group(1)
sys.path.append(f'{work_dir}/Flows/util')
from convert_odb2bookshelf import OdbToBookshelf
lef_dir = f'{work_dir}/Enablements/NanGate45/lef'
lef_list = [f'{lef_dir}/NangateOpenCellLibrary.tech.lef',
f'{lef_dir}/NangateOpenCellLibrary.macro.mod.lef',
f'{lef_dir}/fakeram45_256x16.lef']
db = odb.dbDatabase.create()
for lef_file in lef_list:
odb.read_lef(db, lef_file)
odb.read_def(db, def_file)
chip = db.getChip()
tech = db.getTech()
libs = db.getLibs()
if chip is None:
exit("ERROR: READ DEF Failed")
if not os.path.exists(f'{output_dir}/RePlAce'):
os.makedirs(f'{output_dir}/RePlAce')
odb_file = f'{output_dir}/RePlAce/{design}.odb'
export_result = odb.write_db(db, odb_file)
if export_result != 1:
exit("ERROR: Export failed")
new_db = odb.dbDatabase.create()
odb.read_db(new_db, odb_file)
if new_db is None:
exit("ERROR: Import failed")
if odb.db_diff(db, new_db):
exit("ERROR: Difference found in exported and imported DB")
print(f"Successfully generated ODB format from LEF/DEF for {design}")
bs = OdbToBookshelf(
opendbpy=odb,
opendb=db,
cellPadding=0,
modeFormat="ISPD11",
layerCapacity='layeradjust_empty.tcl')
bs.WriteBookshelf(f'{design}_pad0_ISPD11')
rm -rf output/ ETC/ outputs/
# run ODB to Bookshelf
#./openroad -python odb2bs.py
./openroad -python lefdef_to_odb.py ariane ../../ariane_replace.def ./
# prepare input dir structure for RePlAce
mkdir -p ETC/
ln -s $(readlink -f ./output/*) ./ETC/
# run RePlAce. If you want to change density, please put -den 0.8 (80%), etc.
./RePlAce-static -bmflag etc -bmname ariane_pad0_ISPD11 -pcofmax 1.03 |& tee replace_result.log
# bring the results
#ln -s outputs/ETC/ariane_pad0_ISPD11/experiment0/*.pl ./
# you can run invs to load *.pl results from here
'''
This script generates bookshelf format from odb format
'''
import os
import odb
import sys
import re
work_dir = re.search(r'(/\S+/MacroPlacement)', os.getcwd()).group(1)
sys.path.append(f'{work_dir}/Flows/util')
from convert_odb2bookshelf import OdbToBookshelf
design = sys.argv[1]
odb_file = sys.argv[2]
output_dir = sys.argv[3]
modeFormat = 'ISPD11'
cellPadding = 0
layerCapacity = 'layeradjust_empty.tcl'
def touch(fname, times=None):
with open(fname, 'a'):
os.utime(fname, times)
if not os.path.exists(layerCapacity):
touch(layerCapacity)
db = odb.dbDatabase.create()
odb.read_db(db, odb_file)
bs = OdbToBookshelf(opendbpy=odb, opendb=db, cellPadding=cellPadding,
modeFormat=modeFormat, layerCapacity=layerCapacity)
if not os.path.exists(f'{output_dir}/RePlAce'):
os.makedirs(f'{output_dir}/RePlAce')
bs.WriteBookshelf(f'{design}.bookshelf')
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment