Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions align/pdk/finfet/models.sp
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
.model n nmos nfin=1 w=1 nf=1 l=1 m=1
.model p pmos nfin=1 w=1 nf=1 l=1 m=1
.model nlvt nmos nfin=1 w=1 nf=1 l=1 m=1
.model plvt pmos nfin=1 w=1 nf=1 l=1 m=1
.model npv nmos nfin=1 w=1 nf=1 l=1 m=1 source=sig drain=sig dv=0
.model ppv pmos nfin=1 w=1 nf=1 l=1 m=1 source=sig drain=sig dv=0
.model tfr_flat tfr w=1 l=1
Expand Down
93 changes: 72 additions & 21 deletions tests/pdk/finfet_pdk/circuits.py
Original file line number Diff line number Diff line change
Expand Up @@ -259,27 +259,78 @@ def charge_pump_switch(name, size=16):
""")
return netlist


def niwc_opamp_split(name):
netlist = textwrap.dedent(f"""\
.subckt {name} vtail vbn vbp1 vbp2 vin vip out vccx vssx
m1 cas1 vin tail vssx n w=360e-9 m=8 nf=1 stack=4
m2 cas2 vip tail vssx n w=360e-9 m=8 nf=1 stack=4
mtail tail vtail vssx vssx n w=360e-9 m=32 nf=1 stack=8
m7a y x vssx vssx n w=360e-9 m=8 nf=1 stack=8
m7b y x vssx vssx n w=360e-9 m=8 nf=1 stack=8
m8a z x vssx vssx n w=360e-9 m=8 nf=1 stack=8
m8b z x vssx vssx n w=360e-9 m=8 nf=1 stack=8
m5a x vbn y vssx n w=360e-9 m=4 nf=1 stack=4
m5b x vbn y vssx n w=360e-9 m=4 nf=1 stack=4
m6a out vbn z vssx n w=360e-9 m=4 nf=1 stack=4
m6b out vbn z vssx n w=360e-9 m=4 nf=1 stack=4
m3a x vbp1 cas1 vccx p w=360e-9 m=4 nf=1 stack=4
m3b x vbp1 cas1 vccx p w=360e-9 m=4 nf=1 stack=4
m4a x vbp1 cas2 vccx p w=360e-9 m=4 nf=1 stack=4
m4b x vbp1 cas2 vccx p w=360e-9 m=4 nf=1 stack=4
m11 cas1 vbp2 vccx vccx p w=360e-9 m=32 nf=1 stack=8
m12 cas2 vbp2 vccx vccx p w=360e-9 m=32 nf=1 stack=8
.ends {name}
.END
""")
.subckt {name} vtail vbn vbp1 vbp2 vin vip out vccx vssx
m1 cas1 vin tail vssx n w=360e-9 m=8 nf=1 stack=4
m2 cas2 vip tail vssx n w=360e-9 m=8 nf=1 stack=4
mtail tail vtail vssx vssx n w=360e-9 m=32 nf=1 stack=8
m7a y x vssx vssx n w=360e-9 m=8 nf=1 stack=8
m7b y x vssx vssx n w=360e-9 m=8 nf=1 stack=8
m8a z x vssx vssx n w=360e-9 m=8 nf=1 stack=8
m8b z x vssx vssx n w=360e-9 m=8 nf=1 stack=8
m5a x vbn y vssx n w=360e-9 m=4 nf=1 stack=4
m5b x vbn y vssx n w=360e-9 m=4 nf=1 stack=4
m6a out vbn z vssx n w=360e-9 m=4 nf=1 stack=4
m6b out vbn z vssx n w=360e-9 m=4 nf=1 stack=4
m3a x vbp1 cas1 vccx p w=360e-9 m=4 nf=1 stack=4
m3b x vbp1 cas1 vccx p w=360e-9 m=4 nf=1 stack=4
m4a x vbp1 cas2 vccx p w=360e-9 m=4 nf=1 stack=4
m4b x vbp1 cas2 vccx p w=360e-9 m=4 nf=1 stack=4
m11 cas1 vbp2 vccx vccx p w=360e-9 m=32 nf=1 stack=8
m12 cas2 vbp2 vccx vccx p w=360e-9 m=32 nf=1 stack=8
.ends {name}
.END
""")
return netlist


