def test_input_arbiter(dut): """Test to make sure that input_arbiter module is working properly. """ # start HW sim clock cocotb.fork(Clock(dut.axis_aclk, PERIOD).start()) yield reset_dut(dut) yield ClockCycles(dut.axis_aclk, START_DELAY) # create the pkts and metadata pkts_in_0, meta_in_0 = make_pkts_meta_in(0) pkts_in_1, meta_in_1 = make_pkts_meta_in(1) pkts_in_2, meta_in_2 = make_pkts_meta_in(2) # Attach an AXI4Stream Master to the input pkt interface pkt_master_0 = AXI4StreamMaster(dut, 's_axis_0', dut.axis_aclk) pkt_master_1 = AXI4StreamMaster(dut, 's_axis_1', dut.axis_aclk) pkt_master_2 = AXI4StreamMaster(dut, 's_axis_2', dut.axis_aclk) # Attach an AXI4StreamSlave to the output pkt interface pkt_slave = AXI4StreamSlave(dut, 'm_axis', dut.axis_aclk, tready_delay=BP_COUNT, idle_timeout=IDLE_TIMEOUT) # start reading for pkts pkt_slave_thread = cocotb.fork( pkt_slave.read_n_pkts(3 * len(pkts_in_0), log_raw=True)) # Send pkts and metadata in the HW sim rate = 1.0 * INGRESS_LINK_RATE * 5 / 8.0 # bytes/cycle pkt_master_thread_0 = cocotb.fork( pkt_master_0.write_pkts(pkts_in_0, meta_in_0, rate=rate)) pkt_master_thread_1 = cocotb.fork( pkt_master_1.write_pkts(pkts_in_1, meta_in_1, rate=rate)) pkt_master_thread_2 = cocotb.fork( pkt_master_2.write_pkts(pkts_in_2, meta_in_2, rate=rate)) yield pkt_master_thread_0.join() yield pkt_master_thread_1.join() yield pkt_master_thread_2.join() # Wait for the pkt_slave to finish (or timeout) yield pkt_slave_thread.join() pkts_out = pkt_slave.pkts meta_out = pkt_slave.metadata yield ClockCycles(dut.axis_aclk, 20) print 'len(pkts_out) = {}'.format(len(pkts_out))
def test_event_merger(dut): """Test to make sure that event_merger module is working properly. """ # start HW sim clock cocotb.fork(Clock(dut.axis_aclk, PERIOD).start()) yield reset_dut(dut) yield ClockCycles(dut.axis_aclk, START_DELAY) # read the pkts and rank values pkts_in, meta_in = make_pkts_meta_in() # Attach an AXI4Stream Master to the input pkt interface pkt_master = AXI4StreamMaster(dut, 's_axis', dut.axis_aclk) # # Attach an AXI4StreamSlave to the output pkt interface # pkt_slave = AXI4StreamSlave(dut, 'm_axis', dut.axis_aclk, tready_delay=BP_COUNT, idle_timeout=IDLE_TIMEOUT) # # start reading for pkts # pkt_slave_thread = cocotb.fork(pkt_slave.read_n_pkts(len(pkts_in), log_raw=True)) # Send pkts and metadata in the HW sim rate = 1.0 * INGRESS_LINK_RATE * 5 / 8.0 # bytes/cycle pkt_master_thread = cocotb.fork( pkt_master.write_pkts(pkts_in, meta_in, rate=rate)) yield pkt_master_thread.join() # # Wait for the pkt_slave to finish (or timeout) # yield pkt_slave_thread.join() # pkts_out = pkt_slave.pkts # meta_out = pkt_slave.metadata yield ClockCycles(dut.axis_aclk, 100)
def test_axi_stream_fifo(dut): """Test to make sure that axi_stream_fifo is working properly. """ # start HW sim clock cocotb.fork(Clock(dut.axis_aclk, PERIOD).start()) yield reset_dut(dut) yield ClockCycles(dut.axis_aclk, START_DELAY) # read the pkts and rank values pkts_in, meta_in = make_pkts_meta_in() # Attach an AXI4Stream Master to the input pkt interface pkt_master = AXI4StreamMaster(dut, 's_axis', dut.axis_aclk) # Attach an AXI4StreamSlave to the output pkt interface pkt_slave = AXI4StreamSlave(dut, 'm_axis', dut.axis_aclk, tready_delay=BP_COUNT, idle_timeout=IDLE_TIMEOUT) # start reading for pkts pkt_slave_thread = cocotb.fork(pkt_slave.read_n_pkts(len(pkts_in), log_raw=True)) # Send pkts and metadata in the HW sim rate = 1.0*INGRESS_LINK_RATE*5/8.0 # bytes/cycle pkt_master_thread = cocotb.fork(pkt_master.write_pkts(pkts_in, meta_in, rate=rate)) yield pkt_master_thread.join() # Wait for the pkt_slave to finish (or timeout) yield pkt_slave_thread.join() pkts_out = pkt_slave.pkts meta_out = pkt_slave.metadata # ranks_out = [Metadata(m.get_buff()).rank for m in meta_out] yield ClockCycles(dut.axis_aclk, 20) print 'len(pkts_out) = {}'.format(len(pkts_out)) check_pkts(pkts_in, pkts_out)
def test_drain_pifo(dut): """Testing the simple_tm module """ # start HW sim clock cocotb.fork(Clock(dut.axis_aclk, PERIOD).start()) # Reset the DUT dut._log.debug("Resetting DUT") dut.axis_resetn <= 0 yield ClockCycles(dut.axis_aclk, 10) dut.axis_resetn <= 1 dut._log.debug("Out of reset") # wait for the pifo to finish resetting yield FallingEdge(dut.axis_aclk) while dut.simple_tm_inst.pifo_busy.value: yield RisingEdge(dut.axis_aclk) yield FallingEdge(dut.axis_aclk) yield RisingEdge(dut.axis_aclk) yield ClockCycles(dut.axis_aclk, 100) dut.m_axis_tready <= 0 # build the list of pkts and metadata to insert pkts_meta_in = [] for i in range(NUM_PKTS): # pkt_len = random.randint(50, 1000) # build a packet pkt = Ether(dst='aa:aa:aa:aa:aa:aa', src='bb:bb:bb:bb:bb:bb') pkt = pkt / ('\x11' * 18 + '\x22' * 32) # pkt = pkt / ('\x11'*18 + '\x22'*32 + '\x33'*32 + '\x44'*32 + '\x55'*16) # pkt = pkt / ('\x11'*18 + '\x22'*32 + '\x33'*32 + '\x44'*32 + '\x55'*32 + '\x66'*32 + '\x77'*32 + '\x88'*32 + '\x99'*16) # pkt = pkt / ('\x11'*(pkt_len - 14)) rank = random.randint(0, 100) # build the metadata meta = Metadata(pkt_len=len(pkt), src_port=0b00000001, dst_port=0b00000100, rank=rank) tuser = BinaryValue(bits=len(meta) * 8, bigEndian=False) tuser.set_buff(str(meta)) pkts_meta_in.append((rank, pkt, tuser)) ranks_in = [tup[0] for tup in pkts_meta_in] pkts_in = [tup[1] for tup in pkts_meta_in] meta_in = [tup[2] for tup in pkts_meta_in] # Attach an AXI4Stream Master to the input pkt interface pkt_master = AXI4StreamMaster(dut, 's_axis', dut.axis_aclk) pkt_in_stats = AXI4StreamStats(dut, 's_axis', dut.axis_aclk, idle_timeout=IDLE_TIMEOUT) pkt_in_stats_thread = cocotb.fork( pkt_in_stats.record_n_delays(len(pkts_in))) # Send pkts and metadata in the HW sim yield pkt_master.write_pkts(pkts_in, meta_in) # start recording queue_sizes reg_stats = RegStats(dut) reg_stats_thread = cocotb.fork(reg_stats.start()) # delay between writing pkts and reading them out yield ClockCycles(dut.axis_aclk, 25) # wait for the pifo to finish the final enqueue yield FallingEdge(dut.axis_aclk) while dut.simple_tm_inst.pifo_busy.value: yield RisingEdge(dut.axis_aclk) yield FallingEdge(dut.axis_aclk) yield RisingEdge(dut.axis_aclk) # Attach an AXI4StreamSlave to the output pkt interface tready_delay = 256 / (EGRESS_LINK_RATE * 5) - 1 pkt_slave = AXI4StreamSlave(dut, 'm_axis', dut.axis_aclk, idle_timeout=IDLE_TIMEOUT, tready_delay=tready_delay) pkt_out_stats = AXI4StreamStats(dut, 'm_axis', dut.axis_aclk, idle_timeout=IDLE_TIMEOUT) pkt_out_stats_thread = cocotb.fork( pkt_out_stats.record_n_delays(len(pkts_in))) # Read pkts out yield pkt_slave.read_n_pkts(len(pkts_in)) # # wait for stats threads to finish # yield pkt_in_stats_thread.join() # yield pkt_out_stats_thread.join() # stop the reg_stats reg_stats.stop() yield reg_stats_thread.join() sorted_pkts_meta = sorted(pkts_meta_in, key=lambda x: x[0]) expected_ranks = [tup[0] for tup in sorted_pkts_meta] expected_pkts = [tup[1] for tup in sorted_pkts_meta] expected_meta = [tup[2] for tup in sorted_pkts_meta] pkts_out = pkt_slave.pkts meta_out = pkt_slave.metadata actual_ranks = [Metadata(m.get_buff()).rank for m in meta_out] print 'input ranks = {}'.format(ranks_in) print 'expected output ranks = {}'.format(expected_ranks) print 'actual output ranks = {}'.format(actual_ranks) print '' print 'pkt_in_delays = {}'.format(pkt_in_stats.delays) print 'pkt_out_delays = {}'.format(pkt_out_stats.delays) print '\tmax = {}'.format(max(pkt_out_stats.delays)) print '\tavg = {}'.format( sum(pkt_out_stats.delays) / float(len(pkt_out_stats.delays))) print '\tmin = {}'.format(min(pkt_out_stats.delays)) results = {} results['enq_delays'] = pkt_in_stats.delays results['deq_delays'] = pkt_out_stats.delays with open(RESULTS_FILE, 'w') as f: json.dump(results, f) error = False for (exp_pkt, pkt, exp_meta, meta, i) in zip(expected_pkts, pkts_out, expected_meta, meta_out, range(len(expected_pkts))): if str(exp_pkt) != str(pkt): print 'ERROR: exp_pkt != pkt_out for pkt {}'.format(i) error = True if exp_meta.get_buff() != meta.get_buff(): print 'ERROR: exp_meta != meta_out for pkt {}'.format(i) exp_meta = Metadata(exp_meta.get_buff()) meta = Metadata(meta.get_buff()) print 'exp_meta = {}'.format(exp_meta.summary()) print 'meta = {}'.format(meta.summary()) error = True yield ClockCycles(dut.axis_aclk, 20) plot_reg_size(reg_stats.reg_size) font = {'family': 'normal', 'weight': 'bold', 'size': 22} matplotlib.rc('font', **font) plt.show() if error: print 'ERROR: Test Failed' raise (TestFailure)
def test_axi_stream_pipeline(dut): """Testing axi_stream_pipeline """ # start HW sim clock cocotb.fork(Clock(dut.axis_aclk, PERIOD).start()) # Reset the DUT dut._log.debug("Resetting DUT") dut.axis_resetn <= 0 yield ClockCycles(dut.axis_aclk, 10) dut.axis_resetn <= 1 dut._log.debug("Out of reset") # Attach an AXI4Stream Master to the input pkt interface pkt_master = AXI4StreamMaster(dut, 's_axis', dut.axis_aclk) # Attach and AXI4StreamSlave to the output pkt interfaces pkt_slave = AXI4StreamSlave(dut, 'm_axis', dut.axis_aclk) # build the list of pkts and metadata to insert pkts_meta_in = [] for i in range(20): pkt_len = random.randint(50, 1000) # build a packet pkt = Ether(dst='aa:aa:aa:aa:aa:aa', src='bb:bb:bb:bb:bb:bb') # pkt = pkt / ('\x11'*18 + '\x22'*32) # pkt = pkt / ('\x11'*18 + '\x22'*32 + '\x33'*32 + '\x44'*32 + '\x55'*16) pkt = pkt / ('\x11' * (pkt_len - 14)) rank = random.randint(0, 100) # build the metadata meta = Metadata(pkt_len=len(pkt), src_port=0b00000001, dst_port=0b00000100, rank=rank) tuser = BinaryValue(bits=len(meta) * 8, bigEndian=False) tuser.set_buff(str(meta)) pkts_meta_in.append((pkt, tuser)) pkts_in = [tup[0] for tup in pkts_meta_in] meta_in = [tup[1] for tup in pkts_meta_in] # Read pkts out slave_thread = cocotb.fork(pkt_slave.read_n_pkts(len(pkts_in))) # Send pkts and metadata in the HW sim yield pkt_master.write_pkts(pkts_in, meta_in) yield slave_thread.join() expected_pkts = pkts_in expected_meta = meta_in pkts_out = pkt_slave.pkts meta_out = pkt_slave.metadata error = False for (exp_pkt, pkt, exp_meta, meta, i) in zip(expected_pkts, pkts_out, expected_meta, meta_out, range(len(expected_pkts))): if str(exp_pkt) != str(pkt): print 'ERROR: exp_pkt != pkt_out for pkt {}'.format(i) error = True if exp_meta.get_buff() != meta.get_buff(): print 'ERROR: exp_meta != meta_out for pkt {}'.format(i) exp_meta = Metadata(exp_meta.get_buff()) meta = Metadata(meta.get_buff()) print 'exp_meta = {}'.format(exp_meta.summary()) print 'meta = {}'.format(meta.summary()) error = True yield ClockCycles(dut.axis_aclk, 20) if error: print 'ERROR: Test Failed' raise (TestFailure)
def test_sume_event_switch(dut): """Test to make sure that event_output_queues module is working properly. """ # start HW sim clock cocotb.fork(Clock(dut.axis_aclk, PERIOD).start()) yield reset_dut(dut) yield ClockCycles(dut.axis_aclk, START_DELAY) # read the pkts and rank values pkts_in_0, meta_in_0 = make_pkts_meta_in(0b00000001) pkts_in_1, meta_in_1 = make_pkts_meta_in(0b00000100) pkts_in_2, meta_in_2 = make_pkts_meta_in(0b00010000) pkts_in_3, meta_in_3 = make_pkts_meta_in(0b01000000) # Attach an AXI4Stream Master to the input pkt interface pkt_master_0 = AXI4StreamMaster(dut, 's_axis_0', dut.axis_aclk) pkt_master_1 = AXI4StreamMaster(dut, 's_axis_1', dut.axis_aclk) pkt_master_2 = AXI4StreamMaster(dut, 's_axis_2', dut.axis_aclk) pkt_master_3 = AXI4StreamMaster(dut, 's_axis_3', dut.axis_aclk) # Attach an AXI4StreamSlave to the output pkt interface pkt_slave_0 = AXI4StreamSlave(dut, 'm_axis_0', dut.axis_aclk, tready_delay=BP_COUNT, idle_timeout=IDLE_TIMEOUT) pkt_slave_1 = AXI4StreamSlave(dut, 'm_axis_1', dut.axis_aclk, tready_delay=BP_COUNT, idle_timeout=IDLE_TIMEOUT) pkt_slave_2 = AXI4StreamSlave(dut, 'm_axis_2', dut.axis_aclk, tready_delay=BP_COUNT, idle_timeout=IDLE_TIMEOUT) pkt_slave_3 = AXI4StreamSlave(dut, 'm_axis_3', dut.axis_aclk, tready_delay=BP_COUNT, idle_timeout=IDLE_TIMEOUT) # start reading for pkts pkt_slave_thread_0 = cocotb.fork( pkt_slave_0.read_n_pkts(len(pkts_in_0), log_raw=True)) pkt_slave_thread_1 = cocotb.fork( pkt_slave_1.read_n_pkts(len(pkts_in_1), log_raw=True)) pkt_slave_thread_2 = cocotb.fork( pkt_slave_2.read_n_pkts(len(pkts_in_2), log_raw=True)) pkt_slave_thread_3 = cocotb.fork( pkt_slave_3.read_n_pkts(len(pkts_in_3), log_raw=True)) # Send pkts and metadata in the HW sim rate = 1.0 * INGRESS_LINK_RATE * 5 / 8.0 # bytes/cycle pkt_master_thread_0 = cocotb.fork( pkt_master_0.write_pkts(pkts_in_0, meta_in_0, rate=rate)) pkt_master_thread_1 = cocotb.fork( pkt_master_1.write_pkts(pkts_in_1, meta_in_1, rate=rate)) pkt_master_thread_2 = cocotb.fork( pkt_master_2.write_pkts(pkts_in_2, meta_in_2, rate=rate)) pkt_master_thread_3 = cocotb.fork( pkt_master_3.write_pkts(pkts_in_3, meta_in_3, rate=rate)) yield pkt_master_thread_0.join() yield pkt_master_thread_1.join() yield pkt_master_thread_2.join() yield pkt_master_thread_3.join() # Wait for the pkt_slave to finish (or timeout) yield pkt_slave_thread_0.join() yield pkt_slave_thread_1.join() yield pkt_slave_thread_2.join() yield pkt_slave_thread_3.join() # pkts_out = pkt_slave.pkts # meta_out = pkt_slave.metadata yield ClockCycles(dut.axis_aclk, 20)
def test_slow_egress(dut): """Testing the simple_tm module with a constant fill level """ # start HW sim clock cocotb.fork(Clock(dut.axis_aclk, PERIOD).start()) # Reset the DUT dut._log.debug("Resetting DUT") dut.axis_resetn <= 0 yield ClockCycles(dut.axis_aclk, 10) dut.axis_resetn <= 1 dut._log.debug("Out of reset") # wait for the pifo to finish resetting yield FallingEdge(dut.axis_aclk) while dut.simple_tm_inst.pifo_busy.value: yield RisingEdge(dut.axis_aclk) yield FallingEdge(dut.axis_aclk) yield RisingEdge(dut.axis_aclk) yield ClockCycles(dut.axis_aclk, 100) dut.m_axis_tready <= 0 # Attach an AXI4Stream Master to the input pkt interface pkt_master = AXI4StreamMaster(dut, 's_axis', dut.axis_aclk) # Attach and AXI4StreamSlave to the output pkt interface pkt_slave = AXI4StreamSlave(dut, 'm_axis', dut.axis_aclk, idle_timeout=IDLE_TIMEOUT) # connect stats tools pkt_in_stats = AXI4StreamStats(dut, 's_axis', dut.axis_aclk, idle_timeout=IDLE_TIMEOUT) pkt_out_stats = AXI4StreamStats(dut, 'm_axis', dut.axis_aclk, idle_timeout=IDLE_TIMEOUT) # start counter for stats counter = CycleCounter(dut.axis_aclk) counter_thread = cocotb.fork(counter.start()) # start recording stats pkt_in_stats_thread = cocotb.fork( pkt_in_stats.record_n_start_times(NUM_PKTS, counter)) pkt_out_stats_thread = cocotb.fork( pkt_out_stats.record_n_start_times(NUM_PKTS, counter)) # start writing pkts data = make_pkts_and_meta(NUM_PKTS) pkts_in = [tup[1] for tup in data] meta_in = [tup[2] for tup in data] pkt_master_thread = cocotb.fork(pkt_master.write_pkts(pkts_in, meta_in)) # wait a few cycles between samples for i in range(10): yield FallingEdge(dut.axis_aclk) yield RisingEdge(dut.axis_aclk) expected_ranks = [] for i in range(NUM_PKTS): # compute expected pkt input_ranks = [ Metadata(m.get_buff()).rank for m in pkt_in_stats.metadata ] # print 'input_ranks = {}'.format(input_ranks) output_ranks = [ Metadata(m.get_buff()).rank for m in pkt_out_stats.metadata ] # print 'output_ranks = {}'.format(output_ranks) [input_ranks.remove(r) for r in expected_ranks] # print 'curr_rank_set = {}'.format(input_ranks) try: expected_ranks.append(min(input_ranks)) except ValueError as e: pass # print 'expected_ranks = {}'.format(expected_ranks) # print '=======================' # Read out packet yield pkt_slave.read_n_pkts(1) # wait a few cycles between samples for i in range(10): yield FallingEdge(dut.axis_aclk) yield RisingEdge(dut.axis_aclk) if pkt_slave.error: print "ERROR: pkt_slave timed out" break # get the actual ranks meta_out = pkt_slave.metadata actual_ranks = [Metadata(m.get_buff()).rank for m in meta_out] input_ranks = [Metadata(m.get_buff()).rank for m in pkt_in_stats.metadata] print 'input_ranks = {}'.format(input_ranks) print 'expected output ranks = {}'.format(expected_ranks) print 'actual output ranks = {}'.format(actual_ranks) error = False # for (exp_rank, rank, i) in zip(expected_ranks, actual_ranks, range(len(expected_ranks))): # if exp_rank != rank: # print 'ERROR: exp_rank ({}) != actual_rank ({}) for pkt {}'.format(exp_rank, rank, i) # error = True for r, i in zip(actual_ranks, range(len(actual_ranks))): try: input_ranks.remove(r) except ValueError as e: print 'ERROR: output rank ({}) not in input set'.format(r) print e error = True if len(input_ranks) > 0: print 'ERROR: not all ranks removed: {}'.format(input_ranks) error = True yield ClockCycles(dut.axis_aclk, 20) if error: print 'ERROR: Test Failed' raise (TestFailure)
def test_sched_alg_demo(dut): """Test to make sure that the demo will work in simulation. """ # start HW sim clock cocotb.fork(Clock(dut.axis_aclk, PERIOD).start()) yield reset_dut(dut) yield ClockCycles(dut.axis_aclk, START_DELAY) # read the pkts and rank values nf1_pkts_in, nf1_meta_in = make_pkts_meta_in(NF1_PCAP_FILE, NF1_META_FILE) nf2_pkts_in, nf2_meta_in = make_pkts_meta_in(NF2_PCAP_FILE, NF2_META_FILE) # Attach an AXI4Stream Master to the input pkt interface nf1_master = AXI4StreamMaster(dut, 's_axis_1', dut.axis_aclk) nf2_master = AXI4StreamMaster(dut, 's_axis_2', dut.axis_aclk) # Attach an AXI4StreamSlave to the output pkt interface pkt_slave = AXI4StreamSlave(dut, 'nf0_m_axis', dut.axis_aclk, tready_delay=BP_COUNT, idle_timeout=IDLE_TIMEOUT) input_logger = AXI4StreamSlave(dut, 'nf3_m_axis', dut.axis_aclk, idle_timeout=IDLE_TIMEOUT*1000000) # start reading for pkts num_pkts = len(nf1_pkts_in) + len(nf2_pkts_in) pkt_slave_thread = cocotb.fork(pkt_slave.read_n_pkts(num_pkts, log_raw=True)) input_logger_thread = cocotb.fork(input_logger.read_n_pkts(num_pkts, log_raw=True)) # Send pkts and metadata in the HW sim rate = 1.0*INGRESS_LINK_RATE*5/8.0 # bytes/cycle nf2_master_thread = cocotb.fork(nf2_master.write_pkts(nf2_pkts_in, nf2_meta_in, rate=rate)) for i in range(10000): yield RisingEdge(dut.axis_aclk) yield FallingEdge(dut.axis_aclk) print 'starting nf1_master' nf1_master_thread = cocotb.fork(nf1_master.write_pkts(nf1_pkts_in, nf1_meta_in, rate=rate)) yield nf1_master_thread.join() yield nf2_master_thread.join() # Wait for the pkt_slave to finish (or timeout) yield pkt_slave_thread.join() pkts_out = pkt_slave.pkts meta_out = pkt_slave.metadata # ranks_out = [Metadata(m.get_buff()).rank for m in meta_out] yield ClockCycles(dut.axis_aclk, 20) print 'len(pkts_out) = {}'.format(len(pkts_out)) print 'len(logged_pkts) = {}'.format(len(input_logger.pkts)) check_pkts(pkts_out) # Parse the logged pkts pkt_parser = LogPktParser() input_log_pkts = pkt_parser.parse_pkts(map(str, input_logger.pkts)) # print 'input_log_pkts:' # for p in map(str, input_log_pkts): # print p # plot input / output rates plot_stats(input_log_pkts, EGRESS_LINK_RATE) font = {'family' : 'normal', 'weight' : 'bold', 'size' : 32} matplotlib.rc('font', **font) plt.show()
def test_port_tm(dut): """Testing port_tm """ # start HW sim clock cocotb.fork(Clock(dut.axis_aclk, PERIOD).start()) # Reset the DUT dut._log.debug("Resetting DUT") dut.axis_resetn <= 0 yield ClockCycles(dut.axis_aclk, 10) dut.axis_resetn <= 1 dut._log.debug("Out of reset") print "FINISHED RESET..." dut.m_axis_tready <= 0 dst_port = 0b00000100 # build the list of pkts and metadata to insert pkts_meta_in = [] for i in range(10): # pkt_len = random.randint(50, 1000) # build a packet pkt = Ether(dst='aa:aa:aa:aa:aa:aa', src='bb:bb:bb:bb:bb:bb') pkt = pkt / ('\x11'*18 + '\x22'*32) # pkt = pkt / ('\x11'*18 + '\x22'*32 + '\x33'*32 + '\x44'*32 + '\x55'*16) # pkt = pkt / ('\x11'*(pkt_len - 14)) rank = random.randint(0, 100) # build the metadata meta = Metadata(pkt_len=len(pkt), src_port=0b00000001, dst_port=dst_port, rank=rank) tuser = BinaryValue(bits=len(meta)*8, bigEndian=False) tuser.set_buff(str(meta)) pkts_meta_in.append((rank, pkt, tuser)) ranks_in = [tup[0] for tup in pkts_meta_in] pkts_in = [tup[1] for tup in pkts_meta_in] meta_in = [tup[2] for tup in pkts_meta_in] # Attach an AXI4Stream Master to the input pkt interface pkt_master = AXI4StreamMaster(dut, 's_axis', dut.axis_aclk) # Attach ReqMaster to each input interface nf0_req_master = ReqMaster(dut, 'nf0_sel', dut.axis_aclk) nf1_req_master = ReqMaster(dut, 'nf1_sel', dut.axis_aclk) nf2_req_master = ReqMaster(dut, 'nf2_sel', dut.axis_aclk) nf3_req_master = ReqMaster(dut, 'nf3_sel', dut.axis_aclk) # Send pkts and metadata in the HW sim yield pkt_master.write_pkts(pkts_in, meta_in) # delay between writing pkts and reading them out yield ClockCycles(dut.axis_aclk, 10) # Attach and AXI4StreamSlave to the output pkt interface pkt_slave = AXI4StreamSlave(dut, 'm_axis', dut.axis_aclk) # Read output pkts pkt_slave_thread = cocotb.fork(pkt_slave.read_n_pkts(len(pkts_in))) # start submitting read requests delay = 20 #nf0_req_thread = cocotb.fork(nf0_req_master.write_reqs(requests, delay)) nf1_req_thread = cocotb.fork(nf1_req_master.write_reqs(len(ranks_in), delay)) #nf2_req_thread = cocotb.fork(nf2_req_master.write_reqs(requests, delay)) #nf3_req_thread = cocotb.fork(nf3_req_master.write_reqs(requests, delay)) # wait for all pkts yield pkt_slave_thread.join() sorted_pkts_meta = sorted(pkts_meta_in, key=lambda x: x[0]) expected_ranks = [tup[0] for tup in sorted_pkts_meta] expected_pkts = [tup[1] for tup in sorted_pkts_meta] expected_meta = [tup[2] for tup in sorted_pkts_meta] pkts_out = pkt_slave.pkts meta_out = pkt_slave.metadata actual_ranks = [Metadata(m.get_buff()).rank for m in meta_out] print 'input ranks = {}'.format(ranks_in) print 'expected output ranks = {}'.format(expected_ranks) print 'actual output ranks = {}'.format(actual_ranks) error = False for (exp_pkt, pkt, exp_meta, meta, i) in zip(expected_pkts, pkts_out, expected_meta, meta_out, range(len(expected_pkts))): if str(exp_pkt) != str(pkt): print 'ERROR: exp_pkt != pkt_out for pkt {}'.format(i) error = True if exp_meta.get_buff() != meta.get_buff(): print 'ERROR: exp_meta != meta_out for pkt {}'.format(i) exp_meta = Metadata(exp_meta.get_buff()) meta = Metadata(meta.get_buff()) print 'exp_meta = {}'.format(exp_meta.summary()) print 'meta = {}'.format(meta.summary()) error = True yield ClockCycles(dut.axis_aclk, 20) if error: print 'ERROR: Test Failed' raise(TestFailure)
def test_simple_tm(dut): """Testing the simple_tm module """ # start HW sim clock cocotb.fork(Clock(dut.axis_aclk, PERIOD).start()) # Reset the DUT dut._log.debug("Resetting DUT") dut.axis_resetn <= 0 yield ClockCycles(dut.axis_aclk, 10) dut.axis_resetn <= 1 dut._log.debug("Out of reset") # wait for the pifo to finish resetting yield wait_pifo_busy(dut) yield ClockCycles(dut.axis_aclk, 100) dut.m_axis_tready <= 0 # build the list of pkts and metadata to insert pkts_meta_in = [] for i in range(NUM_PKTS): # pkt_len = random.randint(50, 1000) # build a packet pkt = Ether(dst='aa:aa:aa:aa:aa:aa', src='bb:bb:bb:bb:bb:bb') pkt = pkt / ('\x11' * 18 + '\x22' * 32) rank = random.randint(0, 100) # build the metadata meta = Metadata(pkt_len=len(pkt), src_port=0b00000001, dst_port=0b00000100, rank=rank) tuser = BinaryValue(bits=len(meta) * 8, bigEndian=False) tuser.set_buff(str(meta)) pkts_meta_in.append((rank, pkt, tuser)) ranks_in = [tup[0] for tup in pkts_meta_in] pkts_in = [tup[1] for tup in pkts_meta_in] meta_in = [tup[2] for tup in pkts_meta_in] # Attach an AXI4Stream Master to the input pkt interface pkt_master = AXI4StreamMaster(dut, 's_axis', dut.axis_aclk) pkt_in_stats = AXI4StreamStats(dut, 's_axis', dut.axis_aclk, idle_timeout=IDLE_TIMEOUT) pkt_in_stats_thread = cocotb.fork( pkt_in_stats.record_n_delays(len(pkts_in))) # Send pkts and metadata in the HW sim yield pkt_master.write_pkts(pkts_in, meta_in) # wait for pifo to no longer be busy yield wait_pifo_busy(dut) # delay between writing pkts and reading them out yield ClockCycles(dut.axis_aclk, 25) # wait for the pifo to finish the final enqueue yield FallingEdge(dut.axis_aclk) while dut.simple_tm_inst.pifo_busy.value: yield RisingEdge(dut.axis_aclk) yield FallingEdge(dut.axis_aclk) yield RisingEdge(dut.axis_aclk) # Attach an AXI4StreamSlave to the output pkt interface pkt_slave = AXI4StreamSlave(dut, 'm_axis', dut.axis_aclk, idle_timeout=IDLE_TIMEOUT) pkt_out_stats = AXI4StreamStats(dut, 'm_axis', dut.axis_aclk, idle_timeout=IDLE_TIMEOUT) pkt_out_stats_thread = cocotb.fork( pkt_out_stats.record_n_delays(len(pkts_in))) # Read pkts out yield pkt_slave.read_n_pkts(len(pkts_in)) # # wait for stats threads to finish # yield pkt_in_stats_thread.join() # yield pkt_out_stats_thread.join() sorted_pkts_meta = sorted(pkts_meta_in, key=lambda x: x[0]) expected_ranks = [tup[0] for tup in sorted_pkts_meta] expected_pkts = [tup[1] for tup in sorted_pkts_meta] expected_meta = [tup[2] for tup in sorted_pkts_meta] pkts_out = pkt_slave.pkts meta_out = pkt_slave.metadata actual_ranks = [Metadata(m.get_buff()).rank for m in meta_out] print 'input ranks = {}'.format(ranks_in) print 'expected output ranks = {}'.format(expected_ranks) print 'actual output ranks = {}'.format(actual_ranks) print '' print 'pkt_in_delays = {}'.format(pkt_in_stats.delays) print 'pkt_out_delays = {}'.format(pkt_out_stats.delays) print '\tmax = {}'.format(max(pkt_out_stats.delays)) print '\tavg = {}'.format( sum(pkt_out_stats.delays) / float(len(pkt_out_stats.delays))) print '\tmin = {}'.format(min(pkt_out_stats.delays)) results = {} results['enq_delays'] = pkt_in_stats.delays results['deq_delays'] = pkt_out_stats.delays with open(RESULTS_FILE, 'w') as f: json.dump(results, f) error = False for (exp_pkt, pkt, exp_meta, meta, i) in zip(expected_pkts, pkts_out, expected_meta, meta_out, range(len(expected_pkts))): if str(exp_pkt) != str(pkt): print 'ERROR: exp_pkt != pkt_out for pkt {}'.format(i) error = True if exp_meta.get_buff() != meta.get_buff(): print 'ERROR: exp_meta != meta_out for pkt {}'.format(i) exp_meta = Metadata(exp_meta.get_buff()) meta = Metadata(meta.get_buff()) print 'exp_meta = {}'.format(exp_meta.summary()) print 'meta = {}'.format(meta.summary()) error = True print "******************" print "Checking for duplicates:" print "******************" for r, i in zip(actual_ranks, range(len(actual_ranks))): try: ranks_in.remove(r) except ValueError as e: print 'ERROR: output rank ({}) not in input set'.format(r) print e error = True if len(ranks_in) > 0: print 'ERROR: not all ranks removed: {}'.format(ranks_in) error = True yield ClockCycles(dut.axis_aclk, 20) if error: print 'ERROR: Test Failed' raise (TestFailure)
def test_pifo_pkt_storage(dut): """Testing pifo_pkt_storage module """ # instantiate the interface to the simpy implemenation env = simpy.Environment() ps_simpy = PS_simpy_iface(env) # start HW sim clock cocotb.fork(Clock(dut.axis_aclk, PERIOD).start()) # Reset the DUT dut._log.debug("Resetting DUT") dut.axis_resetn <= 0 dut.m_axis_pkt_tready <= 0 yield ClockCycles(dut.axis_aclk, 10) dut.axis_resetn <= 1 dut.m_axis_pkt_tready <= 1 dut._log.debug("Out of reset") # initialize the read request pointers dut.s_axis_ptr_tvalid <= 0 dut.s_axis_ptr_tdata <= 0 dut.s_axis_ptr_tlast <= 0 # Attach an AXI4Stream Master to the input pkt interface pkt_master = AXI4StreamMaster(dut, 's_axis_pkt', dut.axis_aclk) # Attach and AXI4StreamSlave to the output ptr interface ptr_slave = AXI4StreamSlave(dut, 'm_axis_ptr', dut.axis_aclk) hw_results = {} hw_results['out_ptrs'] = [] # build the list of pkts and metadata to insert all_pkts = [] all_meta = [] for i in range(10): pkt_len = random.randint(50, 1000) # build a packet pkt = Ether(dst='aa:aa:aa:aa:aa:aa', src='bb:bb:bb:bb:bb:bb') # pkt = pkt / ('\x11'*18 + '\x22'*32 + '\x33'*32 + '\x44'*32 + '\x55'*16) pkt = pkt / ('\x11'*(pkt_len - 14)) # build the metadata meta = Metadata(pkt_len=len(pkt), src_port=0b00000001, dst_port=0b00000100) all_pkts.append(pkt) all_meta.append(meta) # send pkts / metadata and read resulting pointers for p, m in zip(all_pkts, all_meta): # Start reading for output ptrs ptr_slave_thread = cocotb.fork(ptr_slave.read()) # send the pkts in the HW sim tuser = BinaryValue(bits=len(m)*8, bigEndian=False) tuser.set_buff(str(m)) yield pkt_master.write_pkts([p], [tuser]) # wait to finish reading pointers yield ptr_slave_thread.join() # ptr_slave.data is all of the ptr words that have been read so far hw_results['out_ptrs'] = ptr_slave.data # check results with simpy simulation env.process(ps_simpy.insert_pkts(all_pkts, all_meta, hw_results)) env.run() if ps_simpy.test_failed: raise TestFailure('Test Failed') # pause between pkt insertions and removals yield ClockCycles(dut.axis_aclk, 10) # Attach an AXI Stream master to read request interface ptr_master = AXI4StreamMaster(dut, 's_axis_ptr', dut.axis_aclk) # Attach an AXI Stream slave to the output packet interface pkt_slave = AXI4StreamSlave(dut, 'm_axis_pkt', dut.axis_aclk) # remove the inserted pkts hw_results['out_pkts'] = [] for ptrs in hw_results['out_ptrs']: # start reading for output pkts pkt_slave_thread = cocotb.fork(pkt_slave.read_pkt()) # submit read request yield ptr_master.write([ptrs]) # wait to finish reading pkt yield pkt_slave_thread.join() yield RisingEdge(dut.axis_aclk) hw_results['out_pkts'] = pkt_slave.pkts hw_results['out_meta'] = [Metadata(m.get_buff()) for m in pkt_slave.metadata] # verify that the removed pkts are the same as the ones that were inserted if len(all_pkts) != len(hw_results['out_pkts']): print 'ERROR: {} pkts inserted, {} pkts removed'.format(len(all_pkts), len(hw_results['out_pkts'])) raise TestFailure('Test Failed') for (pkt_in, pkt_out, meta_in, meta_out, i) in zip(all_pkts, hw_results['out_pkts'], all_meta, hw_results['out_meta'], range(len(all_pkts))): if str(pkt_in) != str(pkt_out): print 'ERROR: pkt_in != pkt_out for pkt {}'.format(i) print 'len(pkt_in) = {}, pkt_in: {}'.format(len(pkt_in), pkt_in.summary()) print 'len(pkt_out) = {}, pkt_out: {}'.format(len(pkt_out), pkt_out.summary()) # raise TestFailure('Test Failed') if str(meta_in) != str(meta_out): print 'ERROR: meta_in != meta_out for pkt {}'.format(i) print '\tmeta_in = {}'.format(meta_in.summary()) print '\tmeta_out = {}'.format(meta_out.summary()) # raise TestFailure('Test Failed') yield ClockCycles(dut.axis_aclk, 20)
def test_both_enqdeq(dut): """Testing the simple_tm module with a constant fill level """ # start HW sim clock cocotb.fork(Clock(dut.axis_aclk, PERIOD).start()) # Reset the DUT dut._log.debug("Resetting DUT") dut.axis_resetn <= 0 yield ClockCycles(dut.axis_aclk, 10) dut.axis_resetn <= 1 dut._log.debug("Out of reset") # wait for the pifo to finish resetting yield FallingEdge(dut.axis_aclk) while dut.simple_tm_inst.pifo_busy.value: yield RisingEdge(dut.axis_aclk) yield FallingEdge(dut.axis_aclk) yield RisingEdge(dut.axis_aclk) yield ClockCycles(dut.axis_aclk, 100) dut.m_axis_tready <= 0 # build the list of pkts and metadata to insert pkts_meta_in = make_pkts_and_meta(FILL_LEVEL - 1) ranks_in = [tup[0] for tup in pkts_meta_in] pkts_in = [tup[1] for tup in pkts_meta_in] meta_in = [tup[2] for tup in pkts_meta_in] # Attach an AXI4Stream Master to the input pkt interface pkt_master = AXI4StreamMaster(dut, 's_axis', dut.axis_aclk) # Send pkts and metadata in the HW sim yield pkt_master.write_pkts(pkts_in, meta_in) # wait a few cycles before begining measurements yield ClockCycles(dut.axis_aclk, 25) # Attach and AXI4StreamSlave to the output pkt interface pkt_slave = AXI4StreamSlave(dut, 'm_axis', dut.axis_aclk, idle_timeout=IDLE_TIMEOUT) # connect stats tools pkt_in_stats = AXI4StreamStats(dut, 's_axis', dut.axis_aclk, idle_timeout=IDLE_TIMEOUT) pkt_out_stats = AXI4StreamStats(dut, 'm_axis', dut.axis_aclk, idle_timeout=IDLE_TIMEOUT) expected_outputs = [] enq_delays = [] deq_delays = [] for i in range(NUM_SAMPLES): data = make_pkts_and_meta(1) pkts_in = [tup[1] for tup in data] meta_in = [tup[2] for tup in data] # compute expected outputs expected_outputs.append(min(pkts_meta_in)) pkts_meta_in.remove(min(pkts_meta_in)) # The removal happens after the insertion pkts_meta_in += data # # start recording stats # pkt_in_stats_thread = cocotb.fork(pkt_in_stats.record_n_delays(1)) # pkt_out_stats_thread = cocotb.fork(pkt_out_stats.record_n_delays(1)) # send in packet pkt_master_thread = cocotb.fork(pkt_master.write_pkts( pkts_in, meta_in)) # Read out packet pkt_slave_thread = cocotb.fork(pkt_slave.read_n_pkts(1)) yield pkt_master_thread.join() yield pkt_slave_thread.join() # # record results # enq_delays += pkt_in_stats.delays # deq_delays += pkt_out_stats.delays # wait a few cycles between samples yield ClockCycles(dut.axis_aclk, 30) if pkt_slave.error: print "ERROR: pkt_slave timed out" break sorted_pkts_meta = sorted(pkts_meta_in, key=lambda x: x[0]) expected_ranks = [tup[0] for tup in expected_outputs] expected_pkts = [tup[1] for tup in expected_outputs] expected_meta = [tup[2] for tup in expected_outputs] pkts_out = pkt_slave.pkts meta_out = pkt_slave.metadata actual_ranks = [Metadata(m.get_buff()).rank for m in meta_out] print 'input_ranks = {}'.format(input_ranks) print 'expected output ranks = {}'.format(expected_ranks) print 'actual output ranks = {}'.format(actual_ranks) print '' print 'pkt_in_delays = {}'.format(enq_delays) print 'pkt_out_delays = {}'.format(deq_delays) results = {} results['enq_delays'] = enq_delays results['deq_delays'] = deq_delays with open(RESULTS_FILE, 'w') as f: json.dump(results, f) error = False for (exp_pkt, pkt, exp_meta, meta, i) in zip(expected_pkts, pkts_out, expected_meta, meta_out, range(len(expected_pkts))): if str(exp_pkt) != str(pkt): print 'ERROR: exp_pkt != pkt_out for pkt {}'.format(i) error = True if exp_meta.get_buff() != meta.get_buff(): print 'ERROR: exp_meta != meta_out for pkt {}'.format(i) exp_meta = Metadata(exp_meta.get_buff()) meta = Metadata(meta.get_buff()) print 'exp_meta = {}'.format(exp_meta.summary()) print 'meta = {}'.format(meta.summary()) error = True yield ClockCycles(dut.axis_aclk, 20) if error: print 'ERROR: Test Failed' raise (TestFailure)