Skip to content

Commit

Permalink
Add the external I/O ports for the transmission gate
Browse files Browse the repository at this point in the history
  • Loading branch information
tsengs0 committed Nov 13, 2024
1 parent 929bf0b commit e5e9a2c
Show file tree
Hide file tree
Showing 6 changed files with 117 additions and 14 deletions.
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
from glayout.flow.blocks.transmission_gate_saltychip.inv_lib import reconfig_inv
from glayout.flow.blocks.transmission_gate_saltychip.transmission_gate import tg_with_inv
from glayout.flow.blocks.transmission_gate_saltychip.cell_config import add_port_lvs
from glayout.flow.blocks.transmission_gate_saltychip.eval import main
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
from typing import ClassVar, Optional, Any, Union, Literal, Iterable, TypedDict
#from glayout.flow.pdk.gf180_mapped import gf180
from glayout.flow.pdk.sky130_mapped import sky130_mapped_pdk as sky130
from glayout.flow.pdk.mappedpdk import MappedPDK
from glayout.flow.pdk.util.comp_utils import evaluate_bbox
from gdsfactory import Component
from gdsfactory.components import rectangle
from glayout.flow.primitives.fet import pmos
from glayout.flow.primitives.fet import nmos
from glayout.flow.routing.straight_route import straight_route
from glayout.flow.routing.c_route import c_route
from glayout.flow.routing.L_route import L_route
from glayout.flow.routing.smart_route import smart_route
from glayout.flow.placement.two_transistor_interdigitized import two_nfet_interdigitized
from glayout.flow.placement.two_transistor_interdigitized import two_pfet_interdigitized
from glayout.flow.pdk.util.comp_utils import prec_ref_center, movey, evaluate_bbox, align_comp_to_port

def add_port_lvs(pdk: MappedPDK, comp: Component, port_list: list[ dict[str, Union[float, str]] ]) -> Component:
'''
To add external I/O ports onto the cell for LVS
@ args:
# pdk: please refer to the glayout library
# comp: please refer to the glayout library
# port_list: tuple[ dict[str, Union[float, str]] ] specifying new port's corresponding pin size, and
the name of new port and exiting port managed to align with in the given
component, e.g.
(
{
"new_port": "drain_new",
"new_port_label": "drain_new_label",
"pin_width": 0.5,
"pin_height": 0.5,
"ref_port": "multiplier_0_drain_E"
},
{
"new_port": "source_new",
"new_port_label": "source_new_label",
"pin_width": 1.5,
"pin_height": 1.5,
"ref_port": "multiplier_0_source_E"
}
)
# return: gdsfactory.Component
@ Limitations:
# So far, only skywater130 process is validated
'''

# Add pins and text labels for LVS
pins_labels_info = list() # list that contains all port and component information
print(f"port_list: {port_list}")
for port in port_list:
# To get the layer's data type mapped to the GDS
ref_port_layer = comp.ports[ port["ref_port"] ].layer[0] # [0]: layer mapping, [1]: pin, drawing, label, net, etc.

# To create the pin w/ label where the layer[1] is mapped to 16
new_port_pin = rectangle(layer=(ref_port_layer, 16), size=(port["pin_width"], port["pin_height"]),centered=True).copy() # True set rectangle's centroid to the relative (0, 0)
new_port_pin.add_label(text=port["new_port_label"], layer=(ref_port_layer, 5)) # layer[1]=5 mapped to the "label" datatype in the GDS

# To align the new port with the designated port existing in the given component
alignment = ('c', 'b')
comp_ref = align_comp_to_port(new_port_pin, comp.ports[ port["ref_port"] ], alignment=alignment)
comp.add(comp_ref)

return comp
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import transmission_gate as tg
#from glayout.flow.pdk.gf180_mapped import gf180
from glayout.flow.pdk.sky130_mapped import sky130_mapped_pdk as sky130
import cell_config as config

