Skip to content

Commit

Permalink
Refactor convo_parser and add DRC and LVS integration for convo gener…
Browse files Browse the repository at this point in the history
…ation
  • Loading branch information
srpathen committed Jun 28, 2024
1 parent e78c389 commit 72efa96
Show file tree
Hide file tree
Showing 4 changed files with 175 additions and 121 deletions.
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from parse_utils import parseKeyValues, parseKwarg, parseTuple, regenKeyValues, regenKwargs, regenTuple

class Command:
def __init__(self, type: str):
self.type = type
Expand Down Expand Up @@ -142,124 +144,10 @@ def __init__(self, line):
self.type = "comment"
def regenCommand(self):
return self.line


def parseKeyValues(line: str):
key = ""
value = ""
keyToken = True
keyValue = dict()
kwargStart = False
tupleStart = False
for ch in line:
if ch == "{":
kwargStart = True
elif ch == "(":
tupleStart = True
elif ch == "}":
kwargStart = False
value = parseKwarg(value)
elif ch == ")":
tupleStart = False
value = parseTuple(value)
elif ch == "=":
keyToken = False
elif (ch == " " or ch == ",") and (not kwargStart and not tupleStart):
if key != "" and value != "":
keyValue[key] = value
keyToken = True
key = ""
value = ""
else:
if keyToken:
key = key + ch
else:
value = value + ch
keyValue[key]= value
return keyValue

def parseKwarg(line: str):
trimmed = line.replace(' ','')
words = trimmed.split(",")
kwargs = dict()
for word in words:
keyVal = word.split(":")
kwargs[keyVal[0][1:-1]] = keyVal[1]
return kwargs

def parseTuple(line: str):
trimmed = line.replace(' ','')
words = trimmed.split(",")
return (words[0], words[1])

def regenKeyValues(keyValues: dict):
keyVals = ""
for key in keyValues:
if key == "kwargs":
value = regenKwargs(keyValues[key])
elif type(keyValues[key]) == tuple:
value = regenTuple(keyValues[key])
else:
value = keyValues[key]
keyVals += f"{key}={value}, "
keyVals = keyVals[:-2]
return keyVals

def regenKwargs(kwargs: dict):
kwarg = "{"
for arg in kwargs:
kwarg += f"\'{arg}\': {kwargs[arg]}, "
kwarg = kwarg[:-2]
kwarg += "}"
return kwarg

def regenTuple(tuple):
return f"({tuple[0]},{tuple[1]})"

class Convo:
def __init__(self, compName):
self.compName = compName
self.commands = []
def addCommand(self, command):
self.commands.append(command)
def changeParam(self, param, newparam):
for command in self.commands:
command.changeParamDependency(param, newparam)
def changeComp(self, comp, newcomp):
for command in self.commands:
command.changeCompDependency(comp, newcomp)
def unparametrize(self, param, value):
for index in range(len(self.commands)):
if self.commands[index].type == "create":
if self.commands[index].name == param:
del self.commands[index]
break
self.changeParam(param, value)

def regen(self):
str = self.compName + "\n"
for command in self.commands:
str += command.regenCommand() + "\n"
str = str[:-1]
return str

class ConvoParser:
def __init__(self, filename: str):
self.fileContents = open(filename).read()
self.readContents()
def readContents(self):
commClassMap = {"import":Import, "create":Param, "place":Place, "move": Move, "route":Route}
lines = self.fileContents.split('\n')
self.convo = Convo(lines[0])
for line in lines[1:]:
commandType = line.split(" ")[0]
if commandType in commClassMap:
self.convo.addCommand(commClassMap[commandType](line))
elif line[0] == "#":
self.convo.addCommand(Comment(line))

convo = ConvoParser("syntax_data/convos/CascodeCommonSourceInterdigitated.convo").convo
convo.changeComp("CascodeCommonSource", "ccs")
convo.changeParam("width", "widthCS")
convo.unparametrize("fingers", "1")
print(convo.regen())

class Newline(Command):
def __init__(self):
self.type = "newline"
def regenCommand(self):
return ""

Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
from Command import Import, Param, Place, Move, Route, Comment, Newline
from validate_synthetic_data import run_all_tests, instantiate_convo
from glayout.flow.pdk.mappedpdk import MappedPDK
import tempfile

class Convo:
def __init__(self, compName):
self.compName = compName
self.commands = []
self.parameters = dict()
self.components = dict()

