Skip to content

Commit 01f46af

Browse files
committed
Starting to get layout to work
1 parent f67a8b3 commit 01f46af

File tree

15 files changed

+299
-39
lines changed

15 files changed

+299
-39
lines changed

src/cicpy/cic.py

Lines changed: 56 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,39 @@
3232
import json
3333
import cicspi
3434
import yaml
35+
import logging
36+
37+
38+
class ColorFormatter(logging.Formatter):
39+
COLORS = {
40+
'DEBUG': '\033[36m', # Cyan
41+
'INFO': '\033[32m', # Green
42+
'WARNING': '\033[33m', # Yellow
43+
'ERROR': '\033[31m', # Red
44+
'CRITICAL': '\033[1;31m' # Bold Red
45+
}
46+
RESET = '\033[0m'
47+
48+
def format(self, record):
49+
color = self.COLORS.get(record.levelname, self.RESET)
50+
message = super().format(record)
51+
return f"{color}{message}{self.RESET}"
52+
53+
log = logging.getLogger("spi2mag")
3554

3655
@click.group()
3756
@click.pass_context
3857
def cli(ctx):
3958
""" Python toolbox for Custom Integrated Circuit Creator (ciccreator). """
4059
ctx.ensure_object(dict)
60+
handler = logging.StreamHandler()
61+
formatter = ColorFormatter('%(levelname)s: %(message)s')
62+
handler.setFormatter(formatter)
63+
64+
logger = logging.getLogger()
65+
logger.addHandler(handler)
66+
logger.setLevel(logging.DEBUG)
67+
4168
pass
4269

4370
@cli.command("transpile")
@@ -251,17 +278,23 @@ def _runMethod(lcell,module,method):
251278
if(module is not None):
252279
if(hasattr(module,method)):
253280
fn = getattr(module,method)
281+
log.info("Running " + method + " from " + lcell.name + ".py")
254282
fn(lcell)
255283

256284

257285
def _spi2mag(spi,lib,cell,libdir,techlib,xspace,yspace,gbreak):
258286

287+
288+
259289
techfile = f"../tech/cic/{techlib}.tech"
260-
print(f"INFO: Loading rules {techfile}")
290+
log.info(f"Loading rules {techfile}")
261291
rules = cic.Rules(techfile)
262292

293+
log.info(f"Finding Magic cells in {libdir}")
263294
design = cic.MagicDesign(techlib,rules)
264295
design.scanLibraryPath(libdir)
296+
297+
log.info(f"Reading {spi}")
265298
lcell = design.readFromSpice(spi,cell)
266299

267300
if("," in gbreak):
@@ -288,25 +321,41 @@ def _spi2mag(spi,lib,cell,libdir,techlib,xspace,yspace,gbreak):
288321
pycell = importlib.import_module(lcell.name)
289322
dir(pycell)
290323

291-
324+
log.info(f"Assembling layout....")
292325

293326
_runMethod(lcell,pycell,"beforePlace")
327+
328+
294329
#- Place cell
330+
log.info(f"place()")
295331
lcell.place()
296332

297333
_runMethod(lcell,pycell,"afterPlace")
298334

335+
_runMethod(lcell,pycell,"beforeRoute")
336+
337+
log.info(f"route()")
338+
lcell.route()
339+
340+
_runMethod(lcell,pycell,"afterRoute")
299341

342+
_runMethod(lcell,pycell,"beforePaint")
300343

344+
log.info(f"paint()")
345+
346+
_runMethod(lcell,pycell,"afterPaint")
347+
348+
log.info(f"addAllPorts()")
349+
lcell.addAllPorts()
301350

302351
obj = cic.MagicPrinter(libdir + lib,rules)
303352
obj.print(design)
304-
obj = design.toJson()
305-
with open(libdir + lib + os.path.sep + lcell.name + ".cic","w") as fo:
306-
fo.write(json.dumps(obj,indent=4))
353+
#for m in design.maglib.values():
354+
#if(m._lay is not None):
307355

308-
#obj = cic.MagicPrinter(libdir + lib,cell)
309-
#obj.print(design)
356+
with open(libdir + lib + os.path.sep + lcell.name + ".cic","w") as fo:
357+
fo.write(json.dumps(design.toJson(),indent=4))
358+
#fo.write(json.dumps(design.maglib["JNWTR_RPPO2"]._lay.toJson(),indent=4))
310359

311360

312361

src/cicpy/core/cell.py

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ def __init__ (self,name=""):
4040
super().__init__()
4141
self.subckt = None
4242
self.name = name
43+
self.allports = dict()
44+
self.allPortNames = list()
4345
self.ignoreBoundaryRouting = False
4446
self.physicalOnly = False
4547
self.abstract = False
@@ -61,9 +63,10 @@ def __init__ (self,name=""):
6163

6264
def getPort(self,name:str):
6365
p = None
66+
6467
if(name in self.ports):
6568
p = self.ports[name]
66-
return
69+
return p
6770

6871
# Find the first rectangle in this cell that uses layer
6972
def getRect(self,layer):
@@ -75,8 +78,10 @@ def add(self, child):
7578
if(child == None):
7679
raise Exception("Null rectangle added")
7780