def opamp_poor(name):
netlist = textwrap.dedent(f"""\
.subckt ps4 d g s b
.param m=1
i0 d0 g s b p m=1 w=180e-9 m=1 nf=1
i1 d1 g d0 b p m=1 w=180e-9 m=1 nf=1
i2 d2 g d1 b p m=1 w=180e-9 m=1 nf=1
i3 d g d2 b p m=1 w=180e-9 m=1 nf=1
.ends
.subckt ns4 d g s b
.param m=1
i0 d0 g s b n m=1 w=180e-9 m=1 nf=1
i1 d1 g d0 b n m=1 w=180e-9 m=1 nf=1
i2 d2 g d1 b n m=1 w=180e-9 m=1 nf=1
i3 d g d2 b n m=1 w=180e-9 m=1 nf=1
.ends
.subckt cascode_p d g s b
i0 d0 g s b ps4 m=2
i1 d g d0 b plvt w=720e-9 m=1 nf=8
.ends
.subckt cascode_n d g s b
i1 d g d0 b nlvt w=720e-9 m=1 nf=8
i0 d0 g s b ns4 m=2
.ends
.subckt {name} vplus vminus vout fbin fbout ibias vccx vssx
iloadl<0> voutb voutb vccx vccx cascode_p
iloadl<1> voutb voutb vccx vccx cascode_p
iloadr<0> vout vout vccx vccx cascode_p
iloadr<1> vout vout vccx vccx cascode_p

idiffl<0> voutb vplus vtail vssx cascode_n
idiffl<1> voutb vplus vtail vssx cascode_n
idiffr<0> vout vminus vtail vssx cascode_n
idiffr<1> vout vminus vtail vssx cascode_n

ibias<0> ibias ibias vssx vssx cascode_n
ibias<1> ibias ibias vssx vssx cascode_n
ibias<2> ibias ibias vssx vssx cascode_n
ibias<3> ibias ibias vssx vssx cascode_n
ibias<4> ibias ibias vssx vssx cascode_n
itail vtail ibias vssx vssx cascode_n

i0 fbout fbin vccx vssx n w=720e-9 m=1 nf=8
i1 fbout ibias vssx vssx cascode_n
.ends {name}
.END
""")
return netlist
23 changes: 23 additions & 0 deletions tests/pdk/finfet_pdk/test_circuits.py
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,7 @@ def test_charge_pump_switch():
shutil.rmtree(run_dir)
shutil.rmtree(ckt_dir)


def test_niwc_opamp_split():
# Tests legal size and exact_patterns restrictions

Expand Down Expand Up @@ -388,3 +389,25 @@ def test_niwc_opamp_split():
if CLEANUP:
shutil.rmtree(run_dir)
shutil.rmtree(ckt_dir)


def test_opamp_poor():
name = f'ckt_{get_test_id()}'
netlist = circuits.opamp_poor(name)
constraints = [
{"constraint": "ConfigureCompiler", "auto_constraint": False, "propagate": True},
{"constraint": "SameTemplate", "instances": ["iloadl<0>", "iloadl<1>", "iloadr<0>", "iloadr<1>"]},
{"constraint": "SameTemplate", "instances": ["idiffl<0>", "idiffl<1>", "idiffr<0>", "idiffr<1>"]},
{"constraint": "SameTemplate", "instances": ["ibias<0>", "ibias<1>", "ibias<2>", "ibias<3>", "ibias<4>", "itail", "i1"]},
{"constraint": "Floorplan",
"order": True,
"regions": [
["iloadl<0>", "iloadr<0>"],
["iloadr<1>", "iloadl<1>"],
["idiffl<0>", "idiffr<0>"],
["idiffr<1>", "idiffl<1>"],
["ibias<0>", "ibias<1>", "ibias<2>", "itail", "ibias<3>", "ibias<4>"]
]}
]
example = build_example(name, netlist, constraints)
run_example(example, cleanup=CLEANUP, log_level=LOG_LEVEL, n=1)