def setup(): c = Canvas() m1 = c.addGen( Wire(nm='m1', layer='M1', direction='v', clg=UncoloredCenterLineGrid(width=400, pitch=720, repeat=2), spg=EnclosureGrid(pitch=720, stoppoint=360))) m2 = c.addGen( Wire(nm='m2', layer='M2', direction='h', clg=UncoloredCenterLineGrid(width=400, pitch=720, repeat=5), spg=EnclosureGrid(pitch=720, stoppoint=360))) m3 = c.addGen( Wire(nm='m3', layer='M3', direction='v', clg=UncoloredCenterLineGrid(width=400, pitch=720, repeat=2), spg=EnclosureGrid(pitch=720, stoppoint=360))) v1 = c.addGen(Via(nm='v1', layer='via1', h_clg=m2.clg, v_clg=m1.clg)) v2 = c.addGen(Via(nm='v2', layer='via2', h_clg=m2.clg, v_clg=m3.clg)) return (c, m1, v1, m2, v2, m3)
def _add_metal_generator(self, layer): m = Wire(layer.name, layer.name, layer.direction, clg=None, spg=None) index = layer.offset m.clg = CenterLineGrid() m.clg.addCenterLine(index, layer.width[0], isLegal=True, color=None if layer.color is None else layer.color[0]) for i in range(1, len(layer.width)): index += (layer.width[i-1] + layer.width[i])//2 + layer.space[i-1] m.clg.addCenterLine(index, layer.width[i], isLegal=True, color=None if layer.color is None else layer.color[i]) i = len(layer.width) - 1 index += (layer.width[i] + layer.width[0])//2 + layer.space[i] m.clg.addCenterLine(index, layer.width[0], isLegal=True, color=None if layer.color is None else layer.color[0]) m.clg.semantic() m.spg = EnclosureGrid(pitch=layer.stop_pitch, offset=layer.stop_offset, stoppoint=layer.stop_point, check=True) setattr(self, layer.name, self.addGen(m)) if layer.color is not None: self.postprocessor.register(layer.name, color_closure(layer=layer, generator=m))
def setup(): p = Pdk().load(pdkfile) c = Canvas(p) c.addGen(Wire(nm='m1', layer='M1', direction='v', clg=None, spg=None)) c.addGen(Wire(nm='m2', layer='M2', direction='h', clg=None, spg=None)) c.addGen(Via(nm="v1", layer="V1", h_clg=None, v_clg=None)) return c
def test_via_multi_terminal_open(): c = Canvas() c.addGen(Wire(nm='m1', layer='M1', direction='v', clg=None, spg=None)) c.addGen(Wire(nm='m2', layer='M2', direction='h', clg=None, spg=None)) c.addGen(Via(nm="v1", layer="via1", h_clg=None, v_clg=None)) c.terminals = [{ 'layer': 'M2', 'netName': None, 'rect': [0, -50, 300, 50] }, { 'layer': 'M1', 'netName': 'M1:S', 'rect': [100, -150, 200, 150] }, { 'layer': 'M1', 'netName': 'M1:D', 'rect': [0, -150, 50, 150] }, { 'layer': 'via1', 'netName': None, 'rect': [100, -50, 200, 50] }, { 'layer': 'via1', 'netName': None, 'rect': [0, -50, 50, 50] }] c.removeDuplicates() assert len(c.rd.shorts) == 0, c.rd.shorts assert len(c.rd.opens) == 2, c.rd.opens assert len(c.rd.subinsts) == 1, c.rd.subinsts assert len(c.rd.subinsts['M1'].pins) == 2, c.rd.subinsts
def test_one(): c = Canvas() c.pdk = {'M1': {'MaxL': None}, 'M2': {'MaxL': 10000}} m1 = c.addGen( Wire(nm='m1', layer='M1', direction='v', clg=UncoloredCenterLineGrid(width=400, pitch=720, repeat=2), spg=EnclosureGrid(pitch=720, stoppoint=360))) m2 = c.addGen( Wire(nm='m2', layer='M2', direction='h', clg=UncoloredCenterLineGrid(width=400, pitch=720, repeat=5), spg=EnclosureGrid(pitch=720, stoppoint=360))) # These three should be merged c.addWire(m1, 'a', 0, (0, 1), (3, 3)) c.addWire(m1, 'a', 0, (4, 1), (5, 3)) c.addWire(m1, 'a', 0, (6, 1), (50, 3)) # Only the first two should be merged c.addWire(m2, 'a', 1, (0, 1), (3, 3)) c.addWire(m2, 'a', 1, (4, 1), (5, 3)) c.addWire(m2, 'a', 1, (6, 1), (50, 3)) new_terminals = c.removeDuplicates(allow_opens=True) print('OLD:', new_terminals) c.join_wires(m1) c.join_wires(m2) new_terminals = c.removeDuplicates(allow_opens=True) print('NEW:', new_terminals) c.computeBbox() fn = "__json_join_wires_one" data = { 'bbox': c.bbox.toList(), 'globalRoutes': [], 'globalRouteGrid': [], 'terminals': c.removeDuplicates(allow_opens=True) } with open(mydir / (fn + "_cand"), "wt") as fp: fp.write(json.dumps(data, indent=2) + '\n') with open(mydir / (fn + "_gold"), "rt") as fp: data2 = json.load(fp) assert data == data2
def test_via_short1(): c = Canvas() c.addGen( Wire( nm='m1', layer='M1', direction='v', clg=None, spg=None)) c.addGen( Wire( nm='m2', layer='M2', direction='h', clg=None, spg=None)) c.addGen( Via( nm="v1", layer="via1", h_clg=None, v_clg=None)) c.terminals = [{'layer': 'M2', 'netName': 'a', 'rect': [ 0, -50, 300, 50], 'netType': 'drawing'}, {'layer': 'M1', 'netName': 'b', 'rect': [100, -150, 200, 150], 'netType': 'drawing'}, {'layer': 'via1', 'netName': None, 'rect': [100, -50, 200, 50], 'netType': 'drawing'} ] print(c.removeDuplicates()) assert len(c.rd.shorts) == 1, c.rd.shorts assert len(c.rd.opens) == 0, c.rd.opens
def setup(): p = Pdk().load(pdkfile) c = Canvas(p) c.addGen(Wire(nm='m1', layer='M1', direction='v', clg=None, spg=None)) c.addGen(Wire(nm='m2', layer='M2', direction='h', clg=None, spg=None)) c.addGen(Via(nm="v1", layer="V1", h_clg=None, v_clg=None)) m1 = p['M1'] v1 = p['V1'] m2 = p['M2'] assert 'Width' in m1 assert 'Width' in m2 assert 'VencA_L' in v1 assert 'VencA_H' in v1 assert 'VencP_L' in v1 assert 'VencP_H' in v1 assert 'WidthX' in v1 assert 'WidthY' in v1 assert 'MinL' in m1 assert 'MinL' in m2 assert m1['MinL'] <= 200 assert m2['MinL'] <= 200 def cr(x, y): assert x % 2 == 0 assert y % 2 == 0 return [-x // 2, -y // 2, x // 2, y // 2] c.terminals = [{ 'layer': 'M1', 'netName': 'x', 'rect': cr(m1['Width'], v1['WidthY'] + 2 * v1['VencA_L']), "netType": "drawing" }, { 'layer': 'M2', 'netName': 'x', 'rect': cr(v1['WidthX'] + 2 * v1['VencA_H'], m2['Width']), "netType": "drawing" }, { 'layer': 'V1', 'netName': 'x', 'rect': cr(v1['WidthX'], v1['WidthY']), "netType": "drawing" }] return c
def test_one(): c = Canvas() m1 = c.addGen( Wire(nm='m1', layer='M1', direction='v', clg=UncoloredCenterLineGrid(width=400, pitch=720, repeat=2), spg=EnclosureGrid(pitch=720, stoppoint=360))) m2 = c.addGen( Wire(nm='m2', layer='M2', direction='h', clg=UncoloredCenterLineGrid(width=400, pitch=720, repeat=5), spg=EnclosureGrid(pitch=720, stoppoint=360))) v1 = c.addGen(Via(nm='v1', layer='via1', h_clg=m2.clg, v_clg=m1.clg)) for i in [0, 2, 4]: c.addWire(m1, 'a', None, i, (0, 1), (4, -1)) for i in [1, 3, 5]: c.addWire(m1, 'b', None, i, (0, 1), (4, -1)) c.addWireAndViaSet('a', None, m2, v1, 2, [0, 2, 4]) c.addWireAndViaSet('b', None, m2, v1, 1, [1, 3, 5]) print(c.terminals) c.computeBbox() fn = "__json_via_set" data = { 'bbox': c.bbox.toList(), 'globalRoutes': [], 'globalRouteGrid': [], 'terminals': c.removeDuplicates() } with open(mydir / (fn + "_cand"), "wt") as fp: fp.write(json.dumps(data, indent=2) + '\n') with open(mydir / (fn + "_gold"), "rt") as fp: data2 = json.load(fp) assert data == data2
def test_different_widths(): c = Canvas() c.addGen( Wire( nm='m2', layer='metal2', direction='h', clg=None, spg=None)) c.terminals = [{'layer': 'metal2', 'netName': 'x', 'rect': [0, -50, 300, 50], 'netType': 'drawing'}, {'layer': 'metal2', 'netName': 'x', 'rect': [0, -60, 300, 60], 'netType': 'drawing'}] c.removeDuplicates() assert len(c.rd.different_widths) > 0
def test_via_multi_terminal_short(): c = Canvas() c.addGen(Wire(nm='m1', layer='M1', direction='v', clg=None, spg=None)) c.addGen(Via(nm="v0", layer="via0", h_clg=None, v_clg=None)) c.terminals = [{ 'layer': 'M1', 'netName': 'x', 'rect': [100, -150, 200, 150] }, { 'layer': 'M1', 'netName': 'y', 'rect': [300, -150, 600, 150] }, { 'layer': 'via0', 'netName': 'M1:S', 'rect': [100, -50, 200, 50] }, { 'layer': 'via0', 'netName': 'M1:S', 'rect': [300, -50, 600, 50] }] c.layer_stack.append(('via0', ('M1', None))) c.removeDuplicates() assert len(c.rd.subinsts) == 1, c.rd.subinsts assert len(c.rd.subinsts['M1'].pins) == 1, c.rd.subinsts assert len(c.rd.shorts) == 1, c.rd.shorts assert len(c.rd.opens) == 0, c.rd.opens
def setup(): p = Pdk().load(pdkfile) c = Canvas(p) c.addGen(Wire(nm='m2', layer='M2', direction='h', clg=None, spg=None)) m2 = p['M2'] m2['AdjacentAttacker'] = 1 assert 'Width' in m2 dy = m2['Width'] // 2 py = m2['Pitch'] c.terminals = [{ 'layer': 'M2', 'netName': 'x', 'rect': [0, 0 * py - dy, 200, 0 * py + dy] }, { 'layer': 'M2', 'netName': 'y', 'rect': [200, 1 * py - dy, 400, 1 * py + dy] }] return c
def test_metal_multi_terminal_connection(): c = Canvas() c.addGen(Wire(nm='m2', layer='metal2', direction='h', clg=None, spg=None)) c.terminals = [{ 'layer': 'metal2', 'netName': 'M1:S', 'rect': [0, -50, 300, 50] }, { 'layer': 'metal2', 'netName': 'inp1', 'rect': [200, -50, 600, 50] }, { 'layer': 'metal2', 'netName': 'M1:D', 'rect': [400, -50, 800, 50] }, { 'layer': 'metal2', 'netName': None, 'rect': [700, -50, 1000, 50] }, { 'layer': 'metal2', 'netName': 'M2:inp', 'rect': [900, -50, 1200, 50] }] c.removeDuplicates() assert len(c.rd.shorts) == 0, c.rd.shorts assert len(c.rd.opens) == 0, c.rd.opens assert len(c.rd.subinsts) == 2 assert len(c.rd.subinsts['M1'].pins) == 2, c.rd.subinsts assert len(c.rd.subinsts['M2'].pins) == 1
def setup(): p = Pdk().load(pdkfile) c = Canvas(p) c.addGen(Wire(nm='m2', layer='M2', direction='h', clg=None, spg=None)) c.addGen(Wire(nm='m3', layer='M3', direction='v', clg=None, spg=None)) c.addGen(Via(nm="v2", layer="V2", h_clg=None, v_clg=None)) m2 = p['M2'] v2 = p['V2'] m3 = p['M3'] assert 'Width' in m2 assert 'Width' in m3 assert 'VencA_L' in v2 assert 'VencA_H' in v2 assert 'VencP_L' in v2 assert 'VencP_H' in v2 assert 'WidthX' in v2 assert 'WidthY' in v2 assert 'MinL' in m2 assert 'MinL' in m3 assert m2['MinL'] <= 210 assert m3['MinL'] <= 210 def cr(x, y): assert x % 2 == 0 assert y % 2 == 0 return [-x // 2, -y // 2, x // 2, y // 2] c.terminals = [{ 'layer': 'M2', 'netName': 'x', 'rect': cr(v2['WidthX'] + 2 * v2['VencA_L'], m2['Width']) }, { 'layer': 'M3', 'netName': 'x', 'rect': cr(m3['Width'], v2['WidthY'] + 2 * v2['VencA_H']) }, { 'layer': 'V2', 'netName': 'x', 'rect': cr(v2['WidthX'], v2['WidthY']) }] return c
def test_overlapping(): c = Canvas() c.addGen( Wire( nm='m2', layer='metal2', direction='h', clg=None, spg=None)) c.terminals = [{'layer': 'metal2', 'netName': 'x', 'rect': [ 0, -50, 300, 50], 'netType': 'drawing'}, {'layer': 'metal2', 'netName': 'x', 'rect': [200, -50, 600, 50], 'netType': 'drawing'}] newTerminals = c.removeDuplicates() assert len(newTerminals) == 1 assert newTerminals[0]['rect'] == [0, -50, 600, 50]
def test_open(): c = Canvas() c.addGen( Wire( nm='m2', layer='metal2', direction='h', clg=None, spg=None)) c.terminals = [{'layer': 'metal2', 'netName': 'x', 'rect': [ 0, -50, 300, 50], 'netType': 'drawing'}, {'layer': 'metal2', 'netName': 'x', 'rect': [400, -50, 600, 50], 'netType': 'drawing'}] c.removeDuplicates() assert len(c.rd.shorts) == 0, c.rd.shorts assert len(c.rd.opens) == 1, c.rd.opens
def test_vertical(): c = Canvas() c.addGen(Wire(nm='m1', layer='metal1', direction='v', clg=None, spg=None)) c.terminals = [{ 'layer': 'metal1', 'netName': 'x', 'rect': [0, 0, 100, 300] }] c.removeDuplicates()
def test_overlapping_drawings_through_blockage(): c = Canvas() c.addGen( Wire( nm='m2', layer='M2', direction='h', clg=None, spg=None)) c.terminals = [ {'layer': 'M2', 'netName': 'a', 'rect': [ 0, -50, 300, 50], 'netType': 'pin'}, {'layer': 'M2', 'netName': None, 'rect': [ 150, -50, 750, 50], 'netType': 'blockage'}, {'layer': 'M2', 'netName': 'b', 'rect': [ 600, -50, 900, 50], 'netType': 'pin'} ] newTerminals = c.removeDuplicates() assert len(c.rd.shorts) == 1, c.rd.shorts assert len(c.rd.opens) == 0, c.rd.opens
def test_blockage_not_merging(): c = Canvas() c.addGen( Wire( nm='m2', layer='M2', direction='h', clg=None, spg=None)) c.terminals = [{'layer': 'M2', 'netName': 'a', 'rect': [ 0, -50, 300, 50], 'netType': 'pin'}, {'layer': 'M2', 'netName': None, 'rect': [ 150, -50, 750, 50], 'netType': 'blockage'} ] newTerminals = c.removeDuplicates() assert len(c.rd.shorts) == 0, c.rd.shorts assert len(c.rd.opens) == 0, c.rd.opens assert len(newTerminals) == 2, len(newTerminals)
def test_two(): c = Canvas() c.pdk = {'M1': {'MaxL': None}, 'M2': {'MaxL': 10000}} m1 = c.addGen( Wire(nm='m1', layer='M1', direction='v', clg=UncoloredCenterLineGrid(width=400, pitch=720, repeat=2), spg=EnclosureGrid(pitch=720, stoppoint=360))) # None of the below should merge c.addWire(m1, 'a', 1, (0, 1), (1, 3)) c.addWire(m1, 'b', 1, (2, 1), (3, 3)) c.addWire(m1, 'a', 1, (4, 1), (5, 3)) # Append different width c.terminals.append({ 'layer': 'M1', 'netName': 'a', 'rect': [540, 4680, 900, 5400], 'netType': 'drawing' }) c.addWire(m1, None, 1, (8, 1), (9, 3)) new_terminals = c.removeDuplicates(allow_opens=True) print(new_terminals) c.join_wires(m1) new_terminals = c.removeDuplicates(allow_opens=True) print('new:', new_terminals) c.computeBbox() fn = "__json_join_wires_two" data = { 'bbox': c.bbox.toList(), 'globalRoutes': [], 'globalRouteGrid': [], 'terminals': c.removeDuplicates(allow_opens=True) } with open(mydir / (fn + "_cand"), "wt") as fp: fp.write(json.dumps(data, indent=2) + '\n') with open(mydir / (fn + "_gold"), "rt") as fp: data2 = json.load(fp) assert data == data2
def test_via_connectf(): c = Canvas() c.addGen(Wire(nm='m1', layer='M1', direction='v', clg=None, spg=None)) c.addGen(Wire(nm='m2', layer='M2', direction='h', clg=None, spg=None)) c.addGen(Via(nm="v1", layer="via1", h_clg=None, v_clg=None)) c.terminals = [{ 'layer': 'M2', 'netName': 'b', 'rect': [0, -50, 300, 50] }, { 'layer': 'M1', 'netName': None, 'rect': [100, -150, 200, 150] }, { 'layer': 'via1', 'netName': None, 'rect': [100, -50, 200, 50] }] terms = c.removeDuplicates() print(terms) assert len(c.rd.shorts) == 0, c.rd.shorts assert len(c.rd.opens) == 0, c.rd.opens assert {d['netName'] for d in terms} == {'b'}
def setup(): p = Pdk().load(pdkfile) c = Canvas(p) c.addGen(Wire(nm='m2', layer='M2', direction='h', clg=None, spg=None)) m2 = p['M2'] assert 'Width' in m2 assert m2['Width'] % 2 == 0 dy0 = m2['Width'] // 2 dy1 = dy0 + 4 return c, dy0, dy1
def test_four(): c = Canvas() c.pdk = {'M1': {'MaxL': None}, 'M2': {'MaxL': 10000}} m1 = c.addGen( Wire(nm='m1', layer='M1', direction='v', clg=UncoloredCenterLineGrid(width=400, pitch=720, repeat=2), spg=EnclosureGrid(pitch=720, stoppoint=360))) # Below wires on same centerline should not be merged c.addWire(m1, 'a', 1, (0, 1), (1, 3), netType="blockage") c.addWire(m1, 'a', 1, (2, 1), (3, 3), netType="blockage") c.addWire(m1, 'a', 2, (0, 1), (1, 3), netType="drawing") c.addWire(m1, 'a', 2, (2, 1), (3, 3), netType="pin") c.addWire(m1, 'a', 4, (0, 1), (1, 3), netType="drawing") c.addWire(m1, 'a', 4, (2, 1), (3, 3), netType="blockage") # Below wires on same centerline should be merged c.addWire(m1, 'a', 3, (0, 1), (1, 3), netType="drawing") c.addWire(m1, 'a', 3, (2, 1), (3, 3), netType="drawing") c.addWire(m1, 'a', 5, (0, 1), (1, 3), netType="pin") c.addWire(m1, 'a', 5, (2, 1), (3, 3), netType="pin") new_terminals = c.removeDuplicates(allow_opens=True) print(new_terminals) c.join_wires(m1) new_terminals = c.removeDuplicates(allow_opens=True) print('new:', new_terminals) c.computeBbox() fn = "__json_join_wires_four" data = { 'bbox': c.bbox.toList(), 'globalRoutes': [], 'globalRouteGrid': [], 'terminals': c.removeDuplicates(allow_opens=True) } with open(mydir / (fn + "_cand"), "wt") as fp: fp.write(json.dumps(data, indent=2) + '\n') with open(mydir / (fn + "_gold"), "rt") as fp: data2 = json.load(fp) assert data == data2
def test_metal_terminal_connection(): c = Canvas() c.addGen(Wire(nm='m2', layer='metal2', direction='h', clg=None, spg=None)) c.terminals = [{ 'layer': 'metal2', 'netName': 'x', 'rect': [0, -50, 300, 50] }, { 'layer': 'metal2', 'netName': 'M1:S', 'rect': [200, -50, 600, 50] }] c.removeDuplicates() assert len(c.rd.shorts) == 0, c.rd.shorts assert len(c.rd.opens) == 0, c.rd.opens assert len(c.rd.subinsts) == 1, c.rd.subinsts
def test_disjoint(): c = Canvas() c.addGen(Wire(nm='m2', layer='metal2', direction='h', clg=None, spg=None)) c.terminals = [{ 'layer': 'metal2', 'netName': 'x', 'rect': [0, -50, 300, 50] }, { 'layer': 'metal2', 'netName': 'x', 'rect': [400, -50, 600, 50] }] newTerminals = c.removeDuplicates() assert len(newTerminals) == 2 assert newTerminals[0]['rect'] == [0, -50, 300, 50] assert newTerminals[1]['rect'] == [400, -50, 600, 50]
def test_three(): c = Canvas() c.pdk = {'M1': {'MaxL': 5000}} m1 = c.addGen( Wire(nm='m1', layer='M1', direction='v', clg=UncoloredCenterLineGrid(width=400, pitch=720, repeat=2), spg=EnclosureGrid(pitch=720, stoppoint=360))) # Below should be merged c.addWire(m1, 'a', 0, (0, 1), (3, 3)) c.addWire(m1, 'a', 0, (4, 1), (5, 3)) # Below should be merged (but not with above) c.addWire(m1, 'a', 0, (6, 1), (8, 3)) c.addWire(m1, 'a', 0, (10, 1), (11, 3)) c.addWire(m1, 'b', 0, (12, 1), (13, 3)) c.addWire(m1, 'a', 0, (14, 1), (15, 3)) new_terminals = c.removeDuplicates(allow_opens=True) print('OLD:', new_terminals) c.join_wires(m1) new_terminals = c.removeDuplicates(allow_opens=True) print('NEW:', new_terminals) c.computeBbox() fn = "__json_join_wires_three" data = { 'bbox': c.bbox.toList(), 'globalRoutes': [], 'globalRouteGrid': [], 'terminals': c.removeDuplicates(allow_opens=True) } with open(mydir / (fn + "_cand"), "wt") as fp: fp.write(json.dumps(data, indent=2) + '\n') with open(mydir / (fn + "_gold"), "rt") as fp: data2 = json.load(fp) assert data == data2
def setup(): p = Pdk().load(pdkfile) c = Canvas(p) c.addGen(Wire(nm='m2', layer='M2', direction='h', clg=None, spg=None)) return c, p
def test_one(): c = Canvas() c.pdk = { "M1": { "Direction": "V" }, "M2": { "Direction": "H" }, "M3": { "Direction": "H" }, "V1": { "Stack": ["M1", "M2"], "SpaceX": 400, "SpaceY": 500, "WidthX": 400, "WidthY": 300, "VencA_L": 0, "VencA_H": 0, "VencP_L": 0, "VencP_H": 0 }, "V2": { "Stack": ["M2", "M3"], "SpaceX": 400, "SpaceY": 500, "WidthX": 400, "WidthY": 300, "VencA_L": 0, "VencA_H": 0, "VencP_L": 0, "VencP_H": 0 } } c.M1 = c.addGen( Wire(nm='m1', layer='M1', direction='v', clg=UncoloredCenterLineGrid(width=400, pitch=800, repeat=2), spg=EnclosureGrid(pitch=900, stoppoint=450))) c.M2 = c.addGen( Wire(nm='m2', layer='M2', direction='h', clg=UncoloredCenterLineGrid(width=400, pitch=900, repeat=5), spg=EnclosureGrid(pitch=800, stoppoint=400))) c.M3 = c.addGen( Wire(nm='m3', layer='M3', direction='v', clg=UncoloredCenterLineGrid(width=400, pitch=800, repeat=2), spg=EnclosureGrid(pitch=900, stoppoint=450))) c.V1 = c.addGen( Via(nm='v1', layer='V1', h_clg=c.M2.clg, v_clg=c.M1.clg, WidthX=c.pdk['V1']['WidthX'], WidthY=c.pdk['V1']['WidthY'])) c.V2 = c.addGen( Via(nm='v2', layer='V2', h_clg=c.M2.clg, v_clg=c.M3.clg, WidthX=c.pdk['V2']['WidthX'], WidthY=c.pdk['V2']['WidthY'])) for x in [1, 2, 3]: c.addWire(c.M1, 'a', x, (0, 1), (3, 3)) for y in [1, 2, 3]: c.addWire(c.M2, 'a', y, (1, 1), (5, 3)) for x in [4, 5, 6]: c.addWire(c.M3, 'a', x, (0, 1), (3, 3)) c.drop_via(c.V1) c.drop_via(c.V2) c.computeBbox() data = { 'bbox': c.bbox.toList(), 'globalRoutes': [], 'globalRouteGrid': [], 'terminals': c.terminals } # for viewing with open( pathlib.Path(os.getenv('ALIGN_HOME')) / 'Viewer' / 'INPUT' / 'drop_via_one.json', "wt") as fp: fp.write(json.dumps(data, indent=2) + '\n') fn = "__json_drop_via_one" with open(mydir / (fn + "_cand"), "wt") as fp: fp.write(json.dumps(data, indent=2) + '\n') with open(mydir / (fn + "_gold"), "rt") as fp: data2 = json.load(fp) assert data == data2
def test_two(): c = Canvas() c.pdk = { "M1": { "Direction": "V" }, "M2": { "Direction": "H" }, "V1": { "Stack": ["M1", "M2"], "SpaceX": 700, "SpaceY": 700, "WidthX": 400, "WidthY": 300, "VencA_L": 50, "VencA_H": 50, "VencP_L": 0, "VencP_H": 0 } } c.M1 = c.addGen( Wire(nm='m1', layer='M1', direction='v', clg=UncoloredCenterLineGrid(width=400, pitch=800, repeat=2), spg=EnclosureGrid(pitch=900, stoppoint=450))) c.M2 = c.addGen( Wire(nm='m2', layer='M2', direction='h', clg=UncoloredCenterLineGrid(width=400, pitch=900, repeat=5), spg=EnclosureGrid(pitch=800, stoppoint=400))) c.V1 = c.addGen( Via(nm='v1', layer='V1', h_clg=c.M2.clg, v_clg=c.M1.clg, WidthX=c.pdk['V1']['WidthX'], WidthY=c.pdk['V1']['WidthY'])) # via existing c.addWire(c.M1, 'a', 1, (0, 1), (1, 3)) c.addWire(c.M2, 'a', 1, (0, 1), (1, 3)) c.addVia(c.V1, 'a', 1, 1) # SpaceY violation c.addWire(c.M1, 'a', 3, (0, 1), (2, 3)) c.addWire(c.M2, 'a', 1, (2, 1), (3, 3)) c.addWire(c.M2, 'a', 2, (2, 1), (3, 3)) # SpaceX violation c.addWire(c.M1, 'a', 5, (0, 1), (2, 3)) c.addWire(c.M1, 'a', 6, (0, 1), (2, 3)) c.addWire(c.M2, 'a', 1, (4, 1), (6, 3)) # enclosure violation c.terminals.append({ "layer": "M1", "netName": "a", "rect": [6200, 750, 6600, 2250], "netType": "drawing" }) c.terminals.append({ "layer": "M2", "netName": "a", "rect": [6200, 1600, 7000, 2000], "netType": "drawing" }) c.addWire(c.M2, 'a', 1, (7, 1), (8, 3)) c.drop_via(c.V1) c.computeBbox() data = { 'bbox': c.bbox.toList(), 'globalRoutes': [], 'globalRouteGrid': [], 'terminals': c.terminals } # for viewing with open( pathlib.Path(os.getenv('ALIGN_HOME')) / 'Viewer' / 'INPUT' / 'drop_via_two.json', "wt") as fp: fp.write(json.dumps(data, indent=2) + '\n') fn = "__json_drop_via_two" with open(mydir / (fn + "_cand"), "wt") as fp: fp.write(json.dumps(data, indent=2) + '\n') with open(mydir / (fn + "_gold"), "rt") as fp: data2 = json.load(fp) assert data == data2
def __init__(self): super().__init__() self.finsPerUnitCell = 14 self.m2PerUnitCell = 7 ndPitch = 360 pdPitch = 360 m2Pitch = 720 self.unitCellHeight = self.m2PerUnitCell * m2Pitch pcPitch = self.unitCellHeight // 2 m1Pitch = 864 m3Pitch = 720 self.unitCellWidth = 2 * m1Pitch plPitch = m1Pitch plOffset = plPitch // 2 dcPitch = m1Pitch pcWidth = 200 m1Width = 400 m2Width = 400 m3Width = 400 dcWidth = 200 plWidth = 200 ndWidth = 120 ndPitch = 360 self.pl = self.addGen( Wire('pl', 'poly', 'v', clg=CenterLineGrid(), spg=EnclosureGrid(pitch=m2Pitch // 2, stoppoint=16))) for i in range(5): self.pl.clg.addCenterLine(i * plPitch // 2, plWidth, i % 2 == 1) self.pl.clg.semantic() self.nd = self.addGen( Region('nd', 'ndiff', h_grid=SingleGrid(pitch=ndPitch), v_grid=self.pl.clg)) self.pd = self.addGen( Region('pd', 'pdiff', h_grid=SingleGrid(pitch=pdPitch), v_grid=self.pl.clg)) self.pc = self.addGen( Wire('pc', 'polycon', 'h', clg=UncoloredCenterLineGrid(width=pcWidth, pitch=pcPitch), spg=EnclosureGrid(pitch=dcPitch, stoppoint=plOffset - plWidth // 2))) self.m1 = self.addGen( Wire('m1', 'M1', 'v', clg=UncoloredCenterLineGrid(width=m1Width, pitch=m1Pitch, repeat=2), spg=EnclosureGrid(pitch=m2Pitch, stoppoint=m2Width // 2))) self.m2 = self.addGen( Wire('m2', 'M2', 'h', clg=UncoloredCenterLineGrid(width=m2Width, pitch=m2Pitch, repeat=self.m2PerUnitCell), spg=EnclosureGrid(pitch=2 * m1Pitch, stoppoint=m1Pitch // 2))) self.m3 = self.addGen( Wire('m3', 'M3', 'v', clg=UncoloredCenterLineGrid(width=m3Width, pitch=m3Pitch), spg=EnclosureGrid(pitch=self.unitCellHeight, stoppoint=self.unitCellHeight // 2 - m2Pitch))) self.dc = self.addGen( Wire('dc', 'diffcon', 'v', clg=CenterLineGrid(), spg=EnclosureGrid(pitch=m2Pitch // 2, stoppoint=0))) for i in range(5): self.dc.clg.addCenterLine(i * dcPitch // 2, dcWidth, i % 2 == 0) self.dc.clg.semantic() self.v0 = self.addGen( Via('v0', 'via0', v_clg=self.m1.clg, h_clg=self.pc.clg)) self.v1 = self.addGen( Via('v1', 'via1', v_clg=self.m1.clg, h_clg=self.m2.clg)) self.v2 = self.addGen( Via('v2', 'via2', v_clg=self.m3.clg, h_clg=self.m2.clg))
def __init__(self): super().__init__() self.finsPerUnitCell = 12 # Must be a multiple of 2 assert self.finsPerUnitCell % 2 == 0 # Should be a multiple of 4 for maximum utilization assert self.finsPerUnitCell % 4 == 0 self.m2PerUnitCell = self.finsPerUnitCell // 2 + 3 m2Pitch = 720 unitCellHeight = self.m2PerUnitCell * m2Pitch pcPitch = unitCellHeight // 2 m1Pitch = 720 m3Pitch = 720 plPitch = m1Pitch plOffset = plPitch // 2 dcPitch = 2 * m1Pitch pcWidth = 200 m1Width = 400 m2Width = 400 m3Width = 400 dcWidth = 200 plWidth = 200 ndWidth = 120 ndPitch = 360 self.nd = self.addGen( Wire('nd', 'ndiff', 'h', clg=UncoloredCenterLineGrid(pitch=ndPitch, width=ndWidth, repeat=2 * self.m2PerUnitCell), spg=SingleGrid(pitch=dcPitch))) self.pc = self.addGen( Wire('pc', 'polycon', 'h', clg=UncoloredCenterLineGrid(width=pcWidth, pitch=pcPitch), spg=EnclosureGrid(pitch=dcPitch, stoppoint=plOffset - plWidth // 2))) self.m1 = self.addGen( Wire('m1', 'M1', 'v', clg=UncoloredCenterLineGrid(width=m1Width, pitch=m1Pitch, repeat=2), spg=EnclosureGrid(pitch=unitCellHeight, stoppoint=unitCellHeight // 2 - m2Pitch))) self.m3 = self.addGen( Wire('m3', 'M3', 'v', clg=UncoloredCenterLineGrid(width=m3Width, pitch=m3Pitch, repeat=2), spg=EnclosureGrid(pitch=unitCellHeight, stoppoint=unitCellHeight // 2 - m2Pitch))) self.m2 = self.addGen( Wire('m2', 'M2', 'h', clg=UncoloredCenterLineGrid(width=m2Width, pitch=m2Pitch, repeat=self.m2PerUnitCell), spg=EnclosureGrid(pitch=2 * m1Pitch, stoppoint=m1Pitch // 2))) self.pl = self.addGen( Wire('pl', 'poly', 'v', clg=UncoloredCenterLineGrid(width=plWidth, pitch=plPitch, offset=plOffset, repeat=2), spg=EnclosureGrid(pitch=unitCellHeight, stoppoint=m1Pitch // 2))) self.dc = self.addGen( Wire('dc', 'diffcon', 'v', clg=UncoloredCenterLineGrid(width=dcWidth, pitch=dcPitch), spg=Grid())) stoppoint = m1Pitch // 2 self.dc.spg.addGridLine(0, False) self.dc.spg.addGridLine(stoppoint, True) self.dc.spg.addGridLine(unitCellHeight // 2 - stoppoint, True) self.dc.spg.addGridLine(unitCellHeight // 2, False) self.dc.spg.addGridLine(unitCellHeight // 2 + stoppoint, True) self.dc.spg.addGridLine(unitCellHeight - stoppoint, True) self.dc.spg.addGridLine(unitCellHeight, False)