-
Notifications
You must be signed in to change notification settings - Fork 111
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added draft PR of generator for strongARM comparator #338
Draft
utkarsh5086
wants to merge
4
commits into
idea-fasoc:main
Choose a base branch
from
utkarsh5086:utkarsh5086-patch-1
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
108 changes: 108 additions & 0 deletions
108
openfasoc/generators/glayout/glayout/flow/blocks/strongARM_US/cross_coupled_load.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
from gdsfactory.components import rectangle | ||
from gdsfactory import Component | ||
from glayout.flow.pdk.mappedpdk import MappedPDK | ||
from glayout.flow.primitives.fet import nmos, pmos | ||
from glayout.flow.placement.two_transistor_interdigitized import two_pfet_interdigitized | ||
from four_transistor_interdigitized import generic_4T_interdigitzed | ||
from glayout.flow.pdk.util.comp_utils import prec_ref_center | ||
from glayout.flow.routing.smart_route import smart_route, c_route, straight_route, L_route | ||
from glayout.flow.pdk.sky130_mapped import sky130_mapped_pdk | ||
from glayout.flow.spice import Netlist | ||
from glayout.flow.primitives.guardring import tapring | ||
from glayout.flow.primitives.via_gen import via_stack, via_array | ||
|
||
def x_coupled_netlist(nfetA: Component, nfetB: Component, pfetA: Component, pfetB: Component, nfetdum: Component, pfetdum: Component): | ||
x_coupled_netlist = Netlist(circuit_name ='cross_cpoupled_load', nodes=['VSN1', 'VSN2', 'VSP1', 'VSP2', 'VO1', 'VO2', 'VBULKN', 'VBULKP']) | ||
x_coupled_netlist.connect_netlist( | ||
nfetA.info['netlist'], | ||
[('G','VO1'), ('D','VO2'), ('S','VSN1'), ('B','VBULKN')] | ||
) | ||
x_coupled_netlist.connect_netlist( | ||
nfetdum.info['netlist'], | ||
[('G','VBULKN'), ('D','VBULKN'), ('S','VBULKN'), ('B','VBULKN')] | ||
) | ||
x_coupled_netlist.connect_netlist( | ||
pfetdum.info['netlist'], | ||
[('G','VBULKP'), ('D','VBULKP'), ('S','VBULKP'), ('B','VBULKP')] | ||
) | ||
x_coupled_netlist.connect_netlist( | ||
nfetB.info['netlist'], | ||
[('G','VO2'), ('D','VO1'), ('S','VSN2'), ('B','VBULKN')] | ||
) | ||
x_coupled_netlist.connect_netlist( | ||
pfetA.info['netlist'], | ||
[('G','VO1'), ('D','VO2'), ('S','VSP1'), ('B','VBULKP')] | ||
) | ||
x_coupled_netlist.connect_netlist( | ||
pfetB.info['netlist'], | ||
[('G','VO2'), ('D','VO1'), ('S','VSP2'), ('B','VBULKP')] | ||
) | ||
return x_coupled_netlist | ||
|
||
def cross_coupled_load(pdk: MappedPDK, ccinv_col): | ||
cross_coupled_load=Component(name="cross_coupled_load") | ||
cross_couple = generic_4T_interdigitzed(pdk, numcols=ccinv_col, top_row_device="pfet", bottom_row_device="nfet", length=0.4, with_substrate_tap = False) | ||
cross_couple_ref = prec_ref_center(cross_couple) | ||
cross_coupled_load.add(cross_couple_ref) | ||
cross_coupled_load.add_ports(cross_couple_ref.get_ports_list(), prefix="cross_couple_") | ||
cross_coupled_load << smart_route(pdk,cross_coupled_load.ports["cross_couple_top_A_source_E"],cross_coupled_load.ports["cross_couple_top_B_source_E"],cross_couple_ref,cross_coupled_load) | ||
cross_coupled_load << c_route(pdk,cross_coupled_load.ports["cross_couple_top_A_drain_E"],cross_coupled_load.ports["cross_couple_top_B_gate_E"]) | ||
cross_coupled_load << c_route(pdk,cross_coupled_load.ports["cross_couple_bottom_A_drain_E"],cross_coupled_load.ports["cross_couple_bottom_B_gate_E"]) | ||
cross_coupled_load << c_route(pdk,cross_coupled_load.ports["cross_couple_top_B_drain_W"],cross_coupled_load.ports["cross_couple_top_A_gate_W"]) | ||
cross_coupled_load << c_route(pdk,cross_coupled_load.ports["cross_couple_bottom_B_drain_W"],cross_coupled_load.ports["cross_couple_bottom_A_gate_W"]) | ||
cross_coupled_load << c_route(pdk,cross_coupled_load.ports["cross_couple_top_B_gate_E"],cross_coupled_load.ports["cross_couple_bottom_A_drain_E"]) | ||
cross_coupled_load << c_route(pdk,cross_coupled_load.ports["cross_couple_top_A_gate_W"],cross_coupled_load.ports["cross_couple_bottom_B_drain_W"]) | ||
|
||
nfetA = nmos(pdk, width=3*ccinv_col, length=0.4, with_dummy=(False, False)) | ||
nfetB = nmos(pdk, width=3*ccinv_col, length=0.4, with_dummy=(False, False)) | ||
pfetA = pmos(pdk, width=3*ccinv_col, length=0.4, with_dummy=(False, False)) | ||
pfetB = pmos(pdk, width=3*ccinv_col, length=0.4, with_dummy=(False, False)) | ||
nfetdum = nmos(pdk, width=3*2, length=0.4, with_dummy=(False, False)) | ||
pfetdum = pmos(pdk, width=3*2, length=0.4, with_dummy=(False, False)) | ||
cross_coupled_load.info['netlist'] = x_coupled_netlist(nfetA, nfetB, pfetA, pfetB, nfetdum, pfetdum) | ||
return cross_coupled_load | ||
|
||
|
||
def add_x_coupled_labels(x_coupled: Component): | ||
x_coupled.unlock() | ||
met1_label = (68, 5) | ||
met1_pin = (68, 16) | ||
move_info = list() | ||
#vo1 label | ||
vo1label = rectangle(layer=met1_pin, size=(0.05,0.05), centered=True).copy() | ||
vo1label.add_label(text="VO1",layer=met1_label) | ||
move_info.append((vo1label,x_coupled.ports["cross_couple_top_B_drain_N"],None)) | ||
#vo2 label | ||
vo2label = rectangle(layer=met1_pin, size=(0.05,0.05), centered=True).copy() | ||
vo2label.add_label(text="VO2",layer=met1_label) | ||
move_info.append((vo2label,x_coupled.ports["cross_couple_top_A_drain_N"],None)) | ||
#vsn1 label | ||
vsn1label = rectangle(layer=met1_pin, size=(0.05,0.05), centered=True).copy() | ||
vsn1label.add_label(text="VSN1",layer=met1_label) | ||
move_info.append((vsn1label,x_coupled.ports["cross_couple_bottom_A_source_N"],None)) | ||
#vsn2 label | ||
vsn2label = rectangle(layer=met1_pin, size=(0.05,0.05), centered=True).copy() | ||
vsn2label.add_label(text="VSN2",layer=met1_label) | ||
move_info.append((vsn2label,x_coupled.ports["cross_couple_bottom_B_source_N"],None)) | ||
#vsp1 label | ||
vsp1label = rectangle(layer=met1_pin, size=(0.05,0.05), centered=True).copy() | ||
vsp1label.add_label(text="VSP1",layer=met1_label) | ||
move_info.append((vsp1label,x_coupled.ports["cross_couple_top_A_source_N"],None)) | ||
#vsp2 label | ||
vsp2label = rectangle(layer=met1_pin, size=(0.05,0.05), centered=True).copy() | ||
vsp2label.add_label(text="VSP2",layer=met1_label) | ||
move_info.append((vsp2label,x_coupled.ports["cross_couple_top_B_source_N"],None)) | ||
#vbulk label | ||
vbulknlabel = rectangle(layer=met1_pin, size=(0.05,0.05), centered=True).copy() | ||
vbulknlabel.add_label(text="VBULKN",layer=met1_label) | ||
move_info.append((vbulknlabel,x_coupled.ports["cross_couple_bottom_welltie_N_top_met_N"],None)) | ||
#vbulk label | ||
vbulkplabel = rectangle(layer=met1_pin, size=(0.05,0.05), centered=True).copy() | ||
vbulkplabel.add_label(text="VBULKP",layer=met1_label) | ||
move_info.append((vbulkplabel,x_coupled.ports["cross_couple_top_welltie_N_top_met_N"],None)) | ||
#move everything to position | ||
for comp, prt, alignment in move_info: | ||
alignment = ('c','b') if alignment is None else alignment | ||
compref = align_comp_to_port(comp, prt, alignment=alignment) | ||
x_coupled.add(compref) | ||
return x_coupled.flatten() |
195 changes: 195 additions & 0 deletions
195
openfasoc/generators/glayout/glayout/flow/blocks/strongARM_US/diff_pair.py
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this a copy of the existing diff pair or are there differences? If it is a copy, you can directly import and use it. If not, can the changes be incorporated into the main one as options/parameters? |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,195 @@ | ||
from typing import Optional, Union | ||
|
||
from gdsfactory.cell import cell | ||
from gdsfactory.component import Component, copy | ||
from gdsfactory.components.rectangle import rectangle | ||
from gdsfactory.routing.route_quad import route_quad | ||
from gdsfactory.routing.route_sharp import route_sharp | ||
from glayout.flow.pdk.mappedpdk import MappedPDK | ||
from glayout.flow.pdk.util.comp_utils import align_comp_to_port, evaluate_bbox, movex, movey | ||
from glayout.flow.pdk.util.port_utils import ( | ||
add_ports_perimeter, | ||
get_orientation, | ||
print_ports, | ||
rename_ports_by_list, | ||
rename_ports_by_orientation, | ||
set_port_orientation, | ||
) | ||
from glayout.flow.pdk.util.snap_to_grid import component_snap_to_grid | ||
from glayout.flow.placement.common_centroid_ab_ba import common_centroid_ab_ba | ||
from glayout.flow.primitives.fet import nmos, pmos | ||
from glayout.flow.primitives.guardring import tapring | ||
from glayout.flow.primitives.via_gen import via_stack | ||
from glayout.flow.routing.c_route import c_route | ||
from glayout.flow.routing.smart_route import smart_route | ||
from glayout.flow.routing.straight_route import straight_route | ||
from glayout.flow.spice import Netlist | ||
|
||
|
||
def diff_pair_netlist(fetL: Component, fetR: Component) -> Netlist: | ||
diff_pair_netlist = Netlist(circuit_name='DIFF_PAIR', nodes=['VP', 'VN', 'VDD1', 'VDD2', 'VTAIL', 'B']) | ||
diff_pair_netlist.connect_netlist( | ||
fetL.info['netlist'], | ||
[('D', 'VDD1'), ('G', 'VP'), ('S', 'VTAIL'), ('B', 'B')] | ||
) | ||
diff_pair_netlist.connect_netlist( | ||
fetR.info['netlist'], | ||
[('D', 'VDD2'), ('G', 'VN'), ('S', 'VTAIL'), ('B', 'B')] | ||
) | ||
return diff_pair_netlist | ||
|
||
@cell | ||
def diff_pair( | ||
pdk: MappedPDK, | ||
width: float = 3, | ||
fingers: int = 4, | ||
length: Optional[float] = None, | ||
n_or_p_fet: bool = True, | ||
plus_minus_seperation: float = 0, | ||
rmult: int = 1, | ||
dummy: Union[bool, tuple[bool, bool]] = True, | ||
substrate_tap: bool=True | ||
) -> Component: | ||
"""create a diffpair with 2 transistors placed in two rows with common centroid place. Sources are shorted | ||
width = width of the transistors | ||
fingers = number of fingers in the transistors (must be 2 or more) | ||
length = length of the transistors, None or 0 means use min length | ||
short_source = if true connects source of both transistors | ||
n_or_p_fet = if true the diffpair is made of nfets else it is made of pfets | ||
substrate_tap: if true place a tapring around the diffpair (connects on met1) | ||
""" | ||
# TODO: error checking | ||
pdk.activate() | ||
diffpair = Component() | ||
# create transistors | ||
well = None | ||
if isinstance(dummy, bool): | ||
dummy = (dummy, dummy) | ||
if n_or_p_fet: | ||
fetL = nmos(pdk, width=width, fingers=fingers,length=length,multipliers=1,with_tie=False,with_dummy=(dummy[0], False),with_dnwell=False,with_substrate_tap=False,rmult=rmult) | ||
fetR = nmos(pdk, width=width, fingers=fingers,length=length,multipliers=1,with_tie=False,with_dummy=(False,dummy[1]),with_dnwell=False,with_substrate_tap=False,rmult=rmult) | ||
fetL2 = nmos(pdk, width=width*2, fingers=fingers,length=length,multipliers=1,with_tie=False,with_dummy=(dummy[0], False),with_dnwell=False,with_substrate_tap=False,rmult=rmult) | ||
fetR2 = nmos(pdk, width=width*2, fingers=fingers,length=length,multipliers=1,with_tie=False,with_dummy=(False,dummy[1]),with_dnwell=False,with_substrate_tap=False,rmult=rmult) | ||
|
||
min_spacing_x = pdk.get_grule("n+s/d")["min_separation"] - 2*(fetL.xmax - fetL.ports["multiplier_0_plusdoped_E"].center[0]) | ||
well = "pwell" | ||
else: | ||
fetL = pmos(pdk, width=width, fingers=fingers,length=length,multipliers=1,with_tie=False,with_dummy=(dummy[0], False),dnwell=False,with_substrate_tap=False,rmult=rmult) | ||
fetR = pmos(pdk, width=width, fingers=fingers,length=length,multipliers=1,with_tie=False,with_dummy=(False,dummy[1]),dnwell=False,with_substrate_tap=False,rmult=rmult) | ||
fetL2 = pmos(pdk, width=width*2, fingers=fingers,length=length,multipliers=1,with_tie=False,with_dummy=(dummy[0], False),with_dnwell=False,with_substrate_tap=False,rmult=rmult) | ||
fetR2 = pmos(pdk, width=width*2, fingers=fingers,length=length,multipliers=1,with_tie=False,with_dummy=(False,dummy[1]),with_dnwell=False,with_substrate_tap=False,rmult=rmult) | ||
|
||
min_spacing_x = pdk.get_grule("p+s/d")["min_separation"] - 2*(fetL.xmax - fetL.ports["multiplier_0_plusdoped_E"].center[0]) | ||
well = "nwell" | ||
# place transistors | ||
viam2m3 = via_stack(pdk,"met2","met3",centered=True) | ||
metal_min_dim = max(pdk.get_grule("met2")["min_width"],pdk.get_grule("met3")["min_width"]) | ||
metal_space = max(pdk.get_grule("met2")["min_separation"],pdk.get_grule("met3")["min_separation"],metal_min_dim) | ||
gate_route_os = evaluate_bbox(viam2m3)[0] - fetL.ports["multiplier_0_gate_W"].width + metal_space | ||
min_spacing_y = metal_space + 2*gate_route_os | ||
min_spacing_y = min_spacing_y - 2*abs(fetL.ports["well_S"].center[1] - fetL.ports["multiplier_0_gate_S"].center[1]) | ||
# TODO: fix spacing where you see +-0.5 | ||
a_topl = (diffpair << fetL).movey(fetL.ymax+min_spacing_y/2+0.5).movex(0-fetL.xmax-min_spacing_x/2) | ||
b_topr = (diffpair << fetR).movey(fetR.ymax+min_spacing_y/2+0.5).movex(fetL.xmax+min_spacing_x/2) | ||
a_botr = (diffpair << fetR) | ||
a_botr.mirror_y().movey(0-0.5-fetL.ymax-min_spacing_y/2).movex(fetL.xmax+min_spacing_x/2) | ||
b_botl = (diffpair << fetL) | ||
b_botl.mirror_y().movey(0-0.5-fetR.ymax-min_spacing_y/2).movex(0-fetL.xmax-min_spacing_x/2) | ||
# if substrate tap place substrate tap | ||
if substrate_tap: | ||
tapref = diffpair << tapring(pdk,evaluate_bbox(diffpair,padding=1),horizontal_glayer="met1") | ||
diffpair.add_ports(tapref.get_ports_list(),prefix="tap_") | ||
try: | ||
diffpair<<straight_route(pdk,a_topl.ports["multiplier_0_dummy_L_gsdcon_top_met_W"],diffpair.ports["tap_W_top_met_W"],glayer2="met1") | ||
except KeyError: | ||
pass | ||
try: | ||
diffpair<<straight_route(pdk,b_topr.ports["multiplier_0_dummy_R_gsdcon_top_met_W"],diffpair.ports["tap_E_top_met_E"],glayer2="met1") | ||
except KeyError: | ||
pass | ||
try: | ||
diffpair<<straight_route(pdk,b_botl.ports["multiplier_0_dummy_L_gsdcon_top_met_W"],diffpair.ports["tap_W_top_met_W"],glayer2="met1") | ||
except KeyError: | ||
pass | ||
try: | ||
diffpair<<straight_route(pdk,a_botr.ports["multiplier_0_dummy_R_gsdcon_top_met_W"],diffpair.ports["tap_E_top_met_E"],glayer2="met1") | ||
except KeyError: | ||
pass | ||
# route sources (short sources) | ||
diffpair << route_quad(a_topl.ports["multiplier_0_source_E"], b_topr.ports["multiplier_0_source_W"], layer=pdk.get_glayer("met2")) | ||
diffpair << route_quad(b_botl.ports["multiplier_0_source_E"], a_botr.ports["multiplier_0_source_W"], layer=pdk.get_glayer("met2")) | ||
sextension = b_topr.ports["well_E"].center[0] - b_topr.ports["multiplier_0_source_E"].center[0] | ||
source_routeE = diffpair << c_route(pdk, b_topr.ports["multiplier_0_source_E"], a_botr.ports["multiplier_0_source_E"],extension=sextension) | ||
source_routeW = diffpair << c_route(pdk, a_topl.ports["multiplier_0_source_W"], b_botl.ports["multiplier_0_source_W"],extension=sextension) | ||
# route drains | ||
# place via at the drain | ||
drain_br_via = diffpair << viam2m3 | ||
drain_bl_via = diffpair << viam2m3 | ||
drain_br_via.move(a_botr.ports["multiplier_0_drain_N"].center).movey(viam2m3.ymin) | ||
drain_bl_via.move(b_botl.ports["multiplier_0_drain_N"].center).movey(viam2m3.ymin) | ||
drain_br_viatm = diffpair << viam2m3 | ||
drain_bl_viatm = diffpair << viam2m3 | ||
drain_br_viatm.move(a_botr.ports["multiplier_0_drain_N"].center).movey(viam2m3.ymin) | ||
drain_bl_viatm.move(b_botl.ports["multiplier_0_drain_N"].center).movey(-1.5 * evaluate_bbox(viam2m3)[1] - metal_space) | ||
# create route to drain via | ||
width_drain_route = b_topr.ports["multiplier_0_drain_E"].width | ||
dextension = source_routeE.xmax - b_topr.ports["multiplier_0_drain_E"].center[0] + metal_space | ||
bottom_extension = viam2m3.ymax + width_drain_route/2 + 2*metal_space | ||
drain_br_viatm.movey(0-bottom_extension - metal_space - width_drain_route/2 - viam2m3.ymax) | ||
diffpair << route_quad(drain_br_viatm.ports["top_met_N"], drain_br_via.ports["top_met_S"], layer=pdk.get_glayer("met3")) | ||
diffpair << route_quad(drain_bl_viatm.ports["top_met_N"], drain_bl_via.ports["top_met_S"], layer=pdk.get_glayer("met3")) | ||
floating_port_drain_bottom_L = set_port_orientation(movey(drain_bl_via.ports["bottom_met_W"],0-bottom_extension), get_orientation("E")) | ||
floating_port_drain_bottom_R = set_port_orientation(movey(drain_br_via.ports["bottom_met_E"],0-bottom_extension - metal_space - width_drain_route), get_orientation("W")) | ||
drain_routeTR_BL = diffpair << c_route(pdk, floating_port_drain_bottom_L, b_topr.ports["multiplier_0_drain_E"],extension=dextension, width1=width_drain_route,width2=width_drain_route) | ||
drain_routeTL_BR = diffpair << c_route(pdk, floating_port_drain_bottom_R, a_topl.ports["multiplier_0_drain_W"],extension=dextension, width1=width_drain_route,width2=width_drain_route) | ||
# cross gate route top with c_route. bar_minus ABOVE bar_plus | ||
get_left_extension = lambda bar, a_topl=a_topl, diffpair=diffpair, pdk=pdk : (abs(diffpair.xmin-min(a_topl.ports["multiplier_0_gate_W"].center[0],bar.ports["e1"].center[0])) + pdk.get_grule("met2")["min_separation"]) | ||
get_right_extension = lambda bar, b_topr=b_topr, diffpair=diffpair, pdk=pdk : (abs(diffpair.xmax-max(b_topr.ports["multiplier_0_gate_E"].center[0],bar.ports["e3"].center[0])) + pdk.get_grule("met2")["min_separation"]) | ||
# lay bar plus and PLUSgate_routeW | ||
bar_comp = rectangle(centered=True,size=(abs(b_topr.xmax-a_topl.xmin), b_topr.ports["multiplier_0_gate_E"].width),layer=pdk.get_glayer("met2")) | ||
bar_plus = (diffpair << bar_comp).movey(diffpair.ymax + bar_comp.ymax + pdk.get_grule("met2")["min_separation"]) | ||
PLUSgate_routeW = diffpair << c_route(pdk, a_topl.ports["multiplier_0_gate_W"], bar_plus.ports["e1"], extension=get_left_extension(bar_plus)) | ||
# lay bar minus and MINUSgate_routeE | ||
plus_minus_seperation = max(pdk.get_grule("met2")["min_separation"], plus_minus_seperation) | ||
bar_minus = (diffpair << bar_comp).movey(diffpair.ymax +bar_comp.ymax + plus_minus_seperation) | ||
MINUSgate_routeE = diffpair << c_route(pdk, b_topr.ports["multiplier_0_gate_E"], bar_minus.ports["e3"], extension=get_right_extension(bar_minus)) | ||
# lay MINUSgate_routeW and PLUSgate_routeE | ||
MINUSgate_routeW = diffpair << c_route(pdk, set_port_orientation(b_botl.ports["multiplier_0_gate_E"],"W"), bar_minus.ports["e1"], extension=get_left_extension(bar_minus)) | ||
PLUSgate_routeE = diffpair << c_route(pdk, set_port_orientation(a_botr.ports["multiplier_0_gate_W"],"E"), bar_plus.ports["e3"], extension=get_right_extension(bar_plus)) | ||
# correct pwell place, add ports, flatten, and return | ||
diffpair.add_ports(a_topl.get_ports_list(),prefix="tl_") | ||
diffpair.add_ports(b_topr.get_ports_list(),prefix="tr_") | ||
diffpair.add_ports(b_botl.get_ports_list(),prefix="bl_") | ||
diffpair.add_ports(a_botr.get_ports_list(),prefix="br_") | ||
diffpair.add_ports(source_routeE.get_ports_list(),prefix="source_routeE_") | ||
diffpair.add_ports(source_routeW.get_ports_list(),prefix="source_routeW_") | ||
diffpair.add_ports(drain_routeTR_BL.get_ports_list(),prefix="drain_routeTR_BL_") | ||
diffpair.add_ports(drain_routeTL_BR.get_ports_list(),prefix="drain_routeTL_BR_") | ||
diffpair.add_ports(MINUSgate_routeW.get_ports_list(),prefix="MINUSgateroute_W_") | ||
diffpair.add_ports(MINUSgate_routeE.get_ports_list(),prefix="MINUSgateroute_E_") | ||
diffpair.add_ports(PLUSgate_routeW.get_ports_list(),prefix="PLUSgateroute_W_") | ||
diffpair.add_ports(PLUSgate_routeE.get_ports_list(),prefix="PLUSgateroute_E_") | ||
diffpair.add_padding(layers=(pdk.get_glayer(well),), default=0) | ||
|
||
component = component_snap_to_grid(rename_ports_by_orientation(diffpair)) | ||
|
||
component.info['netlist'] = diff_pair_netlist(fetL2, fetR2) | ||
return component | ||
|
||
|
||
|
||
@cell | ||
def diff_pair_generic( | ||
pdk: MappedPDK, | ||
width: float = 3, | ||
fingers: int = 4, | ||
length: Optional[float] = None, | ||
n_or_p_fet: bool = True, | ||
plus_minus_seperation: float = 0, | ||
rmult: int = 1, | ||
dummy: Union[bool, tuple[bool, bool]] = True, | ||
substrate_tap: bool=True | ||
) -> Component: | ||
diffpair = common_centroid_ab_ba(pdk,width,fingers,length,n_or_p_fet,rmult,dummy,substrate_tap) | ||
diffpair << smart_route(pdk,diffpair.ports["A_source_E"],diffpair.ports["B_source_E"],diffpair, diffpair) | ||
return diffpair |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not a big deal but there is a typo in the circuit name