def _print_linear_equation(self, lr, is_golden=False, is_simple=False, quite=False): msg_header = self.mdl_msg_header(is_golden) if is_simple: if not quite: map(self._logger.info, print_section(mcode.INFO_030_1 % msg_header, 4)) else: map(self._logger.debug, print_section(mcode.INFO_030_1 % msg_header, 4)) else: if not quite: map(self._logger.info, print_section(mcode.INFO_030 % msg_header, 4)) else: map(self._logger.debug, print_section(mcode.INFO_030 % msg_header, 4)) lr.print_formula(quite)
def _run_multiphase_linear_regression(self, is_simple, lr_param, quite): lrg = self._lrg_simple if is_simple else self._lrg lrr = self._lrr_simple if is_simple else self._lrr lrg_sgt = self._lrg_sgt_simple if is_simple else self._lrg_sgt lrr_sgt = self._lrr_sgt_simple if is_simple else self._lrr_sgt if is_simple: if not quite: map(self._logger.info, print_section(mcode.INFO_027_1, 3)) else: map(self._logger.debug, print_section(mcode.INFO_027_1, 3)) else: if not quite: map(self._logger.info, print_section(mcode.INFO_027, 3)) else: map(self._logger.debug, print_section(mcode.INFO_027, 3)) # 1-phase linear regression self._run_linear_regression_phase1( lrg, lrr, lr_param, is_simple, quite=quite ) # Improving models by filtering out insiginicant predictors if is_simple: if not quite: map(self._logger.info, print_section(mcode.INFO_028_1, 3)) else: map(self._logger.debug, print_section(mcode.INFO_028_1, 3)) else: if not quite: map(self._logger.info, print_section(mcode.INFO_028, 3)) else: map(self._logger.debug, print_section(mcode.INFO_028, 3)) # filter with normalized input sensitivity self._run_linear_regression_phase2( lrg_sgt, lrr_sgt, lr_param, is_simple, no_iter=10, quite=quite )
def __init__(self, ph, test_cfg, logger_id='logger_id'): ''' ph: Port Handler class instance test_cfg: TestConfig class instance ''' self._logger_id = logger_id self._logger = DaVELogger.get_logger('%s.%s.%s' % (logger_id, __name__, self.__class__.__name__)) self.option = { # read vector generation options from test config #'oa_depth': test_cfg.get_option_regression_oa_depth(), 'oa_depth': int(test_cfg.get_option_regression_min_oa_depth()), 'min_oa_depth': int(test_cfg.get_option_regression_min_oa_depth()), 'max_sample': int(test_cfg.get_option_regression_max_sample()), 'en_interact': test_cfg.get_option_regression_en_interact(), 'order': int(test_cfg.get_option_regression_order()) } map(self._logger.info, print_section(mcode.INFO_036, 2)) # print section header # all possible linear circuit configurations by DigitalModePort self._generate_digital_vector(ph.get_digital_input()) # process analog ports self._ph = ph if self._ph.get_by_name('dummy_analoginput') != None: self.option['max_sample'] = 1 self._count_port(ph) # count number of (pinned, unpinned) ports self._update_analog_grid() analog_raw_vector = self._generate_analog_raw_vector() # analog test vectors by scaling raw vector to real range self._a_vector = self._map_analog_vector(analog_raw_vector) self._logger.info(mcode.INFO_045 % self.get_analog_vector_length())
def _print_interim_summary(self, result, test, mode, modetxt): ''' logging error summary ''' map(self._logger.info, print_section(mcode.INFO_058 % modetxt, 3)) moderes = [(mode, modetxt, result)] testres = [(test, [(r[1], r[2]['error_flag_pin'], r[2]['error_flag_residue']) for r in moderes])] tab = generate_check_summary_table(testres) self._logger.info(tab.draw())
def _run_all_modes(self, mode_vector, modetxt, mode_idx): ''' run modes configured by true digital inputs ''' map(self._logger.info, print_section('Testing the mode (%s)' % modetxt, 2)) if self._rptgen != None: self._rptgen.print_testmode(mode_idx+1, modetxt, self._rptgen.make_testmode_link(self._testname, mode_vector)) # create hyperlink for each mode in a report return self._run_mode(mode_idx, mode_vector, modetxt) # checks each configuraed system
def _print_lr_summary(self, is_golden, suggested=False): ''' print linear regression summary ''' if suggested: lr = self._lrg_sgt if is_golden else self._lrr_sgt else: lr = self._lrg if is_golden else self._lrr msg_header = self.mdl_msg_header(is_golden) map(self._logger.info, print_section(mcode.INFO_029 % msg_header, 4)) lr.print_model_summary()
def dump_test_vector(self, ph, workdir): # dump generated test vectors to a csv file csv_d = os.path.join(workdir, EnvFileLoc().csv_vector_prefix+'_digital.csv') # for digital csv_a = os.path.join(workdir, EnvFileLoc().csv_vector_prefix+'_analog.csv') # for analog d_vector = dict([ (k, self.conv_tobin(ph, k, v)) for k, v in self._d_vector.items() ]) a_vector = dict([ (k, self.conv_tobin(ph, k, v)) for k, v in self._a_vector.items() ]) df_d = pd.DataFrame(d_vector) df_a = pd.DataFrame(a_vector) map(self._logger.info, print_section(mcode.INFO_040, 3)) self._logger.info(df_d) self._logger.debug('\n' + mcode.DEBUG_004 % os.path.relpath(csv_d)) df_d.to_csv(csv_d) map(self._logger.info, print_section(mcode.INFO_041, 3)) self._logger.info(df_a) self._logger.debug('\n' + mcode.DEBUG_005 % os.path.relpath(csv_a)) df_a.to_csv(csv_a)
def _dump_vector_measurement(self, nth_mode, vector, meas, is_golden, quite=False): ''' dump vector & measurement data to a .csv file under test directory ''' mdl_type = 'golden' if is_golden else 'revised' csv_file = os.path.join(self.testdir, '_'.join([self._tenvf.csv_vector_meas_prefix, mdl_type, 'mode', str(nth_mode)]) + '.csv') df = pd.DataFrame(dict([ (k, TestVectorGenerator.conv_tobin(self._ph, k, v)) for k, v in vector.items() ])) df = df.join(pd.DataFrame(meas)) if not quite: map(self._logger.info, print_section(mcode.INFO_026 %(mdl_type), 4)) self._logger.info(df) self._logger.debug("\n"+mcode.DEBUG_001 % (mdl_type, os.path.relpath(csv_file))) df.to_csv(csv_file)
def __call__(self): testres = [] # test results self._testnames = self._tcfg.get_all_testnames() # get all test names map(self._logger.info, print_section(mcode.INFO_012, 1)) self._logger.info(self._testnames) if self._inv: dlrtmvkdldjem() # print report header self._rptgen.print_report_header( self._testnames, os.getcwd(), self._workdir, self._root_rundir, self._testfile, self._simfile, self._rptfile ) if self._inv: dlrtmvkdldjem() # run the checking for each test for idx, t in enumerate(self._testnames): test = self._tcfg.get_test(t) # print test information self._rptgen.print_testname(t) self._rptgen.print_test_info(test.get_dut_name(), test.get_description()) # res = self._run_a_test( t, os.path.join(self._root_rundir, t), test, self._scfg, self._rptgen ) testres.append((t, [(r[1], r[2]['error_flag_pin'], r[2]['error_flag_residue']) for r in res])) self._mp.formulate_model_parameters(t, res) # extract parameters of linear models # save the extracted model parameters self._mp.save_model_parameters(self._root_rundir) # display error summary (suggested model only) if not self._goldenonly: self._test_error_summary(testres) # report gen self._rptgen.render() self._rptgen.close() # print where the report file is rptpath = os.path.relpath(self._rptfile, self._workdir) map(self._logger.info, print_section(mcode.INFO_013 % rptpath, 1)) if self._inv: dlrtmvkdldjem()
def _run_a_test(self, testname, testdir, testcfg, simcfg, rptgen): ''' Run the checking of a test ''' map(self._logger.info, print_section(mcode.INFO_014 % testname, 1)) if make_dir(testdir, self._logger, not self._cache): self._logger.warn(mcode.WARN_002 % os.path.relpath(testdir)) testrun = TestUnit(testcfg, simcfg, testdir, rptgen, use_cache=self._cache, no_thread=self._np, goldensim_only=self._goldenonly, no_otfc = self._no_otfc, csocket=self._csocket, logger_id=self._logger_id) res = testrun.run_test() if simcfg.get_sweep(): # sweep==True for either golden or revised shutil.rmtree(testdir) self._logger.info(mcode.INFO_015 % os.path.relpath(testdir)) map(self._logger.info, print_end_msg(mcode.INFO_016 % testname, '==')) return res
def _create_port(self, test_cfg): ''' Create port objects specified in a test configuration A dummy digital mode port will also be created if no digital mode port exists ''' map(self._logger.info, print_section(mcode.INFO_032, 2)) # create port object to port handler for p, v in test_cfg.get_port().items(): self._ph.add_port(p, test_cfg.get_port_type(v), test_cfg.get_port_description(v), test_cfg.get_port_constraint(v) ) # create dummy digital mode port if necessary if self._ph.get_no_of_digitalmode() == 0: self._ph.add_dummy_digitalmode_port() self._logger.warn(mcode.WARN_005) # create dummy analog input port if necessary if self._ph.get_no_of_unpinned_analoginput() == 0: self._ph.add_dummy_analoginput_port() self._logger.warn(mcode.WARN_005_1) # spit out ports information to logger self._logger.info(mcode.INFO_033) self._ph.get_info_all()
def __init__(self, cfg_filename, bypass=False, keep_raw=False, port_xref='', logger_id='logger_id'): ''' set bypass to False if you don't want to create sub-regions of tests set keep_raw to True if you keep the raw configuration set port_xref to a filename which contains port cross reference of modules ''' assert os.path.exists( get_abspath(cfg_filename)), mcode.ERR_001 % cfg_filename assert os.path.exists( get_abspath(port_xref)), mcode.ERR_001_1 % port_xref self._pxref = port_xref self._tenvp = EnvPortName() self._tenvt = EnvTestcfgPort() self._tenvs = EnvTestcfgSection() self._logger = DaVELogger.get_logger( '%s.%s.%s' % (logger_id, __name__, self.__class__.__name__)) self._logger_id = logger_id map(self._logger.info, print_section('Compile test configrations', 1)) if keep_raw: self.config = self._read_raw_config_file(cfg_filename) else: self._test_cfg = {} # list of UnitTestConfig class instances self._test_name_list = [] # list of the corresponding test names self.config = self._read_config_file(cfg_filename) # 1st pass to Validate and update schema_testcfg = SchemaTestConfig(self.config) schema_testcfg.raise_vdterror() self.config = schema_testcfg.get_cfg() self._build(bypass)
def _print_wires(self, tb_filename): wires_declared = sorted([w.split()[-1] for w in self._test_cfg.get_wires()]) wires = [] for l in vp.getline_verilog(tb_filename): if vp.is_instance(l): portmap = vp.parse_port_map(l) wires.append(portmap.values()) wires = sorted(list(set(flatten_list(wires)))) wire_matched = wires_declared == wires def printable_wirename(wire_list): return ["'%s'" % w for w in wire_list] map(self._logger.info, print_section(mcode.INFO_034, 2)) self._logger.warn(mcode.WARN_006 % ', '.join(printable_wirename(wires))) self._logger.warn(mcode.WARN_007 % ', '.join(printable_wirename(wires_declared))) self._logger.warn(mcode.WARN_008 % ('matched' if wire_matched else 'unmatched')) if wire_matched == False: unmatched_wires = list(set(wires_declared)-set(wires))+list(set(wires)-set(wires_declared)) self._logger.warn(mcode.WARN_009 % ('s are' if len(unmatched_wires)>1 else ' is', ', '.join(printable_wirename(unmatched_wires)))) self._logger.warn(mcode.WARN_010)
def _run_mode(self, nth_mode, mode, modetxt): # run analog vectors for each linear circuit mode ''' runs a mode out of all possible linear circuit modes returns the following sets of golden & revised models - test vector with mode inputs being removed - output responses ''' map(self._logger.info, print_section(mcode.INFO_022, 3)) max_run = self._tvh.get_analog_vector_length() # no. of test vector if self._cache: self._logger.info('\n'+mcode.INFO_023) # empty space for vector, measurement exec_vector = dict([ (p, np.zeros(max_run)) for p in self._ph.get_input_port_name() ]) meas_golden = dict([ (p, np.zeros(max_run)) for p in self._ph.get_output_port_name() ]) meas_revised = dict([ (p, np.zeros(max_run)) for p in self._ph.get_output_port_name() ]) if self._inv: dlrtmvkdldjem() # test vector including digital mode vector = [dict(self._tvh.get_analog_vector(i), **mode) for i in range(max_run)] # run simulation for each test vector/ gather measurements #if self._ph.get_by_name('dummy_analoginput') != None: if (not self._no_otfc) and (not self._cache): # unlesss on-the-fly check is disabled Nrun_u = max(8, self._tvh.get_unit_no_testvector()) # initial # of runs without on-the-fly if self.goldensim_only: # extraction mode Nrun_uchk = Nrun_u else: Nrun_uchk = max(4, self._tvh.get_unit_no_testvector_otf()) # unit # of runs in each on-the-fly else: Nrun_u = 1 Nrun_uchk = 1 #else: # Nrun_u = 1 # Nrun_uchk = 1 sim_idx = 0 #for i in range(0, max_run, Nrun_u): while sim_idx < max_run: if sim_idx >= Nrun_u: no_run = min(Nrun_uchk, (max_run - sim_idx)) else: no_run = min(Nrun_u, (max_run - sim_idx)) lastrun = True if (sim_idx+no_run == max_run) else False simres_golden, simres_revised = self._exercise_unit(nth_mode, mode, sim_idx, no_run, max_run, vector) for j in range(sim_idx, sim_idx+no_run): for k, v in vector[j].items(): exec_vector[k][j] = v for k, v in simres_golden[j-sim_idx][1].items(): meas_golden[k][j] = v for k, v in simres_revised[j-sim_idx][1].items(): meas_revised[k][j] = v # chop data upto current run _exec_vector = dict([ (p, exec_vector[p][:sim_idx+no_run]) for p in self._ph.get_input_port_name() ]) _meas_golden = dict([ (p, meas_golden[p][:sim_idx+no_run]) for p in self._ph.get_output_port_name() ]) _meas_revised = dict([ (p, meas_revised[p][:sim_idx+no_run]) for p in self._ph.get_output_port_name() ]) # do regression # check on-the-fly equivalence if (not self._no_otfc) and (not self._cache): # unlesss on-the-fly check is disabled self._logger.info('') exec_vector_new=TestVectorGenerator.get_effective_vector(_exec_vector, self._ph) lr_formulas = self._run_linear_regression(mode, nth_mode, exec_vector_new, _meas_golden, _meas_revised, quite= True) # linear regression equation of a golden model if not self._check_equivalence(): # not equivalent break sim_idx += no_run ## dump vector/measurement exec_vector_new=TestVectorGenerator.get_effective_vector(_exec_vector, self._ph) self._dump_vector_measurement(nth_mode, _exec_vector, _meas_golden, is_golden=True, quite=False) self._dump_vector_measurement(nth_mode, _exec_vector, _meas_revised, is_golden=False, quite=False) lr_formulas = self._run_linear_regression(mode, nth_mode, exec_vector_new, _meas_golden, _meas_revised, quite= False) # linear regression equation of a golden model # generate reports if self._rptgen != None: err_flag_pin, err_flag_residue = self._generate_mode_report() res = {'vector_golden': self._remove_mode_vector(exec_vector_new, mode), 'meas_golden': meas_golden, 'vector_revised': self._remove_mode_vector(exec_vector_new, mode), 'meas_revised': meas_revised, 'error_flag_pin': err_flag_pin, 'error_flag_residue': err_flag_residue, 'lr_formula_suggested': lr_formulas } if not self.goldensim_only: self._print_interim_summary(res, self._testname, mode, modetxt) map(self._logger.info, print_end_msg(mcode.INFO_021 % modetxt, '--')) return res
def _test_error_summary(self, result): ''' logging error summary ''' msg = mcode.INFO_017 % (mcode.INFO_018) map(self._logger.info,print_section(msg, 1)) tab = generate_check_summary_table(result) self._logger.info(tab.draw())