def get_deps_fpga_emu(cell_name=None, impl_file=None, override=None): # set defaults if override is None: override = {} deps = [] deps += get_deps(cell_name=cell_name, impl_file=impl_file, view_order=['fpga_models', 'pack', 'chip_src'], includes=[ get_dir('inc/fpga'), svreal.get_svreal_header().parent, msdsl.get_msdsl_header().parent ], defines={ 'DT_WIDTH': 25, 'DT_EXPONENT': -46, 'VIVADO': None }, skip={ 'svreal', 'assign_real', 'comp_real', 'add_sub_real', 'ite_real', 'dff_real', 'mul_real', 'mem_digital', 'sync_rom_real', 'DW_tap' }, no_descend={ 'chan_core', 'tx_core', 'osc_model_core', 'clk_delay_core', 'rx_adc_core', 'analog_slice' }, override=override) return deps
def compile_and_run(self, target='system-verilog', ext_srcs=None, inc_dirs=None, ext_model_file=True, tmp_dir=None, disp_type=None, real_type=RealType.FixedPoint, defines=None, **kwargs): # set defaults if ext_srcs is None: ext_srcs = [] if inc_dirs is None: inc_dirs = [] if tmp_dir is None: tmp_dir = not self.debug_mode if disp_type is None: disp_type = 'on_error' if (not self.debug_mode) else 'realtime' if defines is None: defines = {} # add to ext_srcs if real_type == RealType.HardFloat: ext_srcs = get_hard_float_sources() + ext_srcs # add to inc_dirs inc_dirs = [get_svreal_header().parent, get_msdsl_header().parent] + inc_dirs if real_type == RealType.HardFloat: inc_dirs = get_hard_float_inc_dirs() + inc_dirs # add defines as needed for the real number type defines = defines.copy() if real_type == RealType.FixedPoint: pass elif real_type == RealType.FloatReal: defines['FLOAT_REAL'] = None elif real_type == RealType.HardFloat: defines['HARD_FLOAT'] = None # call the command super().compile_and_run(target='system-verilog', ext_srcs=ext_srcs, inc_dirs=inc_dirs, defines=defines, ext_model_file=ext_model_file, tmp_dir=tmp_dir, disp_type=disp_type, **kwargs)
def test_clk_delay(simulator_name, float_real): # set defaults if simulator_name is None: simulator_name = 'vivado' # declare circuit class dut(m.Circuit): name = 'test_clk_delay' io = m.IO(code=m.In(m.Bits[N_BITS]), clk_i_val=m.BitIn, clk_o_val=m.BitOut, dt_req=fault.RealIn, emu_dt=fault.RealOut, jitter_seed=m.In(m.Bits[32]), jitter_rms=fault.RealIn, emu_clk=m.In(m.Clock), emu_rst=m.BitIn) # create the tester t = fault.Tester(dut, dut.emu_clk) # utility function for easier waveform debug def check_result(emu_dt, clk_val, abs_tol=DEL_PREC): t.delay((TCLK / 2) - DELTA) t.poke(dut.emu_clk, 0) t.delay(TCLK / 2) t.expect(dut.emu_dt, emu_dt, abs_tol=abs_tol) t.expect(dut.clk_o_val, clk_val) t.poke(dut.emu_clk, 1) t.delay(DELTA) # compute nominal delay del_nom = (DEL_CODE / (2.0**N_BITS)) * T_PER # initialize t.zero_inputs() t.poke(dut.code, DEL_CODE) t.poke(dut.emu_rst, 1) # apply reset t.poke(dut.emu_clk, 1) t.delay(TCLK / 2) t.poke(dut.emu_clk, 0) t.delay(TCLK / 2) # clear reset t.poke(dut.emu_rst, 0) # run a few cycles for _ in range(3): t.poke(dut.emu_clk, 1) t.delay(TCLK / 2) t.poke(dut.emu_clk, 0) t.delay(TCLK / 2) t.poke(dut.emu_clk, 1) t.delay(DELTA) # raise clock val t.poke(dut.clk_i_val, 1) t.poke(dut.dt_req, (0.123e-9) / 4) check_result((0.123e-9) / 4, 0) # wait some time (expect dt_req ~ 0.1 ns) t.poke(dut.clk_i_val, 1) t.poke(dut.dt_req, 0.234e-9) check_result(del_nom, 1) # lower clk_val, wait some time (expect dt_req ~ 0.345 ns) t.poke(dut.clk_i_val, 0) t.poke(dut.dt_req, (0.345e-9) / 4) check_result((0.345e-9) / 4, 1) # wait some time (expect dt_req ~ 0.1 ns) t.poke(dut.clk_i_val, 0) t.poke(dut.dt_req, (0.456e-9) / 4) check_result(del_nom, 0) # raise clk_val, wait some time (expect dt_req ~ 0.567 ns) t.poke(dut.clk_i_val, 1) t.poke(dut.dt_req, (0.567e-9) / 4) check_result((0.567e-9) / 4, 0) # wait some time (expect dt_req ~ 0.1 ns) t.poke(dut.clk_i_val, 1) t.poke(dut.dt_req, (0.678e-9) / 4) check_result(del_nom, 1) # lower clk_val, wait some time (expect dt_req ~ 0.789 ns) t.poke(dut.clk_i_val, 0) t.poke(dut.dt_req, (0.789e-9) / 4) check_result((0.789e-9) / 4, 1) # run the simulation defines = {'DT_WIDTH': 25, 'DT_EXPONENT': -46} if float_real: defines['FLOAT_REAL'] = None t.compile_and_run( target='system-verilog', directory=BUILD_DIR, simulator=simulator_name, ext_srcs=[ get_file('build/fpga_models/clk_delay_core/clk_delay_core.sv'), get_file('tests/fpga_block_tests/clk_delay/test_clk_delay.sv') ], inc_dirs=[get_svreal_header().parent, get_msdsl_header().parent], ext_model_file=True, defines=defines, disp_type='realtime')
def test_chan_model(simulator_name): # set defaults if simulator_name is None: simulator_name = 'vivado' # declare circuit class dut(m.Circuit): name = 'test_chan_model' io = m.IO(in_=fault.RealIn, out=fault.RealOut, dt_sig=fault.RealIn, clk=m.In(m.Clock), cke=m.BitIn, rst=m.BitIn, wdata0=m.In(m.Bits[CFG['func_widths'][0]]), wdata1=m.In(m.Bits[CFG['func_widths'][1]]), waddr=m.In(m.Bits[int(ceil(log2(CFG['func_numel'])))]), we=m.BitIn) # create the t t = fault.Tester(dut, dut.clk) def cycle(k=1): for _ in range(k): t.delay(TPER / 2 - DELTA) t.poke(dut.clk, 0) t.delay(TPER / 2) t.poke(dut.clk, 1) t.delay(DELTA) # initialize t.zero_inputs() t.poke(dut.rst, 1) cycle() t.poke(dut.rst, 0) # initialize step response functions placeholder = PlaceholderFunction(domain=CFG['func_domain'], order=CFG['func_order'], numel=CFG['func_numel'], coeff_widths=CFG['func_widths'], coeff_exps=CFG['func_exps']) coeffs_bin = placeholder.get_coeffs_bin_fmt(CHAN.interp) t.poke(dut.we, 1) for i in range(placeholder.numel): t.poke(dut.wdata0, coeffs_bin[0][i]) t.poke(dut.wdata1, coeffs_bin[1][i]) t.poke(dut.waddr, i) cycle() t.poke(dut.we, 0) # values val1 = +1.23 val2 = -2.34 val3 = +3.45 # timesteps dt0 = (1e-9) / 16 dt1 = (2e-9) / 16 dt2 = (3e-9) / 16 dt3 = (4e-9) / 16 dt4 = (5e-9) / 16 dt5 = (6e-9) / 16 dt6 = (7e-9) / 16 dt7 = (8e-9) / 16 dt8 = (9e-9) / 16 # action sequence t.poke(dut.cke, 0) t.poke(dut.dt_sig, dt0) t.poke(dut.in_, 0.0) cycle() t.poke(dut.cke, 1) t.poke(dut.dt_sig, dt1) t.poke(dut.in_, 0.0) cycle() meas1 = t.get_value(dut.out) t.poke(dut.cke, 0) t.poke(dut.dt_sig, dt2) t.poke(dut.in_, val1) cycle() meas2 = t.get_value(dut.out) t.poke(dut.cke, 0) t.poke(dut.dt_sig, dt3) t.poke(dut.in_, val1) cycle() meas3 = t.get_value(dut.out) t.poke(dut.cke, 1) t.poke(dut.dt_sig, dt4) t.poke(dut.in_, val1) cycle() meas4 = t.get_value(dut.out) t.poke(dut.cke, 0) t.poke(dut.dt_sig, dt5) t.poke(dut.in_, val2) cycle() meas5 = t.get_value(dut.out) t.poke(dut.cke, 1) t.poke(dut.dt_sig, dt6) t.poke(dut.in_, val2) cycle() meas6 = t.get_value(dut.out) t.poke(dut.cke, 0) t.poke(dut.dt_sig, dt7) t.poke(dut.in_, val3) cycle() meas7 = t.get_value(dut.out) t.poke(dut.cke, 0) t.poke(dut.dt_sig, dt8) t.poke(dut.in_, val3) cycle() meas8 = t.get_value(dut.out) # compute expected outputs chan = Filter.from_file(get_file('build/chip_src/adapt_fir/chan.npy')) f = chan.interp expt1 = 0 expt2 = val1 * f(dt2) expt3 = val1 * f(dt2 + dt3) expt4 = val1 * f(dt2 + dt3 + dt4) expt5 = val1 * (f(dt2 + dt3 + dt4 + dt5) - f(dt5)) + val2 * f(dt5) expt6 = val1 * (f(dt2 + dt3 + dt4 + dt5 + dt6) - f(dt5 + dt6)) + val2 * f(dt5 + dt6) expt7 = (val1 * (f(dt2 + dt3 + dt4 + dt5 + dt6 + dt7) - f(dt5 + dt6 + dt7)) + val2 * (f(dt5 + dt6 + dt7) - f(dt7)) + val3 * f(dt7)) # define parameters parameters = { 'width0': CFG['func_widths'][0], 'width1': CFG['func_widths'][1], 'naddr': int(ceil(log2(CFG['func_numel']))) } # run the simulation t.compile_and_run( target='system-verilog', directory=BUILD_DIR, simulator=simulator_name, ext_srcs=[ get_file('build/fpga_models/chan_core/chan_core.sv'), get_file('tests/fpga_block_tests/chan_model/test_chan_model.sv') ], inc_dirs=[get_svreal_header().parent, get_msdsl_header().parent], ext_model_file=True, disp_type='realtime', parameters=parameters, dump_waveforms=False, timescale='1ns/1ps', num_cycles=1e12) # check outputs def check_output(name, meas, expct, abs_tol=0.001): print(f'checking {name}: measured {meas.value}, expected {expct}') if (expct - abs_tol) <= meas.value <= (expct + abs_tol): print('OK') else: raise Exception('Failed') check_output('expr1', meas1, expt1) check_output('expr2', meas2, expt2) check_output('expr3', meas3, expt3) check_output('expr4', meas4, expt4) check_output('expr5', meas5, expt5) check_output('expr6', meas6, expt6) check_output('expr7', meas7, expt7)
def test_analog_slice(simulator_name, slice_offset, dump_waveforms, num_tests=100): # set seed for repeatable behavior random.seed(0) # set defaults if simulator_name is None: simulator_name = 'vivado' # determine the real-number formatting real_type = get_dragonphy_real_type() if real_type in {RealType.FixedPoint, RealType.FloatReal}: func_widths = CFG['func_widths'] elif real_type == RealType.HardFloat: func_widths = [DEF_HARD_FLOAT_WIDTH, DEF_HARD_FLOAT_WIDTH] else: raise Exception('Unsupported RealType.') # declare circuit class dut(m.Circuit): name = 'test_analog_slice' io = m.IO( chunk=m.In(m.Bits[CFG['chunk_width']]), chunk_idx=m.In(m.Bits[int(ceil(log2(CFG['num_chunks'])))]), pi_ctl=m.In(m.Bits[CFG['pi_ctl_width']]), slice_offset=m.In(m.Bits[int(ceil(log2(CFG['slices_per_bank'])))]), sample_ctl=m.BitIn, incr_sum=m.BitIn, write_output=m.BitIn, out_sgn=m.BitOut, out_mag=m.Out(m.Bits[CFG['n_adc']]), clk=m.BitIn, rst=m.BitIn, jitter_rms=fault.RealIn, noise_rms=fault.RealIn, wdata0=m.In(m.Bits[func_widths[0]]), wdata1=m.In(m.Bits[func_widths[1]]), waddr=m.In(m.Bits[9]), we=m.BitIn ) # create the tester t = fault.Tester(dut) def cycle(k=1): for _ in range(k): t.delay(TPER/2 - DELTA) t.poke(dut.clk, 0) t.delay(TPER/2) t.poke(dut.clk, 1) t.delay(DELTA) def to_bv(lis): return int(''.join(str(elem) for elem in lis), 2) # build up a list of test cases test_cases = [] for x in range(num_tests): pi_ctl = random.randint(0, (1 << CFG['pi_ctl_width']) - 1) all_bits = [random.randint(0, 1) for _ in range(CFG['chunk_width'] * CFG['num_chunks'])] test_cases.append([pi_ctl, all_bits]) # initialize # two cycles of reset -- one to reset DFFs, then another to read out ROM values # after the addresses are no longer X t.zero_inputs() t.poke(dut.slice_offset, slice_offset) t.poke(dut.rst, 1) cycle(2) t.poke(dut.rst, 0) # initialize step response functions placeholder = PlaceholderFunction(domain=CFG['func_domain'], order=CFG['func_order'], numel=CFG['func_numel'], coeff_widths=CFG['func_widths'], coeff_exps=CFG['func_exps'], real_type=real_type) coeffs_bin = placeholder.get_coeffs_bin_fmt(CHAN.interp) t.poke(dut.we, 1) for i in range(placeholder.numel): t.poke(dut.wdata0, coeffs_bin[0][i]) t.poke(dut.wdata1, coeffs_bin[1][i]) t.poke(dut.waddr, i) cycle() t.poke(dut.we, 0) # f cycle t.poke(dut.chunk, 0) t.poke(dut.chunk_idx, 0) t.poke(dut.pi_ctl, test_cases[0][0]) t.poke(dut.sample_ctl, 1) t.poke(dut.incr_sum, 1) t.poke(dut.write_output, 1) cycle() # loop through test cases for i in range(num_tests): for j in range(2+CFG['num_chunks']): if j < CFG['num_chunks']: t.poke(dut.chunk, to_bv(test_cases[i][1][(j*CFG['chunk_width']):((j+1)*CFG['chunk_width'])])) t.poke(dut.chunk_idx, j) else: t.poke(dut.chunk, 0) t.poke(dut.chunk_idx, 0) if j != (CFG['num_chunks']+1): t.poke(dut.sample_ctl, 0) t.poke(dut.write_output, 0) else: if i != (num_tests-1): t.poke(dut.pi_ctl, test_cases[i+1][0]) t.poke(dut.sample_ctl, 1) t.poke(dut.write_output, 1) if j != 1: t.poke(dut.incr_sum, 1) else: t.poke(dut.incr_sum, 0) cycle() # gather results test_cases[i].extend([t.get_value(dut.out_sgn), t.get_value(dut.out_mag)]) # define macros defines = {} # include directories inc_dirs = [ get_svreal_header().parent, get_msdsl_header().parent ] # source files ext_srcs = [ get_file('build/fpga_models/analog_slice/analog_slice.sv'), THIS_DIR / 'test_analog_slice.sv' ] # adjust for HardFloat if needed if real_type == RealType.HardFloat: ext_srcs = get_hard_float_sources() + ext_srcs inc_dirs = get_hard_float_inc_dirs() + inc_dirs defines['HARD_FLOAT'] = None defines['FUNC_DATA_WIDTH'] = DEF_HARD_FLOAT_WIDTH # waveform dumping options flags = [] if simulator_name == 'ncsim': flags += ['-unbuffered'] # run the simulation t.compile_and_run( target='system-verilog', directory=BUILD_DIR, simulator=simulator_name, defines=defines, inc_dirs=inc_dirs, ext_srcs=ext_srcs, parameters={ 'chunk_width': CFG['chunk_width'], 'num_chunks': CFG['num_chunks'] }, ext_model_file=True, disp_type='realtime', dump_waveforms=dump_waveforms, flags=flags, timescale='1fs/1fs', num_cycles=1e12 ) # process the results for k, (pi_ctl, all_bits, sgn_meas, mag_meas) in enumerate(test_cases): # compute the expected ADC value analog_sample = channel_model(slice_offset, pi_ctl, all_bits) sgn_expct, mag_expct = adc_model(analog_sample) # print measured and expected print(f'Test case #{k}: slice_offset={slice_offset}, pi_ctl={pi_ctl}, all_bits={all_bits}') print(f'[measured] sgn: {sgn_meas.value}, mag: {mag_meas.value}') print(f'[expected] sgn: {sgn_expct}, mag: {mag_expct}, analog_sample: {analog_sample}') # check result check_adc_result(sgn_meas.value, mag_meas.value, sgn_expct, mag_expct) # declare success print('Success!')
def test_analog_core(simulator_name, dump_waveforms, num_tests=100): # set seed for repeatable behavior random.seed(0) # set defaults if simulator_name is None: simulator_name = 'vivado' # determine the real-number formatting real_type = get_dragonphy_real_type() if real_type in {RealType.FixedPoint, RealType.FloatReal}: func_widths = CFG['func_widths'] elif real_type == RealType.HardFloat: func_widths = [DEF_HARD_FLOAT_WIDTH, DEF_HARD_FLOAT_WIDTH] else: raise Exception('Unsupported RealType.') # set up the IO definitions io_dict = {} io_dict['bits'] = m.In(m.Bits[16]) for k in range(4): io_dict[f'ctl_pi_{k}'] = m.In(m.Bits[9]) for k in range(16): io_dict[f'adder_out_{k}'] = m.Out(m.Bits[8]) io_dict.update(dict( sign_out=m.Out(m.Bits[16]), clk=m.BitIn, rst= m.BitIn, jitter_rms_int= m.In(m.Bits[7]), noise_rms_int= m.In(m.Bits[11]), chan_wdata_0=m.In(m.Bits[func_widths[0]]), chan_wdata_1=m.In(m.Bits[func_widths[1]]), chan_waddr=m.In(m.Bits[9]), chan_we=m.BitIn )) # declare circuit class dut(m.Circuit): name = 'test_analog_core' io = m.IO(**io_dict) # create the tester t = fault.Tester(dut) def cycle(k=1): for _ in range(k): t.delay(TPER/2 - DELTA) t.poke(dut.clk, 0) t.delay(TPER/2) t.poke(dut.clk, 1) t.delay(DELTA) def to_bv(lis): return int(''.join(str(elem) for elem in lis), 2) def poke_bits(bits): t.poke(dut.bits, to_bv(bits)) def poke_pi_ctl(pi_ctl): for k in range(4): t.poke(getattr(dut, f'ctl_pi_{k}'), pi_ctl[k]) def get_adder_out(): retval = [] for k in range(16): retval.append(t.get_value(getattr(dut, f'adder_out_{k}'))) return retval # build up a list of test cases test_cases = [] for x in range(num_tests): pi_ctl = [random.randint(0, (1 << CFG['pi_ctl_width']) - 1) for _ in range(4)] new_bits = [random.randint(0, 1) for _ in range(16)] test_cases.append([pi_ctl, new_bits]) # initialize t.zero_inputs() t.poke(dut.rst, 1) cycle(2) t.poke(dut.rst, 0) for j in range(1 + CFG['num_chunks']): cycle() # initialize step response functions placeholder = PlaceholderFunction(domain=CFG['func_domain'], order=CFG['func_order'], numel=CFG['func_numel'], coeff_widths=CFG['func_widths'], coeff_exps=CFG['func_exps'], real_type=real_type) coeffs_bin = placeholder.get_coeffs_bin_fmt(CHAN.interp) t.poke(dut.chan_we, 1) for i in range(placeholder.numel): t.poke(dut.chan_wdata_0, coeffs_bin[0][i]) t.poke(dut.chan_wdata_1, coeffs_bin[1][i]) t.poke(dut.chan_waddr, i) cycle() t.poke(dut.chan_we, 0) # run test cases results = [] for pi_ctl, new_bits in test_cases: poke_bits(new_bits) poke_pi_ctl(pi_ctl) for j in range(2+CFG['num_chunks']): cycle() results.append([t.get_value(dut.sign_out), get_adder_out()]) # run a few cycles at the end for better waveform visibility cycle(5) # define macros defines = { 'FPGA_MACRO_MODEL': True, 'CHUNK_WIDTH': CFG['chunk_width'], 'NUM_CHUNKS': CFG['num_chunks'] } # include directories inc_dirs = [ get_svreal_header().parent, get_msdsl_header().parent, get_dir('inc/fpga') ] # source files ext_srcs = get_deps_fpga_emu(impl_file=THIS_DIR/'test_analog_core.sv') # adjust for HardFloat if needed if real_type == RealType.HardFloat: ext_srcs = get_hard_float_sources() + ext_srcs inc_dirs = get_hard_float_inc_dirs() + inc_dirs defines['HARD_FLOAT'] = None defines['FUNC_DATA_WIDTH'] = DEF_HARD_FLOAT_WIDTH # waveform dumping options flags = [] if simulator_name == 'ncsim': flags += ['-unbuffered'] if dump_waveforms: defines['DUMP_WAVEFORMS'] = None if simulator_name == 'ncsim': flags += ['-access', '+r'] # run the simulation t.compile_and_run( target='system-verilog', directory=BUILD_DIR, simulator=simulator_name, defines=defines, inc_dirs=inc_dirs, ext_srcs=ext_srcs, ext_model_file=True, disp_type='realtime', dump_waveforms=False, flags=flags, timescale='1fs/1fs', num_cycles=1e12 ) # process the results for k in range(1, len(test_cases)-1): # extract out parameters pi_ctl, new_bits = test_cases[k] prev_bits = test_cases[k-1][1] # compute the expected ADC value analog_sample, sgn_expct, mag_expct = [], [], [] all_bits = new_bits + prev_bits for idx in range(16): # determine the analog value sampled on this channel analog_sample.append(channel_model(idx%4, pi_ctl[idx//4], all_bits)) # determine what the ADC output should be adc_out = adc_model(analog_sample[-1]) sgn_expct.append(adc_out[0]) mag_expct.append(adc_out[1]) # extract out results sgn_meas = [(results[k+1][0].value >> idx) & 1 for idx in range(16)] mag_meas = [elem.value for elem in results[k+1][1]] # print measured and expected print(f'Test case #{k}: pi_ctl={pi_ctl}, all_bits={new_bits}') print(f'[measured] sgn: {sgn_meas}, mag: {mag_meas}') print(f'[expected] sgn: {sgn_expct}, mag: {mag_expct}, analog_sample: {analog_sample}') # check results for sm, mm, se, me in zip(sgn_meas, mag_meas, sgn_expct, mag_expct): check_adc_result(sm, mm, se, me) # declare success print('Success!')
def test_adc_model(simulator_name, should_print=False): # set defaults if simulator_name is None: simulator_name = 'vivado' # declare circuit class dut(m.Circuit): name = 'test_adc_model' io = m.IO( in_=fault.RealIn, clk_val=m.BitIn, out_mag=m.Out(m.Bits[CFG['n']]), out_sgn=m.BitOut, noise_seed=m.In(m.Bits[32]), noise_rms=fault.RealIn, emu_rst=m.BitIn, emu_clk=m.ClockIn ) # create the tester t = fault.Tester(dut, dut.emu_clk) # initialize t.zero_inputs() t.poke(dut.emu_rst, 1) t.step(4) # clear reset t.poke(dut.emu_rst, 0) t.step(4) # create mechanism to run trials def run_trial(in_): # set input t.poke(dut.in_, in_) t.step(4) # toggle clock t.poke(dut.clk_val, 1) t.step(4) t.poke(dut.clk_val, 0) t.step(4) # print output if desired if should_print: t.print('in_: %0f, out_sgn: %0d, out_mag: %0d\n', dut.in_, dut.out_sgn, dut.out_mag) # get expected output expct_sgn, expct_mag = model(in_=in_) # check results t.expect(dut.out_sgn, expct_sgn) t.expect(dut.out_mag, expct_mag) # specify trials to be run delta = 0.1*CFG['vref'] for in_ in np.linspace(-CFG['vref']-delta, CFG['vref']+delta, 100): run_trial(in_=in_) # run the simulation t.compile_and_run( target='system-verilog', directory=BUILD_DIR, simulator=simulator_name, ext_srcs=[get_file('build/fpga_models/rx_adc_core/rx_adc_core.sv'), get_file('tests/fpga_block_tests/adc_model/test_adc_model.sv')], inc_dirs=[get_svreal_header().parent, get_msdsl_header().parent], ext_model_file=True, disp_type='realtime', parameters={'n': CFG['n']}, dump_waveforms=False )