Esempio n. 1
0
 async def async_characterization(self, impl_lib, dsn_name, specs_fname):
     sim = DesignManager(self.bprj, specs_fname)
     pprint.pprint(specs_fname)
     await sim.verify_design(impl_lib, dsn_name, load_from_file=False)
     # just copy the corresponding yaml file, so that everything is in one place
     base_fname = os.path.basename(specs_fname)
     copyfile(specs_fname, os.path.join(sim._root_dir, dsn_name+'/'+base_fname))
     # print('name: {}'.format(dsn_name))
     # dsn_name = list(sim.get_dsn_name_iter())[0]
     summary = sim.get_result(dsn_name)
     return summary
Esempio n. 2
0
def simulate(prj, specs_fname):
    # simulate and report result
    sim = DesignManager(prj, specs_fname)
    sim.characterize_designs(generate=True, measure=True, load_from_file=False)
    # sim.test_layout(gen_sch=False)

    dsn_name = list(sim.get_dsn_name_iter())[0]
    summary = sim.get_result(dsn_name)
    fname = summary['ac']['gain_w3db_file']
    result = load_sim_file(fname)
    gain = result['gain_vout']
    w3db = result['w3db_vout']
    print('%s gain = %.4g' % (dsn_name, gain))
    print('%s w3db = %.4g' % (dsn_name, w3db))

    return gain, w3db
