def __init__(self, dut): self.dut = dut self.log = SimLog("cocotb.tb") self.log.setLevel(logging.DEBUG) # PCIe self.rc = RootComplex() self.rc.max_payload_size = 0x1 # 256 bytes self.rc.max_read_request_size = 0x2 # 512 bytes self.dev = UltraScalePlusPcieDevice( # configuration options pcie_generation=3, pcie_link_width=16, user_clk_frequency=250e6, alignment="dword", cq_cc_straddle=False, rq_rc_straddle=False, rc_4tlp_straddle=False, enable_pf1=False, enable_client_tag=True, enable_extended_tag=True, enable_parity=False, enable_rx_msg_interface=False, enable_sriov=False, enable_extended_configuration=False, enable_pf0_msi=True, enable_pf1_msi=False, # signals # Clock and Reset Interface user_clk=dut.clk_250mhz, user_reset=dut.rst_250mhz, # user_lnk_up # sys_clk # sys_clk_gt # sys_reset # phy_rdy_out # Requester reQuest Interface rq_bus=AxiStreamBus.from_prefix(dut, "m_axis_rq"), pcie_rq_seq_num0=dut.s_axis_rq_seq_num_0, pcie_rq_seq_num_vld0=dut.s_axis_rq_seq_num_valid_0, pcie_rq_seq_num1=dut.s_axis_rq_seq_num_1, pcie_rq_seq_num_vld1=dut.s_axis_rq_seq_num_valid_1, # pcie_rq_tag0 # pcie_rq_tag1 # pcie_rq_tag_av # pcie_rq_tag_vld0 # pcie_rq_tag_vld1 # Requester Completion Interface rc_bus=AxiStreamBus.from_prefix(dut, "s_axis_rc"), # Completer reQuest Interface cq_bus=AxiStreamBus.from_prefix(dut, "s_axis_cq"), # pcie_cq_np_req # pcie_cq_np_req_count # Completer Completion Interface cc_bus=AxiStreamBus.from_prefix(dut, "m_axis_cc"), # Transmit Flow Control Interface # pcie_tfc_nph_av=dut.pcie_tfc_nph_av, # pcie_tfc_npd_av=dut.pcie_tfc_npd_av, # Configuration Management Interface cfg_mgmt_addr=dut.cfg_mgmt_addr, cfg_mgmt_function_number=dut.cfg_mgmt_function_number, cfg_mgmt_write=dut.cfg_mgmt_write, cfg_mgmt_write_data=dut.cfg_mgmt_write_data, cfg_mgmt_byte_enable=dut.cfg_mgmt_byte_enable, cfg_mgmt_read=dut.cfg_mgmt_read, cfg_mgmt_read_data=dut.cfg_mgmt_read_data, cfg_mgmt_read_write_done=dut.cfg_mgmt_read_write_done, # cfg_mgmt_debug_access # Configuration Status Interface # cfg_phy_link_down # cfg_phy_link_status # cfg_negotiated_width # cfg_current_speed cfg_max_payload=dut.cfg_max_payload, cfg_max_read_req=dut.cfg_max_read_req, # cfg_function_status # cfg_vf_status # cfg_function_power_state # cfg_vf_power_state # cfg_link_power_state # cfg_err_cor_out # cfg_err_nonfatal_out # cfg_err_fatal_out # cfg_local_error_out # cfg_local_error_valid # cfg_rx_pm_state # cfg_tx_pm_state # cfg_ltssm_state # cfg_rcb_status # cfg_obff_enable # cfg_pl_status_change # cfg_tph_requester_enable # cfg_tph_st_mode # cfg_vf_tph_requester_enable # cfg_vf_tph_st_mode # Configuration Received Message Interface # cfg_msg_received # cfg_msg_received_data # cfg_msg_received_type # Configuration Transmit Message Interface # cfg_msg_transmit # cfg_msg_transmit_type # cfg_msg_transmit_data # cfg_msg_transmit_done # Configuration Flow Control Interface cfg_fc_ph=dut.cfg_fc_ph, cfg_fc_pd=dut.cfg_fc_pd, cfg_fc_nph=dut.cfg_fc_nph, cfg_fc_npd=dut.cfg_fc_npd, cfg_fc_cplh=dut.cfg_fc_cplh, cfg_fc_cpld=dut.cfg_fc_cpld, cfg_fc_sel=dut.cfg_fc_sel, # Configuration Control Interface # cfg_hot_reset_in # cfg_hot_reset_out # cfg_config_space_enable # cfg_dsn # cfg_bus_number # cfg_ds_port_number # cfg_ds_bus_number # cfg_ds_device_number # cfg_ds_function_number # cfg_power_state_change_ack # cfg_power_state_change_interrupt cfg_err_cor_in=dut.status_error_cor, cfg_err_uncor_in=dut.status_error_uncor, # cfg_flr_in_process # cfg_flr_done # cfg_vf_flr_in_process # cfg_vf_flr_func_num # cfg_vf_flr_done # cfg_pm_aspm_l1_entry_reject # cfg_pm_aspm_tx_l0s_entry_disable # cfg_req_pm_transition_l23_ready # cfg_link_training_enable # Configuration Interrupt Controller Interface # cfg_interrupt_int # cfg_interrupt_sent # cfg_interrupt_pending cfg_interrupt_msi_enable=dut.cfg_interrupt_msi_enable, cfg_interrupt_msi_mmenable=dut.cfg_interrupt_msi_mmenable, cfg_interrupt_msi_mask_update=dut.cfg_interrupt_msi_mask_update, cfg_interrupt_msi_data=dut.cfg_interrupt_msi_data, # cfg_interrupt_msi_select=dut.cfg_interrupt_msi_select, cfg_interrupt_msi_int=dut.cfg_interrupt_msi_int, cfg_interrupt_msi_pending_status=dut. cfg_interrupt_msi_pending_status, cfg_interrupt_msi_pending_status_data_enable=dut. cfg_interrupt_msi_pending_status_data_enable, # cfg_interrupt_msi_pending_status_function_num=dut.cfg_interrupt_msi_pending_status_function_num, cfg_interrupt_msi_sent=dut.cfg_interrupt_msi_sent, cfg_interrupt_msi_fail=dut.cfg_interrupt_msi_fail, # cfg_interrupt_msix_enable # cfg_interrupt_msix_mask # cfg_interrupt_msix_vf_enable # cfg_interrupt_msix_vf_mask # cfg_interrupt_msix_address # cfg_interrupt_msix_data # cfg_interrupt_msix_int # cfg_interrupt_msix_vec_pending # cfg_interrupt_msix_vec_pending_status cfg_interrupt_msi_attr=dut.cfg_interrupt_msi_attr, cfg_interrupt_msi_tph_present=dut.cfg_interrupt_msi_tph_present, cfg_interrupt_msi_tph_type=dut.cfg_interrupt_msi_tph_type, # cfg_interrupt_msi_tph_st_tag=dut.cfg_interrupt_msi_tph_st_tag, # cfg_interrupt_msi_function_number=dut.cfg_interrupt_msi_function_number, # Configuration Extend Interface # cfg_ext_read_received # cfg_ext_write_received # cfg_ext_register_number # cfg_ext_function_number # cfg_ext_write_data # cfg_ext_write_byte_enable # cfg_ext_read_data # cfg_ext_read_data_valid ) # self.dev.log.setLevel(logging.DEBUG) self.rc.make_port().connect(self.dev) self.driver = mqnic.Driver() self.dev.functions[0].msi_cap.msi_multiple_message_capable = 5 self.dev.functions[0].configure_bar( 0, 2**len(dut.core_inst.core_pcie_inst.axil_ctrl_araddr), ext=True, prefetch=True) if hasattr(dut.core_inst.core_pcie_inst, 'pcie_app_ctrl'): self.dev.functions[0].configure_bar( 2, 2**len(dut.core_inst.core_pcie_inst.axil_app_ctrl_araddr), ext=True, prefetch=True) # Ethernet cocotb.start_soon(Clock(dut.qsfp_0_rx_clk, 3.102, units="ns").start()) cocotb.start_soon(Clock(dut.qsfp_0_tx_clk, 3.102, units="ns").start()) self.qsfp_0_mac = EthMac( tx_clk=dut.qsfp_0_tx_clk, tx_rst=dut.qsfp_0_tx_rst, tx_bus=AxiStreamBus.from_prefix(dut, "qsfp_0_tx_axis"), tx_ptp_time=dut.qsfp_0_tx_ptp_time, tx_ptp_ts=dut.qsfp_0_tx_ptp_ts, tx_ptp_ts_tag=dut.qsfp_0_tx_ptp_ts_tag, tx_ptp_ts_valid=dut.qsfp_0_tx_ptp_ts_valid, rx_clk=dut.qsfp_0_rx_clk, rx_rst=dut.qsfp_0_rx_rst, rx_bus=AxiStreamBus.from_prefix(dut, "qsfp_0_rx_axis"), rx_ptp_time=dut.qsfp_0_rx_ptp_time, ifg=12, speed=100e9) cocotb.start_soon(Clock(dut.qsfp_1_rx_clk, 3.102, units="ns").start()) cocotb.start_soon(Clock(dut.qsfp_1_tx_clk, 3.102, units="ns").start()) self.qsfp_1_mac = EthMac( tx_clk=dut.qsfp_1_tx_clk, tx_rst=dut.qsfp_1_tx_rst, tx_bus=AxiStreamBus.from_prefix(dut, "qsfp_1_tx_axis"), tx_ptp_time=dut.qsfp_1_tx_ptp_time, tx_ptp_ts=dut.qsfp_1_tx_ptp_ts, tx_ptp_ts_tag=dut.qsfp_1_tx_ptp_ts_tag, tx_ptp_ts_valid=dut.qsfp_1_tx_ptp_ts_valid, rx_clk=dut.qsfp_1_rx_clk, rx_rst=dut.qsfp_1_rx_rst, rx_bus=AxiStreamBus.from_prefix(dut, "qsfp_1_rx_axis"), rx_ptp_time=dut.qsfp_1_rx_ptp_time, ifg=12, speed=100e9) dut.user_sw.setimmediatevalue(0) dut.qsfp_0_modprs_l.setimmediatevalue(0) dut.qsfp_1_modprs_l.setimmediatevalue(0) dut.qsfp_int_l.setimmediatevalue(1) dut.qsfp_i2c_scl_i.setimmediatevalue(1) dut.qsfp_i2c_sda_i.setimmediatevalue(1) dut.eeprom_i2c_scl_i.setimmediatevalue(1) dut.eeprom_i2c_sda_i.setimmediatevalue(1) dut.qspi_0_dq_i.setimmediatevalue(0) dut.qspi_1_dq_i.setimmediatevalue(0) self.loopback_enable = False cocotb.start_soon(self._run_loopback())
def __init__(self, dut): self.dut = dut self.log = SimLog("cocotb.tb") self.log.setLevel(logging.DEBUG) cocotb.start_soon(Clock(dut.clk_250mhz, 4, units="ns").start()) # AXI self.address_space = AddressSpace() self.pool = self.address_space.create_pool(0, 0x8000_0000) self.axil_master = AxiLiteMaster( AxiLiteBus.from_prefix(dut, "s_axil_ctrl"), dut.clk_250mhz, dut.rst_250mhz) self.address_space.register_region(self.axil_master, 0x10_0000_0000) self.hw_regs = self.address_space.create_window( 0x10_0000_0000, self.axil_master.size) self.axi_slave = AxiSlave(AxiBus.from_prefix(dut, "m_axi"), dut.clk_250mhz, dut.rst_250mhz, self.address_space) self.driver = mqnic.Driver() # Ethernet cocotb.start_soon(Clock(dut.sfp0_rx_clk, 6.4, units="ns").start()) self.sfp0_source = XgmiiSource(dut.sfp0_rxd, dut.sfp0_rxc, dut.sfp0_rx_clk, dut.sfp0_rx_rst) cocotb.start_soon(Clock(dut.sfp0_tx_clk, 6.4, units="ns").start()) self.sfp0_sink = XgmiiSink(dut.sfp0_txd, dut.sfp0_txc, dut.sfp0_tx_clk, dut.sfp0_tx_rst) cocotb.start_soon(Clock(dut.sfp1_rx_clk, 6.4, units="ns").start()) self.sfp1_source = XgmiiSource(dut.sfp1_rxd, dut.sfp1_rxc, dut.sfp1_rx_clk, dut.sfp1_rx_rst) cocotb.start_soon(Clock(dut.sfp1_tx_clk, 6.4, units="ns").start()) self.sfp1_sink = XgmiiSink(dut.sfp1_txd, dut.sfp1_txc, dut.sfp1_tx_clk, dut.sfp1_tx_rst) cocotb.start_soon(Clock(dut.sfp_drp_clk, 8, units="ns").start()) dut.sfp_drp_rst.setimmediatevalue(0) dut.sfp_drp_do.setimmediatevalue(0) dut.sfp_drp_rdy.setimmediatevalue(0) dut.sfp0_rx_error_count.setimmediatevalue(0) dut.sfp1_rx_error_count.setimmediatevalue(0) dut.btnu.setimmediatevalue(0) dut.btnl.setimmediatevalue(0) dut.btnd.setimmediatevalue(0) dut.btnr.setimmediatevalue(0) dut.btnc.setimmediatevalue(0) dut.sw.setimmediatevalue(0) dut.i2c_scl_i.setimmediatevalue(1) dut.i2c_sda_i.setimmediatevalue(1) self.loopback_enable = False cocotb.start_soon(self._run_loopback())
async def run_stress_test(dut, backpressure_inserter=None): tb = TB(dut) stat_count = len(dut.stat_valid) stat_inc_width = len(dut.stat_inc) // stat_count await tb.cycle_reset() tb.set_backpressure_generator(backpressure_inserter) async def worker(num, queue_ref, queue_drive, count=1024): for k in range(count): count = random.randrange(1, 2**stat_inc_width) await queue_drive.put(count) await queue_ref.put((num, count)) await Timer(random.randint(1, 100), 'ns') workers = [] queue_ref = Queue() queue_drive = [Queue() for k in range(stat_count)] for k in range(stat_count): workers.append( cocotb.start_soon(worker(k, queue_ref, queue_drive[k], count=1024))) async def driver(dut, queues): while True: await RisingEdge(dut.clk) inc = 0 valid = 0 for num, queue in enumerate(queues): if not queue.empty(): count = await queue.get() inc |= (count) << (stat_inc_width * num) valid |= 1 << num dut.stat_inc.value = inc dut.stat_valid.value = valid driver = cocotb.start_soon(driver(dut, queue_drive)) while workers: await workers.pop(0).join() await Timer(1000, 'ns') driver.kill() await Timer(1000, 'ns') data_ref = [0] * stat_count while not queue_ref.empty(): num, count = await queue_ref.get() data_ref[num] += count print(data_ref) data = [0] * stat_count while not tb.stat_sink.empty(): stat = await tb.stat_sink.recv() # print(stat) assert stat.tdata != 0 data[stat.tid] += stat.tdata print(data) assert data == data_ref await RisingEdge(dut.clk) await RisingEdge(dut.clk)
def raise_soon(): yield Timer(1) coro = cocotb.start_soon(raise_inner()) yield coro.join()
def __init__(self, dut): self.dut = dut self.log = SimLog("cocotb.tb") self.log.setLevel(logging.DEBUG) cocotb.start_soon(Clock(dut.clk, 6.4, units="ns").start()) # Ethernet self.eth_r0_source = XgmiiSource(dut.eth_r0_rxd, dut.eth_r0_rxc, dut.clk, dut.rst) self.eth_r0_sink = XgmiiSink(dut.eth_r0_txd, dut.eth_r0_txc, dut.clk, dut.rst) self.eth_r1_source = XgmiiSource(dut.eth_r1_rxd, dut.eth_r1_rxc, dut.clk, dut.rst) self.eth_r1_sink = XgmiiSink(dut.eth_r1_txd, dut.eth_r1_txc, dut.clk, dut.rst) self.eth_r2_source = XgmiiSource(dut.eth_r2_rxd, dut.eth_r2_rxc, dut.clk, dut.rst) self.eth_r2_sink = XgmiiSink(dut.eth_r2_txd, dut.eth_r2_txc, dut.clk, dut.rst) self.eth_r3_source = XgmiiSource(dut.eth_r3_rxd, dut.eth_r3_rxc, dut.clk, dut.rst) self.eth_r3_sink = XgmiiSink(dut.eth_r3_txd, dut.eth_r3_txc, dut.clk, dut.rst) self.eth_r4_source = XgmiiSource(dut.eth_r4_rxd, dut.eth_r4_rxc, dut.clk, dut.rst) self.eth_r4_sink = XgmiiSink(dut.eth_r4_txd, dut.eth_r4_txc, dut.clk, dut.rst) self.eth_r5_source = XgmiiSource(dut.eth_r5_rxd, dut.eth_r5_rxc, dut.clk, dut.rst) self.eth_r5_sink = XgmiiSink(dut.eth_r5_txd, dut.eth_r5_txc, dut.clk, dut.rst) self.eth_r6_source = XgmiiSource(dut.eth_r6_rxd, dut.eth_r6_rxc, dut.clk, dut.rst) self.eth_r6_sink = XgmiiSink(dut.eth_r6_txd, dut.eth_r6_txc, dut.clk, dut.rst) self.eth_r7_source = XgmiiSource(dut.eth_r7_rxd, dut.eth_r7_rxc, dut.clk, dut.rst) self.eth_r7_sink = XgmiiSink(dut.eth_r7_txd, dut.eth_r7_txc, dut.clk, dut.rst) self.eth_r8_source = XgmiiSource(dut.eth_r8_rxd, dut.eth_r8_rxc, dut.clk, dut.rst) self.eth_r8_sink = XgmiiSink(dut.eth_r8_txd, dut.eth_r8_txc, dut.clk, dut.rst) self.eth_r9_source = XgmiiSource(dut.eth_r9_rxd, dut.eth_r9_rxc, dut.clk, dut.rst) self.eth_r9_sink = XgmiiSink(dut.eth_r9_txd, dut.eth_r9_txc, dut.clk, dut.rst) self.eth_r10_source = XgmiiSource(dut.eth_r10_rxd, dut.eth_r10_rxc, dut.clk, dut.rst) self.eth_r10_sink = XgmiiSink(dut.eth_r10_txd, dut.eth_r10_txc, dut.clk, dut.rst) self.eth_r11_source = XgmiiSource(dut.eth_r11_rxd, dut.eth_r11_rxc, dut.clk, dut.rst) self.eth_r11_sink = XgmiiSink(dut.eth_r11_txd, dut.eth_r11_txc, dut.clk, dut.rst) self.eth_l0_source = XgmiiSource(dut.eth_l0_rxd, dut.eth_l0_rxc, dut.clk, dut.rst) self.eth_l0_sink = XgmiiSink(dut.eth_l0_txd, dut.eth_l0_txc, dut.clk, dut.rst) self.eth_l1_source = XgmiiSource(dut.eth_l1_rxd, dut.eth_l1_rxc, dut.clk, dut.rst) self.eth_l1_sink = XgmiiSink(dut.eth_l1_txd, dut.eth_l1_txc, dut.clk, dut.rst) self.eth_l2_source = XgmiiSource(dut.eth_l2_rxd, dut.eth_l2_rxc, dut.clk, dut.rst) self.eth_l2_sink = XgmiiSink(dut.eth_l2_txd, dut.eth_l2_txc, dut.clk, dut.rst) self.eth_l3_source = XgmiiSource(dut.eth_l3_rxd, dut.eth_l3_rxc, dut.clk, dut.rst) self.eth_l3_sink = XgmiiSink(dut.eth_l3_txd, dut.eth_l3_txc, dut.clk, dut.rst) self.eth_l4_source = XgmiiSource(dut.eth_l4_rxd, dut.eth_l4_rxc, dut.clk, dut.rst) self.eth_l4_sink = XgmiiSink(dut.eth_l4_txd, dut.eth_l4_txc, dut.clk, dut.rst) self.eth_l5_source = XgmiiSource(dut.eth_l5_rxd, dut.eth_l5_rxc, dut.clk, dut.rst) self.eth_l5_sink = XgmiiSink(dut.eth_l5_txd, dut.eth_l5_txc, dut.clk, dut.rst) self.eth_l6_source = XgmiiSource(dut.eth_l6_rxd, dut.eth_l6_rxc, dut.clk, dut.rst) self.eth_l6_sink = XgmiiSink(dut.eth_l6_txd, dut.eth_l6_txc, dut.clk, dut.rst) self.eth_l7_source = XgmiiSource(dut.eth_l7_rxd, dut.eth_l7_rxc, dut.clk, dut.rst) self.eth_l7_sink = XgmiiSink(dut.eth_l7_txd, dut.eth_l7_txc, dut.clk, dut.rst) self.eth_l8_source = XgmiiSource(dut.eth_l8_rxd, dut.eth_l8_rxc, dut.clk, dut.rst) self.eth_l8_sink = XgmiiSink(dut.eth_l8_txd, dut.eth_l8_txc, dut.clk, dut.rst) self.eth_l9_source = XgmiiSource(dut.eth_l9_rxd, dut.eth_l9_rxc, dut.clk, dut.rst) self.eth_l9_sink = XgmiiSink(dut.eth_l9_txd, dut.eth_l9_txc, dut.clk, dut.rst) self.eth_l10_source = XgmiiSource(dut.eth_l10_rxd, dut.eth_l10_rxc, dut.clk, dut.rst) self.eth_l10_sink = XgmiiSink(dut.eth_l10_txd, dut.eth_l10_txc, dut.clk, dut.rst) self.eth_l11_source = XgmiiSource(dut.eth_l11_rxd, dut.eth_l11_rxc, dut.clk, dut.rst) self.eth_l11_sink = XgmiiSink(dut.eth_l11_txd, dut.eth_l11_txc, dut.clk, dut.rst) dut.sw.setimmediatevalue(0) dut.jp.setimmediatevalue(0) dut.uart_suspend.setimmediatevalue(0) dut.uart_dtr.setimmediatevalue(0) dut.uart_txd.setimmediatevalue(0) dut.uart_rts.setimmediatevalue(0) dut.amh_right_mdio_i.setimmediatevalue(0) dut.amh_left_mdio_i.setimmediatevalue(0)
def __init__(self, dut): self.dut = dut self.log = logging.getLogger("cocotb.tb") self.log.setLevel(logging.DEBUG) # PCIe self.rc = RootComplex() self.dev = UltraScalePlusPcieDevice( # configuration options pcie_generation=3, # pcie_link_width=2, # user_clk_frequency=250e6, alignment="dword", cq_straddle=False, cc_straddle=False, rq_straddle=False, rc_straddle=False, rc_4tlp_straddle=False, pf_count=1, max_payload_size=1024, enable_client_tag=True, enable_extended_tag=True, enable_parity=False, enable_rx_msg_interface=False, enable_sriov=False, enable_extended_configuration=False, pf0_msi_enable=True, pf0_msi_count=32, pf1_msi_enable=False, pf1_msi_count=1, pf2_msi_enable=False, pf2_msi_count=1, pf3_msi_enable=False, pf3_msi_count=1, pf0_msix_enable=False, pf0_msix_table_size=0, pf0_msix_table_bir=0, pf0_msix_table_offset=0x00000000, pf0_msix_pba_bir=0, pf0_msix_pba_offset=0x00000000, pf1_msix_enable=False, pf1_msix_table_size=0, pf1_msix_table_bir=0, pf1_msix_table_offset=0x00000000, pf1_msix_pba_bir=0, pf1_msix_pba_offset=0x00000000, pf2_msix_enable=False, pf2_msix_table_size=0, pf2_msix_table_bir=0, pf2_msix_table_offset=0x00000000, pf2_msix_pba_bir=0, pf2_msix_pba_offset=0x00000000, pf3_msix_enable=False, pf3_msix_table_size=0, pf3_msix_table_bir=0, pf3_msix_table_offset=0x00000000, pf3_msix_pba_bir=0, pf3_msix_pba_offset=0x00000000, # signals user_clk=dut.clk, user_reset=dut.rst, cq_bus=AxiStreamBus.from_prefix(dut, "s_axis_cq")) self.dev.log.setLevel(logging.DEBUG) self.dev.functions[0].configure_bar(0, 16 * 1024 * 1024) self.dev.functions[0].configure_bar(1, 16 * 1024, io=True) self.rc.make_port().connect(self.dev) # AXI self.axi_ram = AxiRamWrite(AxiWriteBus.from_prefix(dut, "m_axi"), dut.clk, dut.rst, size=2**16) # monitor error outputs self.status_error_uncor_asserted = False cocotb.start_soon(self._run_monitor_status_error_uncor())
async def test_task_repr(dut): """Test RunningTask.__repr__.""" log = logging.getLogger("cocotb.test") gen_e = Event("generator_coro_inner") def generator_coro_inner(): gen_e.set() yield Timer(1, units="ns") raise ValueError("inner") @cocotb.coroutine # testing debug with legacy coroutine syntax def generator_coro_outer(): yield from generator_coro_inner() gen_task = generator_coro_outer() log.info(repr(gen_task)) assert re.match(r"<Task \d+ created coro=generator_coro_outer\(\)>", repr(gen_task)) cocotb.start_soon(gen_task) await gen_e.wait() log.info(repr(gen_task)) assert re.match( r"<Task \d+ pending coro=generator_coro_inner\(\) trigger=<Timer of 1000.00ps at \w+>>", repr(gen_task), ) try: await Join(gen_task) except ValueError: pass log.info(repr(gen_task)) assert re.match( r"<Task \d+ finished coro=generator_coro_outer\(\) outcome=Error\(ValueError\('inner',?\)\)>", repr(gen_task), ) coro_e = Event("coroutine_inner") async def coroutine_forked(task): log.info(repr(task)) assert re.match(r"<Task \d+ adding coro=coroutine_outer\(\)>", repr(task)) @cocotb.coroutine # Combine requires use of cocotb.coroutine async def coroutine_wait(): await Timer(1, units="ns") async def coroutine_inner(): await coro_e.wait() this_task = coro_e.data # cr_await is None while the coroutine is running, so we can't get the stack... log.info(repr(this_task)) assert re.match(r"<Task \d+ running coro=coroutine_outer\(\)>", repr(this_task)) cocotb.fork(coroutine_forked(this_task)) await Combine(*(coroutine_wait() for _ in range(2))) return "Combine done" async def coroutine_middle(): return await coroutine_inner() async def coroutine_outer(): return await coroutine_middle() coro_task = await cocotb.start(coroutine_outer()) coro_e.set(coro_task) await NullTrigger() log.info(repr(coro_task)) assert re.match( r"<Task \d+ pending coro=coroutine_inner\(\) trigger=Combine\(Join\(<Task \d+>\), Join\(<Task \d+>\)\)>", repr(coro_task), ) await Timer(2, units="ns") log.info(repr(coro_task)) assert re.match( r"<Task \d+ finished coro=coroutine_outer\(\) outcome=Value\('Combine done'\)", repr(coro_task), ) async def coroutine_first(): await First(coroutine_wait(), Timer(2, units="ns")) coro_task = await cocotb.start(coroutine_first()) log.info(repr(coro_task)) assert re.match( r"<Task \d+ pending coro=coroutine_first\(\) trigger=First\(Join\(<Task \d+>\), <Timer of 2000.00ps at \w+>\)>", repr(coro_task), ) async def coroutine_timer(): await Timer(1, units="ns") coro_task = await cocotb.start(coroutine_timer()) # Trigger.__await__ should be popped from the coroutine stack log.info(repr(coro_task)) assert re.match( r"<Task \d+ pending coro=coroutine_timer\(\) trigger=<Timer of 1000.00ps at \w+>>", repr(coro_task), ) # created but not scheduled yet coro_task = cocotb.start_soon(coroutine_outer()) log.info(repr(coro_task)) assert re.match(r"<Task \d+ created coro=coroutine_outer\(\)>", repr(coro_task))
async def with_timeout(trigger, timeout_time, timeout_unit="step"): r""" Waits on triggers or coroutines, throws an exception if it waits longer than the given time. When a :term:`python:coroutine` is passed, the callee coroutine is started, the caller blocks until the callee completes, and the callee's result is returned to the caller. If timeout occurs, the callee is killed and :exc:`SimTimeoutError` is raised. When an unstarted :class:`~cocotb.coroutine`\ is passed, the callee coroutine is started, the caller blocks until the callee completes, and the callee's result is returned to the caller. If timeout occurs, the callee `continues to run` and :exc:`SimTimeoutError` is raised. When a :term:`task` is passed, the caller blocks until the callee completes and the callee's result is returned to the caller. If timeout occurs, the callee `continues to run` and :exc:`SimTimeoutError` is raised. If a :class:`~cocotb.triggers.Trigger` or :class:`~cocotb.triggers.Waitable` is passed, the caller blocks until the trigger fires, and the trigger is returned to the caller. If timeout occurs, the trigger is cancelled and :exc:`SimTimeoutError` is raised. Usage: .. code-block:: python await with_timeout(coro, 100, 'ns') await with_timeout(First(coro, event.wait()), 100, 'ns') Args: trigger (:class:`~cocotb.triggers.Trigger`, :class:`~cocotb.triggers.Waitable`, :class:`~cocotb.decorators.RunningTask`, or :term:`python:coroutine`): A single object that could be right of an :keyword:`await` expression in cocotb. timeout_time (numbers.Real or decimal.Decimal): Simulation time duration before timeout occurs. timeout_unit (str, optional): Units of timeout_time, accepts any units that :class:`~cocotb.triggers.Timer` does. Returns: First trigger that completed if timeout did not occur. Raises: :exc:`SimTimeoutError`: If timeout occurs. .. versionadded:: 1.3 .. deprecated:: 1.5 Using ``None`` as the *timeout_unit* argument is deprecated, use ``'step'`` instead. .. versionchanged:: 1.7.0 Support passing :term:`python:coroutine`\ s. """ if timeout_unit is None: warnings.warn( 'Using timeout_unit=None is deprecated, use timeout_unit="step" instead.', DeprecationWarning, stacklevel=2, ) timeout_unit = "step" # don't propagate deprecated value if inspect.iscoroutine(trigger): trigger = cocotb.start_soon(trigger) shielded = False else: shielded = True timeout_timer = cocotb.triggers.Timer(timeout_time, timeout_unit) res = await First(timeout_timer, trigger) if res is timeout_timer: if not shielded: trigger.kill() raise cocotb.result.SimTimeoutError else: return res
def __init__(self, dut): self.dut = dut self.log = logging.getLogger("cocotb.tb") self.log.setLevel(logging.DEBUG) # PCIe self.rc = RootComplex() self.dev = UltraScalePlusPcieDevice( # configuration options pcie_generation=3, # pcie_link_width=2, # user_clk_frequency=250e6, alignment="dword", cq_cc_straddle=False, rq_rc_straddle=False, rc_4tlp_straddle=False, enable_pf1=False, enable_client_tag=True, enable_extended_tag=False, enable_parity=False, enable_rx_msg_interface=False, enable_sriov=False, enable_extended_configuration=False, enable_pf0_msi=True, enable_pf1_msi=False, # signals user_clk=dut.clk, user_reset=dut.rst, rq_bus=AxiStreamBus.from_prefix(dut, "m_axis_rq"), pcie_rq_seq_num0=dut.s_axis_rq_seq_num_0, pcie_rq_seq_num_vld0=dut.s_axis_rq_seq_num_valid_0, pcie_rq_seq_num1=dut.s_axis_rq_seq_num_1, pcie_rq_seq_num_vld1=dut.s_axis_rq_seq_num_valid_1, rc_bus=AxiStreamBus.from_prefix(dut, "s_axis_rc"), cfg_max_read_req=dut.max_read_request_size, cfg_fc_sel=0b100, cfg_fc_nph=dut.pcie_tx_fc_nph_av, ) self.dev.log.setLevel(logging.DEBUG) self.rc.make_port().connect(self.dev) # AXI self.axi_ram = AxiRamWrite(AxiWriteBus.from_prefix(dut, "m_axi"), dut.clk, dut.rst, size=2**16) # Control self.read_desc_source = DescSource( DescBus.from_prefix(dut, "s_axis_read_desc"), dut.clk, dut.rst) self.read_desc_status_sink = DescStatusSink( DescStatusBus.from_prefix(dut, "m_axis_read_desc_status"), dut.clk, dut.rst) dut.requester_id.setimmediatevalue(0) dut.requester_id_enable.setimmediatevalue(0) dut.ext_tag_enable.setimmediatevalue(0) dut.enable.setimmediatevalue(0) # monitor error outputs self.status_error_cor_asserted = False self.status_error_uncor_asserted = False cocotb.start_soon(self._run_monitor_status_error_cor()) cocotb.start_soon(self._run_monitor_status_error_uncor())
def __init__(self, dut): self.dut = dut self.log = logging.getLogger("cocotb.tb") self.log.setLevel(logging.DEBUG) if len(dut.xgmii_txd) == 64: cocotb.start_soon(Clock(dut.logic_clk, 6.4, units="ns").start()) cocotb.start_soon(Clock(dut.rx_clk, 6.4, units="ns").start()) cocotb.start_soon(Clock(dut.tx_clk, 6.4, units="ns").start()) else: cocotb.start_soon(Clock(dut.logic_clk, 3.2, units="ns").start()) cocotb.start_soon(Clock(dut.rx_clk, 3.2, units="ns").start()) cocotb.start_soon(Clock(dut.tx_clk, 3.2, units="ns").start()) self.xgmii_source = XgmiiSource(dut.xgmii_rxd, dut.xgmii_rxc, dut.rx_clk, dut.rx_rst) self.xgmii_sink = XgmiiSink(dut.xgmii_txd, dut.xgmii_txc, dut.tx_clk, dut.tx_rst) self.axis_source = AxiStreamSource( AxiStreamBus.from_prefix(dut, "tx_axis"), dut.logic_clk, dut.logic_rst) self.axis_sink = AxiStreamSink( AxiStreamBus.from_prefix(dut, "rx_axis"), dut.logic_clk, dut.logic_rst) dut.ptp_sample_clk.setimmediatevalue(0) dut.ptp_ts_96.setimmediatevalue(0) dut.ptp_ts_step.setimmediatevalue(0)
async def test1(dut): cocotb.start_soon(wait_edge(dut)) await Timer(10, 'ns')
def __init__(self, dut): self.dut = dut self.log = logging.getLogger("cocotb.tb") self.log.setLevel(logging.DEBUG) # PCIe self.rc = RootComplex() self.dev = UltraScalePcieDevice( # configuration options # pcie_generation=3, # pcie_link_width=2, # user_clk_frequency=250e6, alignment="dword", straddle=False, enable_pf1=False, enable_client_tag=True, enable_extended_tag=False, enable_parity=False, enable_rx_msg_interface=False, enable_sriov=False, enable_extended_configuration=False, enable_pf0_msi=True, enable_pf1_msi=False, # signals user_clk=dut.user_clk, user_reset=dut.user_reset, user_lnk_up=dut.user_lnk_up, sys_clk=dut.sys_clk, sys_clk_gt=dut.sys_clk_gt, sys_reset=dut.sys_reset, pcie_perstn1_in=dut.pcie_perstn1_in, pcie_perstn0_out=dut.pcie_perstn0_out, pcie_perstn1_out=dut.pcie_perstn1_out, phy_rdy_out=dut.phy_rdy_out, rq_bus=AxiStreamBus.from_prefix(dut, "s_axis_rq"), pcie_rq_seq_num=dut.pcie_rq_seq_num, pcie_rq_seq_num_vld=dut.pcie_rq_seq_num_vld, pcie_rq_tag=dut.pcie_rq_tag, pcie_rq_tag_av=dut.pcie_rq_tag_av, pcie_rq_tag_vld=dut.pcie_rq_tag_vld, rc_bus=AxiStreamBus.from_prefix(dut, "m_axis_rc"), cq_bus=AxiStreamBus.from_prefix(dut, "m_axis_cq"), pcie_cq_np_req=dut.pcie_cq_np_req, pcie_cq_np_req_count=dut.pcie_cq_np_req_count, cc_bus=AxiStreamBus.from_prefix(dut, "s_axis_cc"), pcie_tfc_nph_av=dut.pcie_tfc_nph_av, pcie_tfc_npd_av=dut.pcie_tfc_npd_av, cfg_phy_link_down=dut.cfg_phy_link_down, cfg_phy_link_status=dut.cfg_phy_link_status, cfg_negotiated_width=dut.cfg_negotiated_width, cfg_current_speed=dut.cfg_current_speed, cfg_max_payload=dut.cfg_max_payload, cfg_max_read_req=dut.cfg_max_read_req, cfg_function_status=dut.cfg_function_status, cfg_function_power_state=dut.cfg_function_power_state, cfg_vf_status=dut.cfg_vf_status, cfg_vf_power_state=dut.cfg_vf_power_state, cfg_link_power_state=dut.cfg_link_power_state, cfg_mgmt_addr=dut.cfg_mgmt_addr, cfg_mgmt_write=dut.cfg_mgmt_write, cfg_mgmt_write_data=dut.cfg_mgmt_write_data, cfg_mgmt_byte_enable=dut.cfg_mgmt_byte_enable, cfg_mgmt_read=dut.cfg_mgmt_read, cfg_mgmt_read_data=dut.cfg_mgmt_read_data, cfg_mgmt_read_write_done=dut.cfg_mgmt_read_write_done, cfg_mgmt_type1_cfg_reg_access=dut.cfg_mgmt_type1_cfg_reg_access, cfg_err_cor_out=dut.cfg_err_cor_out, cfg_err_nonfatal_out=dut.cfg_err_nonfatal_out, cfg_err_fatal_out=dut.cfg_err_fatal_out, cfg_local_error=dut.cfg_local_error, cfg_ltr_enable=dut.cfg_ltr_enable, cfg_ltssm_state=dut.cfg_ltssm_state, cfg_rcb_status=dut.cfg_rcb_status, cfg_dpa_substate_change=dut.cfg_dpa_substate_change, cfg_obff_enable=dut.cfg_obff_enable, cfg_pl_status_change=dut.cfg_pl_status_change, cfg_tph_requester_enable=dut.cfg_tph_requester_enable, cfg_tph_st_mode=dut.cfg_tph_st_mode, cfg_vf_tph_requester_enable=dut.cfg_vf_tph_requester_enable, cfg_vf_tph_st_mode=dut.cfg_vf_tph_st_mode, cfg_msg_received=dut.cfg_msg_received, cfg_msg_received_data=dut.cfg_msg_received_data, cfg_msg_received_type=dut.cfg_msg_received_type, cfg_msg_transmit=dut.cfg_msg_transmit, cfg_msg_transmit_type=dut.cfg_msg_transmit_type, cfg_msg_transmit_data=dut.cfg_msg_transmit_data, cfg_msg_transmit_done=dut.cfg_msg_transmit_done, cfg_fc_ph=dut.cfg_fc_ph, cfg_fc_pd=dut.cfg_fc_pd, cfg_fc_nph=dut.cfg_fc_nph, cfg_fc_npd=dut.cfg_fc_npd, cfg_fc_cplh=dut.cfg_fc_cplh, cfg_fc_cpld=dut.cfg_fc_cpld, cfg_fc_sel=dut.cfg_fc_sel, cfg_per_func_status_control=dut.cfg_per_func_status_control, cfg_per_func_status_data=dut.cfg_per_func_status_data, cfg_per_function_number=dut.cfg_per_function_number, cfg_per_function_output_request=dut. cfg_per_function_output_request, cfg_per_function_update_done=dut.cfg_per_function_update_done, cfg_dsn=dut.cfg_dsn, cfg_power_state_change_ack=dut.cfg_power_state_change_ack, cfg_power_state_change_interrupt=dut. cfg_power_state_change_interrupt, cfg_err_cor_in=dut.cfg_err_cor_in, cfg_err_uncor_in=dut.cfg_err_uncor_in, cfg_flr_in_process=dut.cfg_flr_in_process, cfg_flr_done=dut.cfg_flr_done, cfg_vf_flr_in_process=dut.cfg_vf_flr_in_process, cfg_vf_flr_done=dut.cfg_vf_flr_done, cfg_link_training_enable=dut.cfg_link_training_enable, cfg_interrupt_int=dut.cfg_interrupt_int, cfg_interrupt_pending=dut.cfg_interrupt_pending, cfg_interrupt_sent=dut.cfg_interrupt_sent, cfg_interrupt_msi_enable=dut.cfg_interrupt_msi_enable, cfg_interrupt_msi_vf_enable=dut.cfg_interrupt_msi_vf_enable, cfg_interrupt_msi_mmenable=dut.cfg_interrupt_msi_mmenable, cfg_interrupt_msi_mask_update=dut.cfg_interrupt_msi_mask_update, cfg_interrupt_msi_data=dut.cfg_interrupt_msi_data, cfg_interrupt_msi_select=dut.cfg_interrupt_msi_select, cfg_interrupt_msi_int=dut.cfg_interrupt_msi_int, cfg_interrupt_msi_pending_status=dut. cfg_interrupt_msi_pending_status, cfg_interrupt_msi_pending_status_data_enable=dut. cfg_interrupt_msi_pending_status_data_enable, cfg_interrupt_msi_pending_status_function_num=dut. cfg_interrupt_msi_pending_status_function_num, cfg_interrupt_msi_sent=dut.cfg_interrupt_msi_sent, cfg_interrupt_msi_fail=dut.cfg_interrupt_msi_fail, cfg_interrupt_msi_attr=dut.cfg_interrupt_msi_attr, cfg_interrupt_msi_tph_present=dut.cfg_interrupt_msi_tph_present, cfg_interrupt_msi_tph_type=dut.cfg_interrupt_msi_tph_type, cfg_interrupt_msi_tph_st_tag=dut.cfg_interrupt_msi_tph_st_tag, cfg_interrupt_msi_function_number=dut. cfg_interrupt_msi_function_number, cfg_hot_reset_out=dut.cfg_hot_reset_out, cfg_config_space_enable=dut.cfg_config_space_enable, cfg_req_pm_transition_l23_ready=dut. cfg_req_pm_transition_l23_ready, cfg_hot_reset_in=dut.cfg_hot_reset_in, cfg_ds_port_number=dut.cfg_ds_port_number, cfg_ds_bus_number=dut.cfg_ds_bus_number, cfg_ds_device_number=dut.cfg_ds_device_number, cfg_ds_function_number=dut.cfg_ds_function_number, cfg_subsys_vend_id=dut.cfg_subsys_vend_id) self.dev.log.setLevel(logging.DEBUG) dut.pcie_cq_np_req.setimmediatevalue(1) dut.cfg_mgmt_addr.setimmediatevalue(0) dut.cfg_mgmt_write.setimmediatevalue(0) dut.cfg_mgmt_write_data.setimmediatevalue(0) dut.cfg_mgmt_byte_enable.setimmediatevalue(0) dut.cfg_mgmt_read.setimmediatevalue(0) dut.cfg_mgmt_type1_cfg_reg_access.setimmediatevalue(0) dut.cfg_msg_transmit.setimmediatevalue(0) dut.cfg_msg_transmit_type.setimmediatevalue(0) dut.cfg_msg_transmit_data.setimmediatevalue(0) dut.cfg_fc_sel.setimmediatevalue(0) dut.cfg_per_func_status_control.setimmediatevalue(0) dut.cfg_per_function_number.setimmediatevalue(0) dut.cfg_per_function_output_request.setimmediatevalue(0) dut.cfg_dsn.setimmediatevalue(0) dut.cfg_power_state_change_ack.setimmediatevalue(0) dut.cfg_err_cor_in.setimmediatevalue(0) dut.cfg_err_uncor_in.setimmediatevalue(0) dut.cfg_flr_done.setimmediatevalue(0) dut.cfg_vf_flr_done.setimmediatevalue(0) dut.cfg_link_training_enable.setimmediatevalue(1) dut.cfg_interrupt_int.setimmediatevalue(0) dut.cfg_interrupt_pending.setimmediatevalue(0) dut.cfg_interrupt_msi_select.setimmediatevalue(0) dut.cfg_interrupt_msi_int.setimmediatevalue(0) dut.cfg_interrupt_msi_pending_status.setimmediatevalue(0) dut.cfg_interrupt_msi_pending_status_data_enable.setimmediatevalue(0) dut.cfg_interrupt_msi_pending_status_function_num.setimmediatevalue(0) dut.cfg_interrupt_msi_attr.setimmediatevalue(0) dut.cfg_interrupt_msi_tph_present.setimmediatevalue(0) dut.cfg_interrupt_msi_tph_type.setimmediatevalue(0) dut.cfg_interrupt_msi_tph_st_tag.setimmediatevalue(0) dut.cfg_interrupt_msi_function_number.setimmediatevalue(0) dut.cfg_config_space_enable.setimmediatevalue(1) dut.cfg_req_pm_transition_l23_ready.setimmediatevalue(0) dut.cfg_hot_reset_in.setimmediatevalue(0) dut.cfg_ds_port_number.setimmediatevalue(0) dut.cfg_ds_bus_number.setimmediatevalue(0) dut.cfg_ds_device_number.setimmediatevalue(0) dut.cfg_ds_function_number.setimmediatevalue(0) dut.cfg_subsys_vend_id.setimmediatevalue(0) dut.sys_clk.setimmediatevalue(0) dut.sys_clk_gt.setimmediatevalue(0) dut.sys_reset.setimmediatevalue(1) dut.pcie_perstn1_in.setimmediatevalue(1) self.rc.make_port().connect(self.dev) # user logic self.rq_source = RqSource(AxiStreamBus.from_prefix(dut, "s_axis_rq"), dut.user_clk, dut.user_reset) self.rc_sink = RcSink(AxiStreamBus.from_prefix(dut, "m_axis_rc"), dut.user_clk, dut.user_reset) self.cq_sink = CqSink(AxiStreamBus.from_prefix(dut, "m_axis_cq"), dut.user_clk, dut.user_reset) self.cc_source = CcSource(AxiStreamBus.from_prefix(dut, "s_axis_cc"), dut.user_clk, dut.user_reset) self.regions = [None] * 6 self.regions[0] = mmap.mmap(-1, 1024 * 1024) self.regions[1] = mmap.mmap(-1, 1024 * 1024) self.regions[3] = mmap.mmap(-1, 1024) self.current_tag = 0 self.tag_count = 32 self.tag_active = [False] * 256 self.tag_release = Event() self.dev.functions[0].msi_cap.msi_multiple_message_capable = 5 self.dev.functions[0].configure_bar(0, len(self.regions[0])) self.dev.functions[0].configure_bar(1, len(self.regions[1]), True, True) self.dev.functions[0].configure_bar(3, len(self.regions[3]), False, False, True) cocotb.start_soon(self._run_cq())