Skip to content
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

fix glayout workflows #341

Merged
merged 5 commits into from
Oct 3, 2024
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: 1 addition & 1 deletion .github/scripts/expected_sim_outputs/opamp/means.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"unity gain bandwidth": 13844398.0, "dc gain": 66.52353580000003, "phase margin": 84.28, "ibias_diff": 5.039385475400001e-06, "ibias_cs": 1.0449669692999998e-05, "ibias_out": 9.349999999999991e-05, "area": 47939.755900000026, "power": 0.0004346434165999998, "noise": 4.836155124999999, "3db bandwidth": 3309.127059999999, "two stage power": 9.804341657199995e-05}
{"ugb": 33262790.0, "dcGain": 66.01914, "phaseMargin": 62.0, "Ibias_diffpair": 1.06993205e-05, "Ibias_commonsource": 2.21861111e-05, "Ibias_output": 9.35e-05, "area": 47939.75594998075, "power": 0.000546523847, "noise": 3.9531001, "bw_3db": 7962.968, "power_twostage": 0.000209923847}
2 changes: 1 addition & 1 deletion .github/scripts/expected_sim_outputs/opamp/variances.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"unity gain bandwidth": 674734758516.0, "dc gain": 0.0004632655963598945, "phase margin": 0.48160000000000025, "ibias_diff": 8.904025866969134e-14, "ibias_cs": 3.8285679910532956e-13, "ibias_out": 6.612155723375367e-39, "area": 8.470329472543003e-22, "power": 3.521160625110699e-11, "noise": 0.00031913416941348834, "3db bandwidth": 31892.01486929639, "two stage power": 3.521160707470663e-11}
{"ugb": 674734758516.0, "dcGain": 0.0004632655963598945, "phaseMargin": 0.48160000000000025, "Ibias_diffpair": 8.904025866969134e-14, "Ibias_commonsource": 3.8285679910532956e-13, "Ibias_output": 6.612155723375367e-39, "area": 8.470329472543003e-22, "power": 3.521160625110699e-11, "noise": 0.00031913416941348834, "bw_3db": 31892.01486929639, "power_twostage": 3.521160707470663e-11}
148 changes: 61 additions & 87 deletions .github/scripts/test_glayout_ci.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,67 +153,41 @@ def check_opamp_results(results, path_to_variances, path_to_means):
# read means.json
with open(path_to_means, "r") as f:
means = json.load(f)
warn_ugb = means["unity gain bandwidth"] - np.sqrt(variances["unity gain bandwidth"])
warn_dc_gain = means["dc gain"] - np.sqrt(variances["dc gain"])
warn_phase_margin = means["phase margin"] - np.sqrt(variances["phase margin"])

warn_ugb = means["ugb"] - np.sqrt(variances["ugb"])
warn_dc_gain = means["dcGain"] - np.sqrt(variances["dcGain"])
warn_phase_margin = means["phaseMargin"] - np.sqrt(variances["phaseMargin"])
warn_area = means["area"] + 1e4
warn_power = means["power"] + np.sqrt(variances["power"])
warn_two_stage_power = means["two stage power"] + np.sqrt(variances["two stage power"])
warn_noise = means["noise"] + np.sqrt(variances["noise"])
warn_3db_bandwidth = means["3db bandwidth"] - np.sqrt(variances["3db bandwidth"])


for key, val in results.items():
if key == "unity gain bandwidth":
if val <= warn_ugb:
warnings.warn(f"Unity Gain Bandwidth: {val} is less than the minimum value of {warn_ugb}")
if val <= warn_ugb - 2 * np.sqrt(variances["unity gain bandwidth"]):
raise ValueError(f"Unity Gain Bandwidth: {val} is less than the minimum value of {warn_ugb - 2 * np.sqrt(variances['unity gain bandwidth'])}")

elif key == "dc gain":
if val <= warn_dc_gain:
warnings.warn(f"DC Gain: {val} is less than the minimum value of {warn_dc_gain}")
if val <= warn_dc_gain - 2 * np.sqrt(variances["dc gain"]):
raise ValueError(f"DC Gain: {val} is less than the minimum value of {warn_dc_gain - 2 * np.sqrt(variances['dc gain'])}")

elif key == "phase margin":
if val <= warn_phase_margin:
warnings.warn(f"Phase Margin: {val} is less than the minimum value of {warn_phase_margin}")
if val <= warn_phase_margin - 2 * np.sqrt(variances["phase margin"]):
raise ValueError(f"Phase Margin: {val} is less than the minimum value of {warn_phase_margin - 2 * np.sqrt(variances['phase margin'])}")

