def _get_loadreg_sim(self, **spec): prj = spec['prj'] tb_vars = spec['tb_vars'] tb_lib = spec['tb_lib'] tb_cell = spec['tb_cell'] impl_lib = spec['impl_lib'] # impl_cell = spec['impl_cell'] tb_gen_name = self._get_tb_gen_name(spec['tb_gen_name'], spec['num']) # Generate testbench schematic tb_dsn = prj.create_design_module(tb_lib, tb_cell) tb_dsn.design(**(spec['params'])) tb_dsn.implement_design(impl_lib, top_cell_name=tb_gen_name) # Copy and load ADEXL state of generated testbench tb_obj = prj.configure_testbench(impl_lib, tb_gen_name) # Assign testbench design variables (the ones that show in ADE) for param_name, param_val in tb_vars.items(): tb_obj.set_parameter(param_name, param_val) # Update testbench changes and run simulation tb_obj.update_testbench() print(f'Simulating testbench {tb_gen_name}') save_dir = tb_obj.run_simulation() # Load simulation results into Python print("Simulation done, loading results") results = load_sim_results(save_dir) vreg = results['tran_vreg'] return abs(min(vreg) - max(vreg))
def _get_ss_sim(self, **spec): ''' Inputs: prj: BagProject tb_vars: Testbench variables to set in ADE testbench tb_lib: The template testbench library. tb_cell: The template testbench cell. impl_lib: The implemented testbench library. tb_gen_name: The generated testbench base name. num: The generated testbench number. Outputs: gain: Simulated DC gain in V/V fbw: Simulated 3dB frequency in Hz ugf: Simultaed unity gain frequency in hz pm: Unity gain phase margin in degrees (not calculated in feedback, calculated using the simulated open loop gain and phase) ''' prj = spec['prj'] tb_vars = spec['tb_vars'] tb_lib = spec['tb_lib'] tb_cell = spec['tb_cell'] impl_lib = spec['impl_lib'] impl_cell = spec['impl_cell'] tb_gen_name = self._get_tb_gen_name(spec['tb_gen_name'], spec['num']) # Generate testbench schematic tb_dsn = prj.create_design_module(tb_lib, tb_cell) tb_dsn.design(**(spec['params'])) tb_dsn.implement_design(impl_lib, top_cell_name=tb_gen_name) # Copy and load ADEXL state of generated testbench tb_obj = prj.configure_testbench(impl_lib, tb_gen_name) # Assign testbench design variables (the ones that show in ADE) for param_name, param_val in tb_vars.items(): tb_obj.set_parameter(param_name, param_val) # Update testbench changes and run simulation tb_obj.update_testbench() print(f'Simulating testbench {tb_gen_name}') save_dir = tb_obj.run_simulation() # Load simulation results into Python print("Simulation done, loading results") results = load_sim_results(save_dir) gain = results['acVal_gain'] fbw = results['acVal_f3dB'] ugf = results.get('acVal_ugf', -1) pm = results.get('acVal_pmUnity', np.inf) return gain, fbw, ugf, pm
def sim_tia_inverter(prj, db_n, db_p, sim_env, vdd, cpd, cload, nf_n_vec, nf_p_vec, rf_vec): """ Inputs: Outputs: """ tb_name = get_tb_name() fname = os.path.join(data_dir, '%s.data' % tb_name) print("Creating testbench %s..." % tb_name) # Generate schematic tb_sch = prj.create_design_module(tb_lib, tb_cell) tb_sch.design() tb_sch.implement_design(impl_lib, top_cell_name=tb_name) tb_obj = prj.configure_testbench(impl_lib, tb_name) # Simulating nf_n, nf_p, and rf combinations in the vectors # In the interest of time, it matches each element in the vectors # i.e. nf_n_vec[i] will only be simulated with nf_p_vec[i] and rf_vec[i] for i in range(len(nf_n_vec)): # Setting the parameters in the testbench nf_n = nf_n_vec[i] nf_p = nf_p_vec[i] rf = rf_vec[i] tb_obj.set_parameter('nf_n', nf_n) tb_obj.set_parameter('nf_p', nf_p) tb_obj.set_parameter('Rf', rf) tb_obj.set_parameter('CL', cload) tb_obj.set_parameter('CPD', cpd) tb_obj.set_parameter('VDD', vdd) tb_obj.set_parameter('FIN', 5e9) tb_obj.set_parameter('IIN', 1) # Update the testbench and run the simulation tb_obj.update_testbench() print("Simulating testbench %s..." % tb_name) save_dir = tb_obj.run_simulation() # Load sim results into Python print('Simulation done, saving results') results = load_sim_results(save_dir) # Save sim results into data directory save_sim_results(results, fname) pprint.pprint(results)
def _get_stb_sim(self, **spec): ''' Inputs: prj: BagProject tb_vars: Testbench variables to set in ADE testbench tb_lib: The template testbench library. tb_cell: The template testbench cell. impl_lib: The implemented testbench library. tb_gen_name: The generated testbench base name. num: The generated testbench number. Outputs: pm: Simultaed phase margin in degrees ''' prj = spec['prj'] tb_vars = spec['tb_vars'] tb_lib = spec['tb_lib'] tb_cell = spec['tb_cell'] impl_lib = spec['impl_lib'] # impl_cell = spec['impl_cell'] tb_gen_name = self._get_tb_gen_name(spec['tb_gen_name'], spec['num']) # generate testbench schematic tb_dsn = prj.create_design_module(tb_lib, tb_cell) tb_dsn.design(**spec['params']) tb_dsn.implement_design(impl_lib, top_cell_name=tb_gen_name) # copy and load ADEXL state of generated testbench tb_obj = prj.configure_testbench(impl_lib, tb_gen_name) # Assign testbench design variables (the ones that show in ADE) for param_name, param_val in tb_vars.items(): tb_obj.set_parameter(param_name, param_val) # Update testbench changes and run simulation tb_obj.update_testbench() print(f'Simulating testbench {tb_gen_name}') save_dir = tb_obj.run_simulation() # Load simulation results into Python print('Simulation done, loading results') results = load_sim_results(save_dir) pm = results.get('stb_pm', np.inf) return pm
def characterize(prj): # iterate through all parameters combinations for mos_type in mos_list: for thres in thres_list: for lch in lch_list: # new generated testbench name tb_name = get_tb_name(mos_type, thres, lch) print('Creating testbench %s...' % tb_name) # create schematic generator tb_sch = prj.create_design_module(tb_lib, tb_cell) tb_sch.design(mos_type=mos_type, lch=lch, threshold=thres) tb_sch.implement_design(impl_lib, top_cell_name=tb_name) # copy and load ADEXL state of generated testbench tb_obj = prj.configure_testbench(impl_lib, tb_name) # make sure vgs/vds has correct sign if mos_type == 'nch': tb_obj.set_sweep_parameter('vgs', start=0.0, stop=1.2, step=0.02) tb_obj.set_sweep_parameter('vds', start=0.0, stop=1.2, step=0.10) else: tb_obj.set_sweep_parameter('vgs', start=-1.2, stop=0.0, step=0.02) tb_obj.set_sweep_parameter('vds', start=-1.2, stop=0.0, step=0.10) # update testbench changes and run simulation tb_obj.update_testbench() print('Simulating testbench %s...' % tb_name) save_dir = tb_obj.run_simulation() # load simulation results into Python print('Simulation done, saving results') results = load_sim_results(save_dir) # save simulation results to data directory save_sim_results(results, os.path.join(data_dir, '%s.data' % tb_name)) print('Characterization done.')
async def setup_and_simulate(self, prj, sch_params): # type: (BagProject, Dict[str, Any]) -> Dict[str, Any] if sch_params is None: print('loading testbench %s' % self.tb_name) tb = prj.load_testbench(self.impl_lib, self.tb_name) else: print('Creating testbench %s' % self.tb_name) tb = self._create_tb_schematic(prj, sch_params) print('Configuring testbench %s' % self.tb_name) tb.set_simulation_environments(self.env_list) self.setup_testbench(tb) for cell_name, view_name in self.sim_view_list: tb.set_simulation_view(self.impl_lib, cell_name, view_name) tb.update_testbench() # run simulation and save/return raw result print('Simulating %s' % self.tb_name) save_dir = await tb.async_run_simulation() print('Finished simulating %s' % self.tb_name) results = load_sim_results(save_dir) save_sim_results(results, self.data_fname) return results
def meet_spec(self, **params) -> List[Mapping[str,Any]]: """To be overridden by subclasses to design this module. Returns collection of all possible solutions. Raises a ValueError if there is no solution. """ dut_params = params['dut_params'] num_bits = dut_params['num_bits'] num_sims = params['num_sims'] output_fname = params['output_fname'] seed_offset = params['seed_offset'] assert num_bits < 3, f'Currently only supports up to 2 bits (not {num_bits})' ### Setting up the testbench tb_lib = 'span_ion' tb_cell = 'zz_one_shot_nand_pulseWidth' impl_lib = params['impl_lib'] impl_cell = params['impl_cell'] # Testbench parameters vdd = params['vdd'] cload = params['cload'] td_power = params['td_power'] tstop = params['tstop'] tb_vars = dict(VDD=vdd, CL=cload, TD_POWER=td_power, TSTOP=tstop) # Generate testbench schematic prj = BagProject() tb = prj.create_design_module(tb_lib, tb_cell) tb.design(**dut_params) tb.implement_design(impl_lib, top_cell_name=impl_cell) # Copy and load ADEXL state of generated testbench tb_obj = prj.configure_testbench(impl_lib, impl_cell) # Iterate across digital codes num_codes = int(round(2**num_bits)) for code in range(num_codes): # Specifying the code associated with the file output_fname_full = f'{output_fname}_{code}.csv' # Assign testbench design variables (the ones that show in ADE) var_b0 = code % 2 var_b1 = code // 2 cap_val = dut_params['cap_params']['cap_val'] # Sometimes cap doesn't set correctly tb_vars.update(dict(b0=var_b0, b1=var_b1, CAP_VAL=cap_val)) for param_name, param_val in tb_vars.items(): tb_obj.set_parameter(param_name, param_val) # Update testbench changes and run simulation tb_obj.update_testbench() print(f'Simulating code {code}...') for i in range(num_sims): print(f'\t {i+1}/{num_sims}') idx_run = i + 1 + seed_offset save_dir = tb_obj.run_simulation(sim_type='mc', sim_info=dict(idx_run=idx_run)) # Load simulation results into Python results = load_sim_results(save_dir) t_vec = results['time'] v_vec = results['tran_vout'] data_dict = {t_vec[i]:v_vec[i] for i in range(len(t_vec))} # Get pulse width data pulse_widths = self._get_pulse_widths(data_dict, vdd/2) # Write to a row in a CSV file with open(output_fname_full, 'a', newline='') as csvfile: spamwriter = csv.writer(csvfile, delimiter=',') spamwriter.writerow(pulse_widths) return []