def reset(self): self.dut.data_i <= 0 self.dut.data_stb_i <= 0 self.dut.dclk_rst <= 0 self.dut.rio_phy_rst <= 0 self.dut.trigger <= 0 self.dut._log.info("Waiting initial 120 ns") yield Timer(120, 'ns') self.dut._log.info("Starting reset... ") self.dut.dclk_rst <= 1 self.dut.rio_phy_rst <= 1 yield Combine(self.dclk_re, self.rtio_re) yield Combine(self.dclk_re, self.rtio_re) yield Combine(self.dclk_re, self.rtio_re) yield Combine(self.dclk_re, self.rtio_re) self.dut.dclk_rst <= 0 self.dut.rio_phy_rst <= 0 self.dut._log.info("Reset finished")
def test_combine(dut): """ Test the Combine trigger. """ # gh-852 @cocotb.coroutine def do_something(delay): yield Timer(delay) crs = [cocotb.fork(do_something(dly)) for dly in [10, 30, 20]] yield Combine(*(cr.join() for cr in crs))
def fast_to_slow(dut): axi_input = AxiStream(dut, 'input_', get_clock_signal(dut, CD_I)) axi_output = AxiStream(dut, 'output_', get_clock_signal(dut, CD_O)) init_axis_signals(axi_input, 'input') init_axis_signals(axi_output, 'output') start_clock(dut, CD_I, 10, 'ns') start_clock(dut, CD_O, 20, 'ns') yield Combine(reset_pulse(dut, CD_I), reset_pulse(dut, CD_O)) yield Timer(100, 'ns')
def python_triggers(dut): """Playing with the Python Triggers""" cocotb.fork(Clock(dut.clk_i, 2).start()) yield reset(dut) # t1 = Timer(1) t2 = Timer(2) yield Combine(t1, t2) # Fires when all of the triggers have fired print_fired(dut, "Combine") yield First(t1, t2) # Fires when the first trigger fires print_fired(dut, "First") yield Join(cocotb.fork( reset(dut))) # Fires when the forked coroutine has completed print_fired(dut, "Join")
async def test_recursive_combine(_): """ Test passing a `Combine` trigger directly to another `Combine` trigger. """ done = set() async def waiter(N): await Timer(N, 'ns') done.add(N) start_time = get_sim_time('ns') await Combine(Combine(cocotb.fork(waiter(10)), cocotb.fork(waiter(20))), cocotb.fork(waiter(30))) end_time = get_sim_time('ns') assert end_time - start_time == 30 assert done == {10, 20, 30}
def data_test(dut): tb = TbTdcGpx2Phy(dut, 100, 125) yield tb.initialize() lengths = [14, 20, 22, 38, 44] * 5 values = [randint(0, 2**l - 1) for l in lengths] monitors = [ Join(cocotb.fork(tb.data_out_monitor(ch, values, lengths))) for ch in range(4) ] drivers = [ Join(cocotb.fork(tb.frame_driver(ch, values, lengths))) for ch in range(4) ] yield Combine(*monitors, *drivers)
async def drive_ready(self, value): t1 = cocotb.start_soon(self.data.drive_ready(value)) t2 = cocotb.start_soon(self.resp.drive_ready(value)) return Combine(t1, t2)
def transfer_frame(self, ch, bits, frame_offset=0.0, data_offset=0.0): frame = cocotb.fork(self.generate_frame_signal(ch, frame_offset)) data = cocotb.fork(self.generate_data_signal(ch, bits, data_offset)) yield Combine(Join(frame), Join(data))
def CREATORTESTNAME_test(dut): ## ## first grab the testbench configuration ## config = test_config.get_config() ## ## process input arguments for this test ## input_args = config["input_args"] num_events_to_process = int(input_args["n_events"]) event_level_detail_in_sumary = bool(input_args["event_detail"]) #CREATORSOFTWAREBLOCK## #CREATORSOFTWAREBLOCK## start the software block instance #CREATORSOFTWAREBLOCK## #CREATORSOFTWAREBLOCKCREATORTESTNAME_block_instance = CREATORTESTNAME_block.CREATORCLASSNAMEBlock(dut.clock, "CREATORCLASSNAMEBlock") #CREATORSOFTWAREBLOCKfor i, io in enumerate(CREATORCLASSNAMEPorts.Inputs): #CREATORSOFTWAREBLOCK CREATORTESTNAME_block_instance.add_fifo( #CREATORSOFTWAREBLOCK dut.input_spybuffers[i].spybuffer, #CREATORSOFTWAREBLOCK dut.clock, #CREATORSOFTWAREBLOCK f"{CREATORTESTNAME_block_instance.name}_Input_{i}", #CREATORSOFTWAREBLOCK io, #CREATORSOFTWAREBLOCK direction="in", #CREATORSOFTWAREBLOCK ) #CREATORSOFTWAREBLOCKfor i, io in enumerate(CREATORCLASSNAMEPorts.Outputs): #CREATORSOFTWAREBLOCK CREATORTESTNAME_block_instance.add_fifo( #CREATORSOFTWAREBLOCK dut.output_spybuffers[i].spybuffer, #CREATORSOFTWAREBLOCK dut.clock, #CREATORSOFTWAREBLOCK f"{CREATORTESTNAME_block_instance.name}_Output_{i}", #CREATORSOFTWAREBLOCK io, #CREATORSOFTWAREBLOCK direction="out", #CREATORSOFTWAREBLOCK ) #CREATORSOFTWAREBLOCKCREATORTESTNAME_block_instance.start() ## ## mark the current board ## for i in range(20): dut._log.warning( "AUTOGEN WARNING User should explicitly check the DUT board identifier" ) board_id = 0 # autogen dut._log.info( f"Instantiated CREATORCLASSNAME block with BOARD_ID = {board_id}") for io in CREATORCLASSNAMEPorts.Outputs: if int(io.value) == board_id: this_tp = io break if not this_tp: raise ValueError( f"Unable to find assocated IO for CREATORCLASSNAME BOARD_ID={board_id}" ) dut._log.info(f"Setting test IO with base port_name = {this_tp.name}") ## ## setup the clock and start it ## sim_clock = Clock(dut.clock, int(input_args["clock_period"]), input_args["clock_time_unit"]) cocotb.fork(sim_clock.start()) ## ## initialize the DUT to known state ## initialize_dut(dut) ## ## reset ## dut._log.info("Resetting DUT") yield reset(dut) ## ## get testvectors ## ( input_testvector_files, output_testvector_files, ) = test_config.get_testvector_files_from_config(config) ### ### alternative method for getting testvectors: ### # testvector_dir = config["testvectors"]["testvector_dir"] # ( # input_testvector_files, # output_testvector_files, # ) = CREATORTESTNAME_utils.get_testvector_files(testvector_dir) ## ## initialize the CREATORCLASSNAME block wrapper ## CREATORTESTNAME_wrapper = wrapper.CREATORCLASSNAMEWrapper( clock=dut.clock, name= f"CREATORCLASSNAMEWrapper_{CREATORCLASSNAMEPorts.simplename(this_tp)}", ) for i, io in enumerate(CREATORCLASSNAMEPorts.Inputs): driver = FifoDriver( dut.input_spybuffers[io.value].spybuffer, dut.clock, "CREATORCLASSNAME", io, write_out=True, ) CREATORTESTNAME_wrapper.add_input_driver(driver, io) for i, io in enumerate(CREATORCLASSNAMEPorts.Outputs): active = True monitor = FifoMonitor( dut.output_spybuffers[i].spybuffer, dut.clock, "CREATORCLASSNAME", io, callbacks=[], write_out=True, ) CREATORTESTNAME_wrapper.add_output_monitor(monitor, io, active=active) CREATORTESTNAME_wrapper.sort_ports() ## ## send input events ## dut._log.info("Sending input events") send_finished_signal = CREATORTESTNAME_wrapper.send_input_events( input_testvector_files, n_to_send=num_events_to_process) if not send_finished_signal: raise cocotb.result.TestFailure( f"ERROR Event sending timed out! Number of expected inputs with events = {len(send_finished_signal)}" ) yield Combine(*send_finished_signal) ## ## if you want to put a timeout on the sending of events use ## "with_timeout" instead of just "Combine" ## # try: # yield with_timeout(Combine(*send_finished_signal), 20, "us") # except Exception as ex: # raise cocotb.result.TestFailure( # f"ERROR Timed out waiting for events to send: {ex}" # ) dut._log.info("Sending finished!") timer = Timer(20, "us") dut._log.info("Going to wait 20 microseconds") yield timer ## ## perform testvector comparison test ## all_tests_passed = True all_test_results = [] for oport in CREATORTESTNAME_wrapper.output_ports: ## ## extract the observed data for this output ## monitor, io, is_active = oport words = monitor.observed_words recvd_events = events.load_events(words, "little") cocotb.log.info( f"Output for {io.name} (output port num {io.value}) received {len(recvd_events)} events" ) ## ## extract the expected data for this output ## if config["run_config"]["expected_is_observed"]: # map the "expected" to be the same as the "observed" dut._log.warning( "WARNING Taking expected events to be the same as the observed events!" ) output_testvector_file = "expected_is_observed" expected_output_events = recvd_events else: output_testvector_file = output_testvector_files[io.value] expected_output_events = events.load_events_from_file( output_testvector_file, n_to_load=num_events_to_process) ## ## perform test by comparison with expected testvectors ## events_are_equal, test_results = tb_diff.events_are_equal( recvd_events, expected_output_events, verbose=False) result_summary = result_handler.result_summary_dict( f"{str('CREATORCLASSNAME').upper()}_Output_{io.value:02}", str(output_testvector_file), test_name= f"TEST_{str('CREATORCLASSNAME').upper()}_SRC{this_tp.value:02}_DEST{io.value:02}", test_results=test_results, ) all_test_results.append(result_summary) all_tests_passed = (all_tests_passed and result_summary["test_results"]["test_success"]) this_tp_name = ( f"{this_tp.name.split('_')[0]}{int(this_tp.name.split('_')[1]):02}" ) out_io_name = f"{io.name.split('_')[0]}{int(io.name.split('_')[1]):02}" output_json_name = f"test_results_summary_CREATORCLASSNAME_src{this_tp_name}_dest{out_io_name}.json" with open(output_json_name, "w", encoding="utf-8") as f: json.dump(result_summary, f, ensure_ascii=False, indent=4) result_handler.dump_test_results(all_test_results, event_detail=event_level_detail_in_sumary) cocotb_result = { True: cocotb.result.TestSuccess, False: cocotb.result.TestFailure }[all_tests_passed] raise cocotb_result
def sw_block_test(dut): ## ## first grab the testbench configuration ## config = test_config.get_config() ## ## process input arguments for this test ## input_args = config["input_args"] num_events_to_process = int(input_args["n_events"]) ## ## create the software DUT ## switcher_block = sw_switcher_block.SWSwitcherBlock(dut.clock, "SWSwitcherBlock") for i, io in enumerate(SWSwitcherPorts.Inputs): switcher_block.add_fifo( dut.input_spybuffers[i].spybuffer, dut.clock, f"{switcher_block.name}_Input_{i}", io, direction="in", ) for i, io in enumerate(SWSwitcherPorts.Outputs): switcher_block.add_fifo( dut.output_spybuffers[i].spybuffer, dut.clock, f"{switcher_block.name}_Output_{i}", io, direction="out", ) switcher_block.start() ## ## setup the clock and start it running ## sim_clock = Clock(dut.clock, int(input_args["clock_period"]), input_args["clock_time_unit"]) cocotb.fork(sim_clock.start()) ## ## initialize dut ## initialize_dut(dut) ## ## reset the testbench ## dut._log.info("Resetting DUT") yield reset(dut) ## ## get the testvectors ## ( input_testvector_files, output_testvector_files, ) = test_config.get_testvector_files_from_config(config) ## ## initialize the (software-based) block wrapper ## sw_switcher_wrapper = wrapper.SWSwitcherWrapper(dut.clock, name="SWSwitcherWrapper") for i, io in enumerate(SWSwitcherPorts.Inputs): port_num = io.value driver = FifoDriver( dut.input_spybuffers[port_num].spybuffer, dut.clock, "SWSwitcher", io, write_out=True, ) sw_switcher_wrapper.add_input_driver(driver, io) for i, io in enumerate(SWSwitcherPorts.Outputs): monitor = FifoMonitor( dut.output_spybuffers[i].spybuffer, dut.clock, "SWSwitcher", io, write_out=True, ) sw_switcher_wrapper.add_output_monitor(monitor, io, active=True) sw_switcher_wrapper.sort_ports() ## ## send input events ## dut._log.info("Sending input events") send_finished_signal = sw_switcher_wrapper.send_input_events( input_testvector_files, n_to_send=num_events_to_process) if not send_finished_signal: raise cocotb.result.TestFailure("ERROR Event sending timed out!") yield Combine(*send_finished_signal) dut._log.info("Sending finished!") timer = Timer(500, "us") dut._log.info("Going to wait 20 microseconds") yield timer ## ## perform testvector comparison test ## all_tests_passed = True all_test_results = [] for oport in sw_switcher_wrapper.output_ports: ## ## extract the observed data for this output ## monitor, io, _ = oport words = monitor.observed_words recvd_events = events.load_events(words, "little") cocotb.log.info( f"Output for {io.name} (output port num {io.value}) received {len(recvd_events)} events" ) ## ## extract the expected data for this output ## if config["run_config"]["expected_is_observed"]: # map the "expected" to be the same as the "observed" dut._log.warning( "WARNING Taking expected events to be the same as the observed events!" ) output_testvector_file = "expected_is_observed" expected_output_events = recvd_events else: output_testvector_file = output_testvector_files[io.value] expected_output_events = events.load_events_from_file( output_testvector_file, n_to_load=num_events_to_process) ## ## perform test by comparison with expected testvectors ## events_equal, test_results = tb_diff.events_are_equal( recvd_events, expected_output_events, verbose=False) result_summary = result_handler.result_summary_dict( f"SWSwitcher_Output_{io.value:02}", str(output_testvector_file), test_name=f"TEST_SWSWITCHER_DEST{io.value:02}", test_results=test_results, ) all_tests_passed = (all_tests_passed and result_summary["test_results"]["test_success"]) all_test_results.append(result_summary) output_json_name = f"test_results_summary_SWSwitcher_dest{io.value:02}.json" with open(output_json_name, "w", encoding="utf-8") as f: json.dump(result_summary, f, ensure_ascii=False, indent=4) result_handler.dump_test_results(all_test_results, event_detail=False) cocotb_result = { True: cocotb.result.TestSuccess, False: cocotb.result.TestFailure }[all_tests_passed] raise cocotb_result
def b2b_test_0(dut): ## ## first grab the testbench configuration ## config = test_config.get_config() ## ## process input arguments for this test ## input_args = config["input_args"] num_events_to_process = int(input_args["n_events"]) event_delays = bool(input_args["event_delays"]) event_level_detail_in_summary = bool(input_args["event_detail"]) ## ## Mark the current board ## this_tp = ( B2BPorts.Outputs.AMTP_0 ) # hardcode for now, later take BOARD_ID from env and set the B2B inst to this value board_id = int(dut.board2board_switching_inst.BOARD_ID) dut._log.info(f"Instantiating B2B block with BOARD_ID = {board_id}") this_tp = None for io in B2BPorts.Outputs: if int(io.value) == board_id: this_tp = io break if not this_tp: raise ValueError(f"Unable to find associated IO for B2B BOARD_ID={board_id}") dut._log.info( f"Setting test IO with base (port_name, port_num) = ({this_tp.name}, {this_tp.value})" ) ## ## Setup the clock and start it running ## sim_clock = Clock( dut.clock, int(input_args["clock_period"]), input_args["clock_time_unit"] ) cocotb.fork(sim_clock.start()) ## ## initialize dut for test ## initialize_dut(dut) ## ## reset testbench ## dut._log.info("Resetting DUT") yield reset(dut) ## ## get testvectors ## ( input_testvector_files, output_testvector_files, ) = test_config.get_testvector_files_from_config(config) ## ## initialize B2B block wrapper ## b2b = wrapper.B2BWrapper( clock=dut.clock, name=f"B2BWrapper_{B2BPorts.simplename(this_tp)}" ) for i, io in enumerate(B2BPorts.Inputs): port_num = io.value driver = FifoDriver( dut.input_spybuffers[port_num].spybuffer, dut.clock, "B2B", io, write_out=True, ) b2b.add_input_driver(driver, io) for i, io in enumerate(B2BPorts.Outputs): active = this_tp.value != io.value monitor = FifoMonitor( dut.output_spybuffers[i].spybuffer, dut.clock, "B2B", io, callbacks=[], write_out=True, ) b2b.add_output_monitor(monitor, io, active=active) b2b.sort_ports() ## ## send events ## dut._log.info("Sending input events") send_finished_signal = b2b.send_input_events( input_testvector_files, n_to_send=num_events_to_process, event_delays=event_delays, ) if not send_finished_signal: raise cocotb.result.TestFailure( f"ERROR Event sending timed out! Number of expected inputs with events = {len(send_finished_signal)}" ) yield Combine(*send_finished_signal) dut._log.info("Sending finished!") timer = Timer(20, "us") dut._log.info("Going to wait 20 microseconds") yield timer ## ## perform testvector comparison test ## all_tests_passed = True all_test_results = [] for oport in b2b.output_ports: ## ## extract the observed data for this output ## monitor, io, _ = oport words = monitor.observed_words recvd_events = events.load_events(words, "little") cocotb.log.info( f"Output for {io.name} (output port num {io.value}) received {len(recvd_events)} events" ) ## ## extract the expected data for this output ## if config["run_config"]["expected_is_observed"]: dut._log.warning( "WARNING Taking expected events to be the same as the observed events!" ) output_testvector_file = "expected_is_observed" expected_output_events = recvd_events else: output_testvector_file = output_testvector_files[io.value] expected_output_events = events.load_events_from_file( output_testvector_file, n_to_load=num_events_to_process ) ## ## we expect nothing from the current board but there may be testvectors, ## so "zero" out any testvectors for this output ## if io.value == this_tp.value: expected_output_events = [] ## test events_equal, test_results = tb_diff.events_are_equal( recvd_events, expected_output_events, verbose=False ) result_summary = result_handler.result_summary_dict( f"B2B_Output_{io.value:02}", str(output_testvector_file), test_name=f"TEST_B2B_SRC{this_tp.value:02}_DEST{io.value:02}", test_results=test_results, ) all_tests_passed = ( all_tests_passed and result_summary["test_results"]["test_success"] ) all_test_results.append(result_summary) this_tp_name = ( f"{this_tp.name.split('_')[0]}{int(this_tp.name.split('_')[1]):02}" ) out_io_name = f"{io.name.split('_')[0]}{int(io.name.split('_')[1]):02}" output_json_name = ( f"test_results_summary_B2B_src{this_tp_name}_dest{out_io_name}.json" ) with open(output_json_name, "w", encoding="utf-8") as f: json.dump(result_summary, f, ensure_ascii=False, indent=4) result_handler.dump_test_results( all_test_results, event_detail=event_level_detail_in_summary ) cocotb_result = {True: cocotb.result.TestSuccess, False: cocotb.result.TestFailure}[ all_tests_passed ] raise cocotb_result
def evt_sync_test(dut): ## ## first grab the testbench configuration ## config = test_config.get_config() ## ## process input arguments for this test ## input_args = config["input_args"] num_events_to_process = int(input_args["n_events"]) event_level_detail_in_sumary = bool(input_args["event_detail"]) ## ## mark the current board ## board_id = int(dut.event_sync_inst.BOARD_ID) dut._log.info(f"Instantiated EventSync block with BOARD_ID = {board_id}") for io in EvtSyncPorts.Outputs: if int(io.value) == board_id: this_tp = io break if not this_tp: raise ValueError( f"Unable to find assocated IO for EvtSync BOARD_ID={board_id}") dut._log.info(f"Setting test IO with base port_name = {this_tp.name}") ## ## setup the clock and start it ## sim_clock = Clock(dut.clock, int(input_args["clock_period"]), input_args["clock_time_unit"]) cocotb.fork(sim_clock.start()) ## ## initialize the DUT to known state ## initialize_dut(dut) ## ## reset ## dut._log.info("Resetting DUT") yield reset(dut) ## ## get testvectors ## ( input_testvector_files, output_testvector_files, ) = test_config.get_testvector_files_from_config(config) ## ## initialize the EvtSync block wrapper ## evt_sync_wrapper = wrapper.EvtSyncWrapper( clock=dut.clock, name=f"EvtSyncWrapper_{EvtSyncPorts.simplename(this_tp)}", ) for i, io in enumerate(EvtSyncPorts.Inputs): driver = FifoDriver( dut.input_spybuffers[io.value].spybuffer, dut.clock, "EvtSync", io, write_out=True, ) evt_sync_wrapper.add_input_driver(driver, io) for i, io in enumerate(EvtSyncPorts.Outputs): active = True monitor = FifoMonitor( dut.output_spybuffers[i].spybuffer, dut.clock, "EvtSync", io, callbacks=[], write_out=True, ) evt_sync_wrapper.add_output_monitor(monitor, io, active=active) evt_sync_wrapper.sort_ports() ## ## send input events ## dut._log.info("Sending input events") send_finished_signal = evt_sync_wrapper.send_input_events( input_testvector_files, n_to_send=num_events_to_process) if not send_finished_signal: raise cocotb.result.TestFailure( f"ERROR Event sending timed out! Number of expected inputs with events = {len(send_finished_signal)}" ) try: yield with_timeout(Combine(*send_finished_signal), 20, "us") except Exception as ex: raise cocotb.result.TestFailure( f"ERROR Timed out waiting for events to send: {ex}") dut._log.info("Sending finished!") timer = Timer(20, "us") dut._log.info("Going to wait 20 microseconds") yield timer ## ## perform testvector comparison test ## all_tests_passed = True all_test_results = [] for oport in evt_sync_wrapper.output_ports: ## ## extract the observed data for this output ## monitor, io, is_active = oport words = monitor.observed_words recvd_events = events.load_events(words, "little") cocotb.log.info( f"Output for {io.name} (output port num {io.value}) received {len(recvd_events)} events" ) ## ## extract the expected data for this output ## if config["run_config"]["expected_is_observed"]: # map the "expected" to be the same as the "observed" dut._log.warning( "WARNING Taking expected events to be the same as the observed events!" ) output_testvector_file = "expected_is_observed" expected_output_events = recvd_events else: output_testvector_file = output_testvector_files[io.value] expected_output_events = events.load_events_from_file( output_testvector_file, n_to_load=num_events_to_process) ## ## perform test by comparison with expected testvectors ## events_are_equal, test_results = tb_diff.events_are_equal( recvd_events, expected_output_events, verbose=False) result_summary = result_handler.result_summary_dict( f"EVTSYNC_Output_{io.value:02}", str(output_testvector_file), test_name=f"TEST_EVTSYNC_SRC{this_tp.value:02}_DEST{io.value:02}", test_results=test_results, ) all_test_results.append(result_summary) all_tests_passed = (all_tests_passed and result_summary["test_results"]["test_success"]) this_tp_name = ( f"{this_tp.name.split('_')[0]}{int(this_tp.name.split('_')[1]):02}" ) out_io_name = f"{io.name.split('_')[0]}{int(io.name.split('_')[1]):02}" output_json_name = ( f"test_results_summary_EVTSYNC_src{this_tp_name}_dest{out_io_name}.json" ) with open(output_json_name, "w", encoding="utf-8") as f: json.dump(result_summary, f, ensure_ascii=False, indent=4) result_handler.dump_test_results(all_test_results, event_detail=event_level_detail_in_sumary) cocotb_result = { True: cocotb.result.TestSuccess, False: cocotb.result.TestFailure }[all_tests_passed] raise cocotb_result
def drive_data(self): while True: yield Combine(Edge(self.sig_data_out), Edge(self.sig_data)) if self.slave_en == 1: self.sig_data <= self.sig_data_out