78-
if(child.isPort()):
81+
if(child.isPort() or child.isInstancePort()):
7982
self.ports[child.name] = child
83+
self.allPortNames.append(child.name)
84+
8085

8186
if(not child in self.children):
8287
if(child.isRoute()):
@@ -123,7 +128,7 @@ def moveTo(self,ax, ay):
123128
super().moveTo(ax,ay)
124129
for child in self.children:
125130
child.translate(ax - x1, ay - y1)
126-
self.updateBoundingRect
131+
self.updateBoundingRect()
127132
self.emit_updated()
128133

129134

@@ -301,6 +306,29 @@ def startswith(self,ss):
301306
return True
302307
return False
303308

309+
def isASpicePort(self,name:str):
310+
if(self.subckt is None):
311+
return True
312+
if(name in self.subckt.nodes):
313+
return True
314+
else:
315+
return False
316+
317+
def updatePort(self,name:str,r:Rect):
318+
p = None
319+
if(name in self.ports):
320+
p = self.ports[name]
321+
p.spicePort = self.isASpicePort(name)
322+
p.setRect(r)
323+
else:
324+
if(self.subckt):
325+
if(name in self.subckt.nodes):
326+
p = Port(name)
327+
p.spicePort = self.isASpicePort(name)
328+
p.setRect(r)
329+
self.add(p)
330+
return p
331+
304332
# Port * getPort(QString name);
305333
# Port * getCellPort(QString name);
306334

src/cicpy/core/design.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,15 @@
3535
import gzip
3636
import json
3737
import re
38+
import logging
3839

3940
class Design():
4041

4142
def __init__(self):
4243
self.cells = dict()
4344
self.cellnames = list()
4445
self.jcells = dict()
46+
self.log = logging.getLogger("DesignPrinter")
4547
self.prefix = ""
4648

4749

@@ -102,7 +104,7 @@ def read(self,filename):
102104
with open(filename)as fi:
103105

104106
for line in fi:
105-
if(re.search("^\s*//",line)):
107+
if(re.search(r"^\s*//",line)):
106108
continue
107109
buffer += line
108110

src/cicpy/core/graph.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#!/usr/bin/env python3
2+
import re
3+
class Graph():
4+
5+
def __init__(self):
6+
self.ports = list()
7+
self.name = ""
8+
9+
def append(p:Port):
10+
if(not self.ports.contains(p)):
11+
self.ports.append(p)
12+
13+
def getRectangles(excludeInstances:str,includeInstances:str,layer:str):
14+
rects = list()
15+
for p in self.ports:
16+
i = p.parent()
17+
if(i is None):continue
18+
if(not i.isInstance()): continue
19+
20+
if(excludeInstances is not None):
21+
if( re.search(excludeInstances,i.instanceName) \
22+
or re.search(excludeInstances,i.name)): continue
23+
24+
if(includeInstances is not None):
25+
if(not ( re.search(includeInstances,i.instanceName) \
26+
or re.search(includeInstances,i.name))): continue
27+
rp = p.get(layer)
28+
29+
if(rp is None): rp = p.get()
30+
if(rp is not None):
31+
rects.append(rp)

src/cicpy/core/instance.py

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,10 @@
2727

2828
from .point import Point
2929
from .cell import Cell
30+
from .instanceport import InstancePort
3031
import cicspi as spi
3132
import logging
33+
import re
3234

3335
class Instance(Cell):
3436

@@ -37,6 +39,8 @@ def __init__(self):
3739
self.instanceName = ""
3840
self.cell = ""
3941
self.layoutcell = None
42+
self.instancePorts = dict()
43+
self.instancePortsList = list()
4044
self.libpath = ""
4145
self.angle = ""
4246
self.xcell = 0
@@ -108,7 +112,20 @@ def isLayoutCell(self):
108112
return c.isLayoutCell()
109113
return False
110114

111-
115+
def findRectanglesByNode(self,node:str,filterChild:str):
116+
rects = list()
117+
for pi in self.children:
118+
if(pi is None): continue
119+
if(not pi.isInstancePort()): continue
120+
121+
if(re.search(pi.name,node) and ((filterChild is None) or not re.search(pi.childName,filterChild))):
122+
r = pi.get()
123+
if(r is not None):
124+
r.parent = self
125+
rects.append(r)
126+
return rects
127+
128+
112129

113130
def getCellPoint(self):
114131
p = Point(self.x1 + self.xcell, self.y1 + self.ycell)
@@ -119,8 +136,7 @@ def calcBoundingRect(self):
119136
if(self.layoutcell is None):
120137
return self
121138

122-
r = self.layoutcell
123-
#print(r)
139+
r = self.layoutcell.getCopy()
124140
r.moveTo(self.x1,self.y1)
125141
return r
126142

src/cicpy/core/instanceport.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ def __init__(self,name,port:Port,parent:Cell):
1010
super().__init__(name)
1111
self.childport = port
1212
self.parent = parent
13-
r = p.get()
14-
rules = Rules()
13+
r = port.get()
14+
rules = Rules.getInstance()
1515
if(r):
1616
l = rules.getLayer(r.layer)
17-
self.routeLayer = l
18-
self.setRect(r.layer,r.x1,r.y1,r.width,r.height)
17+
self.routeLayer = l.name
18+
self.setRect(r)

0 commit comments

Comments
 (0)