Exemple #1
0
def ac_response(test):
    """Measure the ac response of the opamp"""

    # create the test utility object
    test_utilities_obj = TestUtilities.TestUtilities()
    test_utilities_obj.netlist_generation(config['ac_response']['netlist'],
                                          "rundir")

    # create the spice interface
    spice_interface_obj = SpiceInterface.SpiceInterface(
        netlist_path="rundir/" +
        config['ac_response']['netlist'].split('.')[0] + ".spice")

    # append the simulation command
    spice_interface_obj.set_sim_command(config['ac_response']['sim_command'])

    # loop through all corners
    for corner in config['pvt']['corners']:

        # set corner
        spice_interface_obj.set_corner(corner)

        for temperature in config['pvt']['temperatures']:

            # set temperaure
            spice_interface_obj.set_temperature(temperature)

            # run the simulation
            spice_interface_obj.run_simulation()

            # save the response
            node = 'v(ac)'
            spice_interface_obj.plot_ac(node,
                                        display=False,
                                        title="AC Response",
                                        linewidth=1,
                                        alpha=0.5,
                                        append=True)

            # get the dc gain and gainbandwidth prodcut
            dc_gain, unity_bandwidth = spice_interface_obj.measure_gain_bandwidth(
                node)

            print("DC Gain: %0.1f dB, Unity Bandwidth: %0.3f MHz" %
                  (dc_gain, unity_bandwidth / 1e6))

            # test the margins
            test.measurements.dc_gain = dc_gain
            test.measurements.unity_bandwidth = unity_bandwidth

    # save the plot to file
    spice_interface_obj.fig.savefig("outputs/ac_response.svg")
Exemple #2
0
def stability_ptat(test):
    """Measure the stability margins of the PTAT control loop"""

    # create the test utility object
    test_utilities_obj = TestUtilities.TestUtilities()
    test_utilities_obj.netlist_generation(config['stability_ptat']['netlist'],
                                          "rundir")

    # create the spice interface
    spice_interface_obj = SpiceInterface.SpiceInterface(
        netlist_path="rundir/" +
        config['stability_ptat']['netlist'].split('.')[0] + ".spice")

    # loop through all corners
    for corner in config['pvt']['corners']:

        # set corner
        spice_interface_obj.set_corner(corner)

        # run the simulation
        spice_interface_obj.run_simulation()

        # save the response
        node = 'v(ac)'
        spice_interface_obj.plot_bode(node,
                                      display=False,
                                      title="PTAT Open Loop Response",
                                      linewidth=1,
                                      alpha=0.5,
                                      append=True,
                                      invert=True)
        # linewidth=1, alpha=0.5, append=True)

        # get the signal and test DC gain
        signal = spice_interface_obj.get_signal(node, complex_out=True)
        test.measurements.dc_gain = 20 * np.log10(abs(signal[0]))

        # get the phase and gain margin
        # phase_margin, gain_margin, unity_bandwidth, inverted_frequency = spice_interface_obj.measure_phase_gain_margin(node)
        phase_margin, gain_margin, unity_bandwidth, inverted_frequency = spice_interface_obj.measure_phase_gain_margin(
            node, invert=True)
        print(phase_margin)

        # test the margins
        test.measurements.phase_margin = phase_margin
        test.measurements.gain_margin = gain_margin

    # save the plot to file
    spice_interface_obj.fig.savefig("outputs/stability_ptat.svg")
from openhtf.plugs.user_input import UserInput
from spintop_openhtf import TestPlan
from openhtf.util import conf

import SpiceInterface
import TestUtilities

from criteria import get_criteria

# import test parameters
# from config import PVT
with open(r'config.yml') as file:
    config = yaml.load(file, Loader=yaml.FullLoader)

# create the test utility object
test_utilities_obj = TestUtilities.TestUtilities()
test_utilities_obj.netlist_generation(config['stability_ptat']['netlist'],
                                      "rundir")

# create the spice interface
spice_interface_obj = SpiceInterface.SpiceInterface(
    netlist_path="rundir/" +
    config['stability_ptat']['netlist'].split('.')[0] + ".spice")

# set corner
# spice_interface_obj.set_corner(current_corner)

# run the simulation
spice_interface_obj.run_simulation()

