예제 #1
0
def get_db(spec_file, intent, interp_method='spline', sim_env='tt'):
    # initialize transistor database from simulation data
    mos_db = MOSDBDiscrete([spec_file], interp_method=interp_method)
    # set process corners
    mos_db.env_list = [sim_env]
    # set layout parameters
    mos_db.set_dsn_params(intent=intent)
    return mos_db
예제 #2
0
def get_db(mos_type, dsn_specs):
    mos_specs = dsn_specs[mos_type]

    spec_file = mos_specs['spec_file']
    interp_method = mos_specs.get('interp_method', 'spline')
    sim_env = mos_specs.get('sim_env', 'tt')
    layout_kwargs = mos_specs['layout_kwargs']

    db = MOSDBDiscrete([spec_file], interp_method=interp_method)
    db.env_list = [sim_env]
    db.set_dsn_params(**layout_kwargs)

    return db
예제 #3
0
def design(amp_dsn_specs, amp_char_specs_fname, amp_char_specs_out_fname):
    nch_config = amp_dsn_specs['nch_config']
    pch_config = amp_dsn_specs['pch_config']

    print('create transistor database')
    nch_db = MOSDBDiscrete([nch_config])
    pch_db = MOSDBDiscrete([pch_config])

    nch_db.set_dsn_params(**amp_dsn_specs['nch'])
    pch_db.set_dsn_params(**amp_dsn_specs['pch'])

    result = design_amp(amp_dsn_specs, nch_db, pch_db)
    if result is None:
        raise ValueError('No solution.')

    pprint.pprint(result)

    # update characterization spec file
    amp_char_specs = read_yaml(amp_char_specs_fname)
    # update bias
    var_dict = amp_char_specs['measurements'][0]['testbenches']['ac'][
        'sim_vars']
    for key in ('vtail', 'vindc', 'voutdc'):
        var_dict[key] = result[key]
    for key in ('vdd', 'cload'):
        var_dict[key] = amp_dsn_specs[key]
    # update segments
    seg_dict = amp_char_specs['layout_params']['seg_dict']
    for key in ('in', 'load', 'tail'):
        seg_dict[key] = result['seg_' + key]

    with open_file(amp_char_specs_out_fname, 'w') as f:
        yaml.dump(amp_char_specs, f)

    return result
예제 #4
0
def design_only():
    interp_method = 'spline'
    nch_conf_list = [
        'data/nch_w4_stack/specs.yaml',
    ]
    pch_conf_list = [
        'data/pch_w4_stack/specs.yaml',
    ]
    amp_specs_fname = 'specs_design/opamp_two_stage_1e8.yaml'

    print('create transistor database')
    nch_db = MOSDBDiscrete(nch_conf_list, interp_method=interp_method)
    pch_db = MOSDBDiscrete(pch_conf_list, interp_method=interp_method)

    top_specs = read_yaml(amp_specs_fname)
    design(top_specs, nch_db, pch_db)
예제 #5
0
def get_db(nch_dir,
           pch_dir,
           intent='standard',
           interp_method='spline',
           sim_env='tt'):
    env_list = [sim_env]

    nch_db = MOSDBDiscrete([nch_dir], interp_method=interp_method)
    pch_db = MOSDBDiscrete([pch_dir], interp_method=interp_method)

    nch_db.env_list = pch_db.env_list = env_list
    nch_db.set_dsn_params(intent=intent)
    pch_db.set_dsn_params(intent=intent)

    return nch_db, pch_db
예제 #6
0
def query(vgs=None, vds=None, vbs=0.0, vstar=None, env_list=None):
    """Get interpolation function and plot/query."""

    spec_list = [spec_file]
    if env_list is None:
        env_list = [env_default]

    # initialize transistor database from simulation data
    nch_db = MOSDBDiscrete(spec_list, interp_method=interp_method)
    # set process corners
    nch_db.env_list = env_list
    # set layout parameters
    nch_db.set_dsn_params(intent=intent)
    # returns a dictionary of smal-signal parameters
    return nch_db.query(vbs=vbs, vds=vds, vgs=vgs, vstar=vstar)
