Replace the SRAM structure with characterization structure.
diff --git a/doitcode/sram.py b/doitcode/sram.py
index cfde4a4..bc0b657 100644
--- a/doitcode/sram.py
+++ b/doitcode/sram.py
@@ -58,36 +58,31 @@
return None
+io_spspecs = (
+ _io_spec(sram_signal="in_shiftclk", io_type="io_in", io_number=14),
+ _io_spec(sram_signal="shift_in", io_type="io_in", io_number=15),
+ _io_spec(sram_signal="in_captureclk_l", io_type="io_out", io_number=16),
+ _io_spec(sram_signal="in_captureclk", io_type="io_in", io_number=17),
+ _io_spec(sram_signal="sramclk", io_type="io_in", io_number=18),
+ _io_spec(sram_signal="out_captureclk_l", io_type="io_out", io_number=13),
+ _io_spec(sram_signal="out_captureclk", io_type="io_in", io_number=12),
+ _io_spec(sram_signal="out_docapture", io_type="io_in", io_number=11),
+ _io_spec(sram_signal="out_shiftclk", io_type="io_in", io_number=10),
+ _io_spec(sram_signal="shift_out", io_type="io_out", io_number=9),
+)
+io_spsig2spec = {
+ spec.sram_signal: spec
+ for spec in io_spspecs
+}
+io_sppin2spec = {
+ spec.toppin_name: spec
+ for spec in io_spspecs
+}
+
+
io_specs = (
- _io_spec(sram_signal="a[8]", io_type="io_in", io_number=14),
- _io_spec(sram_signal="a[7]", io_type="io_in", io_number=15),
- _io_spec(sram_signal="a[6]", io_type="io_in", io_number=16),
- _io_spec(sram_signal="a[5]", io_type="io_in", io_number=17),
- _io_spec(sram_signal="a[4]", io_type="io_in", io_number=18),
- _io_spec(sram_signal="a[3]", io_type="io_in", io_number=19),
- _io_spec(sram_signal="a[2]", io_type="io_in", io_number=20),
- _io_spec(sram_signal="a[1]", io_type="io_in", io_number=21),
- _io_spec(sram_signal="a[0]", io_type="io_in", io_number=22),
- _io_spec(sram_signal="clk", io_type="io_in", io_number=23),
- _io_spec(sram_signal="q[7]", io_type="io_out", io_number=13),
- _io_spec(sram_signal="d[7]", io_type="io_in", io_number=12),
- _io_spec(sram_signal="d[6]", io_type="io_in", io_number=11),
- _io_spec(sram_signal="q[6]", io_type="io_out", io_number=10),
- _io_spec(sram_signal="q[5]", io_type="io_out", io_number=9),
- _io_spec(sram_signal="d[5]", io_type="io_in", io_number=8),
- _io_spec(sram_signal="d[4]", io_type="io_in", io_number=7),
- _io_spec(sram_signal="q[4]", io_type="io_out", io_number=6),
- _io_spec(sram_signal="q[3]", io_type="io_out", io_number=5),
- _io_spec(sram_signal="d[3]", io_type="io_in", io_number=4),
- _io_spec(sram_signal="d[2]", io_type="io_in", io_number=3),
- _io_spec(sram_signal="q[2]", io_type="io_out", io_number=2),
- _io_spec(sram_signal="q[1]", io_type="io_out", io_number=1),
- _io_spec(sram_signal="we[0]", io_type="io_in", io_number=0),
- _io_spec(sram_signal="d[1]", io_type="io_in", io_number=26),
- _io_spec(sram_signal="d[0]", io_type="io_in", io_number=25),
- _io_spec(sram_signal="q[0]", io_type="io_out", io_number=24),
- _io_spec(sram_signal="vdd", io_type="io_analog", io_number=4),
- _io_spec(sram_signal="vss", io_type="io_analog", io_number=5),
+ _io_spec(sram_signal="svdd", io_type="io_analog", io_number=4),
+ _io_spec(sram_signal="svss", io_type="io_analog", io_number=5),
)
io_sig2spec = {
spec.sram_signal: spec
@@ -278,6 +273,10 @@
m2 = cast(_prm.MetalWire, prims.m2)
assert m2.pin is not None
m2pin = m2.pin[0]
+ via2 = cast(_prm.Via, prims.via2)
+ m3 = cast(_prm.MetalWire, prims.m3)
+ assert m3.pin is not None
+ m3pin = m3.pin[0]
# Place the SRAM block
layouter = self.new_circuitlayouter()
@@ -469,6 +468,54 @@
bottom_enclosure="wide", top_enclosure="tall",
)
+ # Connect svss
+ net = nets.svss
+
+ bbs = tuple(ms.shape.bounds for ms in sram_lay.filter_polygons(
+ net=net, mask=m2pin.mask, depth=1, split=True,
+ ))
+ left = max(bb.left for bb in bbs)
+ top = max(bb.top for bb in bbs)
+ bottom = min(bb.bottom for bb in bbs)
+ w = 10.0
+ x_via2 = left + w/2.0
+ right = left + w
+
+ for bb in bbs:
+ y_via2 = bb.center.y
+ layouter.add_wire(
+ net=net, wire=via2, x=x_via2, y=y_via2,
+ bottom_width=w, bottom_enclosure="wide",
+ top_width=w, top_enclosure="wide",
+ )
+
+ shape = _geo.Rect(left=left, bottom=bottom, right=right, top=top)
+ layouter.add_wire(net=net, wire=m3, pin=m3pin, shape=shape)
+
+ # Connect svdd
+ net = nets.svdd
+
+ bbs = tuple(ms.shape.bounds for ms in sram_lay.filter_polygons(
+ net=net, mask=m2pin.mask, depth=1, split=True,
+ ))
+ right = min(bb.right for bb in bbs)
+ top = max(bb.top for bb in bbs)
+ bottom = min(bb.bottom for bb in bbs)
+ w = 10.0
+ x_via2 = right - w/2.0
+ left = right - w
+
+ for bb in bbs:
+ y_via2 = bb.center.y
+ layouter.add_wire(
+ net=net, wire=via2, x=x_via2, y=y_via2,
+ bottom_width=w, bottom_enclosure="wide",
+ top_width=w, top_enclosure="wide",
+ )
+
+ shape = _geo.Rect(left=left, bottom=bottom, right=right, top=top)
+ layouter.add_wire(net=net, wire=m3, pin=m3pin, shape=shape)
+
# Connect sramclk
net = nets.sramclk
@@ -1532,6 +1579,8 @@
via2 = cast(_prm.Via, prims.via2)
m3 = cast(_prm.MetalWire, prims.m3)
m3pin = cast(_prm.Marker, prims["m3.pin"])
+ via3 = cast(_prm.Via, prims.via3)
+ m4 = cast(_prm.MetalWire, prims.m4)
zero_cell = stdcells.zero_x1
zero_nets = zero_cell.circuit.nets
@@ -1563,6 +1612,7 @@
address_groups=(3, 4, 2), word_size=word_size, we_size=we_size,
cell_name="512x8",
)
+ spchar_cell = SPCharacterizationWrapper(lib=lib, spcell=spsram_cell)
dpsram_cell = dpmem_fab.block(
address_groups=(3, 4, 2), word_size=word_size, we_size=we_size,
cell_name="512x8",
@@ -1585,9 +1635,12 @@
# Place the SRAM
#
# instantiate
- spsram = ckt.instantiate(spsram_cell, name="sram")
+ spsram = ckt.instantiate(spchar_cell, name="sram")
dpsram = ckt.instantiate(dpsram_cell, name="sram")
+ dvss.childports += spsram.ports.dvss
+ dvdd.childports += spsram.ports.dvdd
+
# place
_spsram_lay = layouter.inst_layout(inst=spsram)
_spsram_bb = _spsram_lay.boundary
@@ -1597,23 +1650,16 @@
assert _dpsram_bb is not None
x = sky130.tech.on_grid(_frm.boundary.center.x - _spsram_bb.center.x)
- y = _frm.boundary.top - 100.0 - _spsram_bb.top
+ y = _frm.boundary.top - 60.0 - _spsram_bb.top
spsram_lay = layouter.place(_spsram_lay, x=x, y=y)
spsram_bb = spsram_lay.boundary
assert spsram_bb is not None
- x = spsram_bb.right + 100.0
+ x = sky130.tech.on_grid(_frm.boundary.center.x - _dpsram_bb.center.x)
+ y = 1600.0 - _dpsram_bb.bottom
dpsram_lay = layouter.place(_dpsram_lay, x=x, y=y)
dpsram_bb = dpsram_lay.boundary
assert dpsram_bb is not None
- # Temporary add
- spchar_cell = SPCharacterizationWrapper(lib=lib, spcell=spsram_cell)
- spchar = ckt.instantiate(spchar_cell, name="sramchar")
- x = spsram_bb.right + 700
- spchar_lay = layouter.place(
- spchar, x=x, y=(y + 50), rotation=_geo.Rotation.R90,
- )
-
# Make three rows of to place standard cells in
#
dbound = 4.0
@@ -1755,132 +1801,19 @@
layouter.add_wire(net=dvdd, wire=m3, pin=m3pin, shape=dvdd_bb)
- # below SRAM
- rot_midrow = _geo.Rotation.R0
- _tie_rotbb = rot_midrow*_tie_bb
-
- y_midrow = spsram_bb.bottom - dbound - _tie_rotbb.top
-
- inst = ckt.instantiate(tie_cell, name="mltie")
- dvss.childports += inst.ports.vss
- dvdd.childports += inst.ports.vdd
-
- x_tie = spsram_bb.left - _tie_rotbb.left
- lay = layouter.place(inst, x=x_tie, y=y_midrow, rotation=rot_midrow)
- nwmbb1 = lay.bounds(mask=nwm.mask)
- lipindvssbb1 = lay.bounds(mask=lipin.mask, net=dvss, depth=1)
- lipindvddbb1 = lay.bounds(mask=lipin.mask, net=dvdd, depth=1)
-
- inst = ckt.instantiate(tie_cell, name="mrtie")
- dvss.childports += inst.ports.vss
- dvdd.childports += inst.ports.vdd
-
- x_tie = spsram_bb.right - _tie_rotbb.right
- lay = layouter.place(inst, x=x_tie, y=y_midrow, rotation=rot_midrow)
- nwmbb2 = lay.bounds(mask=nwm.mask)
- lipindvssbb2 = lay.bounds(mask=lipin.mask, net=dvss, depth=1)
- lipindvddbb2 = lay.bounds(mask=lipin.mask, net=dvdd, depth=1)
-
- shape = _geo.Rect.from_rect(rect=nwmbb1, right=nwmbb2.right)
- layouter.add_wire(net=dvdd, wire=nwm, shape=shape)
-
- shape = _geo.Rect.from_rect(rect=lipindvssbb1, right=lipindvssbb2.right)
- layouter.add_wire(net=dvss, wire=li, shape=shape)
- w = tech.on_grid(shape.width, mult=2, rounding="floor")
- h = tech.on_grid(shape.height, mult=2, rounding="floor")
- o = tech.on_grid(shape.center)
- lay = layouter.add_wire(
- net=dvss, wire=mcon, origin=o, bottom_width=w, bottom_height=h,
- )
- dvss_midrowm1bb = lay.bounds(mask=m1.mask)
-
- shape = _geo.Rect.from_rect(rect=lipindvddbb1, right=lipindvddbb2.right)
- layouter.add_wire(net=dvdd, wire=li, shape=shape)
- w = tech.on_grid(shape.width, mult=2, rounding="floor")
- h = tech.on_grid(shape.height, mult=2, rounding="floor")
- o = tech.on_grid(shape.center)
- lay = layouter.add_wire(
- net=dvdd, wire=mcon, origin=o, bottom_width=w, bottom_height=h,
- )
- dvdd_midrowm1bb = lay.bounds(mask=m1.mask)
-
- assert dvss_leftrowm1bb.center.x > dvdd_leftrowm1bb.center.x, "Internal error"
- assert dvss_rightrowm1bb.center.x > dvdd_rightrowm1bb.center.x, "Internal error"
-
- shape = _geo.Rect.from_rect(
- rect=dvss_midrowm1bb,
- left=dvss_leftrowm1bb.left, right=dvdd_rightrowm1bb.left - 1.0,
- )
- layouter.add_wire(net=dvss, wire=m1, shape=shape)
-
- w = shape.height
- _via_lay = layouter.wire_layout(
- net=dvss, wire=via, bottom_width=w, bottom_height=w,
- )
- _via_m1bb = _via_lay.bounds(mask=m1.mask)
-
- y_via = shape.center.y
- x_via = shape.right - _via_m1bb.right
- lay = layouter.place(_via_lay, x=x_via, y=y_via)
- m2bb1 = lay.bounds(mask=m2.mask)
- x_via = dvss_rightrowm1bb.center.x
- lay = layouter.place(_via_lay, x=x_via, y=y_via)
- m2bb2 = lay.bounds(mask=m2.mask)
-
- shape = _geo.Rect.from_rect(rect=m2bb1, right=m2bb2.right)
- layouter.add_wire(net=dvss, wire=m2, shape=shape)
-
- shape = _geo.Rect.from_rect(
- rect=dvdd_midrowm1bb,
- left=(dvss_leftrowm1bb.right + 1.0), right=dvdd_rightrowm1bb.right,
- )
- layouter.add_wire(net=dvdd, wire=m1, shape=shape)
-
- w = shape.height
- _via_lay = layouter.wire_layout(
- net=dvdd, wire=via, bottom_width=w, bottom_height=w,
- )
- _via_m1bb = _via_lay.bounds(mask=m1.mask)
-
- y_via = shape.center.y
- x_via = shape.left - _via_m1bb.left
- lay = layouter.place(_via_lay, x=x_via, y=y_via)
- m2bb1 = lay.bounds(mask=m2.mask)
- x_via = dvdd_leftrowm1bb.center.x
- lay = layouter.place(_via_lay, x=x_via, y=y_via)
- m2bb2 = lay.bounds(mask=m2.mask)
-
- shape = _geo.Rect.from_rect(rect=m2bb1, left=m2bb2.left)
- layouter.add_wire(net=dvdd, wire=m2, shape=shape)
-
# Connect the SRAM signals
#
- # vss
- spec = io_sig2spec["vss"]
+ # svss
+ spec = io_sig2spec["svss"]
sram_port = spsram.ports[spec.sram_signal]
net = ckt.new_net(name=spec.toppin_name, external=True, childports=sram_port)
toppin_bb = _frm.toppins[spec.toppin_name]
- bbs = tuple(ms.shape.bounds for ms in spsram_lay.filter_polygons(
- net=net, mask=m2pin.mask, depth=1, split=True,
- ))
- left = max(bb.left for bb in bbs)
- top = max(bb.top for bb in bbs)
- bottom = min(bb.bottom for bb in bbs)
- w = 10.0
- x_via2 = left + w/2.0
- right = left + w
+ sram_m3pinbb = spsram_lay.bounds(mask=m3pin.mask, net=net, depth=1)
+ left = sram_m3pinbb.left
+ right = sram_m3pinbb.right
+ top = sram_m3pinbb.top
- for bb in bbs:
- y_via2 = bb.center.y
- layouter.add_wire(
- net=net, wire=via2, x=x_via2, y=y_via2,
- bottom_width=w, bottom_enclosure="wide",
- top_width=w, top_enclosure="wide",
- )
-
- shape = _geo.Rect(
- left=left, bottom=bottom, right=right, top=(top + 20.0),
- )
+ shape = _geo.Rect.from_rect(rect=sram_m3pinbb, top=(sram_m3pinbb.top + 20.0))
layouter.add_wire(net=net, wire=m3, shape=shape)
shape = _geo.Rect(
left=toppin_bb.left, bottom=(top + 10.0), right=right, top=(top+20.0),
@@ -1895,32 +1828,17 @@
shape = _geo.Rect.from_rect(rect=clamp_bb, bottom=(top + 10))
layouter.add_wire(net=net, wire=m3, shape=shape)
- # vdd
- spec = io_sig2spec["vdd"]
+ # svdd
+ spec = io_sig2spec["svdd"]
sram_port = spsram.ports[spec.sram_signal]
net = ckt.new_net(name=spec.toppin_name, external=True, childports=sram_port)
toppin_bb = _frm.toppins[spec.toppin_name]
- bbs = tuple(ms.shape.bounds for ms in spsram_lay.filter_polygons(
- net=net, mask=m2pin.mask, depth=1, split=True,
- ))
- right = min(bb.right for bb in bbs)
- top = max(bb.top for bb in bbs)
- bottom = min(bb.bottom for bb in bbs)
- w = 10.0
- x_via2 = right - w/2.0
- left = right - w
+ sram_m3pinbb = spsram_lay.bounds(mask=m3pin.mask, net=net, depth=1)
+ left = sram_m3pinbb.left
+ right = sram_m3pinbb.right
+ top = sram_m3pinbb.top
- for bb in bbs:
- y_via2 = bb.center.y
- layouter.add_wire(
- net=net, wire=via2, x=x_via2, y=y_via2,
- bottom_width=w, bottom_enclosure="wide",
- top_width=w, top_enclosure="wide",
- )
-
- shape = _geo.Rect(
- left=left, bottom=bottom, right=right, top=(top + 20.0),
- )
+ shape = _geo.Rect.from_rect(rect=sram_m3pinbb, top=(sram_m3pinbb.top + 20.0))
layouter.add_wire(net=net, wire=m3, shape=shape)
shape = _geo.Rect(
left=left, bottom=(top + 10.0), right=toppin_bb.right, top=(top + 20.0),
@@ -1941,398 +1859,768 @@
)
layouter.add_wire(net=net, wire=m3, shape=shape)
- # connect the input signals
- a_col = 0
- for sig_name in (
- *(f"a[{a_bit}]" for a_bit in reversed(range(a_bits))), # Reversed for a_col
- "clk", "we[0]",
- *(f"d[{bit}]" for bit in range(word_size)),
- ):
- spec = io_sig2spec[sig_name]
+ #
+ # Support functions
+ #
+ def place_ioperiph(*, spec: _io_spec, sram: _ckt._CellInstance):
+ sig_name = spec.sram_signal
prefix = spec.prefix
num = spec.io_number
pin_name = spec.toppin_name
oeb_name = f"io_oeb[{num}]"
out_name = f"io_out[{num}]"
- assert spec.io_type == "io_in", "Internal error"
- assert spec.oeb, "Internal error"
- sram_port = spsram.ports[sig_name]
+ sram_port = sram.ports[sig_name]
- # instantiate cells
- buf = ckt.instantiate(buf_cell, name="{prefix}buf")
- one = ckt.instantiate(one_cell, name=f"{prefix}one")
- zero = ckt.instantiate(zero_cell, name=f"{prefix}zero")
- tie = ckt.instantiate(tie_cell, name=f"{prefix}tie")
+ if spec.io_type == "io_in":
+ assert spec.oeb, "Internal error"
- # create nets
- pin_net = ckt.new_net(name=pin_name, external=True, childports=buf.ports.i)
- sig_net = ckt.new_net(name=sig_name, external=False, childports=(
- buf.ports.q, sram_port,
- ))
- oeb_net = ckt.new_net(
- name=oeb_name, external=True, childports=one.ports.one,
- )
- out_net = ckt.new_net(
- name=out_name, external=True, childports=zero.ports.zero,
- )
+ # instantiate cells
+ buf = ckt.instantiate(buf_cell, name="{prefix}buf")
+ one = ckt.instantiate(one_cell, name=f"{prefix}one")
+ zero = ckt.instantiate(zero_cell, name=f"{prefix}zero")
+ tie = ckt.instantiate(tie_cell, name=f"{prefix}tie")
- # get bbs; SRAM m2 pin to m3 pin
- toppin_bb = _frm.toppins[pin_name]
- oeb_bb = _frm.toppins[oeb_name]
- out_bb = _frm.toppins[out_name]
- if sig_name.startswith("a["):
- # Connect signal up to m2
- sram_m1pinbb = spsram_lay.bounds(mask=m1pin.mask, net=sig_net, depth=1)
+ # create nets
+ pin_net = ckt.new_net(name=pin_name, external=True, childports=buf.ports.i)
+ sig_net = ckt.new_net(name=sig_name, external=False, childports=(
+ buf.ports.q, sram_port,
+ ))
+ oeb_net = ckt.new_net(
+ name=oeb_name, external=True, childports=one.ports.one,
+ )
+ out_net = ckt.new_net(
+ name=out_name, external=True, childports=zero.ports.zero,
+ )
- w = 10.0
- right = spsram_bb.left - (2*a_col + 1)*w
- left = right - 1
- a_col += 1
+ # get bbs
+ toppin_bb = _frm.toppins[pin_name]
+ oeb_bb = _frm.toppins[oeb_name]
+ out_bb = _frm.toppins[out_name]
+ is_leftrow = toppin_bb.center.x < _frm.boundary.center.x
- x_via = right - w/2.0
- y_via = tech.on_grid(sram_m1pinbb.center.y)
- via_lay = layouter.add_wire(
- net=sig_net, wire=via, x=x_via, y=y_via,
+ rot = rot_leftrow if is_leftrow else rot_rightrow
+ x_row = x_leftrow if is_leftrow else x_rightrow
+
+ # place buf
+ _buf_rotilipinbb = rot*_buf_ilipinbb
+ y_buf = tech.on_grid(
+ toppin_bb.top - _buf_rotilipinbb.bottom,
+ mult=2,
+ )
+ buf_lay = layouter.place(buf, x=x_row, y=y_buf, rotation=rot)
+ pinbuf_lipinbb = buf_lay.bounds(mask=lipin.mask, net=pin_net, depth=1)
+ sigbuf_lipinbb = buf_lay.bounds(mask=lipin.mask, net=sig_net, depth=1)
+ buf_bb = buf_lay.boundary
+ assert buf_bb is not None
+
+ # place tie cell
+ _tie_rotbb = rot*_tie_bb
+ if is_leftrow:
+ y_tie = buf_bb.top - _tie_rotbb.bottom
+ else:
+ y_tie = buf_bb.bottom - _tie_rotbb.top
+ layouter.place(tie, x=x_row, y=y_tie, rotation=rot)
+
+ # place zero cell
+ _zero_rotbb = rot*_zero_bb
+ if is_leftrow:
+ y_zero = buf_bb.bottom - _zero_rotbb.top
+ else:
+ y_zero = buf_bb.top - _zero_rotbb.bottom
+ zero_lay = layouter.place(zero, x=x_row, y=y_zero, rotation=rot)
+ zero_bb = zero_lay.boundary
+ assert zero_bb is not None
+ zeroout_lipinbb = zero_lay.bounds(mask=lipin.mask, net=out_net, depth=1)
+
+ # place one cell
+ _one_rotbb = rot*_one_bb
+ if is_leftrow:
+ y_one = zero_bb.bottom - _one_rotbb.top
+ else:
+ y_one = zero_bb.top - _one_rotbb.bottom
+ one_lay = layouter.place(one, x=x_row, y=y_one, rotation=rot)
+ oneoeb_lipinbb = one_lay.bounds(mask=lipin.mask, net=oeb_net, depth=1)
+
+ # connect pin_net
+ w = tech.on_grid(pinbuf_lipinbb.width, mult=2, rounding="floor")
+ o_via = tech.on_grid(pinbuf_lipinbb.center)
+ layouter.add_wire(
+ net=pin_net, wire=mcon, origin=o_via,
bottom_width=w, bottom_enclosure="wide",
top_width=w, top_enclosure="wide",
)
- via_m1bb = via_lay.bounds(mask=m1.mask)
- sram_m2pinbb = via_lay.bounds(mask=m2.mask)
+ layouter.add_wire(
+ net=pin_net, wire=via, origin=o_via,
+ bottom_width=w, bottom_enclosure="wide",
+ top_width=w, top_enclosure="wide",
+ )
+ via2_lay = layouter.add_wire(
+ net=pin_net, wire=via2, origin=o_via,
+ bottom_width=w, bottom_enclosure="wide",
+ top_width=w, top_enclosure="wide",
+ )
+ via2_m3bb = via2_lay.bounds(mask=m3.mask)
- shape = _geo.Rect.from_rect(rect=sram_m1pinbb, left=via_m1bb.left)
- layouter.add_wire(net=sig_net, wire=m1, shape=shape)
+ if is_leftrow:
+ shape = _geo.Rect.from_rect(rect=toppin_bb, right=via2_m3bb.right)
+ else:
+ shape = _geo.Rect.from_rect(rect=toppin_bb, left=via2_m3bb.left)
+ layouter.add_wire(net=pin_net, wire=m3, shape=shape)
+ layouter.add_wire(net=pin_net, wire=m3, pin=m3pin, shape=toppin_bb)
+
+ # connect oeb_net
+ w = tech.on_grid(oneoeb_lipinbb.width, mult=2, rounding="floor")
+ o_via = tech.on_grid(oneoeb_lipinbb.center)
+ layouter.add_wire(
+ net=oeb_net, wire=mcon, origin=o_via,
+ bottom_width=w, bottom_enclosure="wide",
+ top_width=w, top_enclosure="wide",
+ )
+ via_lay = layouter.add_wire(
+ net=oeb_net, wire=via, origin=o_via,
+ bottom_width=w, bottom_enclosure="wide",
+ top_width=w, top_enclosure="wide",
+ )
+ via_m2bb = via_lay.bounds(mask=m2.mask)
+
+ o_via2 = _geo.Point.from_point(point=o_via, y=oeb_bb.center.y)
+ via2_lay = layouter.add_wire(
+ net=oeb_net, wire=via2, origin=o_via2,
+ bottom_width=w, bottom_enclosure="wide",
+ top_width=w, top_enclosure="wide",
+ )
+ via2_m2bb = via2_lay.bounds(mask=m2.mask)
+ via2_m3bb = via2_lay.bounds(mask=m3.mask)
+
+ if is_leftrow:
+ shape = _geo.Rect.from_rect(rect=via_m2bb, bottom=via2_m2bb.bottom)
+ else:
+ shape = _geo.Rect.from_rect(rect=via_m2bb, top=via2_m2bb.top)
+ layouter.add_wire(net=oeb_net, wire=m2, shape=shape)
+ if is_leftrow:
+ shape = _geo.Rect.from_rect(rect=oeb_bb, right=via2_m3bb.right)
+ else:
+ shape = _geo.Rect.from_rect(rect=oeb_bb, left=via2_m3bb.left)
+ layouter.add_wire(net=oeb_net, wire=m3, shape=shape)
+
+ layouter.add_wire(net=oeb_net, wire=m3, pin=m3pin, shape=oeb_bb)
+
+ # connect out_net
+ w = tech.on_grid(zeroout_lipinbb.width, mult=2, rounding="floor")
+ o_via = tech.on_grid(zeroout_lipinbb.center)
+ layouter.add_wire(
+ net=out_net, wire=mcon, origin=o_via,
+ bottom_width=w, bottom_enclosure="wide",
+ top_width=w, top_enclosure="wide",
+ )
+ layouter.add_wire(
+ net=out_net, wire=via, origin=o_via,
+ bottom_width=w, bottom_enclosure="wide",
+ top_width=w, top_enclosure="wide",
+ )
+ via2_lay = layouter.add_wire(
+ net=out_net, wire=via2, origin=o_via,
+ bottom_width=w, bottom_enclosure="wide",
+ top_width=w, top_enclosure="wide",
+ )
+ via2_m3bb = via2_lay.bounds(mask=m3.mask)
+
+ if is_leftrow:
+ shape = _geo.Rect.from_rect(rect=via2_m3bb, bottom=out_bb.bottom)
+ else:
+ shape = _geo.Rect.from_rect(rect=via2_m3bb, top=out_bb.top)
+ layouter.add_wire(net=out_net, wire=m3, shape=shape)
+ if is_leftrow:
+ shape = _geo.Rect.from_rect(rect=out_bb, right=via2_m3bb.right)
+ else:
+ shape = _geo.Rect.from_rect(rect=out_bb, left=via2_m3bb.left)
+ layouter.add_wire(net=out_net, wire=m3, shape=shape)
+
+ layouter.add_wire(net=out_net, wire=m3, pin=m3pin, shape=out_bb)
+
+ # connect sig_net
+ w = tech.on_grid(sigbuf_lipinbb.width, mult=2, rounding="floor")
+ o_via = tech.on_grid(sigbuf_lipinbb.center)
+ layouter.add_wire(
+ net=sig_net, wire=mcon, origin=o_via,
+ bottom_width=w, bottom_enclosure="wide",
+ top_width=w, top_enclosure="wide",
+ )
+ layouter.add_wire(
+ net=sig_net, wire=via, origin=o_via,
+ bottom_width=w, bottom_enclosure="wide",
+ top_width=w, top_enclosure="wide",
+ )
+ via2_lay = layouter.add_wire(
+ net=sig_net, wire=via2, origin=o_via,
+ bottom_width=w, bottom_enclosure="wide",
+ top_width=w, top_enclosure="wide",
+ )
+ via2sig_m3bb = via2_lay.bounds(mask=m3.mask)
+ elif spec.io_type == "io_out":
+ assert not spec.oeb, "Internal error"
+
+ # instantiate cells
+ buf = ckt.instantiate(buf_cell, name="{prefix}buf")
+ zero = ckt.instantiate(zero_cell, name=f"{prefix}zero")
+ tie = ckt.instantiate(tie_cell, name=f"{prefix}tie")
+
+ # create nets
+ sig_net = pin_net = ckt.new_net(
+ name=pin_name, external=True, childports=sram_port,
+ )
+ oeb_net = ckt.new_net(
+ name=oeb_name, external=True, childports=zero.ports.zero,
+ )
+
+ # get bss
+ toppin_bb = _frm.toppins[pin_name]
+ oeb_bb = _frm.toppins[oeb_name]
+
+ is_leftrow = toppin_bb.center.x < _frm.boundary.center.x
+
+ # place zero
+ rot = rot_leftrow if is_leftrow else rot_rightrow
+ x_row = x_leftrow if is_leftrow else x_rightrow
+ _zero_rotzerolipinbb = rot*_zero_zerolipinbb
+ y_zero = oeb_bb.center.y - _zero_rotzerolipinbb.center.y
+ zero_lay = layouter.place(zero, x=x_row, y=y_zero, rotation=rot)
+ zero_zerolipinbb = zero_lay.bounds(mask=lipin.mask, net=oeb_net, depth=1)
+ zero_bb = zero_lay.boundary
+ assert zero_bb is not None
+
+ # place tie
+ _tie_rotbb = rot*_tie_bb
+ y_tie = zero_bb.top - _tie_rotbb.bottom
+ layouter.place(tie, x=x_row, y=y_tie, rotation=rot)
+
+ # connect sig_net
+ layouter.add_wire(net=sig_net, wire=m3, pin=m3pin, shape=toppin_bb)
+ via2sig_m3bb = toppin_bb
+
+ # connect oeb_net
+ w = tech.on_grid(zero_zerolipinbb.width, mult=2, rounding="floor")
+ o_via = tech.on_grid(zero_zerolipinbb.center)
+ layouter.add_wire(
+ net=oeb_net, wire=mcon, origin=o_via,
+ bottom_width=w, bottom_enclosure="wide",
+ top_width=w, top_enclosure="wide",
+ )
+ layouter.add_wire(
+ net=oeb_net, wire=via, origin=o_via,
+ bottom_width=w, bottom_enclosure="wide",
+ top_width=w, top_enclosure="wide",
+ )
+ via2_lay = layouter.add_wire(
+ net=oeb_net, wire=via2, origin=o_via,
+ bottom_width=w, bottom_enclosure="wide",
+ top_width=w, top_enclosure="wide",
+ )
+ via2_m3bb = via2_lay.bounds(mask=m3.mask)
+
+ if is_leftrow:
+ shape = _geo.Rect.from_rect(rect=oeb_bb, right=via2_m3bb.right)
+ else:
+ shape = _geo.Rect.from_rect(rect=oeb_bb, left=via2_m3bb.left)
+ layouter.add_wire(net=oeb_net, wire=m3, shape=shape)
+ layouter.add_wire(net=oeb_net, wire=m3, pin=m3pin, shape=oeb_bb)
else:
- sram_m2pinbb = spsram_lay.bounds(mask=m2pin.mask, net=sig_net, depth=1)
- is_leftrow = toppin_bb.center.x < sram_m2pinbb.center.x
+ assert False, "Internal error"
- rot = rot_leftrow if is_leftrow else rot_rightrow
- x_row = x_leftrow if is_leftrow else x_rightrow
+ return sig_net, via2sig_m3bb
- # place buf
- _buf_rotilipinbb = rot*_buf_ilipinbb
- y_buf = tech.on_grid(
- toppin_bb.top - _buf_rotilipinbb.bottom,
- mult=2,
- )
- buf_lay = layouter.place(buf, x=x_row, y=y_buf, rotation=rot)
- pinbuf_lipinbb = buf_lay.bounds(mask=lipin.mask, net=pin_net, depth=1)
- sigbuf_lipinbb = buf_lay.bounds(mask=lipin.mask, net=sig_net, depth=1)
- buf_bb = buf_lay.boundary
- assert buf_bb is not None
+ #
+ # SP connections
+ #
- # place tie cell
- _tie_rotbb = rot*_tie_bb
- if is_leftrow:
- y_tie = buf_bb.top - _tie_rotbb.bottom
- else:
- y_tie = buf_bb.bottom - _tie_rotbb.top
- layouter.place(tie, x=x_row, y=y_tie, rotation=rot)
+ left_col = 1
+ right_col = 1
+ col_width = 10.0
+ col_pitch = 20.0
+ col_left0 = 20.0
+ col_right0 = 2890.0
- # place zero cell
- _zero_rotbb = rot*_zero_bb
- if is_leftrow:
- y_zero = buf_bb.bottom - _zero_rotbb.top
- else:
- y_zero = buf_bb.top - _zero_rotbb.bottom
- zero_lay = layouter.place(zero, x=x_row, y=y_zero, rotation=rot)
- zero_bb = zero_lay.boundary
- assert zero_bb is not None
- zeroout_lipinbb = zero_lay.bounds(mask=lipin.mask, net=out_net, depth=1)
+ # Connect in_shiftclk
+ sig_net, sig_m3bb = place_ioperiph(
+ spec=io_spsig2spec["in_shiftclk"], sram=spsram,
+ )
- # place one cell
- _one_rotbb = rot*_one_bb
- if is_leftrow:
- y_one = zero_bb.bottom - _one_rotbb.top
- else:
- y_one = zero_bb.top - _one_rotbb.bottom
- one_lay = layouter.place(one, x=x_row, y=y_one, rotation=rot)
- oneoeb_lipinbb = one_lay.bounds(mask=lipin.mask, net=oeb_net, depth=1)
+ sramsig_m1pinbb = spsram_lay.bounds(mask=m1pin.mask, net=sig_net, depth=1)
- # connect pin_net
- w = tech.on_grid(pinbuf_lipinbb.width, mult=2, rounding="floor")
- o_via = tech.on_grid(pinbuf_lipinbb.center)
- layouter.add_wire(
- net=pin_net, wire=mcon, origin=o_via,
- bottom_width=w, bottom_enclosure="wide",
- top_width=w, top_enclosure="wide",
- )
- layouter.add_wire(
- net=pin_net, wire=via, origin=o_via,
- bottom_width=w, bottom_enclosure="wide",
- top_width=w, top_enclosure="wide",
- )
- via2_lay = layouter.add_wire(
- net=pin_net, wire=via2, origin=o_via,
- bottom_width=w, bottom_enclosure="wide",
- top_width=w, top_enclosure="wide",
- )
- via2_m3bb = via2_lay.bounds(mask=m3.mask)
+ _viasig_lay = layouter.wire_layout(
+ net=sig_net, wire=via, rows=10, columns=10,
+ )
+ _viasig_m1bb = _viasig_lay.bounds(mask=m1.mask)
- if is_leftrow:
- shape = _geo.Rect.from_rect(rect=toppin_bb, right=via2_m3bb.right)
- else:
- shape = _geo.Rect.from_rect(rect=toppin_bb, left=via2_m3bb.left)
- layouter.add_wire(net=pin_net, wire=m3, shape=shape)
- layouter.add_wire(net=pin_net, wire=m3, pin=m3pin, shape=toppin_bb)
+ x = sramsig_m1pinbb.right - _viasig_m1bb.right
+ y = sramsig_m1pinbb.center.y
+ layouter.place(_viasig_lay, x=x, y=y)
+ via2_lay = layouter.add_wire(
+ net=sig_net, wire=via2, rows=10, columns=10, x=x, y=y,
+ )
+ via2_m3bb = via2_lay.bounds(mask=m3.mask)
- # connect sig_net
- w = tech.on_grid(sigbuf_lipinbb.width, mult=2, rounding="floor")
- o_via = tech.on_grid(sigbuf_lipinbb.center)
- layouter.add_wire(
- net=sig_net, wire=mcon, origin=o_via,
- bottom_width=w, bottom_enclosure="wide",
- top_width=w, top_enclosure="wide",
- )
- layouter.add_wire(
- net=sig_net, wire=via, origin=o_via,
- bottom_width=w, bottom_enclosure="wide",
- top_width=w, top_enclosure="wide",
- )
- via2_lay = layouter.add_wire(
- net=sig_net, wire=via2, origin=o_via,
- bottom_width=w, bottom_enclosure="wide",
- top_width=w, top_enclosure="wide",
- )
- via2_m3bb1 = via2_lay.bounds(mask=m3.mask)
+ col_left = col_left0 + (left_col - 1)*col_pitch
+ col_right = col_left + col_width
+ shape = _geo.Polygon.from_floats(points=(
+ (sig_m3bb.left, sig_m3bb.bottom),
+ (sig_m3bb.left, sig_m3bb.top + 1.0),
+ (col_left, sig_m3bb.top + 1.0),
+ (col_left, via2_m3bb.top),
+ (via2_m3bb.right, via2_m3bb.top),
+ (via2_m3bb.right, via2_m3bb.bottom),
+ (col_right, via2_m3bb.bottom),
+ (col_right, sig_m3bb.bottom),
+ (sig_m3bb.left, sig_m3bb.bottom),
+ ))
+ layouter.add_wire(net=sig_net, wire=m3, shape=shape)
- _via2_lay = layouter.wire_layout(
- net=sig_net, wire=via2, rows=6, columns=3,
- )
- _via2_m2bb = _via2_lay.bounds(mask=m2.mask)
- if is_leftrow:
- x_via2 = sram_m2pinbb.right - _via2_m2bb.right
- else:
- x_via2 = sram_m2pinbb.left - _via2_m2bb.left
- y_via2 = via2_m3bb1.center.y
- via2_lay = layouter.place(_via2_lay, x=x_via2, y=y_via2)
- via2_m2bb = via2_lay.bounds(mask=m2.mask)
- via2_m3bb2 = via2_lay.bounds(mask=m3.mask)
+ left_col += 1
- shape = _geo.Rect.from_rect(rect=sram_m2pinbb, bottom=via2_m2bb.bottom)
- layouter.add_wire(net=sig_net, wire=m2, shape=shape)
- if is_leftrow:
- shape = _geo.Rect.from_rect(rect=via2_m3bb1, right=via2_m3bb2.right)
- else:
- shape = _geo.Rect.from_rect(rect=via2_m3bb1, left=via2_m3bb2.left)
- layouter.add_wire(net=sig_net, wire=m3, shape=shape)
+ # Connect shift_in
+ sig_net, sig_m3bb = place_ioperiph(
+ spec=io_spsig2spec["shift_in"], sram=spsram,
+ )
- # connect oeb_net
- w = tech.on_grid(oneoeb_lipinbb.width, mult=2, rounding="floor")
- o_via = tech.on_grid(oneoeb_lipinbb.center)
- layouter.add_wire(
- net=oeb_net, wire=mcon, origin=o_via,
- bottom_width=w, bottom_enclosure="wide",
- top_width=w, top_enclosure="wide",
- )
- via_lay = layouter.add_wire(
- net=oeb_net, wire=via, origin=o_via,
- bottom_width=w, bottom_enclosure="wide",
- top_width=w, top_enclosure="wide",
- )
- via_m2bb = via_lay.bounds(mask=m2.mask)
+ sramsig_m1pinbb = spsram_lay.bounds(mask=m1pin.mask, net=sig_net, depth=1)
- o_via2 = _geo.Point.from_point(point=o_via, y=oeb_bb.center.y)
- via2_lay = layouter.add_wire(
- net=oeb_net, wire=via2, origin=o_via2,
- bottom_width=w, bottom_enclosure="wide",
- top_width=w, top_enclosure="wide",
- )
- via2_m2bb = via2_lay.bounds(mask=m2.mask)
- via2_m3bb = via2_lay.bounds(mask=m3.mask)
+ _viasig_lay = layouter.wire_layout(
+ net=sig_net, wire=via, rows=10, columns=10,
+ )
+ _viasig_m1bb = _viasig_lay.bounds(mask=m1.mask)
- if is_leftrow:
- shape = _geo.Rect.from_rect(rect=via_m2bb, bottom=via2_m2bb.bottom)
- else:
- shape = _geo.Rect.from_rect(rect=via_m2bb, top=via2_m2bb.top)
- layouter.add_wire(net=oeb_net, wire=m2, shape=shape)
- if is_leftrow:
- shape = _geo.Rect.from_rect(rect=oeb_bb, right=via2_m3bb.right)
- else:
- shape = _geo.Rect.from_rect(rect=oeb_bb, left=via2_m3bb.left)
- layouter.add_wire(net=oeb_net, wire=m3, shape=shape)
+ x = sramsig_m1pinbb.right - _viasig_m1bb.right
+ y = sramsig_m1pinbb.center.y
+ layouter.place(_viasig_lay, x=x, y=y)
+ via2_lay = layouter.add_wire(
+ net=sig_net, wire=via2, rows=10, columns=10, x=x, y=y,
+ )
+ via2_m3bb = via2_lay.bounds(mask=m3.mask)
- layouter.add_wire(net=oeb_net, wire=m3, pin=m3pin, shape=oeb_bb)
+ col_left = col_left0 + (left_col - 1)*col_pitch
+ col_right = col_left + col_width
+ shape = _geo.Polygon.from_floats(points=(
+ (sig_m3bb.left, sig_m3bb.bottom),
+ (sig_m3bb.left, sig_m3bb.top + 1.0),
+ (col_left, sig_m3bb.top + 1.0),
+ (col_left, via2_m3bb.top),
+ (via2_m3bb.right, via2_m3bb.top),
+ (via2_m3bb.right, via2_m3bb.bottom),
+ (col_right, via2_m3bb.bottom),
+ (col_right, sig_m3bb.bottom),
+ (sig_m3bb.left, sig_m3bb.bottom),
+ ))
+ layouter.add_wire(net=sig_net, wire=m3, shape=shape)
- # connect out_net
- w = tech.on_grid(zeroout_lipinbb.width, mult=2, rounding="floor")
- o_via = tech.on_grid(zeroout_lipinbb.center)
- layouter.add_wire(
- net=out_net, wire=mcon, origin=o_via,
- bottom_width=w, bottom_enclosure="wide",
- top_width=w, top_enclosure="wide",
- )
- layouter.add_wire(
- net=out_net, wire=via, origin=o_via,
- bottom_width=w, bottom_enclosure="wide",
- top_width=w, top_enclosure="wide",
- )
- via2_lay = layouter.add_wire(
- net=out_net, wire=via2, origin=o_via,
- bottom_width=w, bottom_enclosure="wide",
- top_width=w, top_enclosure="wide",
- )
- via2_m3bb = via2_lay.bounds(mask=m3.mask)
+ left_col += 1
- if is_leftrow:
- shape = _geo.Rect.from_rect(rect=via2_m3bb, bottom=out_bb.bottom)
- else:
- shape = _geo.Rect.from_rect(rect=via2_m3bb, top=out_bb.top)
- layouter.add_wire(net=out_net, wire=m3, shape=shape)
- if is_leftrow:
- shape = _geo.Rect.from_rect(rect=out_bb, right=via2_m3bb.right)
- else:
- shape = _geo.Rect.from_rect(rect=out_bb, left=via2_m3bb.left)
- layouter.add_wire(net=out_net, wire=m3, shape=shape)
+ # Connect in_captureclk_l
+ sig_net, sig_m3bb = place_ioperiph(
+ spec=io_spsig2spec["in_captureclk_l"], sram=spsram,
+ )
- layouter.add_wire(net=out_net, wire=m3, pin=m3pin, shape=out_bb)
+ sramsig_m1pinbb = spsram_lay.bounds(mask=m1pin.mask, net=sig_net, depth=1)
- # connect the output signals
- for sig_name in (
- *(f"q[{bit}]" for bit in range(word_size)),
- ):
- spec = io_sig2spec[sig_name]
- prefix = spec.prefix
- num = spec.io_number
+ _viasig_lay = layouter.wire_layout(
+ net=sig_net, wire=via, rows=10, columns=10,
+ )
+ _viasig_m1bb = _viasig_lay.bounds(mask=m1.mask)
- pin_name = spec.toppin_name
- oeb_name = f"io_oeb[{num}]"
- assert spec.io_type == "io_out", "Internal error"
- assert not spec.oeb, "Internal error"
- sram_port = spsram.ports[spec.sram_signal]
+ x = sramsig_m1pinbb.right - _viasig_m1bb.right
+ y = sramsig_m1pinbb.center.y
+ layouter.place(_viasig_lay, x=x, y=y)
+ via2_lay = layouter.add_wire(
+ net=sig_net, wire=via2, rows=10, columns=10, x=x, y=y,
+ )
+ via2_m3bb = via2_lay.bounds(mask=m3.mask)
- # instantiate cells
- buf = ckt.instantiate(buf_cell, name="{prefix}buf")
- zero = ckt.instantiate(zero_cell, name=f"{prefix}zero")
- tie = ckt.instantiate(tie_cell, name=f"{prefix}tie")
+ col_left = col_left0 + (left_col - 1)*col_pitch
+ col_right = col_left + col_width
+ shape = _geo.Polygon.from_floats(points=(
+ (sig_m3bb.left, sig_m3bb.bottom),
+ (sig_m3bb.left, sig_m3bb.top + 1.0),
+ (col_left, sig_m3bb.top + 1.0),
+ (col_left, via2_m3bb.top),
+ (via2_m3bb.right, via2_m3bb.top),
+ (via2_m3bb.right, via2_m3bb.bottom),
+ (col_right, via2_m3bb.bottom),
+ (col_right, sig_m3bb.bottom),
+ (sig_m3bb.left, sig_m3bb.bottom),
+ ))
+ layouter.add_wire(net=sig_net, wire=m3, shape=shape)
- # create nets
- pin_net = ckt.new_net(name=pin_name, external=True, childports=buf.ports.q)
- sig_net = ckt.new_net(name=sig_name, external=False, childports=(
- buf.ports.i, sram_port,
- ))
- oeb_net = ckt.new_net(
- name=oeb_name, external=True, childports=zero.ports.zero,
- )
+ left_col += 1
- # get bss
- toppin_bb = _frm.toppins[pin_name]
- oeb_bb = _frm.toppins[oeb_name]
- sram_m2pinbb = spsram_lay.bounds(mask=m2pin.mask, net=sig_net, depth=1)
+ # Connect in_captureclk
+ sig_net, sig_m3bb = place_ioperiph(
+ spec=io_spsig2spec["in_captureclk"], sram=spsram,
+ )
- is_leftrow = toppin_bb.center.x < sram_m2pinbb.center.x
+ sramsig_m2pinbb = spsram_lay.bounds(mask=m2pin.mask, net=sig_net, depth=1)
- # place buf
- rot = rot_midrow
- y_row = y_midrow
- _buf_rotilipinbb = rot*_buf_ilipinbb
- x_buf = tech.on_grid(
- sram_m2pinbb.right - _buf_rotilipinbb.left,
- mult=2, rounding="ceiling",
- )
- buf_lay = layouter.place(buf, x=x_buf, y=y_row, rotation=rot)
- pinbuf_lipinbb = buf_lay.bounds(mask=lipin.mask, net=pin_net, depth=1)
- sigbuf_lipinbb = buf_lay.bounds(mask=lipin.mask, net=sig_net, depth=1)
- buf_bb = buf_lay.boundary
- assert buf_bb is not None
+ _via2sig_lay = layouter.wire_layout(
+ net=sig_net, wire=via2, rows=10, columns=10,
+ )
+ _via2sig_m2bb = _via2sig_lay.bounds(mask=m2.mask)
- # place zero
- rot = rot_leftrow if is_leftrow else rot_rightrow
- x_row = x_leftrow if is_leftrow else x_rightrow
- _zero_rotzerolipinbb = rot*_zero_zerolipinbb
- y_zero = oeb_bb.center.y - _zero_rotzerolipinbb.center.y
- zero_lay = layouter.place(zero, x=x_row, y=y_zero, rotation=rot)
- zero_zerolipinbb = zero_lay.bounds(mask=lipin.mask, net=oeb_net, depth=1)
- zero_bb = zero_lay.boundary
- assert zero_bb is not None
+ x = sramsig_m2pinbb.right - _via2sig_m2bb.right
+ y = sramsig_m2pinbb.top - _via2sig_m2bb.top
+ via2_lay = layouter.place(_via2sig_lay, x=x, y=y)
+ via2_m3bb = via2_lay.bounds(mask=m3.mask)
- # place tie
- _tie_rotbb = rot*_tie_bb
- y_tie = zero_bb.top - _tie_rotbb.bottom
- layouter.place(tie, x=x_row, y=y_tie, rotation=rot)
+ col_left = col_left0 + (left_col - 1)*col_pitch
+ col_right = col_left + col_width
+ shape = _geo.Polygon.from_floats(points=(
+ (sig_m3bb.left, sig_m3bb.bottom),
+ (sig_m3bb.left, sig_m3bb.top + 1.0),
+ (col_left, sig_m3bb.top + 1.0),
+ (col_left, via2_m3bb.top),
+ (via2_m3bb.right, via2_m3bb.top),
+ (via2_m3bb.right, via2_m3bb.bottom),
+ (col_right, via2_m3bb.bottom),
+ (col_right, sig_m3bb.bottom),
+ (sig_m3bb.left, sig_m3bb.bottom),
+ ))
+ layouter.add_wire(net=sig_net, wire=m3, shape=shape)
- # connect sig_net
- h = tech.on_grid(sigbuf_lipinbb.height, mult=2, rounding="floor")
- o_via = tech.on_grid(sigbuf_lipinbb.center)
- layouter.add_wire(
- net=sig_net, wire=mcon, origin=o_via,
- bottom_height=h, bottom_enclosure="tall",
- top_height=h, top_enclosure="tall",
- )
- via_lay = layouter.add_wire(
- net=sig_net, wire=via, origin=o_via,
- bottom_height=h, bottom_enclosure="tall",
- top_height=h, top_enclosure="tall",
- )
- via_m2bb = via_lay.bounds(mask=m2.mask)
+ left_col += 1
- shape = _geo.Rect.from_rect(rect=sram_m2pinbb, bottom=via_m2bb.bottom)
- layouter.add_wire(net=sig_net, wire=m2, shape=shape)
+ # Connect sramclk
+ sig_net, sig_m3bb = place_ioperiph(
+ spec=io_spsig2spec["sramclk"], sram=spsram,
+ )
- # connect pin_net
- h = tech.on_grid(pinbuf_lipinbb.height, mult=2, rounding="floor")
- o_via = tech.on_grid(pinbuf_lipinbb.center)
+ sramsig_m2pinbb = spsram_lay.bounds(mask=m2pin.mask, net=sig_net, depth=1)
- layouter.add_wire(
- net=sig_net, wire=mcon, origin=o_via,
- bottom_height=h, bottom_enclosure="tall",
- top_height=h, top_enclosure="tall",
- )
- via_lay = layouter.add_wire(
- net=sig_net, wire=via, origin=o_via,
- bottom_height=h, bottom_enclosure="tall",
- top_height=h, top_enclosure="tall",
- )
- via_m2bb = via_lay.bounds(mask=m2.mask)
+ _via2sig_lay = layouter.wire_layout(
+ net=sig_net, wire=via2, rows=10, columns=10,
+ )
+ _via2sig_m2bb = _via2sig_lay.bounds(mask=m2.mask)
- _via2_lay = layouter.wire_layout(
- net=pin_net, wire=via2, rows=6, columns=3,
- )
- _via2_m2bb = _via2_lay.bounds(mask=m2.mask)
- if is_leftrow:
- x_via2 = via_m2bb.right - _via2_m2bb.right
- else:
- x_via2 = via_m2bb.left - _via2_m2bb.left
- y_via2 = toppin_bb.center.y
- via2_lay = layouter.place(_via2_lay, x=x_via2, y=y_via2)
- via2_m2bb = via2_lay.bounds(mask=m2.mask)
- via2_m3bb = via2_lay.bounds(mask=m3.mask)
+ x = sramsig_m2pinbb.right - _via2sig_m2bb.right
+ y = sramsig_m2pinbb.bottom - _via2sig_m2bb.bottom
+ via2_lay = layouter.place(_via2sig_lay, x=x, y=y)
+ via2_m3bb = via2_lay.bounds(mask=m3.mask)
- shape = _geo.Rect.from_rect(rect=via_m2bb, bottom=via2_m2bb.bottom)
- layouter.add_wire(net=pin_net, wire=m2, shape=shape)
- if is_leftrow:
- shape = _geo.Rect.from_rect(rect=toppin_bb, right=via2_m3bb.right)
- else:
- shape = _geo.Rect.from_rect(rect=toppin_bb, left=via2_m3bb.left)
- layouter.add_wire(net=pin_net, wire=m3, shape=shape)
- layouter.add_wire(net=pin_net, wire=m3, pin=m3pin, shape=toppin_bb)
+ col_left = col_left0 + (left_col - 1)*col_pitch
+ col_right = col_left + col_width
+ shape = _geo.Polygon.from_floats(points=(
+ (sig_m3bb.left, sig_m3bb.bottom),
+ (sig_m3bb.left, sig_m3bb.top + 1.0),
+ (col_left, sig_m3bb.top + 1.0),
+ (col_left, via2_m3bb.top),
+ (via2_m3bb.right, via2_m3bb.top),
+ (via2_m3bb.right, via2_m3bb.bottom),
+ (col_right, via2_m3bb.bottom),
+ (col_right, sig_m3bb.bottom),
+ (sig_m3bb.left, sig_m3bb.bottom),
+ ))
+ layouter.add_wire(net=sig_net, wire=m3, shape=shape)
- # connect oeb_net
- w = tech.on_grid(zero_zerolipinbb.width, mult=2, rounding="floor")
- o_via = tech.on_grid(zero_zerolipinbb.center)
- layouter.add_wire(
- net=oeb_net, wire=mcon, origin=o_via,
- bottom_width=w, bottom_enclosure="wide",
- top_width=w, top_enclosure="wide",
- )
- layouter.add_wire(
- net=oeb_net, wire=via, origin=o_via,
- bottom_width=w, bottom_enclosure="wide",
- top_width=w, top_enclosure="wide",
- )
- via2_lay = layouter.add_wire(
- net=oeb_net, wire=via2, origin=o_via,
- bottom_width=w, bottom_enclosure="wide",
- top_width=w, top_enclosure="wide",
- )
- via2_m3bb = via2_lay.bounds(mask=m3.mask)
+ left_col += 1
- if is_leftrow:
- shape = _geo.Rect.from_rect(rect=oeb_bb, right=via2_m3bb.right)
- else:
- shape = _geo.Rect.from_rect(rect=oeb_bb, left=via2_m3bb.left)
- layouter.add_wire(net=oeb_net, wire=m3, shape=shape)
- layouter.add_wire(net=oeb_net, wire=m3, pin=m3pin, shape=oeb_bb)
+ # Connect out_captureclk_l
+ sig_net, sig_m3bb = place_ioperiph(
+ spec=io_spsig2spec["out_captureclk_l"], sram=spsram,
+ )
+
+ sramsig_m1pinbb = spsram_lay.bounds(mask=m1pin.mask, net=sig_net, depth=1)
+
+ _viasig_lay = layouter.wire_layout(
+ net=sig_net, wire=via, rows=10, columns=10,
+ )
+ _viasig_m1bb = _viasig_lay.bounds(mask=m1.mask)
+
+ x = sramsig_m1pinbb.right - _viasig_m1bb.right
+ y = sramsig_m1pinbb.center.y
+ layouter.place(_viasig_lay, x=x, y=y)
+ via2_lay = layouter.add_wire(
+ net=sig_net, wire=via2, rows=10, columns=10, x=x, y=y,
+ )
+ via2_m3bb = via2_lay.bounds(mask=m3.mask)
+
+ col_right = col_right0 - (right_col - 1)*col_pitch
+ col_left = col_right - col_width
+ shape = _geo.Polygon.from_floats(points=(
+ (via2_m3bb.left, via2_m3bb.bottom),
+ (via2_m3bb.left, via2_m3bb.top),
+ (col_right, via2_m3bb.top),
+ (col_right, sig_m3bb.top),
+ (sig_m3bb.right, sig_m3bb.top),
+ (sig_m3bb.right, sig_m3bb.bottom),
+ (col_left, sig_m3bb.bottom),
+ (col_left, via2_m3bb.bottom),
+ (via2_m3bb.left, via2_m3bb.bottom),
+ ))
+ layouter.add_wire(net=sig_net, wire=m3, shape=shape)
+
+ right_col += 1
+
+ # Connect out_captureclk
+ sig_net, sig_m3bb = place_ioperiph(
+ spec=io_spsig2spec["out_captureclk"], sram=spsram,
+ )
+
+ sramsig_m1pinbb = spsram_lay.bounds(mask=m1pin.mask, net=sig_net, depth=1)
+
+ _viasig_lay = layouter.wire_layout(
+ net=sig_net, wire=via, rows=10, columns=10,
+ )
+ _viasig_m1bb = _viasig_lay.bounds(mask=m1.mask)
+
+ x = sramsig_m1pinbb.left - _viasig_m1bb.left
+ y = sramsig_m1pinbb.center.y
+ layouter.place(_viasig_lay, x=x, y=y)
+ via2_lay = layouter.add_wire(
+ net=sig_net, wire=via2, rows=10, columns=10, x=x, y=y,
+ )
+ via2_m3bb = via2_lay.bounds(mask=m3.mask)
+
+ col_right = col_right0 - (right_col - 1)*col_pitch
+ col_left = col_right - col_width
+ shape = _geo.Polygon.from_floats(points=(
+ (via2_m3bb.left, via2_m3bb.bottom),
+ (via2_m3bb.left, via2_m3bb.top),
+ (col_right, via2_m3bb.top),
+ (col_right, sig_m3bb.top),
+ (sig_m3bb.right, sig_m3bb.top),
+ (sig_m3bb.right, sig_m3bb.bottom),
+ (col_left, sig_m3bb.bottom),
+ (col_left, via2_m3bb.bottom),
+ (via2_m3bb.left, via2_m3bb.bottom),
+ ))
+ layouter.add_wire(net=sig_net, wire=m3, shape=shape)
+
+ right_col += 1
+
+ # Connect out_docapture
+ sig_net, sig_m3bb = place_ioperiph(
+ spec=io_spsig2spec["out_docapture"], sram=spsram,
+ )
+
+ sramsig_m1pinbb = spsram_lay.bounds(mask=m1pin.mask, net=sig_net, depth=1)
+
+ _viasig_lay = layouter.wire_layout(
+ net=sig_net, wire=via, rows=10, columns=10,
+ )
+ _viasig_m1bb = _viasig_lay.bounds(mask=m1.mask)
+
+ x = sramsig_m1pinbb.right + 5.0 - _viasig_m1bb.left
+ y = sramsig_m1pinbb.center.y - 1.0
+ via_lay = layouter.place(_viasig_lay, x=x, y=y)
+ via_m1bb = via_lay.bounds(mask=m1.mask)
+ via2_lay = layouter.add_wire(
+ net=sig_net, wire=via2, rows=10, columns=10, x=x, y=y,
+ )
+ via2_m3bb = via2_lay.bounds(mask=m3.mask)
+
+ shape =_geo.Rect.from_rect(rect=sramsig_m1pinbb, right=via_m1bb.right)
+ layouter.add_wire(net=sig_net, wire=m1, shape=shape)
+
+ col_right = col_right0 - (right_col - 1)*col_pitch
+ col_left = col_right - col_width
+ shape = _geo.Polygon.from_floats(points=(
+ (via2_m3bb.left, via2_m3bb.bottom),
+ (via2_m3bb.left, via2_m3bb.top),
+ (col_right, via2_m3bb.top),
+ (col_right, sig_m3bb.top),
+ (sig_m3bb.right, sig_m3bb.top),
+ (sig_m3bb.right, sig_m3bb.bottom),
+ (col_left, sig_m3bb.bottom),
+ (col_left, via2_m3bb.bottom),
+ (via2_m3bb.left, via2_m3bb.bottom),
+ ))
+ layouter.add_wire(net=sig_net, wire=m3, shape=shape)
+
+ right_col += 1
+
+ # Connect out_shiftclk
+ sig_net, sig_m3bb = place_ioperiph(
+ spec=io_spsig2spec["out_shiftclk"], sram=spsram,
+ )
+
+ sramsig_m2pinbb = spsram_lay.bounds(mask=m2pin.mask, net=sig_net, depth=1)
+
+ _via2sig_lay = layouter.wire_layout(
+ net=sig_net, wire=via2, rows=10, columns=10,
+ )
+ _via2sig_m2bb = _via2sig_lay.bounds(mask=m2.mask)
+
+ x = sramsig_m2pinbb.left - _via2sig_m2bb.left
+ y = sramsig_m2pinbb.center.y - _via2sig_m2bb.top
+ via2_lay = layouter.place(_via2sig_lay, x=x, y=y)
+ via2_m3bb = via2_lay.bounds(mask=m3.mask)
+
+ col_right = col_right0 - (right_col - 1)*col_pitch
+ col_left = col_right - col_width
+ shape = _geo.Polygon.from_floats(points=(
+ (via2_m3bb.left, via2_m3bb.bottom),
+ (via2_m3bb.left, via2_m3bb.top),
+ (col_right, via2_m3bb.top),
+ (col_right, sig_m3bb.top),
+ (sig_m3bb.right, sig_m3bb.top),
+ (sig_m3bb.right, sig_m3bb.bottom),
+ (col_left, sig_m3bb.bottom),
+ (col_left, via2_m3bb.bottom),
+ (via2_m3bb.left, via2_m3bb.bottom),
+ ))
+ layouter.add_wire(net=sig_net, wire=m3, shape=shape)
+
+ right_col += 1
+
+ # Connect shift_out
+ sig_net, sig_m3bb = place_ioperiph(
+ spec=io_spsig2spec["shift_out"], sram=spsram,
+ )
+
+ sramsig_m1pinbb = spsram_lay.bounds(mask=m1pin.mask, net=sig_net, depth=1)
+
+ _viasig_lay = layouter.wire_layout(
+ net=sig_net, wire=via, rows=10, columns=10,
+ )
+ _viasig_m1bb = _viasig_lay.bounds(mask=m1.mask)
+
+ x = sramsig_m1pinbb.left - _viasig_m1bb.left
+ y = sramsig_m1pinbb.top - _viasig_m1bb.top
+ layouter.place(_viasig_lay, x=x, y=y)
+ via2_lay = layouter.add_wire(
+ net=sig_net, wire=via2, rows=10, columns=10, x=x, y=y,
+ )
+ via2_m3bb = via2_lay.bounds(mask=m3.mask)
+
+ col_right = col_right0 - (right_col - 1)*col_pitch
+ col_left = col_right - col_width
+ shape = _geo.Polygon.from_floats(points=(
+ (via2_m3bb.left, via2_m3bb.bottom),
+ (via2_m3bb.left, via2_m3bb.top),
+ (col_right, via2_m3bb.top),
+ (col_right, sig_m3bb.top),
+ (sig_m3bb.right, sig_m3bb.top),
+ (sig_m3bb.right, sig_m3bb.bottom),
+ (col_left, sig_m3bb.bottom),
+ (col_left, via2_m3bb.bottom),
+ (via2_m3bb.left, via2_m3bb.bottom),
+ ))
+ layouter.add_wire(net=sig_net, wire=m3, shape=shape)
+
+ right_col += 1
+
+ # Connect dvss/dvdd
+ dc_width = 10.0
+
+ sramdvss_m1pinbb = spsram_lay.bounds(mask=m1pin.mask, net=dvss, depth=1)
+ sramdvdd_m2pinbb = spsram_lay.bounds(mask=m2pin.mask, net=dvdd, depth=1)
+
+ o = sramdvss_m1pinbb.center
+ layouter.add_wire(
+ net=dvss, wire=via, origin=o, rows=3,
+ bottom_width=sramdvss_m1pinbb.width
+ )
+ layouter.add_wire(
+ net=dvss, wire=via2, origin=o,
+ bottom_width=sramdvss_m1pinbb.width, bottom_height=dc_width,
+ )
+ via3dvss_lay = layouter.add_wire(
+ net=dvss, wire=via3, origin=o,
+ bottom_width=sramdvss_m1pinbb.width, bottom_height=dc_width,
+ )
+ via3dvss_m4bb = via3dvss_lay.bounds(mask=m4.mask)
+
+ shape = _geo.Rect.from_rect(
+ rect=via3dvss_m4bb, left=dvss_leftrowm1bb.left, right=dvss_rightrowm1bb.right,
+ )
+ layouter.add_wire(net=dvss, wire=m4, shape=shape)
+
+ shape = _geo.Rect(
+ left=dvss_leftrowm1bb.left, bottom=via3dvss_m4bb.bottom,
+ right=dvss_leftrowm1bb.right, top=via3dvss_m4bb.top,
+ )
+ layouter.add_wire(
+ net=dvss, wire=via, bottom_shape=shape, top_shape=shape,
+ )
+ layouter.add_wire(
+ net=dvss, wire=via2, x=shape.center.x, columns=10,
+ bottom_bottom=shape.bottom, bottom_top=shape.top,
+ top_bottom=shape.bottom, top_top=shape.top,
+ )
+ layouter.add_wire(
+ net=dvss, wire=via3, x=shape.center.x, columns=10,
+ bottom_bottom=shape.bottom, bottom_top=shape.top,
+ top_bottom=shape.bottom, top_top=shape.top,
+ )
+
+ shape = _geo.Rect(
+ left=dvss_rightrowm1bb.left, bottom=via3dvss_m4bb.bottom,
+ right=dvss_rightrowm1bb.right, top=via3dvss_m4bb.top,
+ )
+ layouter.add_wire(
+ net=dvss, wire=via, bottom_shape=shape, top_shape=shape,
+ )
+ layouter.add_wire(
+ net=dvss, wire=via2, x=shape.center.x, columns=10,
+ bottom_bottom=shape.bottom, bottom_top=shape.top,
+ top_bottom=shape.bottom, top_top=shape.top,
+ )
+ layouter.add_wire(
+ net=dvss, wire=via3, x=shape.center.x, columns=10,
+ bottom_bottom=shape.bottom, bottom_top=shape.top,
+ top_bottom=shape.bottom, top_top=shape.top,
+ )
+
+ bottom = via3dvss_m4bb.top + 1.0
+ top = bottom + dc_width
+ right = sramdvdd_m2pinbb.right
+ left = right - dc_width
+ shape = _geo.Rect(left=left, bottom=bottom, right=right, top=top)
+ layouter.add_wire(
+ net=dvss, wire=via2, bottom_shape=shape, top_shape=shape,
+ )
+ via3dvdd_lay = layouter.add_wire(
+ net=dvss, wire=via3, bottom_shape=shape, top_shape=shape,
+ )
+ via3dvdd_m4bb = via3dvdd_lay.bounds(mask=m4.mask)
+
+ shape = _geo.Rect.from_rect(
+ rect=via3dvdd_m4bb, left=dvdd_leftrowm1bb.left, right=dvdd_rightrowm1bb.right,
+ )
+ layouter.add_wire(net=dvss, wire=m4, shape=shape)
+
+ shape = _geo.Rect(
+ left=dvdd_leftrowm1bb.left, bottom=via3dvdd_m4bb.bottom,
+ right=dvdd_leftrowm1bb.right, top=via3dvdd_m4bb.top,
+ )
+ layouter.add_wire(
+ net=dvss, wire=via, bottom_shape=shape, top_shape=shape,
+ )
+ layouter.add_wire(
+ net=dvss, wire=via2, x=shape.center.x, columns=10,
+ bottom_bottom=shape.bottom, bottom_top=shape.top,
+ top_bottom=shape.bottom, top_top=shape.top,
+ )
+ layouter.add_wire(
+ net=dvss, wire=via3, x=shape.center.x, columns=10,
+ bottom_bottom=shape.bottom, bottom_top=shape.top,
+ top_bottom=shape.bottom, top_top=shape.top,
+ )
+
+ shape = _geo.Rect(
+ left=dvdd_rightrowm1bb.left, bottom=via3dvdd_m4bb.bottom,
+ right=dvdd_rightrowm1bb.right, top=via3dvdd_m4bb.top,
+ )
+ layouter.add_wire(
+ net=dvss, wire=via, bottom_shape=shape, top_shape=shape,
+ )
+ layouter.add_wire(
+ net=dvss, wire=via2, x=shape.center.x, columns=10,
+ bottom_bottom=shape.bottom, bottom_top=shape.top,
+ top_bottom=shape.bottom, top_top=shape.top,
+ )
+ layouter.add_wire(
+ net=dvss, wire=via3, x=shape.center.x, columns=10,
+ bottom_bottom=shape.bottom, bottom_top=shape.top,
+ top_bottom=shape.bottom, top_top=shape.top,
+ )
# boundary
#
diff --git a/gds/user_analog_project_wrapper.gds.gz b/gds/user_analog_project_wrapper.gds.gz
index dc51ee5..d54d89f 100644
--- a/gds/user_analog_project_wrapper.gds.gz
+++ b/gds/user_analog_project_wrapper.gds.gz
Binary files differ