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