class TB(object): def __init__(self, dut): self.dut = dut self.log = SimLog("cocotb.tb") self.log.setLevel(logging.DEBUG) # PCIe self.rc = RootComplex() self.dev = UltraScalePlusPcieDevice( # configuration options pcie_generation=3, pcie_link_width=16, 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 # Clock and Reset Interface user_clk=dut.clk, user_reset=dut.rst, # 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_msix_sent # cfg_interrupt_msix_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, # 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.dev.functions[0].configure_bar(0, 2**22) self.dev.functions[0].configure_bar(2, 2**22) dut.btnu.setimmediatevalue(0) dut.btnl.setimmediatevalue(0) dut.btnd.setimmediatevalue(0) dut.btnr.setimmediatevalue(0) dut.btnc.setimmediatevalue(0) dut.sw.setimmediatevalue(0) async def init(self): await FallingEdge(self.dut.rst) await Timer(100, 'ns') await self.rc.enumerate() dev = self.rc.find_device(self.dev.functions[0].pcie_id) await dev.enable_device() await dev.set_master() await dev.alloc_irq_vectors(32, 32)
class TB(object): 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, cq_bus=AxiStreamBus.from_prefix(dut, "s_axis_cq"), cc_bus=AxiStreamBus.from_prefix(dut, "m_axis_cc"), cfg_max_payload=dut.max_payload_size, ) 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 = AxiRamRead(AxiReadBus.from_prefix(dut, "m_axi"), dut.clk, dut.rst, size=2**16) dut.completer_id.setimmediatevalue(0) dut.completer_id_enable.setimmediatevalue(0) # monitor error outputs self.status_error_cor_asserted = False self.status_error_uncor_asserted = False cocotb.fork(self._run_monitor_status_error_cor()) cocotb.fork(self._run_monitor_status_error_uncor()) def set_idle_generator(self, generator=None): if generator: self.dev.cq_source.set_pause_generator(generator()) self.axi_ram.r_channel.set_pause_generator(generator()) def set_backpressure_generator(self, generator=None): if generator: self.dev.cc_sink.set_pause_generator(generator()) self.axi_ram.ar_channel.set_pause_generator(generator()) async def _run_monitor_status_error_cor(self): while True: await RisingEdge(self.dut.status_error_cor) self.log.info("status_error_cor (correctable error) was asserted") self.status_error_cor_asserted = True async def _run_monitor_status_error_uncor(self): while True: await RisingEdge(self.dut.status_error_uncor) self.log.info("status_error_uncor (uncorrectable error) was asserted") self.status_error_uncor_asserted = True
class TB(object): def __init__(self, dut): self.dut = dut self.BAR0_APERTURE = int(os.getenv("PARAM_BAR0_APERTURE")) 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 = UltraScalePcieDevice( # configuration options pcie_generation=3, pcie_link_width=8, user_clk_frequency=250e6, alignment="dword", 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_num=dut.s_axis_rq_seq_num, pcie_rq_seq_num_vld=dut.s_axis_rq_seq_num_valid, # pcie_rq_tag # pcie_rq_tag_av # pcie_rq_tag_vld # 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_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_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_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.rc) self.dev.functions[0].msi_multiple_message_capable = 5 self.dev.functions[0].configure_bar(0, 2**self.BAR0_APERTURE, ext=True, prefetch=True) # Ethernet cocotb.fork(Clock(dut.sfp_1_rx_clk, 6.4, units="ns").start()) self.sfp_1_source = XgmiiSource(dut.sfp_1_rxd, dut.sfp_1_rxc, dut.sfp_1_rx_clk, dut.sfp_1_rx_rst) cocotb.fork(Clock(dut.sfp_1_tx_clk, 6.4, units="ns").start()) self.sfp_1_sink = XgmiiSink(dut.sfp_1_txd, dut.sfp_1_txc, dut.sfp_1_tx_clk, dut.sfp_1_tx_rst) cocotb.fork(Clock(dut.sfp_2_rx_clk, 6.4, units="ns").start()) self.sfp_2_source = XgmiiSource(dut.sfp_2_rxd, dut.sfp_2_rxc, dut.sfp_2_rx_clk, dut.sfp_2_rx_rst) cocotb.fork(Clock(dut.sfp_2_tx_clk, 6.4, units="ns").start()) self.sfp_2_sink = XgmiiSink(dut.sfp_2_txd, dut.sfp_2_txc, dut.sfp_2_tx_clk, dut.sfp_2_tx_rst) dut.sfp_1_npres.setimmediatevalue(0) dut.sfp_2_npres.setimmediatevalue(0) dut.sfp_1_los.setimmediatevalue(0) dut.sfp_2_los.setimmediatevalue(0) dut.sma_in.setimmediatevalue(0) dut.sfp_i2c_scl_i.setimmediatevalue(1) dut.sfp_1_i2c_sda_i.setimmediatevalue(1) dut.sfp_2_i2c_sda_i.setimmediatevalue(1) dut.eeprom_i2c_scl_i.setimmediatevalue(1) dut.eeprom_i2c_sda_i.setimmediatevalue(1) dut.flash_dq_i.setimmediatevalue(0) self.loopback_enable = False cocotb.fork(self._run_loopback()) async def init(self): self.dut.sfp_1_rx_rst.setimmediatevalue(0) self.dut.sfp_1_tx_rst.setimmediatevalue(0) self.dut.sfp_2_rx_rst.setimmediatevalue(0) self.dut.sfp_2_tx_rst.setimmediatevalue(0) await RisingEdge(self.dut.clk_250mhz) await RisingEdge(self.dut.clk_250mhz) self.dut.sfp_1_rx_rst.setimmediatevalue(1) self.dut.sfp_1_tx_rst.setimmediatevalue(1) self.dut.sfp_2_rx_rst.setimmediatevalue(1) self.dut.sfp_2_tx_rst.setimmediatevalue(1) await FallingEdge(self.dut.rst_250mhz) await Timer(100, 'ns') await RisingEdge(self.dut.clk_250mhz) await RisingEdge(self.dut.clk_250mhz) self.dut.sfp_1_rx_rst.setimmediatevalue(0) self.dut.sfp_1_tx_rst.setimmediatevalue(0) self.dut.sfp_2_rx_rst.setimmediatevalue(0) self.dut.sfp_2_tx_rst.setimmediatevalue(0) await self.rc.enumerate(enable_bus_mastering=True, configure_msi=True) async def _run_loopback(self): while True: await RisingEdge(self.dut.clk_250mhz) if self.loopback_enable: if not self.sfp_1_sink.empty(): await self.sfp_1_source.send(await self.sfp_1_sink.recv()) if not self.sfp_2_sink.empty(): await self.sfp_2_source.send(await self.sfp_2_sink.recv())
class TB(object): def __init__(self, dut, msix=False): self.dut = dut self.log = logging.getLogger("cocotb.tb") self.log.setLevel(logging.DEBUG) # PCIe self.rc = RootComplex() self.dev = S10PcieDevice( # configuration options pcie_generation=3, # pcie_link_width=2, # pld_clk_frequency=250e6, l_tile=False, pf_count=1, max_payload_size=1024, enable_extended_tag=True, 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=msix, pf0_msix_table_size=63, pf0_msix_table_bir=4, pf0_msix_table_offset=0x00000000, pf0_msix_pba_bir=4, pf0_msix_pba_offset=0x00008000, 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 # Clock and reset # npor=dut.npor, # pin_perst=dut.pin_perst, # ninit_done=dut.ninit_done, # pld_clk_inuse=dut.pld_clk_inuse, # pld_core_ready=dut.pld_core_ready, reset_status=dut.rst, # clr_st=dut.clr_st, # refclk=dut.refclk, coreclkout_hip=dut.clk, # RX interface rx_bus=S10RxBus.from_prefix(dut, "rx_st"), # TX interface tx_bus=S10TxBus.from_prefix(dut, "tx_st"), # TX flow control tx_ph_cdts=dut.tx_ph_cdts, tx_pd_cdts=dut.tx_pd_cdts, tx_nph_cdts=dut.tx_nph_cdts, tx_npd_cdts=dut.tx_npd_cdts, tx_cplh_cdts=dut.tx_cplh_cdts, tx_cpld_cdts=dut.tx_cpld_cdts, tx_hdr_cdts_consumed=dut.tx_hdr_cdts_consumed, tx_data_cdts_consumed=dut.tx_data_cdts_consumed, tx_cdts_type=dut.tx_cdts_type, tx_cdts_data_value=dut.tx_cdts_data_value, # Hard IP status # int_status=dut.int_status, # int_status_common=dut.int_status_common, # derr_cor_ext_rpl=dut.derr_cor_ext_rpl, # derr_rpl=dut.derr_rpl, # derr_cor_ext_rcv=dut.derr_cor_ext_rcv, # derr_uncor_ext_rcv=dut.derr_uncor_ext_rcv, # rx_par_err=dut.rx_par_err, # tx_par_err=dut.tx_par_err, # ltssmstate=dut.ltssmstate, # link_up=dut.link_up, # lane_act=dut.lane_act, # currentspeed=dut.currentspeed, # Power management # pm_linkst_in_l1=dut.pm_linkst_in_l1, # pm_linkst_in_l0s=dut.pm_linkst_in_l0s, # pm_state=dut.pm_state, # pm_dstate=dut.pm_dstate, # apps_pm_xmt_pme=dut.apps_pm_xmt_pme, # apps_ready_entr_l23=dut.apps_ready_entr_l23, # apps_pm_xmt_turnoff=dut.apps_pm_xmt_turnoff, # app_init_rst=dut.app_init_rst, # app_xfer_pending=dut.app_xfer_pending, # Interrupt interface app_msi_req=dut.app_msi_req, app_msi_ack=dut.app_msi_ack, app_msi_tc=dut.app_msi_tc, app_msi_num=dut.app_msi_num, app_msi_func_num=dut.app_msi_func_num, # app_int_sts=dut.app_int_sts, # Error interface # serr_out=dut.serr_out, # hip_enter_err_mode=dut.hip_enter_err_mode, # app_err_valid=dut.app_err_valid, # app_err_hdr=dut.app_err_hdr, # app_err_info=dut.app_err_info, # app_err_func_num=dut.app_err_func_num, # Configuration output tl_cfg_func=dut.tl_cfg_func, tl_cfg_add=dut.tl_cfg_add, tl_cfg_ctl=dut.tl_cfg_ctl, # Configuration extension bus # ceb_req=dut.ceb_req, # ceb_ack=dut.ceb_ack, # ceb_addr=dut.ceb_addr, # ceb_din=dut.ceb_din, # ceb_dout=dut.ceb_dout, # ceb_wr=dut.ceb_wr, # ceb_cdm_convert_data=dut.ceb_cdm_convert_data, # ceb_func_num=dut.ceb_func_num, # ceb_vf_num=dut.ceb_vf_num, # ceb_vf_active=dut.ceb_vf_active, # Hard IP reconfiguration interface # hip_reconfig_clk=dut.hip_reconfig_clk, # hip_reconfig_address=dut.hip_reconfig_address, # hip_reconfig_read=dut.hip_reconfig_read, # hip_reconfig_readdata=dut.hip_reconfig_readdata, # hip_reconfig_readdatavalid=dut.hip_reconfig_readdatavalid, # hip_reconfig_write=dut.hip_reconfig_write, # hip_reconfig_writedata=dut.hip_reconfig_writedata, # hip_reconfig_waitrequest=dut.hip_reconfig_waitrequest, ) self.test_dev = PcieIfTestDevice( clk=dut.clk, rst=dut.rst, rx_req_tlp_bus=PcieIfRxBus.from_prefix(dut, "rx_req_tlp"), tx_cpl_tlp_bus=PcieIfTxBus.from_prefix(dut, "tx_cpl_tlp"), tx_rd_req_tlp_bus=PcieIfTxBus.from_prefix(dut, "tx_rd_req_tlp"), rd_req_tx_seq_num=dut.m_axis_rd_req_tx_seq_num, rd_req_tx_seq_num_valid=dut.m_axis_rd_req_tx_seq_num_valid, tx_wr_req_tlp_bus=PcieIfTxBus.from_prefix(dut, "tx_wr_req_tlp"), wr_req_tx_seq_num=dut.m_axis_wr_req_tx_seq_num, wr_req_tx_seq_num_valid=dut.m_axis_wr_req_tx_seq_num_valid, rx_cpl_tlp_bus=PcieIfRxBus.from_prefix(dut, "rx_cpl_tlp"), tx_msi_wr_req_tlp_bus=PcieIfTxBus.from_prefix( dut, "tx_msi_wr_req_tlp"), ) self.dev.log.setLevel(logging.DEBUG) self.rc.make_port().connect(self.dev) self.dev.functions[0].configure_bar(0, 1024 * 1024) self.test_dev.add_mem_region(1024 * 1024) self.dev.functions[0].configure_bar(1, 1024 * 1024, True, True) self.test_dev.add_prefetchable_mem_region(1024 * 1024) self.dev.functions[0].configure_bar(3, 1024, False, False, True) self.test_dev.add_io_region(1024) self.dev.functions[0].configure_bar(4, 64 * 1024) self.test_dev.add_mem_region(64 * 1024) self.dut.msi_irq.setimmediatevalue(0) def set_idle_generator(self, generator=None): if generator: self.dev.rx_source.set_pause_generator(generator()) self.test_dev.tx_cpl_tlp_source.set_pause_generator(generator()) self.test_dev.tx_rd_req_tlp_source.set_pause_generator(generator()) self.test_dev.tx_wr_req_tlp_source.set_pause_generator(generator()) def set_backpressure_generator(self, generator=None): if generator: self.dev.tx_sink.set_pause_generator(generator()) self.test_dev.rx_req_tlp_sink.set_pause_generator(generator()) self.test_dev.rx_cpl_tlp_sink.set_pause_generator(generator())
class TB(object): def __init__(self, dut): self.dut = dut self.log = logging.getLogger("cocotb.tb") self.log.setLevel(logging.DEBUG) cocotb.start_soon(Clock(dut.clk, 4, units="ns").start()) # PCIe self.rc = RootComplex() self.dev = PcieIfDevice( clk=dut.clk, rst=dut.rst, rx_req_tlp_bus=PcieIfRxBus.from_prefix(dut, "rx_req_tlp"), tx_cpl_tlp_bus=PcieIfTxBus.from_prefix(dut, "tx_cpl_tlp")) 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.axil_ram = AxiLiteRam(AxiLiteBus.from_prefix(dut, "m_axil"), dut.clk, dut.rst, size=2**16) dut.completer_id.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 set_idle_generator(self, generator=None): if generator: self.dev.rx_req_tlp_source.set_pause_generator(generator()) self.axil_ram.write_if.b_channel.set_pause_generator(generator()) self.axil_ram.read_if.r_channel.set_pause_generator(generator()) def set_backpressure_generator(self, generator=None): if generator: self.dev.tx_cpl_tlp_sink.set_pause_generator(generator()) self.axil_ram.write_if.aw_channel.set_pause_generator(generator()) self.axil_ram.write_if.w_channel.set_pause_generator(generator()) self.axil_ram.read_if.ar_channel.set_pause_generator(generator()) async def _run_monitor_status_error_cor(self): while True: await RisingEdge(self.dut.status_error_cor) self.log.info("status_error_cor (correctable error) was asserted") self.status_error_cor_asserted = True async def _run_monitor_status_error_uncor(self): while True: await RisingEdge(self.dut.status_error_uncor) self.log.info( "status_error_uncor (uncorrectable error) was asserted") self.status_error_uncor_asserted = True async def cycle_reset(self): self.dut.rst.setimmediatevalue(0) await RisingEdge(self.dut.clk) await RisingEdge(self.dut.clk) self.dut.rst.value = 1 await RisingEdge(self.dut.clk) await RisingEdge(self.dut.clk) self.dut.rst.value = 0 await RisingEdge(self.dut.clk) await RisingEdge(self.dut.clk)
class TB(object): def __init__(self, dut): self.dut = dut self.log = logging.getLogger("cocotb.tb") self.log.setLevel(logging.DEBUG) cocotb.start_soon(Clock(dut.clk, 4, units="ns").start()) # PCIe self.rc = RootComplex() self.dev = PcieIfDevice( clk=dut.clk, rst=dut.rst, tx_wr_req_tlp_bus=PcieIfTxBus.from_prefix(dut, "tx_wr_req_tlp"), wr_req_tx_seq_num=dut.s_axis_tx_seq_num, wr_req_tx_seq_num_valid=dut.s_axis_tx_seq_num_valid, cfg_max_payload=dut.max_payload_size, tx_fc_ph_av=dut.pcie_tx_fc_ph_av, tx_fc_pd_av=dut.pcie_tx_fc_pd_av, ) self.dev.log.setLevel(logging.DEBUG) self.rc.make_port().connect(self.dev) # DMA RAM self.dma_ram = PsdpRamRead(PsdpRamReadBus.from_prefix(dut, "ram"), dut.clk, dut.rst, size=2**16) # Control self.write_desc_source = DescSource( DescBus.from_prefix(dut, "s_axis_write_desc"), dut.clk, dut.rst) self.write_desc_status_sink = DescStatusSink( DescStatusBus.from_prefix(dut, "m_axis_write_desc_status"), dut.clk, dut.rst) dut.requester_id.setimmediatevalue(0) dut.enable.setimmediatevalue(0) def set_idle_generator(self, generator=None): if generator: pass def set_backpressure_generator(self, generator=None): if generator: self.dev.tx_wr_req_tlp_sink.set_pause_generator(generator()) self.dma_ram.set_pause_generator(generator()) async def cycle_reset(self): self.dut.rst.setimmediatevalue(0) await RisingEdge(self.dut.clk) await RisingEdge(self.dut.clk) self.dut.rst <= 1 await RisingEdge(self.dut.clk) await RisingEdge(self.dut.clk) self.dut.rst <= 0 await RisingEdge(self.dut.clk) await RisingEdge(self.dut.clk)
class TB(object): 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_rx_clk, 3.102, units="ns").start()) cocotb.start_soon(Clock(dut.qsfp_tx_clk, 3.102, units="ns").start()) self.qsfp_mac = EthMac( tx_clk=dut.qsfp_tx_clk, tx_rst=dut.qsfp_tx_rst, tx_bus=AxiStreamBus.from_prefix(dut, "qsfp_tx_axis"), tx_ptp_time=dut.qsfp_tx_ptp_time, tx_ptp_ts=dut.qsfp_tx_ptp_ts, tx_ptp_ts_tag=dut.qsfp_tx_ptp_ts_tag, tx_ptp_ts_valid=dut.qsfp_tx_ptp_ts_valid, rx_clk=dut.qsfp_rx_clk, rx_rst=dut.qsfp_rx_rst, rx_bus=AxiStreamBus.from_prefix(dut, "qsfp_rx_axis"), rx_ptp_time=dut.qsfp_rx_ptp_time, ifg=12, speed=100e9) dut.qspi_dq_i.setimmediatevalue(0) self.cms_ram = AxiLiteRam(AxiLiteBus.from_prefix(dut, "m_axil_cms"), dut.m_axil_cms_clk, dut.m_axil_cms_rst, size=256 * 1024) self.loopback_enable = False cocotb.start_soon(self._run_loopback()) async def init(self): self.dut.qsfp_rx_rst.setimmediatevalue(0) self.dut.qsfp_tx_rst.setimmediatevalue(0) await RisingEdge(self.dut.clk_250mhz) await RisingEdge(self.dut.clk_250mhz) self.dut.qsfp_rx_rst.setimmediatevalue(1) self.dut.qsfp_tx_rst.setimmediatevalue(1) await FallingEdge(self.dut.rst_250mhz) await Timer(100, 'ns') await RisingEdge(self.dut.clk_250mhz) await RisingEdge(self.dut.clk_250mhz) self.dut.qsfp_rx_rst.setimmediatevalue(0) self.dut.qsfp_tx_rst.setimmediatevalue(0) await self.rc.enumerate(enable_bus_mastering=True, configure_msi=True) async def _run_loopback(self): while True: await RisingEdge(self.dut.clk_250mhz) if self.loopback_enable: if not self.qsfp_mac.tx.empty(): await self.qsfp_mac.rx.send(await self.qsfp_mac.tx.recv())
class TB(object): def __init__(self, dut): self.dut = dut self.log = logging.getLogger("cocotb.tb") self.log.setLevel(logging.DEBUG) cocotb.start_soon(Clock(dut.clk, 4, units="ns").start()) # PCIe self.rc = RootComplex() self.dev = PcieIfDevice( clk=dut.clk, rst=dut.rst, tx_rd_req_tlp_bus=PcieIfTxBus.from_prefix(dut, "tx_rd_req_tlp"), rd_req_tx_seq_num=dut.s_axis_tx_seq_num, rd_req_tx_seq_num_valid=dut.s_axis_tx_seq_num_valid, rx_cpl_tlp_bus=PcieIfRxBus.from_prefix(dut, "rx_cpl_tlp"), cfg_max_read_req=dut.max_read_request_size, cfg_ext_tag_enable=dut.ext_tag_enable, tx_fc_nph_av=dut.pcie_tx_fc_nph_av, ) self.dev.log.setLevel(logging.DEBUG) self.rc.make_port().connect(self.dev) # DMA RAM self.dma_ram = PsdpRamWrite(PsdpRamWriteBus.from_prefix(dut, "ram"), 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.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 set_idle_generator(self, generator=None): if generator: self.dev.rx_cpl_tlp_source.set_pause_generator(generator()) def set_backpressure_generator(self, generator=None): if generator: self.dev.tx_rd_req_tlp_sink.set_pause_generator(generator()) self.dma_ram.set_pause_generator(generator()) async def _run_monitor_status_error_cor(self): while True: await RisingEdge(self.dut.status_error_cor) self.log.info("status_error_cor (correctable error) was asserted") self.status_error_cor_asserted = True async def _run_monitor_status_error_uncor(self): while True: await RisingEdge(self.dut.status_error_uncor) self.log.info( "status_error_uncor (uncorrectable error) was asserted") self.status_error_uncor_asserted = True async def cycle_reset(self): self.dut.rst.setimmediatevalue(0) await RisingEdge(self.dut.clk) await RisingEdge(self.dut.clk) self.dut.rst <= 1 await RisingEdge(self.dut.clk) await RisingEdge(self.dut.clk) self.dut.rst <= 0 await RisingEdge(self.dut.clk) await RisingEdge(self.dut.clk)
class TB(object): def __init__(self, dut): self.dut = dut self.log = SimLog("cocotb.tb") self.log.setLevel(logging.DEBUG) # PCIe self.rc = RootComplex() self.dev = S10PcieDevice( # configuration options pcie_generation=3, # pcie_link_width=8, # pld_clk_frequency=250e6, l_tile=False, pf_count=1, max_payload_size=1024, enable_extended_tag=True, 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 # Clock and reset # npor=dut.npor, # pin_perst=dut.pin_perst, # ninit_done=dut.ninit_done, # pld_clk_inuse=dut.pld_clk_inuse, # pld_core_ready=dut.pld_core_ready, reset_status=dut.rst, # clr_st=dut.clr_st, # refclk=dut.refclk, coreclkout_hip=dut.clk, # RX interface rx_bus=S10RxBus.from_prefix(dut, "rx_st"), # TX interface tx_bus=S10TxBus.from_prefix(dut, "tx_st"), # TX flow control tx_ph_cdts=dut.tx_ph_cdts, tx_pd_cdts=dut.tx_pd_cdts, tx_nph_cdts=dut.tx_nph_cdts, tx_npd_cdts=dut.tx_npd_cdts, tx_cplh_cdts=dut.tx_cplh_cdts, tx_cpld_cdts=dut.tx_cpld_cdts, tx_hdr_cdts_consumed=dut.tx_hdr_cdts_consumed, tx_data_cdts_consumed=dut.tx_data_cdts_consumed, tx_cdts_type=dut.tx_cdts_type, tx_cdts_data_value=dut.tx_cdts_data_value, # Hard IP status # int_status=dut.int_status, # int_status_common=dut.int_status_common, # derr_cor_ext_rpl=dut.derr_cor_ext_rpl, # derr_rpl=dut.derr_rpl, # derr_cor_ext_rcv=dut.derr_cor_ext_rcv, # derr_uncor_ext_rcv=dut.derr_uncor_ext_rcv, # rx_par_err=dut.rx_par_err, # tx_par_err=dut.tx_par_err, # ltssmstate=dut.ltssmstate, # link_up=dut.link_up, # lane_act=dut.lane_act, # currentspeed=dut.currentspeed, # Power management # pm_linkst_in_l1=dut.pm_linkst_in_l1, # pm_linkst_in_l0s=dut.pm_linkst_in_l0s, # pm_state=dut.pm_state, # pm_dstate=dut.pm_dstate, # apps_pm_xmt_pme=dut.apps_pm_xmt_pme, # apps_ready_entr_l23=dut.apps_ready_entr_l23, # apps_pm_xmt_turnoff=dut.apps_pm_xmt_turnoff, # app_init_rst=dut.app_init_rst, # app_xfer_pending=dut.app_xfer_pending, # Interrupt interface app_msi_req=dut.app_msi_req, app_msi_ack=dut.app_msi_ack, app_msi_tc=dut.app_msi_tc, app_msi_num=dut.app_msi_num, app_msi_func_num=dut.app_msi_func_num, # app_int_sts=dut.app_int_sts, # Error interface # app_err_valid=dut.app_err_valid, # app_err_hdr=dut.app_err_hdr, # app_err_info=dut.app_err_info, # app_err_func_num=dut.app_err_func_num, # Configuration output tl_cfg_func=dut.tl_cfg_func, tl_cfg_add=dut.tl_cfg_add, tl_cfg_ctl=dut.tl_cfg_ctl, # Configuration extension bus # ceb_req=dut.ceb_req, # ceb_ack=dut.ceb_ack, # ceb_addr=dut.ceb_addr, # ceb_din=dut.ceb_din, # ceb_dout=dut.ceb_dout, # ceb_wr=dut.ceb_wr, # ceb_cdm_convert_data=dut.ceb_cdm_convert_data, # ceb_func_num=dut.ceb_func_num, # ceb_vf_num=dut.ceb_vf_num, # ceb_vf_active=dut.ceb_vf_active, # Hard IP reconfiguration interface # hip_reconfig_clk=dut.hip_reconfig_clk, # hip_reconfig_address=dut.hip_reconfig_address, # hip_reconfig_read=dut.hip_reconfig_read, # hip_reconfig_readdata=dut.hip_reconfig_readdata, # hip_reconfig_readdatavalid=dut.hip_reconfig_readdatavalid, # hip_reconfig_write=dut.hip_reconfig_write, # hip_reconfig_writedata=dut.hip_reconfig_writedata, # hip_reconfig_waitrequest=dut.hip_reconfig_waitrequest, ) # self.dev.log.setLevel(logging.DEBUG) self.rc.make_port().connect(self.dev) self.dev.functions[0].configure_bar( 0, 2**len(dut.example_core_pcie_s10_inst.core_pcie_inst. axil_ctrl_awaddr)) self.dev.functions[0].configure_bar( 2, 2**len( dut.example_core_pcie_s10_inst.core_pcie_inst.axi_ram_awaddr)) async def init(self): await FallingEdge(self.dut.rst) await Timer(100, 'ns') await self.rc.enumerate() dev = self.rc.find_device(self.dev.functions[0].pcie_id) await dev.enable_device() await dev.set_master() await dev.alloc_irq_vectors(32, 32)
class TB: 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.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, phy_rdy_out=dut.phy_rdy_out, rq_bus=AxiStreamBus.from_prefix(dut, "s_axis_rq"), pcie_rq_seq_num0=dut.pcie_rq_seq_num0, pcie_rq_seq_num_vld0=dut.pcie_rq_seq_num_vld0, pcie_rq_seq_num1=dut.pcie_rq_seq_num1, pcie_rq_seq_num_vld1=dut.pcie_rq_seq_num_vld1, pcie_rq_tag0=dut.pcie_rq_tag0, pcie_rq_tag1=dut.pcie_rq_tag1, pcie_rq_tag_av=dut.pcie_rq_tag_av, pcie_rq_tag_vld0=dut.pcie_rq_tag_vld0, pcie_rq_tag_vld1=dut.pcie_rq_tag_vld1, 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_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=dut.cfg_mgmt_debug_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_valid=dut.cfg_local_error_valid, cfg_local_error_out=dut.cfg_local_error_out, cfg_ltssm_state=dut.cfg_ltssm_state, cfg_rx_pm_state=dut.cfg_rx_pm_state, cfg_tx_pm_state=dut.cfg_tx_pm_state, cfg_rcb_status=dut.cfg_rcb_status, 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_dsn=dut.cfg_dsn, cfg_bus_number=dut.cfg_bus_number, 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_func_num=dut.cfg_vf_flr_func_num, 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_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_pm_aspm_l1_entry_reject=dut.cfg_pm_aspm_l1_entry_reject, cfg_pm_aspm_tx_l0s_entry_disable=dut. cfg_pm_aspm_tx_l0s_entry_disable, 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, ) self.dev.log.setLevel(logging.DEBUG) dut.pcie_cq_np_req.setimmediatevalue(1) dut.cfg_mgmt_addr.setimmediatevalue(0) dut.cfg_mgmt_function_number.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_debug_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_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_func_num.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_pm_aspm_l1_entry_reject.setimmediatevalue(0) dut.cfg_pm_aspm_tx_l0s_entry_disable.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.sys_clk.setimmediatevalue(0) dut.sys_clk_gt.setimmediatevalue(0) dut.sys_reset.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.fork(self._run_cq()) def set_idle_generator(self, generator=None): if generator: self.dev.rc_source.set_pause_generator(generator()) self.dev.cq_source.set_pause_generator(generator()) def set_backpressure_generator(self, generator=None): if generator: self.dev.rq_sink.set_pause_generator(generator()) self.dev.cc_sink.set_pause_generator(generator()) async def alloc_tag(self): tag_count = min(256, self.tag_count) while True: tag = self.current_tag for k in range(tag_count): tag = (tag + 1) % tag_count if not self.tag_active[tag]: self.tag_active[tag] = True self.current_tag = tag return tag self.tag_release.clear() await self.tag_release.wait() def release_tag(self, tag): assert self.tag_active[tag] self.tag_active[tag] = False self.tag_release.set() async def dma_io_write(self, addr, data, timeout=0, timeout_unit='ns'): n = 0 while True: tlp = Tlp_us() tlp.fmt_type = TlpType.IO_WRITE tlp.requester_id = PcieId(0, 0, 0) first_pad = addr % 4 byte_length = min(len(data) - n, 4 - first_pad) tlp.set_addr_be_data(addr, data[n:n + byte_length]) tlp.tag = await self.alloc_tag() await self.rq_source.send(tlp.pack_us_rq()) pkt = await self.rc_sink.recv() self.release_tag(tlp.tag) if not pkt: raise Exception("Timeout") cpl = Tlp_us.unpack_us_rc(pkt) if cpl.status != CplStatus.SC: raise Exception("Unsuccessful completion") n += byte_length addr += byte_length if n >= len(data): break async def dma_io_read(self, addr, length, timeout=0, timeout_unit='ns'): data = b'' n = 0 while True: tlp = Tlp_us() tlp.fmt_type = TlpType.IO_READ tlp.requester_id = PcieId(0, 0, 0) first_pad = addr % 4 byte_length = min(length - n, 4 - first_pad) tlp.set_addr_be(addr, byte_length) tlp.tag = await self.alloc_tag() await self.rq_source.send(tlp.pack_us_rq()) pkt = await self.rc_sink.recv() self.release_tag(tlp.tag) if not pkt: raise Exception("Timeout") cpl = Tlp_us.unpack_us_rc(pkt) if cpl.status != CplStatus.SC: raise Exception("Unsuccessful completion") else: d = cpl.get_data() data += d[first_pad:] n += byte_length addr += byte_length if n >= length: break return data[:length] async def dma_mem_write(self, addr, data, timeout=0, timeout_unit='ns'): n = 0 while True: tlp = Tlp_us() if addr > 0xffffffff: tlp.fmt_type = TlpType.MEM_WRITE_64 else: tlp.fmt_type = TlpType.MEM_WRITE tlp.requester_id = PcieId(0, 0, 0) first_pad = addr % 4 byte_length = len(data) - n # max payload size byte_length = min(byte_length, (128 << self.dut.cfg_max_payload.value.integer) - first_pad) # 4k address align byte_length = min(byte_length, 0x1000 - (addr & 0xfff)) tlp.set_addr_be_data(addr, data[n:n + byte_length]) await self.rq_source.send(tlp.pack_us_rq()) n += byte_length addr += byte_length if n >= len(data): break async def dma_mem_read(self, addr, length, timeout=0, timeout_unit='ns'): data = b'' n = 0 while True: tlp = Tlp_us() if addr > 0xffffffff: tlp.fmt_type = TlpType.MEM_READ_64 else: tlp.fmt_type = TlpType.MEM_READ tlp.requester_id = PcieId(0, 0, 0) first_pad = addr % 4 byte_length = length - n # max read request size byte_length = min( byte_length, (128 << self.dut.cfg_max_read_req.value.integer) - first_pad) # 4k address align byte_length = min(byte_length, 0x1000 - (addr & 0xfff)) tlp.set_addr_be(addr, byte_length) tlp.tag = await self.alloc_tag() await self.rq_source.send(tlp.pack_us_rq()) m = 0 while True: pkt = await self.rc_sink.recv() if not pkt: raise Exception("Timeout") cpl = Tlp_us.unpack_us_rc(pkt) if cpl.status != CplStatus.SC: raise Exception("Unsuccessful completion") else: assert cpl.byte_count + 3 + (cpl.lower_address & 3) >= cpl.length * 4 assert cpl.byte_count == max(byte_length - m, 1) d = cpl.get_data() offset = cpl.lower_address & 3 data += d[offset:offset + cpl.byte_count] m += len(d) - offset if m >= byte_length: break self.release_tag(tlp.tag) n += byte_length addr += byte_length if n >= length: break return data[:length] async def _run_cq(self): while True: pkt = await self.cq_sink.recv() tlp = Tlp_us.unpack_us_cq(pkt) self.log.debug("CQ TLP: %s", repr(tlp)) if tlp.fmt_type == TlpType.IO_READ: self.log.info("IO read") cpl = Tlp_us.create_completion_data_for_tlp( tlp, PcieId(0, 0, 0)) region = tlp.bar_id addr = tlp.address % len(self.regions[region]) offset = 0 start_offset = None mask = tlp.first_be # perform operation data = bytearray(4) for k in range(4): if mask & (1 << k): if start_offset is None: start_offset = offset else: if start_offset is not None and offset != start_offset: data[start_offset:offset] = self.regions[region][ addr + start_offset:addr + offset] start_offset = None offset += 1 if start_offset is not None and offset != start_offset: data[start_offset:offset] = self.regions[region][ addr + start_offset:addr + offset] cpl.set_data(data) cpl.byte_count = 4 cpl.length = 1 self.log.debug("Completion: %s", repr(cpl)) await self.cc_source.send(cpl.pack_us_cc()) elif tlp.fmt_type == TlpType.IO_WRITE: self.log.info("IO write") cpl = Tlp_us.create_completion_for_tlp(tlp, PcieId(0, 0, 0)) region = tlp.bar_id addr = tlp.address % len(self.regions[region]) offset = 0 start_offset = None mask = tlp.first_be # perform operation data = tlp.get_data() for k in range(4): if mask & (1 << k): if start_offset is None: start_offset = offset else: if start_offset is not None and offset != start_offset: self.regions[region][addr + start_offset:addr + offset] = data[ start_offset:offset] start_offset = None offset += 1 if start_offset is not None and offset != start_offset: self.regions[region][addr + start_offset:addr + offset] = data[start_offset:offset] self.log.debug("Completion: %s", repr(cpl)) await self.cc_source.send(cpl.pack_us_cc()) elif tlp.fmt_type in {TlpType.MEM_READ, TlpType.MEM_READ_64}: self.log.info("Memory read") # perform operation region = tlp.bar_id addr = tlp.address % len(self.regions[region]) offset = 0 length = tlp.length # perform read data = self.regions[region][addr:addr + length * 4] # prepare completion TLP(s) m = 0 n = 0 addr = tlp.address + tlp.get_first_be_offset() dw_length = tlp.length byte_length = tlp.get_be_byte_count() while m < dw_length: cpl = Tlp_us.create_completion_data_for_tlp( tlp, PcieId(0, 0, 0)) cpl_dw_length = dw_length - m cpl_byte_length = byte_length - n cpl.byte_count = cpl_byte_length if cpl_dw_length > 32 << self.dut.cfg_max_payload.value.integer: # max payload size cpl_dw_length = 32 << self.dut.cfg_max_payload.value.integer # RCB align cpl_dw_length -= (addr & 0x7c) >> 2 cpl.lower_address = addr & 0x7f cpl.set_data(data[m * 4:(m + cpl_dw_length) * 4]) self.log.debug("Completion: %s", repr(cpl)) await self.cc_source.send(cpl.pack_us_cc()) m += cpl_dw_length n += cpl_dw_length * 4 - (addr & 3) addr += cpl_dw_length * 4 - (addr & 3) elif tlp.fmt_type in {TlpType.MEM_WRITE, TlpType.MEM_WRITE_64}: self.log.info("Memory write") # perform operation region = tlp.bar_id addr = tlp.address % len(self.regions[region]) offset = 0 start_offset = None mask = tlp.first_be length = tlp.length # perform write data = tlp.get_data() # first dword for k in range(4): if mask & (1 << k): if start_offset is None: start_offset = offset else: if start_offset is not None and offset != start_offset: self.regions[region][addr + start_offset:addr + offset] = data[ start_offset:offset] start_offset = None offset += 1 if length > 2: # middle dwords if start_offset is None: start_offset = offset offset += (length - 2) * 4 if length > 1: # last dword mask = tlp.last_be for k in range(4): if mask & (1 << k): if start_offset is None: start_offset = offset else: if start_offset is not None and offset != start_offset: self.regions[region][addr + start_offset:addr + offset] = data[ start_offset:offset] start_offset = None offset += 1 if start_offset is not None and offset != start_offset: self.regions[region][addr + start_offset:addr + offset] = data[start_offset:offset]
class TB(object): 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 # Clock and Reset Interface user_clk=dut.clk, user_reset=dut.rst, # 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 # 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 # cfg_err_uncor_in # 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.test_dev = PcieIfTestDevice( force_64bit_addr=True, clk=dut.clk, rst=dut.rst, rx_req_tlp_bus=PcieIfRxBus.from_prefix(dut, "rx_req_tlp"), tx_cpl_tlp_bus=PcieIfTxBus.from_prefix(dut, "tx_cpl_tlp"), tx_rd_req_tlp_bus=PcieIfTxBus.from_prefix(dut, "tx_rd_req_tlp"), rd_req_tx_seq_num=dut.m_axis_rd_req_tx_seq_num, rd_req_tx_seq_num_valid=dut.m_axis_rd_req_tx_seq_num_valid, tx_wr_req_tlp_bus=PcieIfTxBus.from_prefix(dut, "tx_wr_req_tlp"), wr_req_tx_seq_num=dut.m_axis_wr_req_tx_seq_num, wr_req_tx_seq_num_valid=dut.m_axis_wr_req_tx_seq_num_valid, rx_cpl_tlp_bus=PcieIfRxBus.from_prefix(dut, "rx_cpl_tlp"), ) self.dev.log.setLevel(logging.DEBUG) self.rc.make_port().connect(self.dev) self.dev.functions[0].msi_cap.msi_multiple_message_capable = 5 self.dev.functions[0].configure_bar(0, 1024 * 1024) self.test_dev.add_mem_region(1024 * 1024) self.dev.functions[0].configure_bar(1, 1024 * 1024, True, True) self.test_dev.add_prefetchable_mem_region(1024 * 1024) self.dev.functions[0].configure_bar(3, 1024, False, False, True) self.test_dev.add_io_region(1024) self.dut.msi_irq.setimmediatevalue(0) def set_idle_generator(self, generator=None): if generator: self.dev.rc_source.set_pause_generator(generator()) self.dev.cq_source.set_pause_generator(generator()) self.test_dev.tx_cpl_tlp_source.set_pause_generator(generator()) self.test_dev.tx_rd_req_tlp_source.set_pause_generator(generator()) self.test_dev.tx_wr_req_tlp_source.set_pause_generator(generator()) def set_backpressure_generator(self, generator=None): if generator: self.dev.rq_sink.set_pause_generator(generator()) self.dev.cc_sink.set_pause_generator(generator()) self.test_dev.rx_req_tlp_sink.set_pause_generator(generator()) self.test_dev.rx_cpl_tlp_sink.set_pause_generator(generator())
class TB(object): 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, cfg_max_payload=dut.max_payload_size, cfg_fc_sel=0b100, cfg_fc_ph=dut.pcie_tx_fc_ph_av, cfg_fc_pd=dut.pcie_tx_fc_pd_av, ) self.dev.log.setLevel(logging.DEBUG) self.rc.make_port().connect(self.dev) # tie off RQ input dut.s_axis_rq_tdata.setimmediatevalue(0) dut.s_axis_rq_tkeep.setimmediatevalue(0) dut.s_axis_rq_tlast.setimmediatevalue(0) dut.s_axis_rq_tuser.setimmediatevalue(0) dut.s_axis_rq_tvalid.setimmediatevalue(0) # AXI self.axi_ram = AxiRamRead(AxiReadBus.from_prefix(dut, "m_axi"), dut.clk, dut.rst, size=2**16) # Control self.write_desc_source = DescSource( DescBus.from_prefix(dut, "s_axis_write_desc"), dut.clk, dut.rst) self.write_desc_status_sink = DescStatusSink( DescStatusBus.from_prefix(dut, "m_axis_write_desc_status"), dut.clk, dut.rst) dut.requester_id.setimmediatevalue(0) dut.requester_id_enable.setimmediatevalue(0) dut.enable.setimmediatevalue(0) def set_idle_generator(self, generator=None): if generator: self.axi_ram.r_channel.set_pause_generator(generator()) def set_backpressure_generator(self, generator=None): if generator: self.dev.rq_sink.set_pause_generator(generator()) self.axi_ram.ar_channel.set_pause_generator(generator())
class TB(object): 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_payload=dut.max_payload_size, cfg_max_read_req=dut.max_read_request_size, cfg_fc_sel=0b100, cfg_fc_ph=dut.pcie_tx_fc_ph_av, cfg_fc_pd=dut.pcie_tx_fc_pd_av, 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 = AxiRam(AxiBus.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) self.write_desc_source = DescSource(DescBus.from_prefix(dut, "s_axis_write_desc"), dut.clk, dut.rst) self.write_desc_status_sink = DescStatusSink(DescStatusBus.from_prefix(dut, "m_axis_write_desc_status"), dut.clk, dut.rst) dut.requester_id.setimmediatevalue(0) dut.requester_id_enable.setimmediatevalue(0) dut.ext_tag_enable.setimmediatevalue(0) dut.read_enable.setimmediatevalue(0) dut.write_enable.setimmediatevalue(0) # monitor error outputs self.status_error_cor_asserted = False self.status_error_uncor_asserted = False cocotb.fork(self._run_monitor_status_error_cor()) cocotb.fork(self._run_monitor_status_error_uncor()) def set_idle_generator(self, generator=None): if generator: self.dev.rc_source.set_pause_generator(generator()) self.axi_ram.write_if.b_channel.set_pause_generator(generator()) self.axi_ram.read_if.r_channel.set_pause_generator(generator()) def set_backpressure_generator(self, generator=None): if generator: self.dev.rq_sink.set_pause_generator(generator()) self.axi_ram.write_if.aw_channel.set_pause_generator(generator()) self.axi_ram.write_if.w_channel.set_pause_generator(generator()) self.axi_ram.read_if.ar_channel.set_pause_generator(generator()) async def _run_monitor_status_error_cor(self): while True: await RisingEdge(self.dut.status_error_cor) self.log.info("status_error_cor (correctable error) was asserted") self.status_error_cor_asserted = True async def _run_monitor_status_error_uncor(self): while True: await RisingEdge(self.dut.status_error_uncor) self.log.info("status_error_uncor (uncorrectable error) was asserted") self.status_error_uncor_asserted = True
class TB(object): def __init__(self, dut): self.dut = dut self.log = SimLog("cocotb.tb") self.log.setLevel(logging.DEBUG) cocotb.start_soon(Clock(dut.clk, 4, units="ns").start()) # PCIe self.rc = RootComplex() self.dev = PcieIfDevice( clk=dut.clk, rst=dut.rst, rx_req_tlp_bus=PcieIfRxBus.from_prefix(dut, "rx_req_tlp"), tx_cpl_tlp_bus=PcieIfTxBus.from_prefix(dut, "tx_cpl_tlp"), tx_wr_req_tlp_bus=PcieIfTxBus.from_prefix(dut, "tx_wr_req_tlp"), wr_req_tx_seq_num=dut.s_axis_wr_req_tx_seq_num, wr_req_tx_seq_num_valid=dut.s_axis_wr_req_tx_seq_num_valid, tx_rd_req_tlp_bus=PcieIfTxBus.from_prefix(dut, "tx_rd_req_tlp"), rd_req_tx_seq_num=dut.s_axis_rd_req_tx_seq_num, rd_req_tx_seq_num_valid=dut.s_axis_rd_req_tx_seq_num_valid, rx_cpl_tlp_bus=PcieIfRxBus.from_prefix(dut, "rx_cpl_tlp"), cfg_max_payload=dut.max_payload_size, cfg_max_read_req=dut.max_read_request_size, cfg_ext_tag_enable=dut.ext_tag_enable, tx_fc_ph_av=dut.pcie_tx_fc_ph_av, tx_fc_pd_av=dut.pcie_tx_fc_pd_av, tx_fc_nph_av=dut.pcie_tx_fc_nph_av, ) self.dev.log.setLevel(logging.DEBUG) self.rc.make_port().connect(self.dev) self.dev.functions[0].msi_multiple_message_capable = 5 self.dev.functions[0].configure_bar(0, 2**len(dut.axil_ctrl_awaddr)) self.dev.functions[0].configure_bar(2, 2**len(dut.axi_ram_awaddr)) dut.bus_num.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()) async def _run_monitor_status_error_cor(self): while True: await RisingEdge(self.dut.status_error_cor) self.log.info("status_error_cor (correctable error) was asserted") self.status_error_cor_asserted = True async def _run_monitor_status_error_uncor(self): while True: await RisingEdge(self.dut.status_error_uncor) self.log.info( "status_error_uncor (uncorrectable error) was asserted") self.status_error_uncor_asserted = True async def cycle_reset(self): self.dut.rst.setimmediatevalue(0) await RisingEdge(self.dut.clk) await RisingEdge(self.dut.clk) self.dut.rst.value = 1 await RisingEdge(self.dut.clk) await RisingEdge(self.dut.clk) self.dut.rst.value = 0 await RisingEdge(self.dut.clk) await RisingEdge(self.dut.clk)
class TB(object): 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 = S10PcieDevice( # configuration options pcie_generation=3, # pcie_link_width=2, # pld_clk_frequency=250e6, l_tile=False, # signals # Clock and reset # npor=dut.npor, # pin_perst=dut.pin_perst, # ninit_done=dut.ninit_done, # pld_clk_inuse=dut.pld_clk_inuse, # pld_core_ready=dut.pld_core_ready, reset_status=dut.rst, # clr_st=dut.clr_st, # refclk=dut.refclk, coreclkout_hip=dut.clk, # RX interface rx_bus=S10RxBus.from_prefix(dut, "rx_st"), # TX interface tx_bus=S10TxBus.from_prefix(dut, "tx_st"), # TX flow control tx_ph_cdts=dut.tx_ph_cdts, tx_pd_cdts=dut.tx_pd_cdts, tx_nph_cdts=dut.tx_nph_cdts, tx_npd_cdts=dut.tx_npd_cdts, tx_cplh_cdts=dut.tx_cplh_cdts, tx_cpld_cdts=dut.tx_cpld_cdts, tx_hdr_cdts_consumed=dut.tx_hdr_cdts_consumed, tx_data_cdts_consumed=dut.tx_data_cdts_consumed, tx_cdts_type=dut.tx_cdts_type, tx_cdts_data_value=dut.tx_cdts_data_value, # Hard IP status # int_status=dut.int_status, # int_status_common=dut.int_status_common, # derr_cor_ext_rpl=dut.derr_cor_ext_rpl, # derr_rpl=dut.derr_rpl, # derr_cor_ext_rcv=dut.derr_cor_ext_rcv, # derr_uncor_ext_rcv=dut.derr_uncor_ext_rcv, # rx_par_err=dut.rx_par_err, # tx_par_err=dut.tx_par_err, # ltssmstate=dut.ltssmstate, # link_up=dut.link_up, # lane_act=dut.lane_act, # currentspeed=dut.currentspeed, # Power management # pm_linkst_in_l1=dut.pm_linkst_in_l1, # pm_linkst_in_l0s=dut.pm_linkst_in_l0s, # pm_state=dut.pm_state, # pm_dstate=dut.pm_dstate, # apps_pm_xmt_pme=dut.apps_pm_xmt_pme, # apps_ready_entr_l23=dut.apps_ready_entr_l23, # apps_pm_xmt_turnoff=dut.apps_pm_xmt_turnoff, # app_init_rst=dut.app_init_rst, # app_xfer_pending=dut.app_xfer_pending, # Interrupt interface app_msi_req=dut.app_msi_req, app_msi_ack=dut.app_msi_ack, app_msi_tc=dut.app_msi_tc, app_msi_num=dut.app_msi_num, app_msi_func_num=dut.app_msi_func_num, # app_int_sts=dut.app_int_sts, # Error interface # serr_out=dut.serr_out, # hip_enter_err_mode=dut.hip_enter_err_mode, # app_err_valid=dut.app_err_valid, # app_err_hdr=dut.app_err_hdr, # app_err_info=dut.app_err_info, # app_err_func_num=dut.app_err_func_num, # Configuration output tl_cfg_func=dut.tl_cfg_func, tl_cfg_add=dut.tl_cfg_add, tl_cfg_ctl=dut.tl_cfg_ctl, # Configuration extension bus # ceb_req=dut.ceb_req, # ceb_ack=dut.ceb_ack, # ceb_addr=dut.ceb_addr, # ceb_din=dut.ceb_din, # ceb_dout=dut.ceb_dout, # ceb_wr=dut.ceb_wr, # ceb_cdm_convert_data=dut.ceb_cdm_convert_data, # ceb_func_num=dut.ceb_func_num, # ceb_vf_num=dut.ceb_vf_num, # ceb_vf_active=dut.ceb_vf_active, # Hard IP reconfiguration interface # hip_reconfig_clk=dut.hip_reconfig_clk, # hip_reconfig_address=dut.hip_reconfig_address, # hip_reconfig_read=dut.hip_reconfig_read, # hip_reconfig_readdata=dut.hip_reconfig_readdata, # hip_reconfig_readdatavalid=dut.hip_reconfig_readdatavalid, # hip_reconfig_write=dut.hip_reconfig_write, # hip_reconfig_writedata=dut.hip_reconfig_writedata, # hip_reconfig_waitrequest=dut.hip_reconfig_waitrequest, ) # 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_pcie_inst.axil_ctrl_araddr), ext=True, prefetch=True) if hasattr(dut.core_pcie_inst, 'pcie_app_ctrl'): self.dev.functions[0].configure_bar( 2, 2**len(dut.core_pcie_inst.axil_app_ctrl_araddr), ext=True, prefetch=True) # Ethernet self.port_mac = [] eth_int_if_width = len(dut.core_pcie_inst.core_inst.iface[0].port[0]. rx_async_fifo_inst.m_axis_tdata) eth_clock_period = 6.4 eth_speed = 10e9 if eth_int_if_width == 64: # 10G eth_clock_period = 6.4 eth_speed = 10e9 elif eth_int_if_width == 128: # 25G eth_clock_period = 2.56 eth_speed = 25e9 elif eth_int_if_width == 512: # 100G eth_clock_period = 3.102 eth_speed = 100e9 for iface in dut.core_pcie_inst.core_inst.iface: for port in iface.port: cocotb.start_soon( Clock(port.port_rx_clk, eth_clock_period, units="ns").start()) cocotb.start_soon( Clock(port.port_tx_clk, eth_clock_period, units="ns").start()) port.port_rx_rst.setimmediatevalue(0) port.port_tx_rst.setimmediatevalue(0) mac = EthMac(tx_clk=port.port_tx_clk, tx_rst=port.port_tx_rst, tx_bus=AxiStreamBus.from_prefix(port, "axis_tx"), tx_ptp_time=port.ptp.tx_ptp_cdc_inst.output_ts, tx_ptp_ts=port.ptp.axis_tx_ptp_ts, tx_ptp_ts_tag=port.ptp.axis_tx_ptp_ts_tag, tx_ptp_ts_valid=port.ptp.axis_tx_ptp_ts_valid, rx_clk=port.port_rx_clk, rx_rst=port.port_rx_rst, rx_bus=AxiStreamBus.from_prefix(port, "axis_rx"), rx_ptp_time=port.ptp.rx_ptp_cdc_inst.output_ts, ifg=12, speed=eth_speed) self.port_mac.append(mac) dut.ctrl_reg_wr_wait.setimmediatevalue(0) dut.ctrl_reg_wr_ack.setimmediatevalue(0) dut.ctrl_reg_rd_data.setimmediatevalue(0) dut.ctrl_reg_rd_wait.setimmediatevalue(0) dut.ctrl_reg_rd_ack.setimmediatevalue(0) dut.ptp_sample_clk.setimmediatevalue(0) dut.s_axis_stat_tdata.setimmediatevalue(0) dut.s_axis_stat_tid.setimmediatevalue(0) dut.s_axis_stat_tvalid.setimmediatevalue(0) self.loopback_enable = False cocotb.start_soon(self._run_loopback()) async def init(self): for mac in self.port_mac: mac.rx.reset.setimmediatevalue(0) mac.tx.reset.setimmediatevalue(0) await RisingEdge(self.dut.clk) await RisingEdge(self.dut.clk) for mac in self.port_mac: mac.rx.reset.setimmediatevalue(1) mac.tx.reset.setimmediatevalue(1) await FallingEdge(self.dut.rst) await Timer(100, 'ns') await RisingEdge(self.dut.clk) await RisingEdge(self.dut.clk) for mac in self.port_mac: mac.rx.reset.setimmediatevalue(0) mac.tx.reset.setimmediatevalue(0) await self.rc.enumerate(enable_bus_mastering=True, configure_msi=True) async def _run_loopback(self): while True: await RisingEdge(self.dut.clk) if self.loopback_enable: for mac in self.port_mac: if not mac.tx.empty(): await mac.rx.send(await mac.tx.recv())
class TB(object): 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 = S10PcieDevice( # configuration options pcie_generation=3, # pcie_link_width=8, # pld_clk_frequency=250e6, l_tile=False, # signals # Clock and reset # npor=dut.npor, # pin_perst=dut.pin_perst, # ninit_done=dut.ninit_done, # pld_clk_inuse=dut.pld_clk_inuse, # pld_core_ready=dut.pld_core_ready, reset_status=dut.rst_250mhz, # clr_st=dut.clr_st, # refclk=dut.refclk, coreclkout_hip=dut.clk_250mhz, # RX interface rx_bus=S10RxBus.from_prefix(dut, "rx_st"), # TX interface tx_bus=S10TxBus.from_prefix(dut, "tx_st"), # TX flow control tx_ph_cdts=dut.tx_ph_cdts, tx_pd_cdts=dut.tx_pd_cdts, tx_nph_cdts=dut.tx_nph_cdts, tx_npd_cdts=dut.tx_npd_cdts, tx_cplh_cdts=dut.tx_cplh_cdts, tx_cpld_cdts=dut.tx_cpld_cdts, tx_hdr_cdts_consumed=dut.tx_hdr_cdts_consumed, tx_data_cdts_consumed=dut.tx_data_cdts_consumed, tx_cdts_type=dut.tx_cdts_type, tx_cdts_data_value=dut.tx_cdts_data_value, # Hard IP status # int_status=dut.int_status, # int_status_common=dut.int_status_common, # derr_cor_ext_rpl=dut.derr_cor_ext_rpl, # derr_rpl=dut.derr_rpl, # derr_cor_ext_rcv=dut.derr_cor_ext_rcv, # derr_uncor_ext_rcv=dut.derr_uncor_ext_rcv, # rx_par_err=dut.rx_par_err, # tx_par_err=dut.tx_par_err, # ltssmstate=dut.ltssmstate, # link_up=dut.link_up, # lane_act=dut.lane_act, # currentspeed=dut.currentspeed, # Power management # pm_linkst_in_l1=dut.pm_linkst_in_l1, # pm_linkst_in_l0s=dut.pm_linkst_in_l0s, # pm_state=dut.pm_state, # pm_dstate=dut.pm_dstate, # apps_pm_xmt_pme=dut.apps_pm_xmt_pme, # apps_ready_entr_l23=dut.apps_ready_entr_l23, # apps_pm_xmt_turnoff=dut.apps_pm_xmt_turnoff, # app_init_rst=dut.app_init_rst, # app_xfer_pending=dut.app_xfer_pending, # Interrupt interface app_msi_req=dut.app_msi_req, app_msi_ack=dut.app_msi_ack, app_msi_tc=dut.app_msi_tc, app_msi_num=dut.app_msi_num, app_msi_func_num=dut.app_msi_func_num, # app_int_sts=dut.app_int_sts, # Error interface # app_err_valid=dut.app_err_valid, # app_err_hdr=dut.app_err_hdr, # app_err_info=dut.app_err_info, # app_err_func_num=dut.app_err_func_num, # Configuration output tl_cfg_func=dut.tl_cfg_func, tl_cfg_add=dut.tl_cfg_add, tl_cfg_ctl=dut.tl_cfg_ctl, # Configuration extension bus # ceb_req=dut.ceb_req, # ceb_ack=dut.ceb_ack, # ceb_addr=dut.ceb_addr, # ceb_din=dut.ceb_din, # ceb_dout=dut.ceb_dout, # ceb_wr=dut.ceb_wr, # ceb_cdm_convert_data=dut.ceb_cdm_convert_data, # ceb_func_num=dut.ceb_func_num, # ceb_vf_num=dut.ceb_vf_num, # ceb_vf_active=dut.ceb_vf_active, # Hard IP reconfiguration interface # hip_reconfig_clk=dut.hip_reconfig_clk, # hip_reconfig_address=dut.hip_reconfig_address, # hip_reconfig_read=dut.hip_reconfig_read, # hip_reconfig_readdata=dut.hip_reconfig_readdata, # hip_reconfig_readdatavalid=dut.hip_reconfig_readdatavalid, # hip_reconfig_write=dut.hip_reconfig_write, # hip_reconfig_writedata=dut.hip_reconfig_writedata, # hip_reconfig_waitrequest=dut.hip_reconfig_waitrequest, ) # 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.qsfp0_rx_clk_1, 6.4, units="ns").start()) self.qsfp0_1_source = XgmiiSource(dut.qsfp0_rxd_1, dut.qsfp0_rxc_1, dut.qsfp0_rx_clk_1, dut.qsfp0_rx_rst_1) cocotb.start_soon(Clock(dut.qsfp0_tx_clk_1, 6.4, units="ns").start()) self.qsfp0_1_sink = XgmiiSink(dut.qsfp0_txd_1, dut.qsfp0_txc_1, dut.qsfp0_tx_clk_1, dut.qsfp0_tx_rst_1) cocotb.start_soon(Clock(dut.qsfp0_rx_clk_2, 6.4, units="ns").start()) self.qsfp0_2_source = XgmiiSource(dut.qsfp0_rxd_2, dut.qsfp0_rxc_2, dut.qsfp0_rx_clk_2, dut.qsfp0_rx_rst_2) cocotb.start_soon(Clock(dut.qsfp0_tx_clk_2, 6.4, units="ns").start()) self.qsfp0_2_sink = XgmiiSink(dut.qsfp0_txd_2, dut.qsfp0_txc_2, dut.qsfp0_tx_clk_2, dut.qsfp0_tx_rst_2) cocotb.start_soon(Clock(dut.qsfp0_rx_clk_3, 6.4, units="ns").start()) self.qsfp0_3_source = XgmiiSource(dut.qsfp0_rxd_3, dut.qsfp0_rxc_3, dut.qsfp0_rx_clk_3, dut.qsfp0_rx_rst_3) cocotb.start_soon(Clock(dut.qsfp0_tx_clk_3, 6.4, units="ns").start()) self.qsfp0_3_sink = XgmiiSink(dut.qsfp0_txd_3, dut.qsfp0_txc_3, dut.qsfp0_tx_clk_3, dut.qsfp0_tx_rst_3) cocotb.start_soon(Clock(dut.qsfp0_rx_clk_4, 6.4, units="ns").start()) self.qsfp0_4_source = XgmiiSource(dut.qsfp0_rxd_4, dut.qsfp0_rxc_4, dut.qsfp0_rx_clk_4, dut.qsfp0_rx_rst_4) cocotb.start_soon(Clock(dut.qsfp0_tx_clk_4, 6.4, units="ns").start()) self.qsfp0_4_sink = XgmiiSink(dut.qsfp0_txd_4, dut.qsfp0_txc_4, dut.qsfp0_tx_clk_4, dut.qsfp0_tx_rst_4) cocotb.start_soon(Clock(dut.qsfp1_rx_clk_1, 6.4, units="ns").start()) self.qsfp1_1_source = XgmiiSource(dut.qsfp1_rxd_1, dut.qsfp1_rxc_1, dut.qsfp1_rx_clk_1, dut.qsfp1_rx_rst_1) cocotb.start_soon(Clock(dut.qsfp1_tx_clk_1, 6.4, units="ns").start()) self.qsfp1_1_sink = XgmiiSink(dut.qsfp1_txd_1, dut.qsfp1_txc_1, dut.qsfp1_tx_clk_1, dut.qsfp1_tx_rst_1) cocotb.start_soon(Clock(dut.qsfp1_rx_clk_2, 6.4, units="ns").start()) self.qsfp1_2_source = XgmiiSource(dut.qsfp1_rxd_2, dut.qsfp1_rxc_2, dut.qsfp1_rx_clk_2, dut.qsfp1_rx_rst_2) cocotb.start_soon(Clock(dut.qsfp1_tx_clk_2, 6.4, units="ns").start()) self.qsfp1_2_sink = XgmiiSink(dut.qsfp1_txd_2, dut.qsfp1_txc_2, dut.qsfp1_tx_clk_2, dut.qsfp1_tx_rst_2) cocotb.start_soon(Clock(dut.qsfp1_rx_clk_3, 6.4, units="ns").start()) self.qsfp1_3_source = XgmiiSource(dut.qsfp1_rxd_3, dut.qsfp1_rxc_3, dut.qsfp1_rx_clk_3, dut.qsfp1_rx_rst_3) cocotb.start_soon(Clock(dut.qsfp1_tx_clk_3, 6.4, units="ns").start()) self.qsfp1_3_sink = XgmiiSink(dut.qsfp1_txd_3, dut.qsfp1_txc_3, dut.qsfp1_tx_clk_3, dut.qsfp1_tx_rst_3) cocotb.start_soon(Clock(dut.qsfp1_rx_clk_4, 6.4, units="ns").start()) self.qsfp1_4_source = XgmiiSource(dut.qsfp1_rxd_4, dut.qsfp1_rxc_4, dut.qsfp1_rx_clk_4, dut.qsfp1_rx_rst_4) cocotb.start_soon(Clock(dut.qsfp1_tx_clk_4, 6.4, units="ns").start()) self.qsfp1_4_sink = XgmiiSink(dut.qsfp1_txd_4, dut.qsfp1_txc_4, dut.qsfp1_tx_clk_4, dut.qsfp1_tx_rst_4) # dut.qsfp0_i2c_scl_i.setimmediatevalue(1) # dut.qsfp0_i2c_sda_i.setimmediatevalue(1) # dut.qsfp0_intr_n.setimmediatevalue(1) # dut.qsfp0_mod_prsnt_n.setimmediatevalue(0) # dut.qsfp0_rx_error_count_0.setimmediatevalue(0) # dut.qsfp0_rx_error_count_1.setimmediatevalue(0) # dut.qsfp0_rx_error_count_2.setimmediatevalue(0) # dut.qsfp0_rx_error_count_3.setimmediatevalue(0) # dut.qsfp1_i2c_scl_i.setimmediatevalue(1) # dut.qsfp1_i2c_sda_i.setimmediatevalue(1) # dut.qsfp1_intr_n.setimmediatevalue(1) # dut.qsfp1_mod_prsnt_n.setimmediatevalue(0) # dut.qsfp1_rx_error_count_0.setimmediatevalue(0) # dut.qsfp1_rx_error_count_1.setimmediatevalue(0) # dut.qsfp1_rx_error_count_2.setimmediatevalue(0) # dut.qsfp1_rx_error_count_3.setimmediatevalue(0) # dut.qspi_dq_i.setimmediatevalue(0) self.loopback_enable = False cocotb.start_soon(self._run_loopback()) async def init(self): self.dut.qsfp0_rx_rst_1.setimmediatevalue(0) self.dut.qsfp0_tx_rst_1.setimmediatevalue(0) self.dut.qsfp0_rx_rst_2.setimmediatevalue(0) self.dut.qsfp0_tx_rst_2.setimmediatevalue(0) self.dut.qsfp0_rx_rst_3.setimmediatevalue(0) self.dut.qsfp0_tx_rst_3.setimmediatevalue(0) self.dut.qsfp0_rx_rst_4.setimmediatevalue(0) self.dut.qsfp0_tx_rst_4.setimmediatevalue(0) self.dut.qsfp1_rx_rst_1.setimmediatevalue(0) self.dut.qsfp1_tx_rst_1.setimmediatevalue(0) self.dut.qsfp1_rx_rst_2.setimmediatevalue(0) self.dut.qsfp1_tx_rst_2.setimmediatevalue(0) self.dut.qsfp1_rx_rst_3.setimmediatevalue(0) self.dut.qsfp1_tx_rst_3.setimmediatevalue(0) self.dut.qsfp1_rx_rst_4.setimmediatevalue(0) self.dut.qsfp1_tx_rst_4.setimmediatevalue(0) await RisingEdge(self.dut.clk_250mhz) await RisingEdge(self.dut.clk_250mhz) self.dut.qsfp0_rx_rst_1.setimmediatevalue(1) self.dut.qsfp0_tx_rst_1.setimmediatevalue(1) self.dut.qsfp0_rx_rst_2.setimmediatevalue(1) self.dut.qsfp0_tx_rst_2.setimmediatevalue(1) self.dut.qsfp0_rx_rst_3.setimmediatevalue(1) self.dut.qsfp0_tx_rst_3.setimmediatevalue(1) self.dut.qsfp0_rx_rst_4.setimmediatevalue(1) self.dut.qsfp0_tx_rst_4.setimmediatevalue(1) self.dut.qsfp1_rx_rst_1.setimmediatevalue(1) self.dut.qsfp1_tx_rst_1.setimmediatevalue(1) self.dut.qsfp1_rx_rst_2.setimmediatevalue(1) self.dut.qsfp1_tx_rst_2.setimmediatevalue(1) self.dut.qsfp1_rx_rst_3.setimmediatevalue(1) self.dut.qsfp1_tx_rst_3.setimmediatevalue(1) self.dut.qsfp1_rx_rst_4.setimmediatevalue(1) self.dut.qsfp1_tx_rst_4.setimmediatevalue(1) await FallingEdge(self.dut.rst_250mhz) await Timer(100, 'ns') await RisingEdge(self.dut.clk_250mhz) await RisingEdge(self.dut.clk_250mhz) self.dut.qsfp0_rx_rst_1.setimmediatevalue(0) self.dut.qsfp0_tx_rst_1.setimmediatevalue(0) self.dut.qsfp0_rx_rst_2.setimmediatevalue(0) self.dut.qsfp0_tx_rst_2.setimmediatevalue(0) self.dut.qsfp0_rx_rst_3.setimmediatevalue(0) self.dut.qsfp0_tx_rst_3.setimmediatevalue(0) self.dut.qsfp0_rx_rst_4.setimmediatevalue(0) self.dut.qsfp0_tx_rst_4.setimmediatevalue(0) self.dut.qsfp1_rx_rst_1.setimmediatevalue(0) self.dut.qsfp1_tx_rst_1.setimmediatevalue(0) self.dut.qsfp1_rx_rst_2.setimmediatevalue(0) self.dut.qsfp1_tx_rst_2.setimmediatevalue(0) self.dut.qsfp1_rx_rst_3.setimmediatevalue(0) self.dut.qsfp1_tx_rst_3.setimmediatevalue(0) self.dut.qsfp1_rx_rst_4.setimmediatevalue(0) self.dut.qsfp1_tx_rst_4.setimmediatevalue(0) await self.rc.enumerate(enable_bus_mastering=True, configure_msi=True) async def _run_loopback(self): while True: await RisingEdge(self.dut.clk_250mhz) if self.loopback_enable: if not self.qsfp0_1_sink.empty(): await self.qsfp0_1_source.send(await self.qsfp0_1_sink.recv()) if not self.qsfp0_2_sink.empty(): await self.qsfp0_2_source.send(await self.qsfp0_2_sink.recv()) if not self.qsfp0_3_sink.empty(): await self.qsfp0_3_source.send(await self.qsfp0_3_sink.recv()) if not self.qsfp0_4_sink.empty(): await self.qsfp0_4_source.send(await self.qsfp0_4_sink.recv()) if not self.qsfp1_1_sink.empty(): await self.qsfp1_1_source.send(await self.qsfp1_1_sink.recv()) if not self.qsfp1_2_sink.empty(): await self.qsfp1_2_source.send(await self.qsfp1_2_sink.recv()) if not self.qsfp1_3_sink.empty(): await self.qsfp1_3_source.send(await self.qsfp1_3_sink.recv()) if not self.qsfp1_4_sink.empty(): await self.qsfp1_4_source.send(await self.qsfp1_4_sink.recv())