First trial with dual port SRAM added.
diff --git a/doitcode/sram.py b/doitcode/sram.py
index afcdc78..24bac9b 100644
--- a/doitcode/sram.py
+++ b/doitcode/sram.py
@@ -105,7 +105,8 @@
stdcells = sky130.stdcelllib.cells
- mem_fab = sky130.Sky130SP6TFactory(lib=self.lib)
+ spmem_fab = sky130.Sky130SP6TFactory(lib=self.lib)
+ dpmem_fab = sky130.Sky130DP8TFactory(lib=self.lib)
nwm = cast(_prm.Well, prims.nwm)
li = cast(_prm.MetalWire, prims.li)
@@ -142,11 +143,18 @@
_tie_bb = tie_cell.layout.boundary
assert _tie_bb is not None
- sram_cell = mem_fab.block(
- address_groups=(3, 4, 2), word_size=8, we_size=1, cell_name="512x8",
+ word_size = 8
+ we_size = 1
+ address_groups = (3, 4, 2)
+ a_bits = sum(address_groups)
+ spsram_cell = spmem_fab.block(
+ address_groups=(3, 4, 2), word_size=word_size, we_size=we_size,
+ cell_name="512x8",
)
- self.a_bits = sram_cell.a_bits
- self.word_size = sram_cell.word_size
+ dpsram_cell = dpmem_fab.block(
+ address_groups=(3, 4, 2), word_size=word_size, we_size=we_size,
+ cell_name="512x8",
+ )
ckt = self.new_circuit()
layouter = self.new_circuitlayouter()
@@ -167,18 +175,26 @@
# Place the SRAM
#
# instantiate
- sram = ckt.instantiate(sram_cell, name="sram")
+ spsram = ckt.instantiate(spsram_cell, name="sram")
+ dpsram = ckt.instantiate(dpsram_cell, name="sram")
# place
- _sram_lay = layouter.inst_layout(inst=sram)
- _sram_bb = _sram_lay.boundary
- assert _sram_bb is not None
+ _spsram_lay = layouter.inst_layout(inst=spsram)
+ _spsram_bb = _spsram_lay.boundary
+ assert _spsram_bb is not None
+ _dpsram_lay = layouter.inst_layout(inst=dpsram)
+ _dpsram_bb = _dpsram_lay.boundary
+ assert _dpsram_bb is not None
- x = sky130.tech.on_grid(_frm.boundary.center.x - _sram_bb.center.x)
- y = _frm.boundary.top - 100.0 - _sram_bb.top
- sram_lay = layouter.place(_sram_lay, x=x, y=y)
- sram_bb = sram_lay.boundary
- assert sram_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
+ 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
+ dpsram_lay = layouter.place(_dpsram_lay, x=x, y=y)
+ dpsram_bb = dpsram_lay.boundary
+ assert dpsram_bb is not None
# Make three rows of to place standard cells in
@@ -326,13 +342,13 @@
rot_midrow = _geo.Rotation.R0
_tie_rotbb = rot_midrow*_tie_bb
- y_midrow = sram_bb.bottom - dbound - _tie_rotbb.top
+ 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 = sram_bb.left - _tie_rotbb.left
+ 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)
@@ -342,7 +358,7 @@
dvss.childports += inst.ports.vss
dvdd.childports += inst.ports.vdd
- x_tie = sram_bb.right - _tie_rotbb.right
+ 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)
@@ -424,10 +440,10 @@
#
# vss
spec = io_sig2spec["vss"]
- sram_port = sram.ports[spec.sram_signal]
+ 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 sram_lay.filter_polygons(
+ 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)
@@ -464,10 +480,10 @@
# vdd
spec = io_sig2spec["vdd"]
- sram_port = sram.ports[spec.sram_signal]
+ 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 sram_lay.filter_polygons(
+ 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)
@@ -511,9 +527,9 @@
# connect the input signals
a_col = 0
for sig_name in (
- *(f"a[{a_bit}]" for a_bit in reversed(range(self.a_bits))), # Reversed for a_col
+ *(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(self.word_size)),
+ *(f"d[{bit}]" for bit in range(word_size)),
):
spec = io_sig2spec[sig_name]
prefix = spec.prefix
@@ -524,7 +540,7 @@
out_name = f"io_out[{num}]"
assert spec.io_type == "io_in", "Internal error"
assert spec.oeb, "Internal error"
- sram_port = sram.ports[sig_name]
+ sram_port = spsram.ports[sig_name]
# instantiate cells
buf = ckt.instantiate(buf_cell, name="{prefix}buf")
@@ -550,10 +566,10 @@
out_bb = _frm.toppins[out_name]
if sig_name.startswith("a["):
# Connect signal up to m2
- sram_m1pinbb = sram_lay.bounds(mask=m1pin.mask, net=sig_net, depth=1)
+ sram_m1pinbb = spsram_lay.bounds(mask=m1pin.mask, net=sig_net, depth=1)
w = 10.0
- right = sram_bb.left - (2*a_col + 1)*w
+ right = spsram_bb.left - (2*a_col + 1)*w
left = right - 1
a_col += 1
@@ -570,7 +586,7 @@
shape = _geo.Rect.from_rect(rect=sram_m1pinbb, left=via_m1bb.left)
layouter.add_wire(net=sig_net, wire=m1, shape=shape)
else:
- sram_m2pinbb = sram_lay.bounds(mask=m2pin.mask, net=sig_net, depth=1)
+ sram_m2pinbb = spsram_lay.bounds(mask=m2pin.mask, net=sig_net, depth=1)
is_leftrow = toppin_bb.center.x < sram_m2pinbb.center.x
rot = rot_leftrow if is_leftrow else rot_rightrow
@@ -756,7 +772,7 @@
# connect the output signals
for sig_name in (
- *(f"q[{bit}]" for bit in range(self.word_size)),
+ *(f"q[{bit}]" for bit in range(word_size)),
):
spec = io_sig2spec[sig_name]
prefix = spec.prefix
@@ -766,7 +782,7 @@
oeb_name = f"io_oeb[{num}]"
assert spec.io_type == "io_out", "Internal error"
assert not spec.oeb, "Internal error"
- sram_port = sram.ports[spec.sram_signal]
+ sram_port = spsram.ports[spec.sram_signal]
# instantiate cells
buf = ckt.instantiate(buf_cell, name="{prefix}buf")
@@ -785,7 +801,7 @@
# get bss
toppin_bb = _frm.toppins[pin_name]
oeb_bb = _frm.toppins[oeb_name]
- sram_m2pinbb = sram_lay.bounds(mask=m2pin.mask, net=sig_net, depth=1)
+ sram_m2pinbb = spsram_lay.bounds(mask=m2pin.mask, net=sig_net, depth=1)
is_leftrow = toppin_bb.center.x < sram_m2pinbb.center.x
diff --git a/gds/user_analog_project_wrapper.gds.gz b/gds/user_analog_project_wrapper.gds.gz
index e0c643f..e410f8a 100644
--- a/gds/user_analog_project_wrapper.gds.gz
+++ b/gds/user_analog_project_wrapper.gds.gz
Binary files differ