Esempio n. 3
0
def generate_and_sim(prj, generate=True):
    ver_specs_fname = 'specs_verification/opamp_two_stage_1e8.yaml'
    sim_specs_fname = 'specs_verification/opamp_two_stage_1e8_sim.yaml'

    ver_specs = read_yaml(ver_specs_fname)
    ver_specs['measurements'][0]['find_cfb'] = False

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

    sim = DesignManager(prj, sim_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']

    print('result:')
    pprint.pprint(summary)
Esempio n. 4
0
    def generate_and_sim(self):
        """
        phase 1 of evaluation is generation of layout, schematic, LVS and RCX
        If any of LVS or RCX fail results_ph1 will contain Exceptions for the corresponding instance
        We proceed to phase 2 only if phase 1 was successful.
        phase 2 is running the simulation with post extracted netlist view
        Then we aggregate the results of phase 1 and phase 2 in a single list, in the same order
        that designs were ordered, if phase 1 was failed the corresponding entry will contain
        a Phase1Error exception
        """
        results = []
        with open_file(self.sim_specs_fname, 'w') as f:
            yaml.dump(self.ver_specs, f)

        sim = DesignManager(self.bprj, self.sim_specs_fname)
        results_ph1 = sim.characterize_designs(generate=True, measure=False, load_from_file=False)
        # hacky: do parallel measurements, you should not sweep anything other than 'swp_spec_file' in sweep_params
        # the new yaml files themselves should not include any sweep_param
        start = time.time()
        impl_lib = self.ver_specs['impl_lib']
        coro_list = []
        file_list = self.ver_specs['sweep_params']['swp_spec_file']
        for ph1_iter_index, combo_list in enumerate(sim.get_combinations_iter()):
            dsn_name = sim.get_design_name(combo_list)
            specs_fname = os.path.join(self.swp_spec_dir, file_list[ph1_iter_index] + '.yaml')
            if isinstance(results_ph1[ph1_iter_index], Exception):
                continue
            coro_list.append(self.async_characterization(impl_lib, dsn_name, specs_fname))

        results_ph2 = batch_async_task(coro_list)
        print("sim time: {}".format(time.time() - start))
        # this part returns the correct order of results if some of the instances failed phase1 of evaluation
        ph2_iter_index = 0
        for ph1_iter_index, combo_list in enumerate(sim.get_combinations_iter()):
            if isinstance(results_ph1[ph1_iter_index], Exception):
                results.append(Phase1Error)
            else:
                results.append(results_ph2[ph2_iter_index])
                ph2_iter_index+=1
        pprint.pprint(results)

        return results
Esempio n. 5
0
# -*- coding: utf-8 -*-

from bag.core import BagProject

from bag.simulation.core import DesignManager

if __name__ == '__main__':

    config_file = 'specs_test/nch_w0d5.yaml'

    local_dict = locals()
    if 'bprj' not in local_dict:
        print('creating BAG project')
        bprj = BagProject()

    else:
        print('loading BAG project')
        bprj = local_dict['bprj']

    sim = DesignManager(bprj, config_file)
    sim.test_layout(gen_sch=True)
Esempio n. 6
0
"""
The script for testing the Design Manager Module
This file can generate layout/schematic, Do LVS and RCX, and run overdrive test recovery testbench
To be able to use this the top level yaml file has to follow certain conventions. DTSA.yaml is an example
"""
from bag import BagProject
from bag.simulation.core import DesignManager
from bag.io import read_yaml, open_file

if __name__ == '__main__':
    local_dict = locals()
    if 'bprj' not in local_dict:
        print('creating BAG project')
        bprj = BagProject()

    else:
        print('loading BAG project')
        bprj = local_dict['bprj']

    fname = 'specs_design/opamp_two_stage_1e8.yaml'
    sim = DesignManager(bprj, fname)
    sim.characterize_designs(generate=False,
                             measure=True,
                             load_from_file=False)
 def __init__(self, *args, **kwargs):
     self._temp_db = None
     DesignManager.__init__(self, *args, **kwargs)
Esempio n. 8
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
Esempio n. 9
0
    def __init__(
        self,
        spec_list,  # type: List[str]
        interp_method='spline',  # type: str
        bag_config_path=None,  # type: Optional[str]
        meas_type='mos_ss',  # type: str
        vgs_res=5e-3,  # type: float
        is_schematic=False,
        width_var='w',
    ):
        # type: (...) -> None
        # error checking

        tech_info = create_tech_info(bag_config_path=bag_config_path)

        self._width_res = tech_info.tech_params['mos']['width_resolution']
        self._sim_envs = None
        self._ss_swp_names = None
        self._manager_list = []  # type: List[DesignManager]
        self._ss_list = []
        self._ss_outputs = None
        self._width_list = []
        self._vgs_res = vgs_res

        param_name = 'schematic_params' if is_schematic else 'layout_params'
        for spec in spec_list:
            dsn_manager = DesignManager(None, spec)
            cur_width = dsn_manager.specs[param_name][width_var]
            cur_width = int(round(cur_width / self._width_res))
            self._width_list.append(cur_width)

            # error checking
            if 'w' in dsn_manager.swp_var_list:
                raise ValueError(
                    'MOSDBDiscrete assumes transistor width is not swept.')

            ss_fun_table = {}
            for dsn_name in dsn_manager.get_dsn_name_iter():
                meas_dir = dsn_manager.get_measurement_directory(
                    dsn_name, meas_type)
                ss_dict = load_sim_file(
                    os.path.join(meas_dir, 'ss_params.hdf5'))

                cur_corners = ss_dict['corner'].tolist()
                cur_ss_swp_names = ss_dict['sweep_params']['ibias'][1:]
                if self._sim_envs is None:
                    # assign attributes for the first time
                    self._sim_envs = cur_corners
                    self._ss_swp_names = cur_ss_swp_names
                elif self._sim_envs != cur_corners:
                    raise ValueError(
                        'Simulation environments mismatch between given specs.'
                    )
                elif self._ss_swp_names != cur_ss_swp_names:
                    raise ValueError(
                        'signal-signal parameter sweep names mismatch.')

                cur_fun_dict = self._make_ss_functions(ss_dict, cur_corners,
                                                       cur_ss_swp_names,
                                                       interp_method)

                if self._ss_outputs is None:
                    self._ss_outputs = sorted(cur_fun_dict.keys())

                ss_fun_table[dsn_name] = cur_fun_dict

            self._manager_list.append(dsn_manager)
            self._ss_list.append(ss_fun_table)

        self._env_list = self._sim_envs
        self._cur_idx = 0
        self._dsn_params = dict(w=self._width_list[0] * self._width_res)