elif key == "area":
if val >= warn_area:
warnings.warn(f"Area: {val} is greater than the maximum value of {warn_area}")
if val >= warn_area + 2 * np.sqrt(variances["area"]):
raise ValueError(f"Area: {val} is greater than the maximum value of {warn_area + 2 * np.sqrt(variances['area'])}")

elif key == "power":
if val >= warn_power:
warnings.warn(f"Power: {val} is greater than the maximum value of {warn_power}")
if val >= warn_power + 2 * np.sqrt(variances["power"]):
raise ValueError(f"Power: {val} is greater than the maximum value of {warn_power + 2 * np.sqrt(variances['power'])}")

elif key == "two stage power":
if val >= warn_two_stage_power:
warnings.warn(f"Two Stage Power: {val} is greater than the maximum value of {warn_two_stage_power}")
if val >= warn_two_stage_power + 2 * np.sqrt(variances["two stage power"]):
raise ValueError(f"Two Stage Power: {val} is greater than the maximum value of {warn_two_stage_power + 2 * np.sqrt(variances['two stage power'])}")

elif key == "noise":
if val >= warn_noise:
warnings.warn(f"Noise: {val} is greater than the maximum value of {warn_noise}")
if val >= warn_noise + 2 * np.sqrt(variances["noise"]):
raise ValueError(f"Noise: {val} is greater than the maximum value of {warn_noise + 2 * np.sqrt(variances['noise'])}")

elif key == "3db bandwidth":
if val <= warn_3db_bandwidth:
warnings.warn(f"3dB Bandwidth: {val} is less than the minimum value of {warn_3db_bandwidth}")
if val <= warn_3db_bandwidth - 2 * np.sqrt(variances["3db bandwidth"]):
raise ValueError(f"3dB Bandwidth: {val} is less than the minimum value of {warn_3db_bandwidth - 2 * np.sqrt(variances['3db bandwidth'])}")
warn_3db_bandwidth = means["bw_3db"] - np.sqrt(variances["bw_3db"])
warn_two_stage_power = means["power_twostage"] + np.sqrt(variances["power_twostage"])
warn_ibdp = means["Ibias_diffpair"] + np.sqrt(variances['Ibias_diffpair'])
warn_ibcs = means["Ibias_commonsource"] + np.sqrt(variances['Ibias_commonsource'])
warn_ibop = means["Ibias_output"] + np.sqrt(variances['Ibias_output'])

warn = [warn_ugb, warn_dc_gain, warn_phase_margin, warn_ibdp, warn_ibcs, warn_ibop, warn_area, warn_power, warn_noise, warn_3db_bandwidth, warn_two_stage_power]
multipliers = [-1, -1, -1, 0, 0, 0, 1, 1, 1, -1, 1]
# names = ["ugb", "dcGain", "phaseMargin", "Ibias_diffpair", "Ibias_commonsource", "Ibias_output", "area", "power", "power_twostage", "noise", "bw_3db"]

for index, (key, val) in enumerate(results.items()):
if "Ibias" in key:
continue
else:
if multipliers[index] == -1:
if val <= warn[index]:
warnings.warn(f'{key}: {val} is less than the minimum value of {warn[index]}')
elif val <= warn[index] - 2 * np.sqrt(variances[key]):
raise ValueError(f'{key}: {val} is less than the minimum value of {warn[index] - 2 * np.sqrt(variances[key])}')
if multipliers[index] == 1:
if val >= warn[index]:
warnings.warn(f'{key}: {val} is greater than the maximum value of {warn[index]}')
elif val >= warn[index] + 2 * np.sqrt(variances[key]):
raise ValueError(f'{key}: {val} is greater than the maximum value of {warn[index] - 2 * np.sqrt(variances[key])}')


def opamp_parametric_sim():
# import pdb; pdb.set_trace()
json_paths = Path(__file__).resolve().parents[5] / ".github" / "scripts" / "expected_sim_outputs" / "opamp"
path_to_variances = json_paths / "variances.json"
path_to_means = json_paths / "means.json"
Expand All @@ -239,39 +213,39 @@ def opamp_parametric_sim():
noparasitics=False,
hardfail=True
)

check_opamp_results(results, path_to_variances, path_to_means)

