def nt_gen_replay_mem_read_test(dut): """Test bench main function.""" # open trace file trace = File("files/random.file") # get trace file size trace_size = trace.size() # trace file size must be a multiple of AXI data width if trace.size() % (AXI_BIT_WIDTH / 8) != 0: raise cocotb.result.TestFailure("invalid trace size") # calculate ring buffer sizes ring_buff_sizes = [] for ring_buff_size in RING_BUFF_SIZES: # size of ring buffer is determined by multiplying the size factor by # the size of the trace ring_buff_size = int(ring_buff_size * trace_size) # make sure that the ring buffer size is multiple of AXI data width if ring_buff_size % (AXI_BIT_WIDTH / 8) != 0: ring_buff_size += AXI_BIT_WIDTH/8 - ring_buff_size % \ (AXI_BIT_WIDTH/8) ring_buff_sizes.append(ring_buff_size) # create a ring buffer memory (initially of size 0) and connect it to the # DUT ring_buff = Mem(0) ring_buff.connect(dut) # start the clock cocotb.fork(clk_gen(dut.clk, CLK_FREQ_MHZ)) # deassert sw reset dut.rst_sw <= 0 # initially module start is not triggered dut.ctrl_start_i <= 0 # reset dut yield rstn(dut.clk, dut.rstn) # start the ring buffer memory main routine cocotb.fork(ring_buff.main()) # wait some more clock cycles yield wait_n_cycles(dut.clk, 5) # randomly toggle fifo_prog_full input signal dut.fifo_prog_full_i <= 0 cocotb.fork(toggle_signal(dut.clk, dut.fifo_prog_full_i)) # iterate over all ring buffer sizes for i, ring_buff_size in enumerate(ring_buff_sizes): # set ring buffer size ring_buff.set_size(ring_buff_size) # iterate over all adderesses where ring buffer shall be located in # memory for j, ring_buff_addr in enumerate(RING_BUFF_ADDRS): # print status print("Test %d/%d" % (i * len(RING_BUFF_ADDRS) + j + 1, len(RING_BUFF_ADDRS) * len(RING_BUFF_SIZES))) # we have a total of 8 GByte of memory. Make sure the ring buffer # fits at the desired address if ring_buff_addr + ring_buff_size > 0x1FFFFFFFF: raise cocotb.result.TestFailure("ring buffer is too large") # to reduce the simulation memory footprint, provide the memory # module the first memory address that we actually care about ring_buff.set_offset(ring_buff_addr) # apply ring buffer memory location to dut dut.ctrl_mem_addr_hi_i <= ring_buff_addr >> 32 dut.ctrl_mem_addr_lo_i <= ring_buff_addr & 0xFFFFFFFF # apply ring buffer address range to dut dut.ctrl_mem_range_i <= ring_buff_size - 1 # apply trace size to dut dut.ctrl_trace_size_hi_i <= trace_size >> 32 dut.ctrl_trace_size_lo_i <= trace_size & 0xFFFFFFFF # reset write address pointer dut.ctrl_addr_wr_i <= 0 # start reading from the ring buffer dut.ctrl_start_i <= 1 yield RisingEdge(dut.clk) dut.ctrl_start_i <= 0 yield RisingEdge(dut.clk) # start writing the ring buffer cocotb.fork(ring_buff_write(dut, ring_buff, trace)) # start checking dut output and wait until it completes yield cocotb.fork(check_output(dut, trace)).join() # clear the ring buffer contents ring_buff.clear() # close trace file trace.close()
def nt_gen_replay_top_test(dut): """Test bench main function.""" # start the clock cocotb.fork(clk_gen(dut.clk, CLK_FREQ_MHZ)) # no software reset dut.rst_sw <= 0 # reset dut yield rstn(dut.clk, dut.rstn) # open trace file trace = File("files/random.file") # get trace file size trace_size = trace.size() # trace file must be a multiple of the AXI data width if trace.size() % (AXI_MEM_BIT_WIDTH / 8) != 0: raise cocotb.result.TestFailure("invalid trace size") # calculate ring buffer sizes ring_buff_sizes = [] for ring_buff_size in RING_BUFF_SIZES: # size of ring buffer is determined by multiplying the size factor by # the size of the trace ring_buff_size = int(ring_buff_size * trace_size) # make sure that the ring buffer size is multiple of AXI data width if ring_buff_size % (AXI_MEM_BIT_WIDTH / 8) != 0: ring_buff_size += AXI_MEM_BIT_WIDTH/8 - \ ring_buff_size % (AXI_MEM_BIT_WIDTH/8) ring_buff_sizes.append(ring_buff_size) # create a ring buffer memory (initially of size 0) and connect it to the # DUT ring_buff = Mem(0) ring_buff.connect(dut, "ddr3") # create axi lite writer, connect and reset axi_lite_writer = AXI_Lite_Writer() axi_lite_writer.connect(dut, dut.clk, AXI_LITE_BIT_WIDTH, "ctrl") yield axi_lite_writer.rst() # create axi lite reader, connect and reset axi_lite_reader = AXI_Lite_Reader() axi_lite_reader.connect(dut, dut.clk, AXI_LITE_BIT_WIDTH, "ctrl") yield axi_lite_reader.rst() # create axi stream reader, connect and reset axis_reader = AXIS_Reader() axis_reader.connect(dut, dut.clk, AXIS_BIT_WIDTH) yield axis_reader.rst() # start the ring buffer memory main routine cocotb.fork(ring_buff.main()) # toggle m_axis_tready cocotb.fork(toggle_signal(dut.clk, dut.m_axis_tready)) # iterate over all ring buffer sizes for i, ring_buff_size in enumerate(ring_buff_sizes): # set ring buffer size ring_buff.set_size(ring_buff_size) # iterate over all addresses where ring buffer shall be located in # memory for j, ring_buff_addr in enumerate(RING_BUFF_ADDRS): # print status print("Test %d/%d" % (i * len(RING_BUFF_ADDRS) + j + 1, len(RING_BUFF_ADDRS) * len(RING_BUFF_SIZES))) print("Ring Buff Addr: 0x%x, Size: %d" % (ring_buff_addr, ring_buff_size)) # we have a total of 8 GByte of memory. Make sure the ring buffer # fits at the desired address if ring_buff_addr + ring_buff_size > 0x1FFFFFFFF: raise cocotb.result.TestFailure("ring buffer is too large") # to reduce the simulation memory footprint, provide the memory # module the first memory address that we acutally care about ring_buff.set_offset(ring_buff_addr) # configure ring buffer memory location yield axi_lite_writer.write(CPUREG_OFFSET_CTRL_MEM_ADDR_HI, ring_buff_addr >> 32) yield axi_lite_writer.write(CPUREG_OFFSET_CTRL_MEM_ADDR_LO, ring_buff_addr & 0xFFFFFFFF) # configure ring buffer address range yield axi_lite_writer.write(CPUREG_OFFSET_CTRL_MEM_RANGE, ring_buff_size - 1) # configure trace size yield axi_lite_writer.write(CPUREG_OFFSET_CTRL_TRACE_SIZE_HI, trace_size >> 32) yield axi_lite_writer.write(CPUREG_OFFSET_CTRL_TRACE_SIZE_LO, trace_size & 0xFFFFFFFF) # reset write address pointer yield axi_lite_writer.write(CPUREG_OFFSET_CTRL_ADDR_WR, 0x0) # make sure module initially is inactive status = yield axi_lite_reader.read(CPUREG_OFFSET_STATUS) if status & 0x3 != 0: raise cocotb.reset.TestFailure("module is active") # start the module yield axi_lite_writer.write(CPUREG_OFFSET_CTRL_START, 0x1) # wait a few cycles yield wait_n_cycles(dut.clk, 10) # start writing the ring buffer cocotb.fork( ring_buff_write(dut, ring_buff, trace, ring_buff_addr, axi_lite_reader, axi_lite_writer)) # start coroutine that checks dut output coroutine_chk_out = cocotb.fork( check_output(dut, trace, axis_reader)) # wait a few cycles and make sure module is active yield wait_n_cycles(dut.clk, 10) status = yield axi_lite_reader.read(CPUREG_OFFSET_STATUS) if status & 0x1 == 0x0: raise cocotb.result.TestFailure("mem read not active") if status & 0x2 == 0x0: raise cocotb.result.TestFailure("packet assembly not active") # wait for output check to complete yield coroutine_chk_out.join() # wait a few cycles yield wait_n_cycles(dut.clk, 10) # make sure module is now inactive status = yield axi_lite_reader.read(CPUREG_OFFSET_STATUS) if status & 0x3 != 0x0: raise cocotb.result.TestFailure("module does not become " + "inactive") # clear the ring buffer contents ring_buff.clear() # close the trace file trace.close()
def nt_recv_capture_mem_write_test(dut): """Test bench main function.""" # open file with random content try: f = File("files/random.file") except IOError: raise cocotb.result.TestFailure("Generate input data by calling " + "'./create_random.py' in 'files' " + "folder!") # file size must be a multiple of AXI data width if f.size() % (BIT_WIDTH_MEM_WRITE / 8) != 0: raise cocotb.result.TestFailure("invalid input data size") # create a ring buffer memory (initially of size 0) and connect it to the # DuT ring_buff = Mem(0) ring_buff.connect(dut) # start the clock cocotb.fork(clk_gen(dut.clk, CLK_FREQ_MHZ)) # deassert sw reset dut.rst_sw <= 0 # initially module is disabled dut.active_i <= 0 # initially no FIFO flush dut.flush_i <= 0 # reset DuT yield rstn(dut.clk, dut.rstn) # start the ring buffer memory main routine cocotb.fork(ring_buff.main()) # wait some more clock cycles yield wait_n_cycles(dut.clk, 5) # iterate over all ring buffer sizes for i, ring_buff_size in enumerate(RING_BUFF_SIZES): # set ring buffer size ring_buff.set_size(ring_buff_size) # iterate over all adderesses where ring buffer shall be located in # memory for j, ring_buff_addr in enumerate(RING_BUFF_ADDRS): # print status print("Test %d/%d" % (i * len(RING_BUFF_ADDRS) + j + 1, len(RING_BUFF_ADDRS) * len(RING_BUFF_SIZES))) # we have a total of 8 GByte of memory. Make sure the ring buffer # fits at the desired address if ring_buff_addr + ring_buff_size > 0x1FFFFFFFF: raise cocotb.result.TestFailure("ring buffer is too large") # to reduce the simulation memory footprint, provide the memory # module the first memory address that we actually care about ring_buff.set_offset(ring_buff_addr) # apply ring buffer memory location to dut dut.mem_addr_hi_i <= ring_buff_addr >> 32 dut.mem_addr_lo_i <= ring_buff_addr & 0xFFFFFFFF # apply ring buffer address range to dut dut.mem_range_i <= ring_buff_size - 1 # reset read address pointer dut.addr_rd_i <= 0 # start a couroutine that applies input data cocotb.fork(apply_input(dut, f)) # wait a few clock cycles yield wait_n_cycles(dut.clk, 10) # start the ring buffer read coroutine and wait until it completes yield ring_buff_read(dut, ring_buff, f) # clear the ring buffer contents ring_buff.clear() # close file f.close()