def bench(): # Parameters AXIS_PCIE_DATA_WIDTH = 256 AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH / 32) AXIS_PCIE_RC_USER_WIDTH = 75 AXIS_PCIE_RQ_USER_WIDTH = 60 RQ_SEQ_NUM_WIDTH = 4 if AXIS_PCIE_RQ_USER_WIDTH == 60 else 6 RQ_SEQ_NUM_ENABLE = 1 SEG_COUNT = max(2, int(AXIS_PCIE_DATA_WIDTH * 2 / 128)) SEG_DATA_WIDTH = AXIS_PCIE_DATA_WIDTH * 2 / SEG_COUNT SEG_ADDR_WIDTH = 12 SEG_BE_WIDTH = int(SEG_DATA_WIDTH / 8) RAM_SEL_WIDTH = 2 RAM_ADDR_WIDTH = SEG_ADDR_WIDTH + (SEG_COUNT - 1).bit_length() + ( SEG_BE_WIDTH - 1).bit_length() PCIE_ADDR_WIDTH = 64 PCIE_TAG_COUNT = 64 if AXIS_PCIE_RQ_USER_WIDTH == 60 else 256 PCIE_TAG_WIDTH = (PCIE_TAG_COUNT - 1).bit_length() PCIE_EXT_TAG_ENABLE = (PCIE_TAG_COUNT > 32) LEN_WIDTH = 16 TAG_WIDTH = 8 READ_OP_TABLE_SIZE = PCIE_TAG_COUNT READ_TX_LIMIT = 2**(RQ_SEQ_NUM_WIDTH - 1) WRITE_OP_TABLE_SIZE = 2**(RQ_SEQ_NUM_WIDTH - 1) WRITE_TX_LIMIT = 2**(RQ_SEQ_NUM_WIDTH - 1) # Inputs clk = Signal(bool(0)) rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) s_axis_rc_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) s_axis_rc_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) s_axis_rc_tvalid = Signal(bool(0)) s_axis_rc_tlast = Signal(bool(0)) s_axis_rc_tuser = Signal(intbv(0)[AXIS_PCIE_RC_USER_WIDTH:]) m_axis_rq_tready = Signal(bool(0)) s_axis_rq_seq_num_0 = Signal(intbv(0)[RQ_SEQ_NUM_WIDTH:]) s_axis_rq_seq_num_valid_0 = Signal(bool(0)) s_axis_rq_seq_num_1 = Signal(intbv(0)[RQ_SEQ_NUM_WIDTH:]) s_axis_rq_seq_num_valid_1 = Signal(bool(0)) s_axis_read_desc_pcie_addr = Signal(intbv(0)[PCIE_ADDR_WIDTH:]) s_axis_read_desc_ram_sel = Signal(intbv(0)[RAM_SEL_WIDTH:]) s_axis_read_desc_ram_addr = Signal(intbv(0)[RAM_ADDR_WIDTH:]) s_axis_read_desc_len = Signal(intbv(0)[LEN_WIDTH:]) s_axis_read_desc_tag = Signal(intbv(0)[TAG_WIDTH:]) s_axis_read_desc_valid = Signal(bool(0)) s_axis_write_desc_pcie_addr = Signal(intbv(0)[PCIE_ADDR_WIDTH:]) s_axis_write_desc_ram_sel = Signal(intbv(0)[RAM_SEL_WIDTH:]) s_axis_write_desc_ram_addr = Signal(intbv(0)[RAM_ADDR_WIDTH:]) s_axis_write_desc_len = Signal(intbv(0)[LEN_WIDTH:]) s_axis_write_desc_tag = Signal(intbv(0)[TAG_WIDTH:]) s_axis_write_desc_valid = Signal(bool(0)) ram_wr_cmd_ready = Signal(intbv(0)[SEG_COUNT:]) ram_rd_cmd_ready = Signal(intbv(0)[SEG_COUNT:]) ram_rd_resp_data = Signal(intbv(0)[SEG_COUNT * SEG_DATA_WIDTH:]) ram_rd_resp_valid = Signal(intbv(0)[SEG_COUNT:]) read_enable = Signal(bool(0)) write_enable = Signal(bool(0)) ext_tag_enable = Signal(bool(0)) requester_id = Signal(intbv(0)[16:]) requester_id_enable = Signal(bool(0)) max_read_request_size = Signal(intbv(0)[3:]) max_payload_size = Signal(intbv(0)[3:]) # Outputs s_axis_rc_tready = Signal(bool(0)) m_axis_rq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) m_axis_rq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) m_axis_rq_tvalid = Signal(bool(0)) m_axis_rq_tlast = Signal(bool(0)) m_axis_rq_tuser = Signal(intbv(0)[AXIS_PCIE_RQ_USER_WIDTH:]) s_axis_read_desc_ready = Signal(bool(0)) m_axis_read_desc_status_tag = Signal(intbv(0)[TAG_WIDTH:]) m_axis_read_desc_status_valid = Signal(bool(0)) s_axis_write_desc_ready = Signal(bool(0)) m_axis_write_desc_status_tag = Signal(intbv(0)[TAG_WIDTH:]) m_axis_write_desc_status_valid = Signal(bool(0)) ram_wr_cmd_sel = Signal(intbv(0)[SEG_COUNT * RAM_SEL_WIDTH:]) ram_wr_cmd_be = Signal(intbv(0)[SEG_COUNT * SEG_BE_WIDTH:]) ram_wr_cmd_addr = Signal(intbv(0)[SEG_COUNT * SEG_ADDR_WIDTH:]) ram_wr_cmd_data = Signal(intbv(0)[SEG_COUNT * SEG_DATA_WIDTH:]) ram_wr_cmd_valid = Signal(intbv(0)[SEG_COUNT:]) ram_rd_cmd_sel = Signal(intbv(0)[SEG_COUNT * RAM_SEL_WIDTH:]) ram_rd_cmd_addr = Signal(intbv(0)[SEG_COUNT * SEG_ADDR_WIDTH:]) ram_rd_cmd_valid = Signal(intbv(0)[SEG_COUNT:]) ram_rd_resp_ready = Signal(intbv(0)[SEG_COUNT:]) status_error_cor = Signal(bool(0)) status_error_uncor = Signal(bool(0)) # Clock and Reset Interface user_clk = Signal(bool(0)) user_reset = Signal(bool(0)) sys_clk = Signal(bool(0)) sys_reset = Signal(bool(0)) # PCIe DMA RAM dma_ram_inst = dma_ram.PSDPRam(2**16) dma_ram_pause = Signal(bool(0)) dma_ram_port0_wr = dma_ram_inst.create_write_ports( user_clk, ram_wr_cmd_be=ram_wr_cmd_be, ram_wr_cmd_addr=ram_wr_cmd_addr, ram_wr_cmd_data=ram_wr_cmd_data, ram_wr_cmd_valid=ram_wr_cmd_valid, ram_wr_cmd_ready=ram_wr_cmd_ready, pause=dma_ram_pause, name='port0_wr') dma_ram_port0_rd = dma_ram_inst.create_read_ports( user_clk, ram_rd_cmd_addr=ram_rd_cmd_addr, ram_rd_cmd_valid=ram_rd_cmd_valid, ram_rd_cmd_ready=ram_rd_cmd_ready, ram_rd_resp_data=ram_rd_resp_data, ram_rd_resp_valid=ram_rd_resp_valid, ram_rd_resp_ready=ram_rd_resp_ready, pause=dma_ram_pause, name='port0_rd') # sources and sinks read_desc_source = axis_ep.AXIStreamSource() read_desc_source_logic = read_desc_source.create_logic( user_clk, user_reset, tdata=(s_axis_read_desc_pcie_addr, s_axis_read_desc_ram_sel, s_axis_read_desc_ram_addr, s_axis_read_desc_len, s_axis_read_desc_tag), tvalid=s_axis_read_desc_valid, tready=s_axis_read_desc_ready, name='read_desc_source') read_desc_status_sink = axis_ep.AXIStreamSink() read_desc_status_sink_logic = read_desc_status_sink.create_logic( user_clk, user_reset, tdata=(m_axis_read_desc_status_tag, ), tvalid=m_axis_read_desc_status_valid, name='read_desc_status_sink') write_desc_source = axis_ep.AXIStreamSource() write_desc_source_logic = write_desc_source.create_logic( user_clk, user_reset, tdata=(s_axis_write_desc_pcie_addr, s_axis_write_desc_ram_sel, s_axis_write_desc_ram_addr, s_axis_write_desc_len, s_axis_write_desc_tag), tvalid=s_axis_write_desc_valid, tready=s_axis_write_desc_ready, name='write_desc_source') write_desc_status_sink = axis_ep.AXIStreamSink() write_desc_status_sink_logic = write_desc_status_sink.create_logic( user_clk, user_reset, tdata=(m_axis_write_desc_status_tag, ), tvalid=m_axis_write_desc_status_valid, name='write_desc_status_sink') # PCIe devices rc = pcie.RootComplex() mem_base, mem_data = rc.alloc_region(16 * 1024 * 1024) dev = pcie_us.UltrascalePCIe() dev.pcie_generation = 3 dev.pcie_link_width = 8 dev.user_clock_frequency = 256e6 rc.make_port().connect(dev) cq_pause = Signal(bool(0)) cc_pause = Signal(bool(0)) rq_pause = Signal(bool(0)) rc_pause = Signal(bool(0)) pcie_logic = dev.create_logic( # Completer reQuest Interface m_axis_cq_tdata=Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]), m_axis_cq_tuser=Signal(intbv(0)[85:]), m_axis_cq_tlast=Signal(bool(0)), m_axis_cq_tkeep=Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]), m_axis_cq_tvalid=Signal(bool(0)), m_axis_cq_tready=Signal(bool(1)), pcie_cq_np_req=Signal(bool(1)), pcie_cq_np_req_count=Signal(intbv(0)[6:]), # Completer Completion Interface s_axis_cc_tdata=Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]), s_axis_cc_tuser=Signal(intbv(0)[33:]), s_axis_cc_tlast=Signal(bool(0)), s_axis_cc_tkeep=Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]), s_axis_cc_tvalid=Signal(bool(0)), s_axis_cc_tready=Signal(bool(0)), # Requester reQuest Interface s_axis_rq_tdata=m_axis_rq_tdata, s_axis_rq_tuser=m_axis_rq_tuser, s_axis_rq_tlast=m_axis_rq_tlast, s_axis_rq_tkeep=m_axis_rq_tkeep, s_axis_rq_tvalid=m_axis_rq_tvalid, s_axis_rq_tready=m_axis_rq_tready, pcie_rq_seq_num=s_axis_rq_seq_num_0, pcie_rq_seq_num_vld=s_axis_rq_seq_num_valid_0, # pcie_rq_tag=pcie_rq_tag, # pcie_rq_tag_av=pcie_rq_tag_av, # pcie_rq_tag_vld=pcie_rq_tag_vld, # Requester Completion Interface m_axis_rc_tdata=s_axis_rc_tdata, m_axis_rc_tuser=s_axis_rc_tuser, m_axis_rc_tlast=s_axis_rc_tlast, m_axis_rc_tkeep=s_axis_rc_tkeep, m_axis_rc_tvalid=s_axis_rc_tvalid, m_axis_rc_tready=s_axis_rc_tready, # Transmit Flow Control Interface # pcie_tfc_nph_av=pcie_tfc_nph_av, # pcie_tfc_npd_av=pcie_tfc_npd_av, # Configuration Control Interface # cfg_hot_reset_in=cfg_hot_reset_in, # cfg_hot_reset_out=cfg_hot_reset_out, # cfg_config_space_enable=cfg_config_space_enable, # cfg_per_function_update_done=cfg_per_function_update_done, # cfg_per_function_number=cfg_per_function_number, # cfg_per_function_output_request=cfg_per_function_output_request, # cfg_dsn=cfg_dsn, # cfg_ds_bus_number=cfg_ds_bus_number, # cfg_ds_device_number=cfg_ds_device_number, # cfg_ds_function_number=cfg_ds_function_number, # cfg_power_state_change_ack=cfg_power_state_change_ack, # cfg_power_state_change_interrupt=cfg_power_state_change_interrupt, # cfg_err_cor_in=cfg_err_cor_in, # cfg_err_uncor_in=cfg_err_uncor_in, # cfg_flr_done=cfg_flr_done, # cfg_vf_flr_done=cfg_vf_flr_done, # cfg_flr_in_process=cfg_flr_in_process, # cfg_vf_flr_in_process=cfg_vf_flr_in_process, # cfg_req_pm_transition_l23_ready=cfg_req_pm_transition_l23_ready, # cfg_link_training_enable=cfg_link_training_enable, # Clock and Reset Interface user_clk=user_clk, user_reset=user_reset, #user_lnk_up=user_lnk_up, sys_clk=sys_clk, sys_clk_gt=sys_clk, sys_reset=sys_reset, cq_pause=cq_pause, cc_pause=cc_pause, rq_pause=rq_pause, rc_pause=rc_pause) # DUT if os.system(build_cmd): raise Exception("Error running build command") dut = Cosimulation( "vvp -m myhdl %s.vvp -lxt2" % testbench, clk=user_clk, rst=user_reset, current_test=current_test, s_axis_rc_tdata=s_axis_rc_tdata, s_axis_rc_tkeep=s_axis_rc_tkeep, s_axis_rc_tvalid=s_axis_rc_tvalid, s_axis_rc_tready=s_axis_rc_tready, s_axis_rc_tlast=s_axis_rc_tlast, s_axis_rc_tuser=s_axis_rc_tuser, m_axis_rq_tdata=m_axis_rq_tdata, m_axis_rq_tkeep=m_axis_rq_tkeep, m_axis_rq_tvalid=m_axis_rq_tvalid, m_axis_rq_tready=m_axis_rq_tready, m_axis_rq_tlast=m_axis_rq_tlast, m_axis_rq_tuser=m_axis_rq_tuser, s_axis_rq_seq_num_0=s_axis_rq_seq_num_0, s_axis_rq_seq_num_valid_0=s_axis_rq_seq_num_valid_0, s_axis_rq_seq_num_1=s_axis_rq_seq_num_1, s_axis_rq_seq_num_valid_1=s_axis_rq_seq_num_valid_1, s_axis_read_desc_pcie_addr=s_axis_read_desc_pcie_addr, s_axis_read_desc_ram_sel=s_axis_read_desc_ram_sel, s_axis_read_desc_ram_addr=s_axis_read_desc_ram_addr, s_axis_read_desc_len=s_axis_read_desc_len, s_axis_read_desc_tag=s_axis_read_desc_tag, s_axis_read_desc_valid=s_axis_read_desc_valid, s_axis_read_desc_ready=s_axis_read_desc_ready, m_axis_read_desc_status_tag=m_axis_read_desc_status_tag, m_axis_read_desc_status_valid=m_axis_read_desc_status_valid, s_axis_write_desc_pcie_addr=s_axis_write_desc_pcie_addr, s_axis_write_desc_ram_sel=s_axis_write_desc_ram_sel, s_axis_write_desc_ram_addr=s_axis_write_desc_ram_addr, s_axis_write_desc_len=s_axis_write_desc_len, s_axis_write_desc_tag=s_axis_write_desc_tag, s_axis_write_desc_valid=s_axis_write_desc_valid, s_axis_write_desc_ready=s_axis_write_desc_ready, m_axis_write_desc_status_tag=m_axis_write_desc_status_tag, m_axis_write_desc_status_valid=m_axis_write_desc_status_valid, ram_wr_cmd_sel=ram_wr_cmd_sel, ram_wr_cmd_be=ram_wr_cmd_be, ram_wr_cmd_addr=ram_wr_cmd_addr, ram_wr_cmd_data=ram_wr_cmd_data, ram_wr_cmd_valid=ram_wr_cmd_valid, ram_wr_cmd_ready=ram_wr_cmd_ready, ram_rd_cmd_sel=ram_rd_cmd_sel, ram_rd_cmd_addr=ram_rd_cmd_addr, ram_rd_cmd_valid=ram_rd_cmd_valid, ram_rd_cmd_ready=ram_rd_cmd_ready, ram_rd_resp_data=ram_rd_resp_data, ram_rd_resp_valid=ram_rd_resp_valid, ram_rd_resp_ready=ram_rd_resp_ready, read_enable=read_enable, write_enable=write_enable, ext_tag_enable=ext_tag_enable, requester_id=requester_id, requester_id_enable=requester_id_enable, max_read_request_size=max_read_request_size, max_payload_size=max_payload_size, status_error_cor=status_error_cor, status_error_uncor=status_error_uncor) @always(delay(4)) def clkgen(): clk.next = not clk @always_comb def clk_logic(): sys_clk.next = clk sys_reset.next = not rst @instance def check(): yield delay(100) yield clk.posedge rst.next = 1 yield clk.posedge rst.next = 0 yield clk.posedge yield delay(100) yield clk.posedge # testbench stimulus cur_tag = 1 max_payload_size.next = 0 max_read_request_size.next = 2 read_enable.next = 1 write_enable.next = 1 yield user_clk.posedge print("test 1: enumeration") current_test.next = 1 yield rc.enumerate(enable_bus_mastering=True) yield delay(100) yield user_clk.posedge print("test 2: PCIe write") current_test.next = 2 pcie_addr = 0x00000000 ram_addr = 0x00000000 test_data = b'\x11\x22\x33\x44' dma_ram_inst.write_mem(ram_addr, test_data) mem_data[pcie_addr:pcie_addr + len(test_data)] = b'\x00' * len(test_data) data = dma_ram_inst.read_mem(ram_addr, 32) for i in range(0, len(data), 16): print(" ".join( ("{:02x}".format(c) for c in bytearray(data[i:i + 16])))) write_desc_source.send([(mem_base + pcie_addr, 0, ram_addr, len(test_data), cur_tag)]) yield write_desc_status_sink.wait(1000) yield delay(50) status = write_desc_status_sink.recv() print(status) assert status.data[0][0] == cur_tag data = mem_data[pcie_addr:pcie_addr + 32] for i in range(0, len(data), 16): print(" ".join( ("{:02x}".format(c) for c in bytearray(data[i:i + 16])))) assert mem_data[pcie_addr:pcie_addr + len(test_data)] == test_data cur_tag = (cur_tag + 1) % 256 yield delay(100) yield user_clk.posedge print("test 3: PCIe read") current_test.next = 3 pcie_addr = 0x00000000 ram_addr = 0x00000000 test_data = b'\x11\x22\x33\x44' dma_ram_inst.write_mem(ram_addr, b'\x00' * len(test_data)) mem_data[pcie_addr:pcie_addr + len(test_data)] = test_data data = mem_data[pcie_addr:pcie_addr + 32] for i in range(0, len(data), 16): print(" ".join( ("{:02x}".format(c) for c in bytearray(data[i:i + 16])))) read_desc_source.send([(pcie_addr, 0, ram_addr, len(test_data), cur_tag)]) yield read_desc_status_sink.wait(2000) status = read_desc_status_sink.recv() print(status) assert status.data[0][0] == cur_tag data = dma_ram_inst.read_mem(ram_addr, 32) for i in range(0, len(data), 16): print(" ".join( ("{:02x}".format(c) for c in bytearray(data[i:i + 16])))) assert dma_ram_inst.read_mem(ram_addr, len(test_data)) == test_data cur_tag = (cur_tag + 1) % 256 yield delay(100) raise StopSimulation return instances()
def bench(): # Parameters SEG_COUNT = 4 SEG_DATA_WIDTH = 128 SEG_ADDR_WIDTH = 12 SEG_BE_WIDTH = int(SEG_DATA_WIDTH / 8) RAM_ADDR_WIDTH = SEG_ADDR_WIDTH + SEG_COUNT.bit_length( ) + SEG_BE_WIDTH.bit_length() AXIS_DATA_WIDTH = 64 AXIS_KEEP_ENABLE = (AXIS_DATA_WIDTH > 8) AXIS_KEEP_WIDTH = (AXIS_DATA_WIDTH / 8) AXIS_LAST_ENABLE = 1 AXIS_ID_ENABLE = 0 AXIS_ID_WIDTH = 8 AXIS_DEST_ENABLE = 0 AXIS_DEST_WIDTH = 8 AXIS_USER_ENABLE = 1 AXIS_USER_WIDTH = 1 LEN_WIDTH = 20 TAG_WIDTH = 8 # Inputs clk = Signal(bool(0)) rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) s_axis_write_desc_ram_addr = Signal(intbv(0)[RAM_ADDR_WIDTH:]) s_axis_write_desc_len = Signal(intbv(0)[LEN_WIDTH:]) s_axis_write_desc_tag = Signal(intbv(0)[TAG_WIDTH:]) s_axis_write_desc_valid = Signal(bool(0)) s_axis_write_data_tdata = Signal(intbv(0)[AXIS_DATA_WIDTH:]) s_axis_write_data_tkeep = Signal(intbv(0)[AXIS_KEEP_WIDTH:]) s_axis_write_data_tvalid = Signal(bool(0)) s_axis_write_data_tlast = Signal(bool(0)) s_axis_write_data_tid = Signal(intbv(0)[AXIS_ID_WIDTH:]) s_axis_write_data_tdest = Signal(intbv(0)[AXIS_DEST_WIDTH:]) s_axis_write_data_tuser = Signal(intbv(0)[AXIS_USER_WIDTH:]) ram_wr_cmd_ready = Signal(intbv(0)[SEG_COUNT:]) enable = Signal(bool(0)) abort = Signal(bool(0)) # Outputs s_axis_write_desc_ready = Signal(bool(0)) m_axis_write_desc_status_len = Signal(intbv(0)[LEN_WIDTH:]) m_axis_write_desc_status_tag = Signal(intbv(0)[TAG_WIDTH:]) m_axis_write_desc_status_id = Signal(intbv(0)[AXIS_ID_WIDTH:]) m_axis_write_desc_status_dest = Signal(intbv(0)[AXIS_DEST_WIDTH:]) m_axis_write_desc_status_user = Signal(intbv(0)[AXIS_USER_WIDTH:]) m_axis_write_desc_status_valid = Signal(bool(0)) s_axis_write_data_tready = Signal(bool(0)) ram_wr_cmd_be = Signal(intbv(0)[SEG_COUNT * SEG_BE_WIDTH:]) ram_wr_cmd_addr = Signal(intbv(0)[SEG_COUNT * SEG_ADDR_WIDTH:]) ram_wr_cmd_data = Signal(intbv(0)[SEG_COUNT * SEG_DATA_WIDTH:]) ram_wr_cmd_valid = Signal(intbv(0)[SEG_COUNT:]) # PCIe DMA RAM dma_ram_inst = dma_ram.PSDPRam(2**16) dma_ram_pause = Signal(bool(0)) dma_ram_port0 = dma_ram_inst.create_write_ports( clk, ram_wr_cmd_be=ram_wr_cmd_be, ram_wr_cmd_addr=ram_wr_cmd_addr, ram_wr_cmd_data=ram_wr_cmd_data, ram_wr_cmd_valid=ram_wr_cmd_valid, ram_wr_cmd_ready=ram_wr_cmd_ready, pause=dma_ram_pause, name='port0') # sources and sinks write_desc_source = axis_ep.AXIStreamSource() write_desc_source_pause = Signal(bool(False)) write_desc_source_logic = write_desc_source.create_logic( clk, rst, tdata=(s_axis_write_desc_ram_addr, s_axis_write_desc_len, s_axis_write_desc_tag), tvalid=s_axis_write_desc_valid, tready=s_axis_write_desc_ready, pause=write_desc_source_pause, name='write_desc_source') write_desc_status_sink = axis_ep.AXIStreamSink() write_desc_status_sink_logic = write_desc_status_sink.create_logic( clk, rst, tdata=(m_axis_write_desc_status_len, m_axis_write_desc_status_tag, m_axis_write_desc_status_id, m_axis_write_desc_status_dest, m_axis_write_desc_status_user), tvalid=m_axis_write_desc_status_valid, name='write_desc_status_sink') write_data_source = axis_ep.AXIStreamSource() write_data_source_pause = Signal(bool(False)) write_data_source_logic = write_data_source.create_logic( clk, rst, tdata=s_axis_write_data_tdata, tkeep=s_axis_write_data_tkeep, tvalid=s_axis_write_data_tvalid, tready=s_axis_write_data_tready, tlast=s_axis_write_data_tlast, tid=s_axis_write_data_tid, tdest=s_axis_write_data_tdest, tuser=s_axis_write_data_tuser, pause=write_data_source_pause, name='write_data_source') # DUT if os.system(build_cmd): raise Exception("Error running build command") dut = Cosimulation( "vvp -m myhdl %s.vvp -lxt2" % testbench, clk=clk, rst=rst, current_test=current_test, s_axis_write_desc_ram_addr=s_axis_write_desc_ram_addr, s_axis_write_desc_len=s_axis_write_desc_len, s_axis_write_desc_tag=s_axis_write_desc_tag, s_axis_write_desc_valid=s_axis_write_desc_valid, s_axis_write_desc_ready=s_axis_write_desc_ready, m_axis_write_desc_status_len=m_axis_write_desc_status_len, m_axis_write_desc_status_tag=m_axis_write_desc_status_tag, m_axis_write_desc_status_id=m_axis_write_desc_status_id, m_axis_write_desc_status_dest=m_axis_write_desc_status_dest, m_axis_write_desc_status_user=m_axis_write_desc_status_user, m_axis_write_desc_status_valid=m_axis_write_desc_status_valid, s_axis_write_data_tdata=s_axis_write_data_tdata, s_axis_write_data_tkeep=s_axis_write_data_tkeep, s_axis_write_data_tvalid=s_axis_write_data_tvalid, s_axis_write_data_tready=s_axis_write_data_tready, s_axis_write_data_tlast=s_axis_write_data_tlast, s_axis_write_data_tid=s_axis_write_data_tid, s_axis_write_data_tdest=s_axis_write_data_tdest, s_axis_write_data_tuser=s_axis_write_data_tuser, ram_wr_cmd_be=ram_wr_cmd_be, ram_wr_cmd_addr=ram_wr_cmd_addr, ram_wr_cmd_data=ram_wr_cmd_data, ram_wr_cmd_valid=ram_wr_cmd_valid, ram_wr_cmd_ready=ram_wr_cmd_ready, enable=enable, abort=abort) @always(delay(4)) def clkgen(): clk.next = not clk def wait_normal(): while write_desc_status_sink.empty(): yield clk.posedge def wait_pause_ram(): while write_desc_status_sink.empty(): dma_ram_pause.next = True yield clk.posedge yield clk.posedge yield clk.posedge dma_ram_pause.next = False yield clk.posedge def wait_pause_source(): while write_desc_status_sink.empty(): write_data_source_pause.next = True yield clk.posedge yield clk.posedge yield clk.posedge write_data_source_pause.next = False yield clk.posedge @instance def check(): yield delay(100) yield clk.posedge rst.next = 1 yield clk.posedge rst.next = 0 yield clk.posedge yield delay(100) yield clk.posedge # testbench stimulus cur_tag = 1 enable.next = 1 yield clk.posedge print("test 1: write") current_test.next = 1 addr = 0x00000000 test_data = b'\x11\x22\x33\x44' write_desc_source.send([(addr, len(test_data), cur_tag)]) write_data_source.send(axis_ep.AXIStreamFrame(test_data, id=cur_tag)) yield write_desc_status_sink.wait(2000) status = write_desc_status_sink.recv() print(status) assert status.data[0][0] == len(test_data) assert status.data[0][1] == cur_tag assert status.data[0][2] == cur_tag data = dma_ram_inst.read_mem(addr, 32) for i in range(0, len(data), 16): print(" ".join( ("{:02x}".format(c) for c in bytearray(data[i:i + 16])))) assert dma_ram_inst.read_mem(addr, len(test_data)) == test_data cur_tag = (cur_tag + 1) % 256 yield delay(100) yield clk.posedge print("test 2: various writes") current_test.next = 2 for length in list(range(1, 66)) + [128]: for offset in list(range(8, 65, 8)) + list( range(4096 - 64, 4096, 8)): for diff in [-16, -2, -1, 0, 1, 2, 16]: if length + diff < 1: continue for wait in wait_normal, wait_pause_ram, wait_pause_source: print("length %d, offset %d, diff %d" % (length, offset, diff)) #addr = length * 0x100000000 + offset * 0x10000 + offset addr = offset test_data = bytearray([x % 256 for x in range(length)]) test_data2 = bytearray( [x % 256 for x in range(length + diff)]) dma_ram_inst.write_mem( addr & 0xffff80, b'\xaa' * (len(test_data) + 256)) write_desc_source.send([(addr, len(test_data), cur_tag) ]) write_data_source.send( axis_ep.AXIStreamFrame(test_data2, id=cur_tag)) yield wait() yield clk.posedge yield clk.posedge status = write_desc_status_sink.recv() print(status) assert status.data[0][0] == min( len(test_data), len(test_data2)) assert status.data[0][1] == cur_tag assert status.data[0][2] == cur_tag data = dma_ram_inst.read_mem(addr & 0xfffff0, 64) for i in range(0, len(data), 16): print(" ".join( ("{:02x}".format(c) for c in bytearray(data[i:i + 16])))) if len(test_data) <= len(test_data2): assert dma_ram_inst.read_mem( addr - 8, len(test_data) + 16) == b'\xaa' * 8 + test_data + b'\xaa' * 8 else: assert dma_ram_inst.read_mem( addr - 8, len(test_data2) + 16) == b'\xaa' * 8 + test_data2 + b'\xaa' * 8 cur_tag = (cur_tag + 1) % 256 yield delay(100) raise StopSimulation return instances()
def bench(): # Parameters AXIS_PCIE_DATA_WIDTH = 512 AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH / 32) AXIS_PCIE_RQ_USER_WIDTH = 137 RQ_SEQ_NUM_WIDTH = 4 if AXIS_PCIE_RQ_USER_WIDTH == 60 else 6 RQ_SEQ_NUM_ENABLE = 1 SEG_COUNT = max(2, int(AXIS_PCIE_DATA_WIDTH * 2 / 128)) SEG_DATA_WIDTH = AXIS_PCIE_DATA_WIDTH * 2 / SEG_COUNT SEG_ADDR_WIDTH = 12 SEG_BE_WIDTH = int(SEG_DATA_WIDTH / 8) RAM_SEL_WIDTH = 2 RAM_ADDR_WIDTH = SEG_ADDR_WIDTH + (SEG_COUNT - 1).bit_length() + ( SEG_BE_WIDTH - 1).bit_length() PCIE_ADDR_WIDTH = 64 LEN_WIDTH = 16 TAG_WIDTH = 8 OP_TABLE_SIZE = 2**(RQ_SEQ_NUM_WIDTH - 1) TX_LIMIT = 2**(RQ_SEQ_NUM_WIDTH - 1) TX_FC_ENABLE = 1 # Inputs clk = Signal(bool(0)) rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) s_axis_rq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) s_axis_rq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) s_axis_rq_tvalid = Signal(bool(0)) s_axis_rq_tlast = Signal(bool(0)) s_axis_rq_tuser = Signal(intbv(0)[AXIS_PCIE_RQ_USER_WIDTH:]) m_axis_rq_tready = Signal(bool(0)) s_axis_rq_seq_num_0 = Signal(intbv(0)[RQ_SEQ_NUM_WIDTH:]) s_axis_rq_seq_num_valid_0 = Signal(bool(0)) s_axis_rq_seq_num_1 = Signal(intbv(0)[RQ_SEQ_NUM_WIDTH:]) s_axis_rq_seq_num_valid_1 = Signal(bool(0)) pcie_tx_fc_ph_av = Signal(intbv(0)[8:]) pcie_tx_fc_pd_av = Signal(intbv(0)[12:]) s_axis_write_desc_pcie_addr = Signal(intbv(0)[PCIE_ADDR_WIDTH:]) s_axis_write_desc_ram_sel = Signal(intbv(0)[RAM_SEL_WIDTH:]) s_axis_write_desc_ram_addr = Signal(intbv(0)[RAM_ADDR_WIDTH:]) s_axis_write_desc_len = Signal(intbv(0)[LEN_WIDTH:]) s_axis_write_desc_tag = Signal(intbv(0)[TAG_WIDTH:]) s_axis_write_desc_valid = Signal(bool(0)) ram_rd_cmd_ready = Signal(intbv(0)[SEG_COUNT:]) ram_rd_resp_data = Signal(intbv(0)[SEG_COUNT * SEG_DATA_WIDTH:]) ram_rd_resp_valid = Signal(intbv(0)[SEG_COUNT:]) enable = Signal(bool(0)) requester_id = Signal(intbv(0)[16:]) requester_id_enable = Signal(bool(0)) max_payload_size = Signal(intbv(0)[3:]) # Outputs s_axis_rq_tready = Signal(bool(0)) m_axis_rq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) m_axis_rq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) m_axis_rq_tvalid = Signal(bool(0)) m_axis_rq_tlast = Signal(bool(0)) m_axis_rq_tuser = Signal(intbv(0)[AXIS_PCIE_RQ_USER_WIDTH:]) m_axis_rq_seq_num_0 = Signal(intbv(0)[RQ_SEQ_NUM_WIDTH:]) m_axis_rq_seq_num_valid_0 = Signal(bool(0)) m_axis_rq_seq_num_1 = Signal(intbv(0)[RQ_SEQ_NUM_WIDTH:]) m_axis_rq_seq_num_valid_1 = Signal(bool(0)) s_axis_write_desc_ready = Signal(bool(0)) m_axis_write_desc_status_tag = Signal(intbv(0)[TAG_WIDTH:]) m_axis_write_desc_status_valid = Signal(bool(0)) ram_rd_cmd_sel = Signal(intbv(0)[SEG_COUNT * RAM_SEL_WIDTH:]) ram_rd_cmd_addr = Signal(intbv(0)[SEG_COUNT * SEG_ADDR_WIDTH:]) ram_rd_cmd_valid = Signal(intbv(0)[SEG_COUNT:]) ram_rd_resp_ready = Signal(intbv(0)[SEG_COUNT:]) # Clock and Reset Interface user_clk = Signal(bool(0)) user_reset = Signal(bool(0)) sys_clk = Signal(bool(0)) sys_reset = Signal(bool(0)) # PCIe DMA RAM dma_ram_inst = dma_ram.PSDPRam(2**16) dma_ram_pause = Signal(bool(0)) dma_ram_port0 = dma_ram_inst.create_read_ports( user_clk, ram_rd_cmd_addr=ram_rd_cmd_addr, ram_rd_cmd_valid=ram_rd_cmd_valid, ram_rd_cmd_ready=ram_rd_cmd_ready, ram_rd_resp_data=ram_rd_resp_data, ram_rd_resp_valid=ram_rd_resp_valid, ram_rd_resp_ready=ram_rd_resp_ready, pause=dma_ram_pause, name='port0') # sources and sinks write_desc_source = axis_ep.AXIStreamSource() write_desc_source_logic = write_desc_source.create_logic( user_clk, user_reset, tdata=(s_axis_write_desc_pcie_addr, s_axis_write_desc_ram_sel, s_axis_write_desc_ram_addr, s_axis_write_desc_len, s_axis_write_desc_tag), tvalid=s_axis_write_desc_valid, tready=s_axis_write_desc_ready, name='write_desc_source') write_desc_status_sink = axis_ep.AXIStreamSink() write_desc_status_sink_logic = write_desc_status_sink.create_logic( user_clk, user_reset, tdata=(m_axis_write_desc_status_tag, ), tvalid=m_axis_write_desc_status_valid, name='write_desc_status_sink') # PCIe devices rc = pcie.RootComplex() mem_base, mem_data = rc.alloc_region(16 * 1024 * 1024) dev = pcie_usp.UltrascalePlusPCIe() dev.pcie_generation = 3 dev.pcie_link_width = 16 dev.user_clock_frequency = 256e6 rc.make_port().connect(dev) cq_pause = Signal(bool(0)) cc_pause = Signal(bool(0)) rq_pause = Signal(bool(0)) rc_pause = Signal(bool(0)) pcie_logic = dev.create_logic( # Completer reQuest Interface m_axis_cq_tdata=Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]), m_axis_cq_tuser=Signal(intbv(0)[183:]), m_axis_cq_tlast=Signal(bool(0)), m_axis_cq_tkeep=Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]), m_axis_cq_tvalid=Signal(bool(0)), m_axis_cq_tready=Signal(bool(1)), pcie_cq_np_req=Signal(intbv(3)[2:]), pcie_cq_np_req_count=Signal(intbv(0)[6:]), # Completer Completion Interface s_axis_cc_tdata=Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]), s_axis_cc_tuser=Signal(intbv(0)[81:]), s_axis_cc_tlast=Signal(bool(0)), s_axis_cc_tkeep=Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]), s_axis_cc_tvalid=Signal(bool(0)), s_axis_cc_tready=Signal(bool(0)), # Requester reQuest Interface s_axis_rq_tdata=m_axis_rq_tdata, s_axis_rq_tuser=m_axis_rq_tuser, s_axis_rq_tlast=m_axis_rq_tlast, s_axis_rq_tkeep=m_axis_rq_tkeep, s_axis_rq_tvalid=m_axis_rq_tvalid, s_axis_rq_tready=m_axis_rq_tready, pcie_rq_seq_num0=s_axis_rq_seq_num_0, pcie_rq_seq_num_vld0=s_axis_rq_seq_num_valid_0, pcie_rq_seq_num1=s_axis_rq_seq_num_1, pcie_rq_seq_num_vld1=s_axis_rq_seq_num_valid_1, # pcie_rq_tag0=pcie_rq_tag0, # pcie_rq_tag1=pcie_rq_tag1, # pcie_rq_tag_av=pcie_rq_tag_av, # pcie_rq_tag_vld0=pcie_rq_tag_vld0, # pcie_rq_tag_vld1=pcie_rq_tag_vld1, # Requester Completion Interface m_axis_rc_tdata=Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]), m_axis_rc_tuser=Signal(intbv(0)[161:]), m_axis_rc_tlast=Signal(bool(0)), m_axis_rc_tkeep=Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]), m_axis_rc_tvalid=Signal(bool(0)), m_axis_rc_tready=Signal(bool(0)), # Transmit Flow Control Interface # pcie_tfc_nph_av=pcie_tfc_nph_av, # pcie_tfc_npd_av=pcie_tfc_npd_av, # Configuration Flow Control Interface cfg_fc_ph=pcie_tx_fc_ph_av, cfg_fc_pd=pcie_tx_fc_pd_av, #cfg_fc_nph=cfg_fc_nph, #cfg_fc_npd=cfg_fc_npd, #cfg_fc_cplh=cfg_fc_cplh, #cfg_fc_cpld=cfg_fc_cpld, cfg_fc_sel=Signal(intbv(0b100)[3:]), # Configuration Control Interface # cfg_hot_reset_in=cfg_hot_reset_in, # cfg_hot_reset_out=cfg_hot_reset_out, # cfg_config_space_enable=cfg_config_space_enable, # cfg_dsn=cfg_dsn, # cfg_ds_port_number=cfg_ds_port_number, # cfg_ds_bus_number=cfg_ds_bus_number, # cfg_ds_device_number=cfg_ds_device_number, # cfg_ds_function_number=cfg_ds_function_number, # cfg_power_state_change_ack=cfg_power_state_change_ack, # cfg_power_state_change_interrupt=cfg_power_state_change_interrupt, # cfg_err_cor_in=cfg_err_cor_in, # cfg_err_uncor_in=cfg_err_uncor_in, # cfg_flr_done=cfg_flr_done, # cfg_vf_flr_done=cfg_vf_flr_done, # cfg_flr_in_process=cfg_flr_in_process, # cfg_vf_flr_in_process=cfg_vf_flr_in_process, # cfg_req_pm_transition_l23_ready=cfg_req_pm_transition_l23_ready, # cfg_link_training_enable=cfg_link_training_enable, # Clock and Reset Interface user_clk=user_clk, user_reset=user_reset, #user_lnk_up=user_lnk_up, sys_clk=sys_clk, sys_clk_gt=sys_clk, sys_reset=sys_reset, cq_pause=cq_pause, cc_pause=cc_pause, rq_pause=rq_pause, rc_pause=rc_pause) # DUT if os.system(build_cmd): raise Exception("Error running build command") dut = Cosimulation( "vvp -m myhdl %s.vvp -lxt2" % testbench, clk=user_clk, rst=user_reset, current_test=current_test, s_axis_rq_tdata=s_axis_rq_tdata, s_axis_rq_tkeep=s_axis_rq_tkeep, s_axis_rq_tvalid=s_axis_rq_tvalid, s_axis_rq_tready=s_axis_rq_tready, s_axis_rq_tlast=s_axis_rq_tlast, s_axis_rq_tuser=s_axis_rq_tuser, m_axis_rq_tdata=m_axis_rq_tdata, m_axis_rq_tkeep=m_axis_rq_tkeep, m_axis_rq_tvalid=m_axis_rq_tvalid, m_axis_rq_tready=m_axis_rq_tready, m_axis_rq_tlast=m_axis_rq_tlast, m_axis_rq_tuser=m_axis_rq_tuser, s_axis_rq_seq_num_0=s_axis_rq_seq_num_0, s_axis_rq_seq_num_valid_0=s_axis_rq_seq_num_valid_0, s_axis_rq_seq_num_1=s_axis_rq_seq_num_1, s_axis_rq_seq_num_valid_1=s_axis_rq_seq_num_valid_1, m_axis_rq_seq_num_0=m_axis_rq_seq_num_0, m_axis_rq_seq_num_valid_0=m_axis_rq_seq_num_valid_0, m_axis_rq_seq_num_1=m_axis_rq_seq_num_1, m_axis_rq_seq_num_valid_1=m_axis_rq_seq_num_valid_1, pcie_tx_fc_ph_av=pcie_tx_fc_ph_av, pcie_tx_fc_pd_av=pcie_tx_fc_pd_av, s_axis_write_desc_pcie_addr=s_axis_write_desc_pcie_addr, s_axis_write_desc_ram_sel=s_axis_write_desc_ram_sel, s_axis_write_desc_ram_addr=s_axis_write_desc_ram_addr, s_axis_write_desc_len=s_axis_write_desc_len, s_axis_write_desc_tag=s_axis_write_desc_tag, s_axis_write_desc_valid=s_axis_write_desc_valid, s_axis_write_desc_ready=s_axis_write_desc_ready, m_axis_write_desc_status_tag=m_axis_write_desc_status_tag, m_axis_write_desc_status_valid=m_axis_write_desc_status_valid, ram_rd_cmd_sel=ram_rd_cmd_sel, ram_rd_cmd_addr=ram_rd_cmd_addr, ram_rd_cmd_valid=ram_rd_cmd_valid, ram_rd_cmd_ready=ram_rd_cmd_ready, ram_rd_resp_data=ram_rd_resp_data, ram_rd_resp_valid=ram_rd_resp_valid, ram_rd_resp_ready=ram_rd_resp_ready, enable=enable, requester_id=requester_id, requester_id_enable=requester_id_enable, max_payload_size=max_payload_size) @always(delay(4)) def clkgen(): clk.next = not clk @always_comb def clk_logic(): sys_clk.next = clk sys_reset.next = not rst cq_pause_toggle = Signal(bool(0)) cc_pause_toggle = Signal(bool(0)) rq_pause_toggle = Signal(bool(0)) rc_pause_toggle = Signal(bool(0)) @instance def pause_toggle(): while True: if (cq_pause_toggle or cc_pause_toggle or rq_pause_toggle or rc_pause_toggle): cq_pause.next = cq_pause_toggle cc_pause.next = cc_pause_toggle rq_pause.next = rq_pause_toggle rc_pause.next = rc_pause_toggle yield user_clk.posedge yield user_clk.posedge yield user_clk.posedge cq_pause.next = 0 cc_pause.next = 0 rq_pause.next = 0 rc_pause.next = 0 yield user_clk.posedge @instance def check(): yield delay(100) yield clk.posedge rst.next = 1 yield clk.posedge rst.next = 0 yield clk.posedge yield delay(100) yield clk.posedge # testbench stimulus cur_tag = 1 max_payload_size.next = 0 enable.next = 1 yield user_clk.posedge print("test 1: enumeration") current_test.next = 1 yield rc.enumerate(enable_bus_mastering=True) yield delay(100) yield user_clk.posedge print("test 2: PCIe write") current_test.next = 2 pcie_addr = 0x00000000 ram_addr = 0x00000000 test_data = b'\x11\x22\x33\x44' dma_ram_inst.write_mem(ram_addr, test_data) data = dma_ram_inst.read_mem(ram_addr, 32) for i in range(0, len(data), 16): print(" ".join( ("{:02x}".format(c) for c in bytearray(data[i:i + 16])))) write_desc_source.send([(mem_base + pcie_addr, 0, ram_addr, len(test_data), cur_tag)]) yield write_desc_status_sink.wait(1000) yield delay(50) status = write_desc_status_sink.recv() print(status) assert status.data[0][0] == cur_tag data = mem_data[pcie_addr:pcie_addr + 32] for i in range(0, len(data), 16): print(" ".join( ("{:02x}".format(c) for c in bytearray(data[i:i + 16])))) assert mem_data[pcie_addr:pcie_addr + len(test_data)] == test_data cur_tag = (cur_tag + 1) % 256 yield delay(100) yield user_clk.posedge print("test 3: various writes") current_test.next = 3 for length in list(range(1, 67)) + list(range(128 - 4, 128 + 4)) + [1024]: for pcie_offset in list(range(8, 13)) + list( range(4096 - 4, 4096 + 4)): for ram_offset in list(range(8, 137)) + list( range(4096 - 128, 4096)): for pause in [False, True]: print("length %d, pcie_offset %d, ram_offset %d" % (length, pcie_offset, ram_offset)) #pcie_addr = length * 0x100000000 + pcie_offset * 0x10000 + offset pcie_addr = pcie_offset ram_addr = ram_offset test_data = bytearray([x % 256 for x in range(length)]) dma_ram_inst.write_mem( ram_addr & 0xffff80, b'\x55' * (len(test_data) + 256)) mem_data[(pcie_addr - 1) & 0xffff80:((pcie_addr - 1) & 0xffff80) + len(test_data) + 256] = b'\xaa' * (len(test_data) + 256) dma_ram_inst.write_mem(ram_addr, test_data) data = dma_ram_inst.read_mem(ram_addr & 0xfffff0, 64) for i in range(0, len(data), 16): print(" ".join( ("{:02x}".format(c) for c in bytearray(data[i:i + 16])))) rq_pause_toggle.next = pause write_desc_source.send([ (mem_base + pcie_addr, 0, ram_addr, len(test_data), cur_tag) ]) yield write_desc_status_sink.wait(4000) yield delay(50) rq_pause_toggle.next = 0 status = write_desc_status_sink.recv() print(status) assert status.data[0][0] == cur_tag data = mem_data[pcie_addr & 0xfffff0:(pcie_addr & 0xfffff0) + 64] for i in range(0, len(data), 16): print(" ".join( ("{:02x}".format(c) for c in bytearray(data[i:i + 16])))) print(mem_data[pcie_addr - 1:pcie_addr + len(test_data) + 1]) assert mem_data[pcie_addr - 1:pcie_addr + len(test_data) + 1] == b'\xaa' + test_data + b'\xaa' cur_tag = (cur_tag + 1) % 256 yield delay(100) raise StopSimulation return instances()
def bench(): # Parameters SEG_COUNT = 2 SEG_DATA_WIDTH = 64 SEG_ADDR_WIDTH = 12 SEG_BE_WIDTH = int(SEG_DATA_WIDTH / 8) RAM_ADDR_WIDTH = SEG_ADDR_WIDTH + (SEG_COUNT - 1).bit_length() + ( SEG_BE_WIDTH - 1).bit_length() AXIS_DATA_WIDTH = SEG_DATA_WIDTH * SEG_COUNT / 2 AXIS_KEEP_ENABLE = (AXIS_DATA_WIDTH > 8) AXIS_KEEP_WIDTH = (AXIS_DATA_WIDTH / 8) AXIS_LAST_ENABLE = 1 AXIS_ID_ENABLE = 1 AXIS_ID_WIDTH = 8 AXIS_DEST_ENABLE = 0 AXIS_DEST_WIDTH = 8 AXIS_USER_ENABLE = 1 AXIS_USER_WIDTH = 1 LEN_WIDTH = 20 TAG_WIDTH = 8 # Inputs clk = Signal(bool(0)) rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) s_axis_read_desc_ram_addr = Signal(intbv(0)[RAM_ADDR_WIDTH:]) s_axis_read_desc_len = Signal(intbv(0)[LEN_WIDTH:]) s_axis_read_desc_tag = Signal(intbv(0)[TAG_WIDTH:]) s_axis_read_desc_id = Signal(intbv(0)[AXIS_ID_WIDTH:]) s_axis_read_desc_dest = Signal(intbv(0)[AXIS_DEST_WIDTH:]) s_axis_read_desc_user = Signal(intbv(0)[AXIS_USER_WIDTH:]) s_axis_read_desc_valid = Signal(bool(0)) m_axis_read_data_tready = Signal(bool(0)) ram_rd_cmd_ready = Signal(intbv(0)[SEG_COUNT:]) ram_rd_resp_data = Signal(intbv(0)[SEG_COUNT * SEG_DATA_WIDTH:]) ram_rd_resp_valid = Signal(intbv(0)[SEG_COUNT:]) enable = Signal(bool(0)) # Outputs s_axis_read_desc_ready = Signal(bool(0)) m_axis_read_desc_status_tag = Signal(intbv(0)[TAG_WIDTH:]) m_axis_read_desc_status_valid = Signal(bool(0)) m_axis_read_data_tdata = Signal(intbv(0)[AXIS_DATA_WIDTH:]) m_axis_read_data_tkeep = Signal(intbv(0)[AXIS_KEEP_WIDTH:]) m_axis_read_data_tvalid = Signal(bool(0)) m_axis_read_data_tlast = Signal(bool(0)) m_axis_read_data_tid = Signal(intbv(0)[AXIS_ID_WIDTH:]) m_axis_read_data_tdest = Signal(intbv(0)[AXIS_DEST_WIDTH:]) m_axis_read_data_tuser = Signal(intbv(0)[AXIS_USER_WIDTH:]) ram_rd_cmd_addr = Signal(intbv(0)[SEG_COUNT * SEG_ADDR_WIDTH:]) ram_rd_cmd_valid = Signal(intbv(0)[SEG_COUNT:]) ram_rd_resp_ready = Signal(intbv(0)[SEG_COUNT:]) # PCIe DMA RAM dma_ram_inst = dma_ram.PSDPRam(2**16) dma_ram_pause = Signal(bool(0)) dma_ram_port0 = dma_ram_inst.create_read_ports( clk, ram_rd_cmd_addr=ram_rd_cmd_addr, ram_rd_cmd_valid=ram_rd_cmd_valid, ram_rd_cmd_ready=ram_rd_cmd_ready, ram_rd_resp_data=ram_rd_resp_data, ram_rd_resp_valid=ram_rd_resp_valid, ram_rd_resp_ready=ram_rd_resp_ready, pause=dma_ram_pause, name='port0') # sources and sinks read_desc_source = axis_ep.AXIStreamSource() read_desc_source_pause = Signal(bool(False)) read_desc_source_logic = read_desc_source.create_logic( clk, rst, tdata=(s_axis_read_desc_ram_addr, s_axis_read_desc_len, s_axis_read_desc_tag, s_axis_read_desc_id, s_axis_read_desc_dest, s_axis_read_desc_user), tvalid=s_axis_read_desc_valid, tready=s_axis_read_desc_ready, pause=read_desc_source_pause, name='read_desc_source') read_desc_status_sink = axis_ep.AXIStreamSink() read_desc_status_sink_logic = read_desc_status_sink.create_logic( clk, rst, tdata=(m_axis_read_desc_status_tag, ), tvalid=m_axis_read_desc_status_valid, name='read_desc_status_sink') read_data_sink = axis_ep.AXIStreamSink() read_data_sink_pause = Signal(bool(False)) read_data_sink_logic = read_data_sink.create_logic( clk, rst, tdata=m_axis_read_data_tdata, tkeep=m_axis_read_data_tkeep, tvalid=m_axis_read_data_tvalid, tready=m_axis_read_data_tready, tlast=m_axis_read_data_tlast, tid=m_axis_read_data_tid, tdest=m_axis_read_data_tdest, tuser=m_axis_read_data_tuser, pause=read_data_sink_pause, name='read_data_sink') # DUT if os.system(build_cmd): raise Exception("Error running build command") dut = Cosimulation( "vvp -m myhdl %s.vvp -lxt2" % testbench, clk=clk, rst=rst, current_test=current_test, s_axis_read_desc_ram_addr=s_axis_read_desc_ram_addr, s_axis_read_desc_len=s_axis_read_desc_len, s_axis_read_desc_tag=s_axis_read_desc_tag, s_axis_read_desc_id=s_axis_read_desc_id, s_axis_read_desc_dest=s_axis_read_desc_dest, s_axis_read_desc_user=s_axis_read_desc_user, s_axis_read_desc_valid=s_axis_read_desc_valid, s_axis_read_desc_ready=s_axis_read_desc_ready, m_axis_read_desc_status_tag=m_axis_read_desc_status_tag, m_axis_read_desc_status_valid=m_axis_read_desc_status_valid, m_axis_read_data_tdata=m_axis_read_data_tdata, m_axis_read_data_tkeep=m_axis_read_data_tkeep, m_axis_read_data_tvalid=m_axis_read_data_tvalid, m_axis_read_data_tready=m_axis_read_data_tready, m_axis_read_data_tlast=m_axis_read_data_tlast, m_axis_read_data_tid=m_axis_read_data_tid, m_axis_read_data_tdest=m_axis_read_data_tdest, m_axis_read_data_tuser=m_axis_read_data_tuser, ram_rd_cmd_addr=ram_rd_cmd_addr, ram_rd_cmd_valid=ram_rd_cmd_valid, ram_rd_cmd_ready=ram_rd_cmd_ready, ram_rd_resp_data=ram_rd_resp_data, ram_rd_resp_valid=ram_rd_resp_valid, ram_rd_resp_ready=ram_rd_resp_ready, enable=enable) @always(delay(4)) def clkgen(): clk.next = not clk def wait_normal(): while read_desc_status_sink.empty() or read_data_sink.empty(): yield clk.posedge def wait_pause_ram(): while read_desc_status_sink.empty() or read_data_sink.empty(): dma_ram_pause.next = True yield clk.posedge yield clk.posedge yield clk.posedge dma_ram_pause.next = False yield clk.posedge def wait_pause_sink(): while read_desc_status_sink.empty() or read_data_sink.empty(): read_data_sink_pause.next = True yield clk.posedge yield clk.posedge yield clk.posedge read_data_sink_pause.next = False yield clk.posedge @instance def check(): yield delay(100) yield clk.posedge rst.next = 1 yield clk.posedge rst.next = 0 yield clk.posedge yield delay(100) yield clk.posedge # testbench stimulus cur_tag = 1 enable.next = 1 yield clk.posedge print("test 1: read") current_test.next = 1 addr = 0x00000000 test_data = b'\x11\x22\x33\x44' dma_ram_inst.write_mem(addr, test_data) data = dma_ram_inst.read_mem(addr, 32) for i in range(0, len(data), 16): print(" ".join( ("{:02x}".format(c) for c in bytearray(data[i:i + 16])))) read_desc_source.send([(addr, len(test_data), cur_tag, cur_tag, 0, 0)]) yield read_desc_status_sink.wait(1000) yield read_data_sink.wait(1000) status = read_desc_status_sink.recv() read_data = read_data_sink.recv() print(status) print(read_data) assert status.data[0][0] == cur_tag assert read_data.data == test_data assert read_data.id[0] == cur_tag cur_tag = (cur_tag + 1) % 256 yield delay(100) yield clk.posedge print("test 2: various reads") current_test.next = 2 for length in list(range(1, 34)) + [128]: for offset in list(range(8, 17, 8)) + list(range( 4096 - 8, 4096, 8)): for wait in wait_normal, wait_pause_ram, wait_pause_sink: print("length %d, offset %d" % (length, offset)) #addr = length * 0x100000000 + offset * 0x10000 + offset addr = offset test_data = bytearray([x % 256 for x in range(length)]) dma_ram_inst.write_mem(addr & 0xffff80, b'\xaa' * (len(test_data) + 256)) dma_ram_inst.write_mem(addr, test_data) data = dma_ram_inst.read_mem(addr & 0xfffff0, 64) for i in range(0, len(data), 16): print(" ".join(("{:02x}".format(c) for c in bytearray(data[i:i + 16])))) read_desc_source.send([(addr, len(test_data), cur_tag, cur_tag, 0, 0)]) yield wait() status = read_desc_status_sink.recv() read_data = read_data_sink.recv() print(status) print(read_data) assert status.data[0][0] == cur_tag assert read_data.data == test_data assert read_data.id[0] == cur_tag cur_tag = (cur_tag + 1) % 256 yield delay(100) raise StopSimulation return instances()