def addParam(self, param, type, line):
self.parameters[param]= (type, line)

def addComp(self, comp, type, line):
self.components[comp] = (type, line)

def addCommand(self, command):
self.commands.append(command)

def changeParam(self, param, newparam):
for command in self.commands:
command.changeParamDependency(param, newparam)
old = self.parameters[param]
del self.parameters[param]
self.parameters[newparam] = old

def changeComp(self, comp, newcomp):
for command in self.commands:
command.changeCompDependency(comp, newcomp)
old = self.components[comp]
del self.components[comp]
self.parameters[newcomp] = old

def unparametrize(self, param, value):
del self.commands[self.parameters[param][1]]
self.changeParam(param, value)
del self.parameters[param]

def regen(self):
str = self.compName + "\n"
for command in self.commands:
str += command.regenCommand() + "\n"
str = str[:-2]
return str

def runDRC(self, pdk: MappedPDK):
temp = tempfile.NamedTemporaryFile()
temp.write(self.regen())
component = instantiate_convo(pdk, temp.name, return_component=True)
pdk.drc_magic(component, component.name)

def run_LVSandPEX(self, pdk, netlist):
temp = tempfile.NamedTemporaryFile()
temp.write(self.regen())
component = instantiate_convo(pdk, temp.name, return_component=True)
pdk.lvs_netgen(component, component.name, copy_intermediate_files=True, netlist=netlist)

class ConvoParser:
def __init__(self, filename: str):
self.fileContents = open(filename).read()
self.readContents()

def readContents(self):
commClassMap = {"import":Import, "create":Param, "place":Place, "move": Move, "route":Route}
lines = self.fileContents.split('\n')
self.convo = Convo(lines[0])

lineIndex = 0
for line in lines[1:]:
commandType = line.split(" ")[0]

if commandType in commClassMap:
command = commClassMap[commandType](line)
self.convo.addCommand(command)
if commandType == "create":
self.convo.addParam(command.name, command.paramType, lineIndex)
elif commandType == "place":
self.convo.addComp(command.compName, command.compType, lineIndex)

elif len(line) > 0 and line[0] == "#":
self.convo.addCommand(Comment(line))

elif line == "":
self.convo.addCommand(Newline())

lineIndex += 1
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
def parseKeyValues(line: str):
key = ""
value = ""
keyToken = True
keyValue = dict()
kwargStart = False
tupleStart = False
for ch in line:
if ch == "{":
kwargStart = True
elif ch == "(":
tupleStart = True
elif ch == "}":
kwargStart = False
value = parseKwarg(value)
elif ch == ")":
tupleStart = False
value = parseTuple(value)
elif ch == "=":
keyToken = False
elif (ch == " " or ch == ",") and (not kwargStart and not tupleStart):
if key != "" and value != "":
keyValue[key] = value
keyToken = True
key = ""
value = ""
else:
if keyToken:
key = key + ch
else:
value = value + ch
keyValue[key]= value
return keyValue

def parseKwarg(line: str):
trimmed = line.replace(' ','')
words = trimmed.split(",")
kwargs = dict()
for word in words:
keyVal = word.split(":")
kwargs[keyVal[0][1:-1]] = keyVal[1]
return kwargs

def parseTuple(line: str):
trimmed = line.replace(' ','')
words = trimmed.split(",")
return (words[0], words[1])

def regenKeyValues(keyValues: dict):
keyVals = ""
for key in keyValues:
if key == "kwargs":
value = regenKwargs(keyValues[key])
elif type(keyValues[key]) == tuple:
value = regenTuple(keyValues[key])
else:
value = keyValues[key]
keyVals += f"{key}={value}, "
keyVals = keyVals[:-2]
return keyVals

def regenKwargs(kwargs: dict):
kwarg = "{"
for arg in kwargs:
kwarg += f"\'{arg}\': {kwargs[arg]}, "
kwarg = kwarg[:-2]
kwarg += "}"
return kwarg

def regenTuple(tuple):
return f"({tuple[0]},{tuple[1]})"
7 changes: 7 additions & 0 deletions openfasoc/generators/glayout/glayout/llm/parser_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import sys,os
sys.path.append('convo_parser')

from convo_parser.convoparser import Convo, ConvoParser

convo = ConvoParser("syntax_data/convos/CurrentMirrorNtype.convo").convo
print(convo.regen())

0 comments on commit 72efa96

Please sign in to comment.