parser = argparse.ArgumentParser()
parser.add_argument('--component', type=str, help='Component name to simulate')
args = parser.parse_args()

# simulate the component
if args.component == 'opamp':
comp = (opamp(sky130_mapped_pdk, add_output_stage=True))
comp.name = 'opamp_test'
simulate_component(comp, sky130_mapped_pdk)

elif args.component == 'opamp_parametric':
from tapeout.tapeout_and_RL.sky130_nist_tapeout import *
opamp_parametric_sim()
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument('--component', type=str, help='Component name to simulate')
args = parser.parse_args()

elif args.component == 'diff_pair':
comp = (diff_pair(sky130_mapped_pdk))
comp.name = 'diff_pair_test'
simulate_component(comp, sky130_mapped_pdk)
# simulate the component
if args.component == 'opamp':
comp = (opamp(sky130_mapped_pdk, add_output_stage=True))
comp.name = 'opamp_test'
simulate_component(comp, sky130_mapped_pdk)

elif args.component == 'nmos':
comp = (nmos(sky130_mapped_pdk))
comp.name = 'nmos_test'
simulate_component(comp, sky130_mapped_pdk)
elif args.component == 'opamp_parametric':
from tapeout.tapeout_and_RL.sky130_nist_tapeout import *
opamp_parametric_sim()

elif args.component == 'diff_pair':
comp = (diff_pair(sky130_mapped_pdk))
comp.name = 'diff_pair_test'
simulate_component(comp, sky130_mapped_pdk)

elif args.component == 'nmos':
comp = (nmos(sky130_mapped_pdk))
comp.name = 'nmos_test'
simulate_component(comp, sky130_mapped_pdk)

elif args.component == 'pmos':
comp = pmos(sky130_mapped_pdk)
comp.name = 'pmos_test'
simulate_component(comp, sky130_mapped_pdk)

elif args.component == 'pmos':
comp = pmos(sky130_mapped_pdk)
comp.name = 'pmos_test'
simulate_component(comp, sky130_mapped_pdk)

elif args.component == 'current_mirror':
comp = current_mirror(sky130_mapped_pdk, numcols = 3, with_dummy=False)
comp.name = 'currmirror_test'
simulate_component(comp, sky130_mapped_pdk)
elif args.component == 'current_mirror':
comp = current_mirror(sky130_mapped_pdk, numcols = 3, with_dummy=False)
comp.name = 'currmirror_test'
simulate_component(comp, sky130_mapped_pdk)
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from glayout.flow.pdk.mappedpdk import MappedPDK
from typing import Optional, Union
from glayout.flow.primitives.fet import nmos, pmos, multiplier
from glayout.flow.blocks.diff_pair import diff_pair
from glayout.flow.blocks.elementary.diff_pair import diff_pair
from glayout.flow.primitives.guardring import tapring
from glayout.flow.primitives.mimcap import mimcap_array, mimcap
from glayout.flow.routing.L_route import L_route
Expand All @@ -19,13 +19,13 @@
from pydantic import validate_arguments
from glayout.flow.placement.two_transistor_interdigitized import two_nfet_interdigitized

from glayout.flow.blocks.diffpair_cmirror_bias import diff_pair_ibias
from glayout.flow.blocks.stacked_current_mirror import stacked_nfet_current_mirror
from glayout.flow.blocks.differential_to_single_ended_converter import differential_to_single_ended_converter
from glayout.flow.blocks.opamp.row_csamplifier_diff_to_single_ended_converter import row_csamplifier_diff_to_single_ended_converter
from glayout.flow.blocks.opamp.diff_pair_stackedcmirror import diff_pair_stackedcmirror
from glayout.flow.blocks.composite.diffpair_cmirror_bias import diff_pair_ibias
from glayout.flow.blocks.composite.stacked_current_mirror import stacked_nfet_current_mirror
from glayout.flow.blocks.composite.differential_to_single_ended_converter import differential_to_single_ended_converter
from glayout.flow.blocks.composite.opamp.row_csamplifier_diff_to_single_ended_converter import row_csamplifier_diff_to_single_ended_converter
from glayout.flow.blocks.composite.opamp.diff_pair_stackedcmirror import diff_pair_stackedcmirror
from glayout.flow.spice import Netlist
from glayout.flow.blocks.current_mirror import current_mirror_netlist
from glayout.flow.blocks.elementary.current_mirror import current_mirror_netlist

@validate_arguments
def __create_and_route_pins(
Expand Down