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))
Exemple #2
0
    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
Exemple #3
0
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.')
Exemple #6
0
    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 []