예제 #7
0
def design_close_loop(prj, funity_min_first=None, max_iter=100):
    interp_method = 'spline'
    nch_conf_list = [
        'data/nch_w4_stack/specs.yaml',
    ]
    pch_conf_list = [
        'data/pch_w4_stack/specs.yaml',
    ]
    amp_specs_fname = 'specs_design/opamp_two_stage_1e8.yaml'
    ver_specs_fname = 'specs_verification/opamp_two_stage_1e8.yaml'
    iter_cnt = 0
    f_unit_min_sim = -1
    k_max = 2.0
    k_min = 1.1

    print('create transistor database')
    nch_db = MOSDBDiscrete(nch_conf_list, interp_method=interp_method)
    pch_db = MOSDBDiscrete(pch_conf_list, interp_method=interp_method)

    top_specs = read_yaml(amp_specs_fname)
    funity_dsn_targ = funity_targ = top_specs['dsn_specs']['f_unit']

    sim, dsn_info = None, None
    summary = None
    while f_unit_min_sim < funity_targ and iter_cnt < max_iter:
        print('Iteration %d, f_unit_dsn_targ = %.4g' %
              (iter_cnt, funity_dsn_targ))
        top_specs['dsn_specs']['f_unit'] = funity_dsn_targ
        if dsn_info is not None:
            top_specs['dsn_specs']['i1_min_size'] = dsn_info['i1_size']

        if funity_min_first is not None and iter_cnt == 0:
            generate = False
            f_unit_min_dsn = funity_min_first
        else:
            generate = True
            dsn = design(top_specs, nch_db, pch_db)
            dsn_info = dsn.get_dsn_info()
            f_unit_min_dsn = min(dsn_info['f_unit'])

            ver_specs = dsn.get_specs_verification(top_specs)

            with open_file(ver_specs_fname, 'w') as f:
                yaml.dump(ver_specs, f)

        sim = DesignManager(prj, ver_specs_fname)
        sim.characterize_designs(generate=generate,
                                 measure=True,
                                 load_from_file=False)
        dsn_name = list(sim.get_dsn_name_iter())[0]
        summary = sim.get_result(dsn_name)['opamp_ac']

        funity_list = summary['funity']

        print('Iteration %d, result:' % iter_cnt)
        pprint.pprint(summary)

        f_unit_min_sim = min(funity_list)
        k = funity_targ / f_unit_min_sim
        k_real = max(k_min, min(k, k_max))
        print('k = %.4g, k_real = %.4g' % (k, k_real))
        funity_dsn_targ = f_unit_min_dsn * k_real
        iter_cnt += 1

    print('close loop design done.  Final result:')
    pprint.pprint(summary)

    return dsn_info
예제 #8
0
def plot_data(name='ibias', bounds=None, unit_val=None, unit_label=None):
    """Get interpolation function and plot/query."""
    env_list = [env_default]
    vbs = 0.0
    nvds = 41
    nvgs = 81
    spec_list = [spec_file]

    print('create transistor database')
    nch_db = MOSDBDiscrete(spec_list, interp_method=interp_method)
    nch_db.env_list = env_list
    nch_db.set_dsn_params(intent=intent)

    f = nch_db.get_function(name)
    vds_min, vds_max = f.get_input_range(1)
    vgs_min, vgs_max = f.get_input_range(2)
    if bounds is not None:
        if 'vgs' in bounds:
            v0, v1 = bounds['vgs']
            if v0 is not None:
                vgs_min = max(vgs_min, v0)
            if v1 is not None:
                vgs_max = min(vgs_max, v1)
        if 'vds' in bounds:
            v0, v1 = bounds['vds']
            if v0 is not None:
                vds_min = max(vds_min, v0)
            if v1 is not None:
                vds_max = min(vds_max, v1)

    # query values.
    vds_test = (vds_min + vds_max) / 2
    vgs_test = (vgs_min + vgs_max) / 2
    pprint.pprint(nch_db.query(vbs=vbs, vds=vds_test, vgs=vgs_test))

    vbs_vec = [vbs]
    vds_vec = np.linspace(vds_min, vds_max, nvds, endpoint=True)
    vgs_vec = np.linspace(vgs_min, vgs_max, nvgs, endpoint=True)
    vbs_mat, vds_mat, vgs_mat = np.meshgrid(vbs_vec, vds_vec, vgs_vec, indexing='ij', copy=False)
    arg = np.stack((vbs_mat, vds_mat, vgs_mat), axis=-1)
    ans = f(arg)

    vds_mat = vds_mat.reshape((nvds, nvgs))
    vgs_mat = vgs_mat.reshape((nvds, nvgs))
    ans = ans.reshape((nvds, nvgs, len(env_list)))

    formatter = ticker.ScalarFormatter(useMathText=True)
    formatter.set_scientific(True)
    formatter.set_powerlimits((-2, 3))
    if unit_label is not None:
        zlabel = '%s (%s)' % (name, unit_label)
    else:
        zlabel = name
    for idx, env in enumerate(env_list):
        fig = plt.figure(idx + 1)
        ax = fig.add_subplot(111, projection='3d')
        cur_val = ans[..., idx]
        if unit_val is not None:
            cur_val = cur_val / unit_val
        ax.plot_surface(vds_mat, vgs_mat, cur_val, rstride=1, cstride=1, linewidth=0, cmap=cm.cubehelix)
        ax.set_title('%s (corner=%s)' % (name, env))
        ax.set_xlabel('Vds (V)')
        ax.set_ylabel('Vgs (V)')
        ax.set_zlabel(zlabel)
        ax.w_zaxis.set_major_formatter(formatter)

    plt.show()