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
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
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)
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
# -*- 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)
""" 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)
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
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)