import Cfg
from Hurricane import Box
from Hurricane import Transformation
+from Hurricane import Breakpoint
+from Hurricane import Instance
from coriolis2.settings import af
from utils import Module, SessionManager, Config
+import Etesian
+import helpers
+from helpers.overlay import UpdateSession
import symbolic.cmos # do not remove
BIT_WIDTH = 16
-
+widths = {32: 600.0, 16: 490}
def coriolis_setup():
with Config(Cfg.Parameter.Priority.UserFile) as cfg:
cfg.misc_verboseLevel1 = True
cfg.misc_verboseLevel2 = True
cfg.etesian_effort = 2
- cfg.etesian_spaceMargin = "20.0%"
+ cfg.etesian_spaceMargin = "10.0%"
cfg.etesian_aspectRatio = "100.0%"
cfg.etesian_uniformDensity = True
cfg.anabatic_edgeLenght = 24
""" Main routine. """
with SessionManager():
- self.compute_ab()
+ #self.compute_ab()
self.create_pins()
if self.editor:
class ALU16(Module):
+ def place_datapath(self, datapath_insts, x_orig, y_orig, fold):
+ channel_sff1 = self.to_dbu(0)
+ with SessionManager():
+ slice_height = self.to_dbu(50.0)
+ for i in range(len(datapath_insts)):
+ if not i%fold:
+ x = self.to_dbu(x_orig)
+ slice = i/fold
+ if slice%2:
+ y = self.to_dbu(y_orig) + slice_height*(slice+1)
+ orient = Transformation.Orientation.MY
+ else:
+ y = self.to_dbu(y_orig) + slice_height*slice
+ orient = Transformation.Orientation.ID
+
+ for (opname, inst) in datapath_insts[i]:
+ if opname == 'sff1':
+ x += channel_sff1
+ inst.setTransformation(Transformation(x, y, orient))
+ inst.setPlacementStatus(Instance.PlacementStatus.PLACED)
+ x += inst.getAbutmentBox().getWidth()
+
+ def place(self):
+ """ALU16.place(), manual placement overload."""
+ datapath_insts = []
+ add, sub = self.submodules
+ #print (sub.ab, dir(list(sub.cell.getInstances())[0]))
+ #print (list(sub.cell.getInstances())[0].getAbutmentBox())
+ subx = widths[BIT_WIDTH] - 40 #self.from_dbu(sub.ab.getXMax())
+ addx = self.from_dbu(add.ab.getWidth()) + 5
+
+ for i in range(BIT_WIDTH):
+ dp = [['nmx2', None],
+ ['no2', None],
+ ['sff1', None]]
+
+ # XXX here is the computed abutment box which we want to
+ # place the auto-located cells into, using *auto* place
+ # *not* manual place.
+ y = 40.0 + i * 50
+ y1 = y + 50
+ ab = Box(self.to_dbu(addx), self.to_dbu(y),
+ self.to_dbu(subx), self.to_dbu(y1))
+ print ("ab", addx, subx, ab, self.from_dbu(ab.getWidth()),
+ self.from_dbu(ab.getHeight()))
+
+ # automatically locate all non-placed cells connected to
+ # o(0)....o(15)
+ find = self.get_net_connections(['o(%d)' % i],
+ ['clk', 'rst', 'op'])
+ for inst in find:
+ print (inst, inst.getName(), dir(inst))
+ print ("place", ab, inst, dir(inst))
+ for column in dp:
+ if inst.getName().find(column[0]) != -1:
+ column[1] = inst
+ # XXX TODO: want to auto-place the instances
+ #with SessionManager():
+ #cell.setAbutmentBox(ab)
+ #etesian = Etesian.EtesianEngine.create(cell)
+ #etesian.place()
+ datapath_insts.append(dp)
+
+ # place to right of add
+ add, sub = self.submodules
+ add_wid = self.from_dbu(add.ab.getWidth())
+ self.place_datapath(datapath_insts, add_wid, 40.0, 1)
+
+ def _old_place(self):
+ """ALU16.place(), manual placement overload."""
+ datapath_insts = []
+ for i in range(BIT_WIDTH):
+ datapath_insts.append([['nmx2', None],
+ ['no2', None],
+ ['sff1', None]])
+
+ for inst in self.cell.getInstances():
+ if (Module.match_instance(datapath_insts, 'nmx2', 'i0', inst) or
+ Module.match_instance(datapath_insts, 'no2', 'nq', inst) or
+ Module.match_instance(datapath_insts, 'sff1', 'i', inst)):
+ continue
+
+ # place to right of add
+ add, sub = self.submodules
+ add_wid = self.from_dbu(add.ab.getWidth())
+ self.place_datapath(datapath_insts, add_wid, 40.0, 1)
+
def save(self):
self.name = self.name + '_r'
self.af.saveCell(self.cell, CRL.Catalog.State.Views)
def build(self):
- h_margin = 25.0
- v_margin = 75.0
+ h_margin = 0.0
+ v_margin = 40.0
if not self.build_submodules():
return False
) + 4*h_margin
height = self.from_dbu(max([
self.ab.getHeight(), add.ab.getHeight(), sub.ab.getHeight()
- ])) + 2*v_margin
+ ])) + v_margin
+
+ # experiment, over-ride
+ width = widths[BIT_WIDTH]
+ #width = 1310
+ #height = 370
+
self.ab = Box(0, 0, self.to_dbu(width), self.to_dbu(height))
- self.place_submodule(add, h_margin, v_margin)
- self.place_submodule(sub, width-sub.ab_width-h_margin, v_margin)
+ add_wid = self.from_dbu(add.ab.getWidth())
+ sub_ht = self.from_dbu(sub.ab.getHeight())
+ sub_wid = self.from_dbu(sub.ab.getWidth())
+
+ self.place_submodule(add, 0, v_margin)
+ self.place_submodule(sub, width-sub_wid, v_margin)
# TODO: replace with some form of lazy evaluation?
y_north = self.from_dbu(self.ab.getYMax())
self.create_pins()
+ if False:
+ find = self.get_net_connections(['o(15)'],
+ ['clk', 'rst', 'op'])
+ print (find)
+ sys.exit(0)
+ find = self.get_net_connections(['o_next(0)'],
+ ['clk', 'vss', 'vdd', 'rst'])
+ print (find)
+
if self.editor:
self.editor.setCell(self.cell)
# this puts all the remaining cells (little ones)
# into this (small) space so that they do not go
# "all over the place" around the add and sub
- self.ab = Box(
- self.to_dbu((width-self.ab_width)/2 - h_margin),
- self.to_dbu(v_margin),
- self.to_dbu((width+self.ab_width)/2 + h_margin),
- self.to_dbu(height - v_margin)
- )
- self.place()
+
+ # XXX this doesn't work: box is far too big, covers the entire
+ # area (including "under" the add and sub)
+ #self.ab = Box(
+ # self.to_dbu((width-self.ab_width)/2 - h_margin),
+ # self.to_dbu(v_margin),
+ # self.to_dbu((width+self.ab_width)/2 + h_margin),
+ # self.to_dbu(height - v_margin)
+ #)
+ #self.ab = Box(self.to_dbu(475), self.to_dbu(10),
+ # self.to_dbu(840), self.to_dbu(360))
+ self.ab = Box(0, 0, self.to_dbu(width), self.to_dbu(height))
+ self.place() # place only
# then route (globally)
# this connects up not just in the remaining (little) cells,
# it connects *to add and sub and the outside world as well*
- self.ab = Box(0, 0, self.to_dbu(width), self.to_dbu(height))
- result = self.place_and_route()
+ result = self.route()
self.save()
return result
-def ScriptMain(editor=None, **kwargs):
+def scriptMain(editor=None, **kwargs):
coriolis_setup()
add = AddSub(
'add', editor,
- north_pins=[
- {'net': 'a({})', 'x': 10.0, 'delta': 10.0, 'repeat': BIT_WIDTH},
- {'net': 'b({})', 'x': 15.0, 'delta': 10.0, 'repeat': BIT_WIDTH},
- {'net': 'o({})', 'x': 180.0, 'delta': 10.0, 'repeat': BIT_WIDTH},
- ],
- south_pins=[
+ east_pins=[
+ {'net': 'a({})', 'y': 15.0, 'delta': 50.0,
+ 'repeat': BIT_WIDTH, 'layer': 'METAL2'},
+ {'net': 'b({})', 'y': 20.0, 'delta': 50.0,
+ 'repeat': BIT_WIDTH, 'layer': 'METAL2'},
+ {'net': 'o({})', 'y': 25.0, 'delta': 50.0,
+ 'repeat': BIT_WIDTH, 'layer': 'METAL2'},
],
pads={
'b({})'.format(BIT_WIDTH-1): (
},
orientation=Transformation.Orientation.ID,
)
+ add.set_ab(160.0, 50.0 * BIT_WIDTH)
sub = AddSub(
'sub', editor,
- north_pins=[
- {'net': 'a({})', 'x': 180.0, 'delta': 10.0, 'repeat': BIT_WIDTH},
- {'net': 'b({})', 'x': 185.0, 'delta': 10.0, 'repeat': BIT_WIDTH},
- {'net': 'o({})', 'x': 10.0, 'delta': 10.0, 'repeat': BIT_WIDTH},
- ],
- south_pins=[
+ west_pins=[
+ {'net': 'a({})', 'y': 15.0, 'delta': 50.0,
+ 'repeat': BIT_WIDTH, 'layer': 'METAL2'},
+ {'net': 'b({})', 'y': 20.0, 'delta': 50.0,
+ 'repeat': BIT_WIDTH, 'layer': 'METAL2'},
+ {'net': 'o({})', 'y': 25.0, 'delta': 50.0,
+ 'repeat': BIT_WIDTH, 'layer': 'METAL2'},
],
pads={
'b({})'.format(BIT_WIDTH-1): (
'BLOCKAGE2', 'BLOCKAGE3', 'BLOCKAGE4',
),
},
- orientation=Transformation.Orientation.XR,
+ orientation=Transformation.Orientation.ID,
)
+ sub.set_ab(165.0, 50.0 * BIT_WIDTH)
+ o = 00.0
alu16 = ALU16(
'alu16', editor, submodules=[add, sub],
north_pins=[
- {'net': 'o({})', 'x': 50.0, 'delta': 60.0, 'repeat': BIT_WIDTH},
+ {'net': 'o({})', 'x': 245.0+o, 'delta': 5.0, 'repeat': BIT_WIDTH},
{'net': 'op'},
],
south_pins=[
- {'net': 'a({})', 'x': 50.0, 'delta': 60.0, 'repeat': BIT_WIDTH},
- {'net': 'b({})', 'x': 80.0, 'delta': 60.0, 'repeat': BIT_WIDTH},
+ {'net': 'a({})', 'x': 195.0+o, 'delta': 10.0, 'repeat': BIT_WIDTH},
+ {'net': 'b({})', 'x': 200.0+o, 'delta': 10.0, 'repeat': BIT_WIDTH},
],
- west_pins=[
- {'net': 'rst', 'y': 140.0, 'layer': 'METAL2'},
+ east_pins=[
+ {'net': 'rst', 'y': 10.0, 'layer': 'METAL2'},
],
)
return alu16.build()
if __name__ == '__main__':
kwargs = {}
- success = ScriptMain(**kwargs)
+ success = scriptMain(**kwargs)
shellSuccess = 0
if not success:
shellSuccess = 1