def main():
tg_inst = tg.tg_with_inv(pdk=sky130, pmos_width=1, pmos_length=0.15, nmos_width=1, nmos_length=0.15)
tg_inst = config.add_port_lvs(
pdk=sky130,
comp=tg_inst,
port_list=[
{
"new_port": "tg_ctrl",
"new_port_label": "ctrl",
"pin_width": tg_inst.ports["inv_nmos_multiplier_0_gate_S"].width,
"pin_height": tg_inst.ports["inv_nmos_multiplier_0_gate_S"].width,
"ref_port": "inv_nmos_multiplier_0_gate_S"
},
{
"new_port": "tg_din",
"new_port_label": "din",
"pin_width": 0.3,#tg_inst.ports["tg_nmos_multiplier_0_source_S"].width,
"pin_height": 0.3,#tg_inst.ports["tg_nmos_multiplier_0_source_S"].width,
"ref_port": "tg_pmos_multiplier_0_source_W"
},
{
"new_port": "tg_dout",
"new_port_label": "dout",
"pin_width": 0.3,#tg_inst.ports["tg_nmos_multiplier_0_drain_S"].width,
"pin_height": 0.3,#tg_inst.ports["tg_nmos_multiplier_0_drain_S"].width,
"ref_port": "tg_nmos_multiplier_0_drain_N"
}
]
)
#tg_inst.flatten()
tg_inst.show()
tg_inst.write_gds("gds/tg_with_inv.gds")

if __name__ == "__main__":
main()
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@

# My own cell library
from inv_lib import reconfig_inv
import cell_config as config

'''
def naive_tg_cell(pdk: MappedPDK, pmos_width, pmos_length, nmos_width, nmos_length):
# To prepare all necessary cells to construct a transmission gate, i.e.
Expand Down Expand Up @@ -180,29 +182,21 @@ def tg_with_inv(pdk: MappedPDK, pmos_width, pmos_length, nmos_width, nmos_length
top_level.add(tg_ref)
top_level.add(inv_ref)

# Adding the ports
top_level.add_ports(tg_ref.get_ports_list(), prefix="tg_")
top_level.add_ports(inv_ref.get_ports_list(), prefix="inv_")

# Placement
mos_spacing = pdk.util_max_metal_seperation()
nwell_min_spacing = pdk.get_grule("nwell")["min_separation"]
inv_cell_width = inv_ref.xsize # or = evaluate_bbox(inv)[0]
tg_ref.movex(inv_cell_width + nwell_min_spacing)

# Routing
# 1) PMOS of the TG is switched on/off by the inverter's output
# 2) NMOS of the TG is switched on/off by an external control signal connected to inverter's input port as well
top_level << smart_route(pdk, inv_ref.ports["pmos_multiplier_0_drain_E"], tg_ref.ports["pmos_multiplier_0_gate_W"])
top_level << smart_route(pdk, inv_ref.ports["nmos_multiplier_0_gate_S"], tg_ref.ports["nmos_multiplier_0_gate_S"])
#top_level << smart_route(pdk, pfet_ref.ports["multiplier_0_source_W"], nfet_ref.ports["multiplier_0_drain_W"]) # "in" of the TG
#top_level << smart_route(pdk, pfet_ref.ports["multiplier_0_drain_E"], nfet_ref.ports["multiplier_0_source_E"]) # "out" of the TG

return top_level #top_level.flatten()
# Adding the ports
top_level.add_ports(tg_ref.get_ports_list(), prefix="tg_")
top_level.add_ports(inv_ref.get_ports_list(), prefix="inv_")

def display_component(component, scale = 3):
# Save to a GDS file
with hide:
component.write_gds("out.gds")
return top_level

tg_inst = tg_with_inv(pdk=sky130, pmos_width=1, pmos_length=0.15, nmos_width=1, nmos_length=0.15)
tg_inst.show()
tg_inst.write_gds("gds/tg_with_inv.gds")

0 comments on commit e5e9a2c

Please sign in to comment.