# save the response
Exemple #4
0
def operating_point(test):
    """Test the trimming control functionality"""

    # create the test utility object
    test_utilities_obj = TestUtilities.TestUtilities()
    test_utilities_obj.netlist_generation(
        config['temperature_sweep']['netlist'], "rundir")

    # create the spice interface
    spice_interface_obj = SpiceInterface.SpiceInterface(
        netlist_path="rundir/" +
        config['temperature_sweep']['netlist'].split('.')[0] + ".spice")
    spice_interface_obj.config['simulator']['shared'] = True
    spice_interface_obj.config['simulator']['silent'] = True

    # append the simulation command
    spice_interface_obj.set_sim_command(
        config['operating_point']['sim_command'])

    # prepopulate
    results = np.zeros(
        (len(config['pvt']['corners']), len(config['pvt']['vdd']), 101))

    # find all the devices
    devices = spice_interface_obj.find_all_mosfets()

    # insert the command to save the devices
    spice_interface_obj.insert_op_save(devices, ['vsat_marg'])

    exempt_list = [
        'xdut.xbmr.XMdiff_n3',
        'xdut.XMcap_ptat',
        'xdut.XMcap_ctat',
        'xdut.xtrim_ptat.XMcurr_3',
        'xdut.xtrim_ptat.XMcurr_2',
        'xdut.xtrim_ptat.XMcurr_1',
        'xdut.xtrim_ptat.XMcurr_0',
        'xdut.xtrim_ctat.XMcurr_3',
        'xdut.xtrim_ctat.XMcurr_2',
        'xdut.xtrim_ctat.XMcurr_1',
        'xdut.xtrim_ctat.XMcurr_0',
    ]

    # loop through all corners
    for corner_i, corner in enumerate(config['pvt']['corners']):

        # set corner
        spice_interface_obj.set_corner(corner)

        # reload the circuit
        spice_interface_obj.restart_simulation()

        # loop through the supply voltages
        for vdd_i, vdd in enumerate(config['pvt']['vdd']):

            # set the vdd voltage
            spice_interface_obj.set_parameters([['vdd', vdd], ['en', vdd],
                                                ['start_n', vdd]])

            # check device operating regions
            spice_interface_obj.check_op_region('temp-sweep',
                                                exempt_list=exempt_list,
                                                skip_insertion=True,
                                                devices=devices)
Exemple #5
0
def temperature_sweep(test):
    """Measure the response over temperature"""

    # create the test utility object
    test_utilities_obj = TestUtilities.TestUtilities()
    test_utilities_obj.netlist_generation(
        config['temperature_sweep']['netlist'], "rundir")

    # create the spice interface
    spice_interface_obj = SpiceInterface.SpiceInterface(
        netlist_path="rundir/" +
        config['temperature_sweep']['netlist'].split('.')[0] + ".spice")
    spice_interface_obj.config['simulator']['shared'] = True
    spice_interface_obj.config['simulator']['silent'] = True

    # append the simulation command
    spice_interface_obj.set_sim_command(
        config['temperature_sweep']['sim_command'])

    # prepopulate
    results = np.zeros(
        (len(config['pvt']['corners']), len(config['pvt']['vdd']), 101))

    # loop through all corners
    for corner_i, corner in enumerate(config['pvt']['corners']):

        # set corner
        spice_interface_obj.set_corner(corner)

        # reload the circuit
        spice_interface_obj.restart_simulation()

        # loop through the supply voltages
        for vdd_i, vdd in enumerate(config['pvt']['vdd']):

            # set the vdd voltage
            spice_interface_obj.set_parameters([['vdd', vdd], ['en', vdd],
                                                ['start_n', vdd]])

            # run the simulation
            spice_interface_obj.run_simulation(new_instance=False)

            # save the response
            node = 'i(viout)'
            sweepvar = 'temp-sweep'
            spice_interface_obj.plot_dc_sweep(
                sweepvar,
                node,
                display=False,
                title="Output Current Over Temperature",
                linewidth=1,
                alpha=0.5,
                append=True)

            # get the output current
            output_current = spice_interface_obj.get_signal(node)
            temp = spice_interface_obj.get_signal(sweepvar)

            test_signal = spice_interface_obj.get_signal('i(v.xdut.vmeas3)')

            # print("   %0.1fC: %0.3f uA, %0.1fC: %0.3f uA, %0.1fC: %0.3f uA, " % (temp[0], output_current[0]*1e6, temp[40], output_current[40]*1e6, temp[-1], output_current[-1]*1e6))
            print("   %0.1fC: %0.3f uA, %0.1fC: %0.3f uA, %0.1fC: %0.3f uA, " %
                  (temp[0], 2 * test_signal[0] * 1e6, temp[40], 2 *
                   test_signal[40] * 1e6, temp[-1], 2 * test_signal[-1] * 1e6))

            # record the measurement
            for i, value in enumerate(output_current):
                dimensions = (corner, vdd, temp[i])
                test.measurements['current'][dimensions] = value

            # validate
            test.measurements.current_regulation_temp[(corner,
                                                       vdd)] = output_current
            test.measurements.current_regulation_process[(
                corner, vdd)] = output_current

    # save the plot to file
    spice_interface_obj.fig.savefig("outputs/temperature_sweep.svg")