def register_test_with_vunit(vu, directory, filenames, top_entity, all_generics, test_class, top_params): ''' Register a test with vunit. Args: `vu`: A vunit instance. `directory`: A directory in which generated files are placed. `filenames`: The filenames for the test. Does not include testbench. `top_entity`: The name of the top level entity. `all_generics`: An iterable of dictionaries of the top level generics to test. `test_class`: A function that takes (resolved, generics, top_params) and returns an object with make_input_data and check_output_data methods. `top_params`: Top level parameters to pass to the test class. ''' ftb_directory = os.path.join(directory, 'ftb') if os.path.exists(ftb_directory): shutil.rmtree(ftb_directory) os.makedirs(ftb_directory) logger.debug('update_vunit deleting {}'.format(ftb_directory)) with_slvcodec_files = add_slvcodec_files(directory, filenames) generated_fns, resolved = filetestbench_generator.prepare_files( directory=ftb_directory, filenames=with_slvcodec_files, top_entity=top_entity) combined_filenames = with_slvcodec_files + generated_fns register_rawtest_with_vunit( vu=vu, resolved=resolved, filenames=combined_filenames, top_entity=top_entity, all_generics=all_generics, test_class=test_class, top_params=top_params, )
def register_coretest_with_vunit(vu, test, test_output_directory): ''' Register a test with vunit. Args: `vu`: A vunit instance. `test_output_directory`: A directory in which generated files are placed. `test`: A dictionary containing: `param_sets`: An iteratable of top_params with lists of generics. `core_name`: The name of the fusesoc core to test. `top_entity`: The name of the entity to test. `generator`: A function that takes (resolved, generics, top_params) and returns an object with make_input_data and check_output_data methods. ''' if 'param_sets' in test: param_sets = test['param_sets'] elif 'all_generics' in test: param_sets = [{ 'generic_sets': test['all_generics'], 'top_params': {}, }] else: param_sets = [{ 'generic_sets': [{}], 'top_params': {}, }] for param_set in param_sets: generic_sets = param_set['generic_sets'] top_params = param_set['top_params'] h = hash(params_helper.make_hashable(top_params)) generation_directory = os.path.join(test_output_directory, test['core_name'], 'generated_{}'.format(h)) if os.path.exists(generation_directory): shutil.rmtree(generation_directory) logger.debug('Removing directory {}'.format(generation_directory)) os.makedirs(generation_directory) # Create this side effect object so that we can create a function # that has the interface fusesoc_generator expects but we can still # get access to the 'resolved' from parsing. filenames = fusesoc_generators.get_filenames_from_core( generation_directory, test['core_name'], test['entity_name'], generic_sets, top_params, add_slvcodec_files) ftb_directory = os.path.join(generation_directory, 'ftb') if os.path.exists(ftb_directory): shutil.rmtree(ftb_directory) os.makedirs(ftb_directory) generated_fns, resolved = filetestbench_generator.prepare_files( directory=ftb_directory, filenames=filenames, top_entity=test['entity_name']) combined_filenames = filenames + generated_fns register_rawtest_with_vunit( vu=vu, resolved=resolved, filenames=combined_filenames, top_entity=test['entity_name'], all_generics=generic_sets, test_class=test['generator'], top_params=top_params, )
def get_coretest_files(test, test_output_directory, param_set, add_double_wrapper, default_generics, fusesoc_config_filename, generate_iteratively, verbose=False): generated_index = 0 generic_sets = param_set['generic_sets'] top_params = param_set['top_params'] generation_directory = os.path.join(test_output_directory, test['core_name'], 'generated_{}'.format(generated_index)) while os.path.exists(generation_directory): generated_index += 1 generation_directory = os.path.join( test_output_directory, test['core_name'], 'generated_{}'.format(generated_index)) os.makedirs(generation_directory) if generate_iteratively: filenames = fusesoc_wrapper.generate_core_iteratively( core_name=test['core_name'], work_root=generation_directory, all_top_generics=generic_sets, top_params=top_params, top_name=test['entity_name'], config_filename=fusesoc_config_filename, additional_generator=add_slvcodec_files, verbose=verbose, ) else: filenames = fusesoc_wrapper.generate_core( working_directory=generation_directory, core_name=test['core_name'], parameters=top_params, config_filename=fusesoc_config_filename, additional_generator=add_slvcodec_files, verbose=verbose, ) filenames = add_slvcodec_files(generation_directory, filenames) ftb_directory = os.path.join(generation_directory, 'ftb') if os.path.exists(ftb_directory): shutil.rmtree(ftb_directory) os.makedirs(ftb_directory) generated_fns, generated_wrapper_fns, resolved = filetestbench_generator.prepare_files( directory=ftb_directory, filenames=filenames, top_entity=test['entity_name'], add_double_wrapper=add_double_wrapper, clock_domains=test.get('clock_domains', None), clock_periods=test.get('clock_periods', None), clock_offsets=test.get('clock_offsets', None), default_generics=default_generics, ) combined_filenames = filenames + generated_fns + generated_wrapper_fns return filenames, combined_filenames, resolved
def run_test(): # Create VUnit instance by parsing command line arguments vu = VUnit.from_argv() # Create library 'lib' lib = vu.add_library("lib") files = ( 'vhdl_type_pkg.vhd', 'dummy.vhd', ) directory = 'deleteme' os.makedirs(directory) generated_fns, entity = filetestbench_generator.prepare_files( directory, files, 'dummy') # Add all files ending in .vhd in current working directory to library lib.add_source_files(generated_fns) lib.add_source_files('../vhdl/*.vhd') lib.add_source_files('*.vhd') datainfilename = os.path.join(directory, 'indata.das') dataoutfilename = os.path.join(directory, 'outdata.das') generics = {'length': 3} test = DummyTest(entity, generics) i_data = test.make_input_data() lines = [entity.inputs_to_slv(line, generics=generics) for line in i_data] with open(datainfilename, 'w') as f: f.write('\n'.join(lines)) def post_check(directory): with open(dataoutfilename, 'r') as f: lines = f.readlines() o_data = [ entity.outputs_from_slv(line, generics=generics) for line in lines ] test.check_output_data(i_data, o_data) return True tb_generated = lib.entity('dummy_tb') tb_generated.add_config( name="bug", generics={ 'datainfilename': datainfilename, 'dataoutfilename': dataoutfilename, 'length': 5, }, post_check=post_check, ) # Run vunit function vu.main()
def make_complex_mag2_testbench(): base_filenames = [ os.path.join(thisdir, 'complex_pkg.vhd'), os.path.join(thisdir, 'complex_mag2.vhd'), ] slvcodec_fns = make_slvcodec_package() with_slvcodec_fns = base_filenames + slvcodec_fns directory = os.path.join(thisdir, 'generated') generated_fns, resolved = filetestbench_generator.prepare_files( directory=directory, filenames=with_slvcodec_fns, top_entity='complex_mag2') return generated_fns
def test_conversion(): output_dir = os.path.join(testoutput_dir, 'test_conversion') if os.path.exists(output_dir): shutil.rmtree(output_dir) max_data = pow(2, 6) - 1 data = [{ 'reset': random.randint(0, 1), 'i_valid': random.randint(0, 1), 'i_dummy': { 'manydata': [random.randint(0, max_data) for i in range(2)], 'data': random.randint(0, max_data), 'logic': random.randint(0, 1), 'slv': 7, }, 'i_datas': [random.randint(0, max_data) for i in range(3)], } for i in range(20)] entity_filename = os.path.join(vhdl_dir, 'dummy.vhd') package_filenames = [ os.path.join(vhdl_dir, 'vhdl_type_pkg.vhd'), os.path.join(vhdl_dir, 'test_pkg.vhd') ] filenames = [entity_filename] + package_filenames generation_directory = os.path.join(output_dir, 'generated') os.makedirs(generation_directory) with_slvcodec_files = filetestbench_generator.add_slvcodec_files( generation_directory, filenames) ftb_directory = os.path.join(generation_directory, 'ftb') top_entity = 'dummy' os.mkdir(ftb_directory) generated_tb_fns, generated_dut_fns, resolved = filetestbench_generator.prepare_files( directory=ftb_directory, filenames=with_slvcodec_files, top_entity=top_entity) ent = resolved['entities'][top_entity] generics = {'length': 3} for d in data: slv = ent.inputs_to_slv(d, generics=generics) obj = ent.inputs_from_slv(slv, generics=generics) assert obj == d
def register_coretest_with_vunit(vu, test, test_output_directory, add_double_wrapper=False, default_generics={}): ''' Register a test with vunit. Args: `vu`: A vunit instance. `test_output_directory`: A directory in which generated files are placed. `test`: A dictionary containing: `param_sets`: An iteratable of top_params with lists of generics. `core_name`: The name of the fusesoc core to test. `top_entity`: The name of the entity to test. `generator`: A function that takes (resolved, generics, top_params) and returns an object with make_input_data and check_output_data methods. `add_double_wrapper`: Adds wrappers that convert to and from std_logic_vector. Useful if you want the test to also work post-synthesis. `default_generics`: Default values for generics. ''' # Put this import here so we only need it if necessary. # FIXME: Remove fusesoc generators requirement here. import fusesoc_generators if 'param_sets' in test: param_sets = test['param_sets'] elif 'all_generics' in test: param_sets = [{ 'generic_sets': test['all_generics'], 'top_params': {}, }] else: param_sets = [{ 'generic_sets': [{}], 'top_params': {}, }] generated_index = 0 for param_set_index, param_set in enumerate(param_sets): generic_sets = param_set['generic_sets'] top_params = param_set['top_params'] generation_directory = os.path.join( test_output_directory, test['core_name'], 'generated_{}'.format(generated_index)) while os.path.exists(generation_directory): generated_index += 1 generation_directory = os.path.join( test_output_directory, test['core_name'], 'generated_{}'.format(generated_index)) os.makedirs(generation_directory) filenames = fusesoc_generators.get_filenames_from_core( generation_directory, test['core_name'], test['entity_name'], generic_sets, top_params, add_slvcodec_files) ftb_directory = os.path.join(generation_directory, 'ftb') if os.path.exists(ftb_directory): shutil.rmtree(ftb_directory) os.makedirs(ftb_directory) generated_fns, generated_wrapper_fns, resolved = filetestbench_generator.prepare_files( directory=ftb_directory, filenames=filenames, top_entity=test['entity_name'], add_double_wrapper=add_double_wrapper, clock_domains=test.get('clock_domains', None), clock_periods=test.get('clock_periods', None), clock_offsets=test.get('clock_offsets', None), default_generics=default_generics, ) combined_filenames = filenames + generated_fns + generated_wrapper_fns register_rawtest_with_vunit( vu=vu, resolved=resolved, filenames=combined_filenames, top_entity=test['entity_name'], all_generics=generic_sets, test_class=test['generator'], top_params=top_params, ) return { 'filenames': filenames, 'combined_filenames': combined_filenames, }
def __init__(self, directory, filenames, top_entity, generics, clk_name='clk'): clock_domains = {clk_name: ['.*']} generation_directory = os.path.join(directory, 'generated') os.makedirs(generation_directory) ftb_directory = os.path.join(directory, 'ftb') os.makedirs(ftb_directory) top_testbench = top_entity + '_tb' logger.debug('Making testbench') with_slvcodec_files = add_slvcodec_files(directory, filenames) generated_fns, generated_wrapper_fns, resolved = filetestbench_generator.prepare_files( directory=ftb_directory, filenames=with_slvcodec_files, top_entity=top_entity, use_pipes=True, use_vunit=False, clock_domains=clock_domains, default_generics=generics, ) combined_filenames = with_slvcodec_files + generated_fns + generated_wrapper_fns logger.debug('Creating named pipes.') os.mkfifo(os.path.join(directory, 'indata_{}.dat'.format(clk_name))) os.mkfifo(os.path.join(directory, 'outdata_{}.dat'.format(clk_name))) self.entity = resolved['entities'][top_entity] self.resolved = resolved logger.debug('Start simulation process.') self.process = start_ghdl_process(directory, combined_filenames, top_testbench) logger.debug('Simulation process started.') self.stdout_poll = select.poll() self.stdout_poll.register(self.process.stdout, select.POLLIN) self.stderr_poll = select.poll() self.stderr_poll.register(self.process.stderr, select.POLLIN) self.log() logger.debug('Opening handles') self.in_handle = open( os.path.join(directory, 'indata_{}.dat'.format(clk_name)), 'w') self.out_handle = open( os.path.join(directory, 'outdata_{}.dat'.format(clk_name))) logger.debug('Opened handles') self.out_width = self.entity.output_width(generics) self.clk_name = clk_name self.generics = generics logger.debug('Making dut interface.') self.dut = DutInterface(resolved, top_entity, ignored_ports=[clk_name], generics=self.generics) self.clk_signal = 'My clock signal' setattr(self.dut, clk_name, self.clk_signal)
def from_fusesoc_core( directory, corename, entityname, generics, top_params, board_name=None, frequency=None, frequency_b=None, overwrite_ok=False, testbench_type=None, ): board_params = boards.params[board_name] filenames = fusesoc_generators.get_filenames_from_core( work_root=directory, top_core_name=corename, top_entity_name=entityname, generic_sets=[generics], top_params=top_params, additional_generator=add_slvcodec_files, ) if testbench_type == 'jtag': frequency_b = 0 if frequency_b is None else frequency_b files_and_ip = jtagtestbench_generator.get_files_and_ip( directory, filenames, entityname, generics, board_params, frequency, frequency_b) resolved = {} out_of_context = False elif testbench_type == 'file': output_path = os.path.join(directory, 'simulation_output') tb_fns, wrapper_fns, resolved = filetestbench_generator.prepare_files( directory, filenames, entityname, add_double_wrapper=True, use_vunit=False, dut_directory=None, default_generics=generics, default_output_path=output_path) files_and_ip = { 'design_files': filenames + wrapper_fns, 'simulation_files': tb_fns, 'ips': [], 'top_module': entityname + '_fromslvcodec', } out_of_context = True else: files_and_ip = { 'design_files': filenames, 'simulation_files': [], 'ips': [], 'top_module': entityname, } out_of_context = True resolved = {} p = base_project.BaseProject( directory=directory, files_and_ip=files_and_ip, overwrite_ok=overwrite_ok, ) v = vivado_project.VivadoProject( project=p, board=board_name, wait_for_creation=True, out_of_context=out_of_context, frequency=frequency, clock_name='clk', ) return v, resolved