def test_grid_hier(): b0 = CellLeaf( "block0", Rect(0,0,4,2)) b1 = CellLeaf( "block1", Rect(0,0,2,4)) m = 4 g = CellHier( "grid") for i in range(m): inst_name = 'u%d' % i g.instances[inst_name] = CellInstance( inst_name, b0) for i in range(m): inst_name = 'v%d' % i g.instances[inst_name] = CellInstance( inst_name, b1) nx = 9 ny = 9 s = tally.Tally() r = Raster( s, g, nx, ny) r.semantic() r.solve() g.updateBbox() with open( "mydesign_dr_globalrouting.json", "wt") as fp: tech = Tech() g.write_globalrouting_json( fp, tech)
def sat_subgraph_isomorphism(g, h): # h is a subgraph g # each vertex in h maps to some vertex in g # set up two dimensional array s = tally.Tally() mgr = tally.VarMgr(s) lst = [] for n in g.nodes: lst.append(mgr.add_var(tally.BitVec(s, str(n), len(h.nodes)))) s.emit_at_most_one(lst[-1].vars) for (idx, n) in enumerate(h.nodes): l = [] for bv in lst: l.append(bv.vars[idx]) s.emit_exactly_one(l) isMapped = [] for bv in lst: isMapped.append(s.add_var()) s.emit_or(bv.vars, isMapped[-1]) for eg in g.edges: lits = [] lits.append(-isMapped[eg[0]]) lits.append(-isMapped[eg[1]]) for eh in h.edges: lits.append(s.add_var()) s.emit_and([lst[eg[0]].vars[eh[0]], lst[eg[1]].vars[eh[1]]], lits[-1]) lits.append(s.add_var()) s.emit_and([lst[eg[1]].vars[eh[0]], lst[eg[0]].vars[eh[1]]], lits[-1]) s.add_clause(lits) s.solve() if s.state == 'SAT': for bv in lst: print(bv.val()) res_tbl = [] for (idx, n) in enumerate(h.nodes): res = None for (jdx, bv) in enumerate(lst): if bv.val(idx): res = jdx assert res is not None res_tbl.append(res) print(res_tbl) assert check_subgraph_isomorphism(g, h, res_tbl) return s.state == 'SAT'
def semantic( self, max_capacity=1, different_net_max_capacity=None): self.s = tally.Tally() self.per_net_grid = OrderedDict() for k in list(self.nets.keys()) + ['!kor']: self.per_net_grid[k] = OrderedDict() for ly in self.layers: self.per_net_grid[k][ly] = tally.BitVec( self.s, k + '_' + ly, self.nx * self.ny) self.genMaxCapacityConstraints( max_capacity=max_capacity) if different_net_max_capacity is not None: self.genDifferentNetMaxCapacityConstraints( different_net_max_capacity) self.genRoutes()
def test_non_unit_pins(): b0 = CellLeaf( "block0", Rect(0,0,4,2)) b0.addTerminal( "l", Rect(0,0,0,2)) b0.addTerminal( "r", Rect(4,0,4,2)) m = 2 g = CellHier( "grid") for i in range(m): inst_name = 'u%d' % i g.instances[inst_name] = CellInstance( inst_name, b0) g.instances['u0'].fa_map['l'] = 'a' g.instances['u0'].fa_map['r'] = 'b' g.instances['u1'].fa_map['l'] = 'b' g.instances['u1'].fa_map['r'] = 'c' nx = 8 ny = 2 s = tally.Tally() r = Raster( s, g, nx, ny) r.semantic() ri_map = { ri.ci.nm : ri for ri in r.ris} #place in corner s.emit_always( ri_map['u0'].anchor.var( r.idx( 0, 0))) for x in range(nx): for y in range(ny): pass s.emit_never( ri_map['u1'].anchor.var( r.idx( x, y))) # s.emit_never( ri_map['u1'].anchorMX.var( r.idx( x, y))) s.emit_never( ri_map['u1'].anchorMY.var( r.idx( x, y))) s.emit_never( ri_map['u1'].anchorMXY.var( r.idx( x, y))) r.solve() g.updateBbox() assert ri_map['u1'].anchorMX.val( r.idx(4,1)) is True with open( "mydesign_dr_globalrouting.json", "wt") as fp: tech = Tech() g.write_globalrouting_json( fp, tech)
def test_flat_hier(): l = CellLeaf( "ndev") l.addTerminal( "sd0", Rect(0,0,0,1)) l.addTerminal( "sd1", Rect(1,0,1,1)) h = CellHier( "flat") nx = 20 ny = 10 for x in range(nx): for y in range(ny): inst_name = 'u_%d_%d' % (x,y) h.addInstance( CellInstance( inst_name, l)) h.instances[inst_name].fa_map['sd0'] = 'a_%d_%d' % (x+1,y) h.instances[inst_name].fa_map['sd1'] = 'a_%d_%d' % (x+0,y) s = tally.Tally() r = Raster( s, h, nx, ny) r.semantic() ri_map = { ri.ci.nm : ri for ri in r.ris} for x in range(nx): for y in range(ny): inst_name = 'u_%d_%d' % (x,y) for xx in range(nx): for yy in range(ny): # s.emit_never( ri_map[inst_name].anchor.var( r.idx( xx, yy))) s.emit_never( ri_map[inst_name].anchorMY.var( r.idx( xx, yy))) s.emit_never( ri_map[inst_name].anchorMX.var( r.idx( xx, yy))) s.emit_never( ri_map[inst_name].anchorMXY.var( r.idx( xx, yy))) for y in range(ny): for x in range(nx): inst_name = 'u_%d_%d' % (x,y) s.emit_always( ri_map[inst_name].anchor.var( r.idx( nx-1-x, y))) r.solve() h.updateBbox() with open( "mydesign_dr_globalrouting.json", "wt") as fp: tech = Tech() h.write_globalrouting_json( fp, tech)
def test_build_raster(): s = tally.Tally() raster = Raster( s, 'xy', 4, 10) s.solve() assert s.state == 'SAT'
def test_sc(): ndev = CellLeaf( "ndev", Rect(0,0,2,2)) ndev.addTerminal( "d", Rect(0,0,0,2)) ndev.addTerminal( "g", Rect(1,0,1,2)) ndev.addTerminal( "s", Rect(2,0,2,2)) cc = CellLeaf( "cc", Rect(0,0,3,2)) cc.addTerminal( "cp1", Rect(0,0,0,2)) cc.addTerminal( "cn1", Rect(1,0,1,2)) cc.addTerminal( "cn2", Rect(2,0,2,2)) cc.addTerminal( "cp2", Rect(3,0,3,2)) ccbig = CellLeaf( "ccbig", Rect(0,0,5,2)) ccbig.addTerminal( "cp1", Rect(0,0,0,2)) ccbig.addTerminal( "cn1", Rect(1,0,1,2)) ccbig.addTerminal( "cn2", Rect(4,0,4,2)) ccbig.addTerminal( "cp2", Rect(5,0,5,2)) sc = CellHier( "sc") sc.addInstance( CellInstance( "L0_MM0", ndev)) sc.addInstance( CellInstance( "L0_MM1", ndev)) sc.addInstance( CellInstance( "L0_MM2", ndev)) sc.addInstance( CellInstance( "L0_MM3", ndev)) sc.addInstance( CellInstance( "L0_MM4", ndev)) sc.addInstance( CellInstance( "L0_MM5", ndev)) sc.addInstance( CellInstance( "L0_MM6", ndev)) sc.addInstance( CellInstance( "L0_MM7", ndev)) sc.addInstance( CellInstance( "L0_MM8", ndev)) sc.addInstance( CellInstance( "L0_MM9", ndev)) sc.addInstance( CellInstance( "L0_MM10", ndev)) sc.addInstance( CellInstance( "L0_MM11", ndev)) sc.addInstance( CellInstance( "L1_CC5_CC7", cc)) sc.addInstance( CellInstance( "L1_CC4_CC6", ccbig)) sc.addInstance( CellInstance( "L1_CC1_CC3", ccbig)) sc.addInstance( CellInstance( "L1_CC0_CC2", ccbig)) sc.connect( 'L1_CC5_CC7', 'cp1', 'net23') sc.connect( 'L1_CC0_CC2', 'cp1', 'net23') sc.connect( 'L0_MM1', 's', 'net23') # sc.connect( 'I0', 'Vinn', 'net23') sc.connect( 'L0_MM0', 's', 'net3') sc.connect( 'L0_MM10', 's', 'net3') sc.connect( 'L1_CC4_CC6', 'cn1', 'net3') sc.connect( 'L0_MM11', 's', 'net12') sc.connect( 'L0_MM8', 'd', 'net12') sc.connect( 'L1_CC1_CC3', 'cn2', 'net12') sc.connect( 'L0_MM3', 'd', 'net7') sc.connect( 'L1_CC5_CC7', 'cp2', 'net7') sc.connect( 'L1_CC0_CC2', 'cp2', 'net7') # sc.connect( 'I0', 'Vinp', 'net7') sc.connect( 'L0_MM5', 'd', 'net5') sc.connect( 'L0_MM3', 's', 'net5') sc.connect( 'L1_CC4_CC6', 'cp2', 'net5') sc.connect( 'L1_CC1_CC3', 'cp1', 'net5') sc.connect( 'L0_MM9', 's', 'net6') sc.connect( 'L0_MM1', 'd', 'net6') sc.connect( 'L1_CC4_CC6', 'cp1', 'net6') sc.connect( 'L1_CC1_CC3', 'cp2', 'net6') # sc.connect( 'terminal Vbiasn', 'Vbiasn') # sc.connect( 'I0', 'Vbiasn', 'Vbiasn') # sc.connect( 'terminal Vbiasp1', 'Vbiasp1') # sc.connect( 'I0', 'Vbiasp1', 'Vbiasp1') # sc.connect( 'terminal Vbiasp2', 'Vbiasp2') # sc.connect( 'I0', 'Vbiasp2', 'Vbiasp2') sc.connect( 'L0_MM2', 's', 'Vinn') sc.connect( 'L1_CC5_CC7', 'cn1', 'Vinn') # sc.connect( 'terminal Vinn', 'Vinn') sc.connect( 'L0_MM0', 'd', 'Vinp') sc.connect( 'L1_CC5_CC7', 'cn2', 'Vinp') # sc.connect( 'terminal Vinp', 'Vinp') sc.connect( 'L0_MM7', 'd', 'Voutn') sc.connect( 'L1_CC0_CC2', 'cn2', 'Voutn') # sc.connect( 'I0', 'Voutn', 'Voutn') # sc.connect( 'terminal Voutn', 'Voutn') sc.connect( 'L0_MM8', 's', 'Voutp') sc.connect( 'L1_CC0_CC2', 'cn1', 'Voutp') # sc.connect( 'I0', 'Voutp', 'Voutp') # sc.connect( 'terminal Voutp', 'Voutp') sc.connect( 'L0_MM11', 'g', 'phi1') sc.connect( 'L0_MM6', 'g', 'phi1') sc.connect( 'L0_MM1', 'g', 'phi1') sc.connect( 'L0_MM3', 'g', 'phi1') sc.connect( 'L0_MM0', 'g', 'phi1') sc.connect( 'L0_MM2', 'g', 'phi1') # sc.connect( 'terminal phi1', 'phi1') sc.connect( 'L0_MM2', 'd', 'net4') sc.connect( 'L0_MM4', 'd', 'net4') sc.connect( 'L1_CC4_CC6', 'cn2', 'net4') sc.connect( 'L0_MM8', 'g', 'phi2') sc.connect( 'L0_MM7', 'g', 'phi2') sc.connect( 'L0_MM9', 'g', 'phi2') sc.connect( 'L0_MM5', 'g', 'phi2') sc.connect( 'L0_MM4', 'g', 'phi2') sc.connect( 'L0_MM10', 'g', 'phi2') # sc.connect( 'terminal phi2', 'phi2') # sc.connect( 'I0', 'vdd!', 'vdd!') # sc.connect( 'terminal vdd!', 'vdd!') # sc.connect( 'terminal Id', 'Id') # sc.connect( 'I0', 'Id', 'Id') sc.connect( 'L0_MM11', 'd', 'gnd!') sc.connect( 'L0_MM6', 's', 'gnd!') sc.connect( 'L0_MM9', 'd', 'gnd!') sc.connect( 'L0_MM5', 's', 'gnd!') sc.connect( 'L0_MM4', 's', 'gnd!') sc.connect( 'L0_MM10', 'd', 'gnd!') # sc.connect( 'I0', 'gnd!', 'gnd!') # sc.connect( 'terminal gnd!', 'gnd!') sc.connect( 'L0_MM6', 'd', 'net11') sc.connect( 'L0_MM7', 's', 'net11') sc.connect( 'L1_CC1_CC3', 'cn1', 'net11') nx = 16 ny = 12 sc.bbox = Rect( 0, 0, nx, ny) s = tally.Tally() r = Raster( s, sc, nx, ny) r.semantic( skipTerminals=False) for x in range(nx): for y in range(ny): for ri in r.ris: if y % 2 != 0: s.emit_never( ri.anchor.var( r.idx( x,y))) s.emit_never( ri.anchorMX.var( r.idx( x,y))) s.emit_never( ri.anchorMY.var( r.idx( x,y))) s.emit_never( ri.anchorMXY.var( r.idx( x,y))) else: s.emit_never( ri.anchorMX.var( r.idx( x,y))) s.emit_never( ri.anchorMXY.var( r.idx( x,y))) #put a raft on the left and right for x in [0,nx-1]: for y in range(ny): for ri in r.ris: print( ri.ci.nm, x, y) s.emit_never( ri.filled.var( r.idx( x, y))) print( "First solve") s.solve() assert s.state == 'SAT' priority_nets_0 = ['net7','net23'] priority_nets_1 = ['phi1','phi2'] power_nets = ['gnd!'] specified_nets = set( priority_nets_0 + priority_nets_1 + power_nets) remaining_nets = [ n for n in r.nets.keys() if n not in specified_nets] def chunk( it, size): it = iter(it) return iter( lambda: tuple(itertools.islice(it, size)), ()) groups = [ list(tup) for tup in chunk( remaining_nets, 6)] r.optimizeNets( [priority_nets_0, priority_nets_1] + groups + [power_nets]) sc.dump()
def test_ota_bigger(): ndual = CellLeaf( "ndual", Rect(0,0,10,4)) ndual.addTerminal( "d1", Rect(0,0,0,4)) ndual.addTerminal( "g1", Rect(2,0,2,4)) ndual.addTerminal( "s1", Rect(4,0,4,4)) ndual.addTerminal( "s2", Rect(6,0,6,4)) ndual.addTerminal( "g2", Rect(8,0,8,4)) ndual.addTerminal( "d2", Rect(10,0,10,4)) ndualss = CellLeaf( "ndualss", Rect(0,0,8,4)) ndualss.addTerminal( "d1", Rect(0,0,0,4)) ndualss.addTerminal( "g1", Rect(2,0,2,4)) ndualss.addTerminal( "s", Rect(4,0,4,4)) ndualss.addTerminal( "g2", Rect(6,0,6,4)) ndualss.addTerminal( "d2", Rect(8,0,8,4)) ncap = CellLeaf( "ncap", Rect(0,0,8,4)) ncap.addTerminal( "d1", Rect(0,0,0,4)) ncap.addTerminal( "s", Rect(4,0,4,4)) ncap.addTerminal( "d2", Rect(8,0,8,4)) ota = CellHier( "ota") ota.addInstance( CellInstance( "L1_MM4_MM3", ncap)) ota.addInstance( CellInstance( "L1_MM1_MM0", ndualss)) ota.addInstance( CellInstance( "L1_MM9_MM8", ndual)) ota.addInstance( CellInstance( "L1_MM7_MM6", ndual)) ota.addInstance( CellInstance( "L1_MM10_MM2", ndual)) ota.connect('L1_MM1_MM0','g1','Vinp') ota.connect('L1_MM7_MM6','s1','net13') ota.connect('L1_MM9_MM8','d1','net13') ota.connect('L1_MM7_MM6','d2','Voutp') ota.connect('L1_MM10_MM2','d2','Voutp') ota.connect('L1_MM7_MM6','d1','Voutn') ota.connect('L1_MM10_MM2','d1','Voutn') ota.connect('L1_MM10_MM2','s1','net10') ota.connect('L1_MM1_MM0','d1','net10') ota.connect('L1_MM9_MM8','s1','vdd!') ota.connect('L1_MM9_MM8','s2','vdd!') ota.connect('L1_MM10_MM2','g1','Vbiasn') ota.connect('L1_MM10_MM2','g2','Vbiasn') ota.connect('L1_MM10_MM2','s2','net11') ota.connect('L1_MM1_MM0','d2','net11') ota.connect('L1_MM9_MM8','g1','Vbiasp2') ota.connect('L1_MM9_MM8','g2','Vbiasp2') ota.connect('L1_MM7_MM6','g1','Vbiasp1') ota.connect('L1_MM7_MM6','g2','Vbiasp1') ota.connect('L1_MM4_MM3','s','gnd!') ota.connect('L1_MM7_MM6','s2','net12') ota.connect('L1_MM9_MM8','d2','net12') ota.connect('L1_MM1_MM0','s','net6') ota.connect('L1_MM4_MM3','d2','net6') ota.connect('L1_MM1_MM0','g2','Vinn') ota.connect('L1_MM4_MM3','d1','net1') nx = 12 ny = 20 ota.bbox = Rect( 0, 0, nx, ny) s = tally.Tally() r = Raster( s, ota, nx, ny) r.semantic() #put a raft on the left and right for x in [0,nx-1]: for y in range(ny): for ri in r.ris: print( ri.ci.nm, x, y) s.emit_never( ri.filled.var( r.idx( x, y))) for x in range(nx): for y in range(ny): for ri in r.ris: if y % 4 != 0: s.emit_never( ri.anchor.var( r.idx( x,y))) s.emit_never( ri.anchorMX.var( r.idx( x,y))) s.emit_never( ri.anchorMY.var( r.idx( x,y))) s.emit_never( ri.anchorMXY.var( r.idx( x,y))) else: s.emit_never( ri.anchorMX.var( r.idx( x,y))) s.emit_never( ri.anchorMXY.var( r.idx( x,y))) s.solve() assert s.state == 'SAT' priority0_nets = ['net6', 'Voutn', 'Voutp', 'net12', 'net13'] priority1_nets = ['Vbiasn', 'Vbiasp1', 'Vbiasp2'] mentioned_nets = set( priority0_nets + priority1_nets) other_nets = [ n for n in r.nets.keys() if n not in mentioned_nets] r.optimizeNets( [priority0_nets,priority1_nets,other_nets]) ota.dump()
def test_ota(): ndual = CellLeaf( "ndual", Rect(0,0,5,2)) ndual.addTerminal( "d1", Rect(0,0,0,2)) ndual.addTerminal( "g1", Rect(1,0,1,2)) ndual.addTerminal( "s1", Rect(2,0,2,2)) ndual.addTerminal( "s2", Rect(3,0,3,2)) ndual.addTerminal( "g2", Rect(4,0,4,2)) ndual.addTerminal( "d2", Rect(5,0,5,2)) ndualss = CellLeaf( "ndualss", Rect(0,0,4,2)) ndualss.addTerminal( "d1", Rect(0,0,0,2)) ndualss.addTerminal( "g1", Rect(1,0,1,2)) ndualss.addTerminal( "s", Rect(2,0,2,2)) ndualss.addTerminal( "g2", Rect(3,0,3,2)) ndualss.addTerminal( "d2", Rect(4,0,4,2)) ncap = CellLeaf( "ncap", Rect(0,0,4,2)) ncap.addTerminal( "d1", Rect(0,0,0,2)) ncap.addTerminal( "s", Rect(2,0,2,2)) ncap.addTerminal( "d2", Rect(4,0,4,2)) ota = CellHier( "ota") ota.addInstance( CellInstance( "L1_MM4_MM3", ncap)) ota.addInstance( CellInstance( "L1_MM1_MM0", ndualss)) ota.addInstance( CellInstance( "L1_MM9_MM8", ndual)) ota.addInstance( CellInstance( "L1_MM7_MM6", ndual)) ota.addInstance( CellInstance( "L1_MM10_MM2", ndual)) ota.connect('L1_MM1_MM0','g1','Vinp') ota.connect('L1_MM7_MM6','s1','net13') ota.connect('L1_MM9_MM8','d1','net13') ota.connect('L1_MM7_MM6','d2','Voutp') ota.connect('L1_MM10_MM2','d2','Voutp') ota.connect('L1_MM7_MM6','d1','Voutn') ota.connect('L1_MM10_MM2','d1','Voutn') ota.connect('L1_MM10_MM2','s1','net10') ota.connect('L1_MM1_MM0','d1','net10') ota.connect('L1_MM9_MM8','s1','vdd!') ota.connect('L1_MM9_MM8','s2','vdd!') ota.connect('L1_MM10_MM2','g1','Vbiasn') ota.connect('L1_MM10_MM2','g2','Vbiasn') ota.connect('L1_MM10_MM2','s2','net11') ota.connect('L1_MM1_MM0','d2','net11') ota.connect('L1_MM9_MM8','g1','Vbiasp2') ota.connect('L1_MM9_MM8','g2','Vbiasp2') ota.connect('L1_MM7_MM6','g1','Vbiasp1') ota.connect('L1_MM7_MM6','g2','Vbiasp1') ota.connect('L1_MM4_MM3','s','gnd!') ota.connect('L1_MM7_MM6','s2','net12') ota.connect('L1_MM9_MM8','d2','net12') ota.connect('L1_MM1_MM0','s','net6') ota.connect('L1_MM4_MM3','d2','net6') ota.connect('L1_MM1_MM0','g2','Vinn') ota.connect('L1_MM4_MM3','d1','net1') nx = 8 ny = 12 ota.bbox = Rect( 0, 0, nx, ny) s = tally.Tally() r = Raster( s, ota, nx, ny) r.semantic() for x in range(nx): for y in range(ny): for ri in r.ris: if y % 2 == 1: s.emit_never( ri.anchor.var( r.idx( x,y))) s.emit_never( ri.anchorMX.var( r.idx( x,y))) s.emit_never( ri.anchorMY.var( r.idx( x,y))) s.emit_never( ri.anchorMXY.var( r.idx( x,y))) else: s.emit_never( ri.anchorMX.var( r.idx( x,y))) s.emit_never( ri.anchorMXY.var( r.idx( x,y))) #put a raft on the left and right for x in [0,nx-1]: for y in range(ny): for ri in r.ris: print( ri.ci.nm, x, y) s.emit_never( ri.filled.var( r.idx( x, y))) s.solve() assert s.state == 'SAT' priority0_nets = ['net6', 'Voutn', 'Voutp', 'net12', 'net13'] priority1_nets = ['Vbiasn', 'Vbiasp1', 'Vbiasp2'] mentioned_nets = set( priority0_nets + priority1_nets) other_nets = [ n for n in r.nets.keys() if n not in mentioned_nets] r.optimizeNets( [priority0_nets,priority1_nets,other_nets]) with open( "mydesign_dr_globalrouting.json", "wt") as fp: tech = Tech() ota.write_globalrouting_json( fp, tech) with open( "ota_placer_out.json", "wt") as fp: tech = Tech() ota.dumpJson( fp, tech)