def process_output(self, state, data, tb_manager): # type: (str, Dict[str, Any], ACTB) -> Tuple[bool, str, Dict[str, Any]] done = True next_state = '' gain_w3db_results = tb_manager.get_gain_and_w3db( data, tb_manager.get_outputs()) file_name = os.path.join(self.data_dir, 'gain_w3db.hdf5') save_sim_results(gain_w3db_results, file_name) output = dict(gain_w3db_file=file_name) return done, next_state, output
def process_output( self, state, # type: str data, # type: Dict[str, Any] tb_manager, # type: Union[MOSIdTB, MOSSPTB, MOSNoiseTB] ): # type: (...) -> Tuple[bool, str, Dict[str, Any]] ss_fname = os.path.join(self.data_dir, 'ss_params.hdf5') if state == 'ibias': done = False next_state = 'sp' vgs_range = tb_manager.get_vgs_range(data) output = dict(vgs_range=vgs_range) elif state == 'sp': testbenches = self.specs['testbenches'] if 'noise' in testbenches: done = False next_state = 'noise' else: done = True next_state = '' ss_params = tb_manager.get_ss_params(data) # save SS parameters save_sim_results(ss_params, ss_fname) output = dict(ss_file=ss_fname) elif state == 'noise': done = True next_state = '' temp = self.specs['noise_temp_kelvin'] fstart = self.specs['noise_integ_fstart'] fstop = self.specs['noise_integ_fstop'] scale = self.specs.get('noise_integ_scale', 1.0) ss_params = load_sim_file(ss_fname) ss_params = tb_manager.get_integrated_noise(data, ss_params, temp, fstart, fstop, scale=scale) save_sim_results(ss_params, ss_fname) output = dict(ss_file=ss_fname) else: raise ValueError('Unknown state: %s' % state) return done, next_state, output
def simulate(prj, name_list, sim_params): impl_lib = sim_params['impl_lib'] save_root = sim_params['save_root'] tb_lib = sim_params['tb_lib'] tb_cell = sim_params['tb_cell'] env_list = sim_params['env_list'] vload_list = sim_params['vload_list'] sim_view = sim_params['sim_view'] params = sim_params['params'] for name in name_list: print('DUT: ', name) dut_cell = name impl_cell = name + '_TB' save_fname = os.path.join(save_root, '%s.hdf5' % name) print('run lvs') lvs_passed, lvs_log = prj.run_lvs(impl_lib, dut_cell) if not lvs_passed: raise ValueError('LVS failed...') print('run rcx') rcx_passed, rcx_log = prj.run_rcx(impl_lib, dut_cell) if not rcx_passed: raise ValueError('RCX failed...') print('make tb') dsn = prj.create_design_module(tb_lib, tb_cell) dsn.design(dut_lib=impl_lib, dut_cell=dut_cell) dsn.implement_design(impl_lib, top_cell_name=impl_cell) print('update testbench') tb = prj.configure_testbench(impl_lib, impl_cell) tb.set_simulation_environments(env_list) tb.set_simulation_view(impl_lib, dut_cell, sim_view) for key, val in params.items(): tb.set_parameter(key, val) tb.set_sweep_parameter('vload', values=vload_list) tb.add_output('outac', """getData("/outac", ?result 'ac)""") tb.update_testbench() print('run simulation') save_dir = tb.run_simulation() print('load data') data = load_sim_results(save_dir) print('save_data') save_sim_results(data, save_fname)
def simulate(prj, save_fname, tb_lib, tb_cell, dut_lib, dut_cell, impl_lib, impl_cell, env_list, sim_view): vck_amp = 0.4 vdd = 0.9 vstar_max = 0.3 vstar_num = 31 params = dict( incm=0.7, vdd=vdd, outcm=0.8, vb0=-vck_amp, vb1=vdd, num=40, ) vstar_step = vstar_max * 2 / (vstar_num - 1) print('compute design') dsn = prj.create_design_module(tb_lib, tb_cell) dsn.design(dut_lib=dut_lib, dut_cell=dut_cell) print('implement design') dsn.implement_design(impl_lib, top_cell_name=impl_cell) print('create testbench') tb = prj.configure_testbench(impl_lib, tb_cell) tb.set_simulation_environments(env_list) tb.set_simulation_view(dut_lib, dut_cell, sim_view) for key, val in params.items(): tb.set_parameter(key, val) tb.set_sweep_parameter('indm', start=-vstar_max, stop=vstar_max, step=vstar_step) tb.add_output('ioutp', """getData("/VOP/MINUS", ?result 'dc)""") tb.add_output('ioutn', """getData("/VON/MINUS", ?result 'dc)""") print('update testbench') tb.update_testbench() print('run simulation') save_dir = tb.run_simulation() print('load data') data = load_sim_results(save_dir) print('save_data') save_sim_results(data, save_fname)
async def async_measure_performance(self, name: str, sim_dir: Path, sim_db: SimulationDB, dut: Optional[DesignInstance]) -> Dict[str, Any]: """ A coroutine that performs measurement. This will... 1. Acquire every sweep point/configuration (get_swp_list) 2. Run simulation for each sweep point (_run_sim) 3. Aggregate results and return (aggregate_results) Parameters ---------- name : str name of measurement sim_dir : Path simulation directory sim_db : SimulationDB the simulation database object dut : Optional[DesignInstance] the DUT to measure Returns ------- results dictionary """ assert len(self._sim_envs) > 0 self.tbm_dict: Dict[str, TestbenchManager] = {k: None for k in self.tbm_order} res = {} for idx, tbm_name in enumerate(self.tbm_order): if not self._run_tbm[tbm_name]: continue tbm = self.add_tbm(tbm_name) sim_results = await sim_db.async_simulate_tbm_obj(tbm_name, sim_dir / tbm_name, dut, tbm, tb_params={}) data = sim_results.data ss_fname = str(sim_dir / 'ss_params.hdf5') if tbm_name == 'ibias': tbm: MOSIdTB vgs_range = tbm.get_vgs_range(data) if self._run_tbm['sp']: self.specs['tbm_specs']['sp']['vgs_range'] = vgs_range if self._run_tbm['noise']: self.specs['tbm_specs']['noise']['vgs_range'] = vgs_range self.commit() res['vgs_range'] = vgs_range elif tbm_name == 'sp': tbm: MOSSPTB ss_params = tbm.get_ss_params(data) # save SS parameters save_sim_results(ss_params, ss_fname) res['ss_file'] = ss_fname elif tbm_name == 'noise': # TODO: needs to be verified tbm: MOSNoiseTB temp = self.specs['noise_temp_kelvin'] fstart = self.specs['noise_integ_fstart'] fstop = self.specs['noise_integ_fstop'] scale = self.specs.get('noise_integ_scale', 1.0) ss_params = load_sim_file(ss_fname) ss_params = tbm.get_integrated_noise(data, ss_params, temp, fstart, fstop, scale=scale) save_sim_results(ss_params, ss_fname) res['ss_file'] = ss_fname else: raise ValueError(f"Unknown tbm name {tbm_name}") write_yaml(sim_dir / f'{name}.yaml', res) return res