async def run_test(dut, config_clk="NoC_slwT_AXI", idle_inserter=None, backpressure_inserter=None): noc_flavor = os.getenv("FLAVOR") noc_cfg = noc_const.NOC_CFG[noc_flavor] # Setup testbench tb = Tb(dut, f"sim_{config_clk}", noc_cfg) await tb.setup_clks(config_clk) await tb.arst(config_clk) if (noc_cfg['max_nodes'] >= 3) and (noc_cfg['n_virt_chn'] > 1): max_size = (noc_cfg['max_sz_pkt'] - 1) * (int( noc_cfg['flit_data_width'] / 8)) high_prior_vc = (noc_cfg['n_virt_chn'] - 1) if noc_cfg['h_priority'] == "ZeroLowPrior" else 0 low_prior_vc = 0 if noc_cfg['h_priority'] == "ZeroLowPrior" else ( noc_cfg['n_virt_chn'] - 1) pkt_lp = RaveNoC_pkt(cfg=noc_cfg, msg=tb._get_random_string(max_size), src_dest=(1, noc_cfg['max_nodes'] - 1), virt_chn_id=low_prior_vc) pkt_hp = RaveNoC_pkt(cfg=noc_cfg, src_dest=(0, noc_cfg['max_nodes'] - 1), virt_chn_id=high_prior_vc) pkts = [pkt_hp, pkt_lp] #We need to extend the timeout once it's the max pkt sz wr_lp_pkt = cocotb.fork( tb.write_pkt(pkt=pkt_lp, timeout=noc_const.TIMEOUT_AXI_EXT)) wr_hp_pkt = cocotb.fork(tb.write_pkt(pkt=pkt_hp, use_side_if=1)) # HP pkt should finish first await wr_hp_pkt # Just to ensure the HP pkt has been sent over the NoC # and the LP pkt is still being processed assert ((wr_lp_pkt._finished == False) and (wr_hp_pkt._finished == True)) lp_prior = 2**(noc_cfg['n_virt_chn'] - 1) hp_prior = 2**(0) irq_lp_hp = (lp_prior + hp_prior) << (noc_cfg['max_nodes'] - 1) * noc_cfg['n_virt_chn'] tb.log.info("IRQs to wait: %d", irq_lp_hp) await tb.wait_irq_x(irq_lp_hp) for pkt in pkts: resp = await tb.read_pkt(pkt=pkt, timeout=noc_const.TIMEOUT_AXI_EXT) tb.check_pkt(resp.data, pkt.msg) else: tb.log.info( "Test not executed due to the NoC cfg, min >=3 routers && min > 1 VCs" )
async def run_test(dut, config_clk="NoC_slwT_AXI", idle_inserter=None, backpressure_inserter=None): noc_flavor = os.getenv("FLAVOR") noc_cfg = noc_const.NOC_CFG[noc_flavor] # Setup testbench tb = Tb(dut, f"sim_{config_clk}", noc_cfg) await tb.setup_clks(config_clk) await tb.arst(config_clk) max_size = (noc_cfg['max_sz_pkt'] - 1) * (int( noc_cfg['flit_data_width'] / 8)) msg = tb._get_random_string(length=max_size) pkt = RaveNoC_pkt(cfg=noc_cfg, src_dest=(0, noc_cfg['max_nodes'] - 1), msg=msg) start_time = get_sim_time(units='ns') write = cocotb.fork(tb.write_pkt(pkt, timeout=noc_const.TIMEOUT_AXI_EXT)) await tb.wait_irq() resp = await tb.read_pkt(pkt, timeout=noc_const.TIMEOUT_AXI_EXT) end_time = get_sim_time(units='ns') delta_time_txn = end_time - start_time max_size += (int(noc_cfg['flit_data_width'] / 8) ) # Adding header flit into account tb.log.info("Delta time = %d ns", delta_time_txn) tb.log.info("Bytes transferred = %d B", max_size) bw = [] bw.append(float(max_size / (1024**2)) / float(delta_time_txn * 10**-9)) bw.append(float(max_size / (1024**3)) / float(delta_time_txn * 10**-9)) tb.log.info("BW = %.2f MB/s (%.2f GB/s)", bw[0], bw[1]) tb.check_pkt(resp.data, pkt.msg)
async def run_test(dut, config_clk="NoC_slwT_AXI", idle_inserter=None, backpressure_inserter=None): noc_flavor = os.getenv("FLAVOR") noc_cfg = noc_const.NOC_CFG[noc_flavor] # Setup testbench idle = "no_idle" if idle_inserter == None else "w_idle" backp = "no_backpressure" if backpressure_inserter == None else "w_backpressure" tb = Tb(dut, f"sim_{config_clk}_{idle}_{backp}", noc_cfg) tb.set_idle_generator(idle_inserter) tb.set_backpressure_generator(backpressure_inserter) await tb.setup_clks(config_clk) await tb.arst(config_clk) max_size = (noc_cfg['max_sz_pkt']-1)*(int(noc_cfg['flit_data_width']/8)) msg = tb._get_random_string(length=max_size) pkt = RaveNoC_pkt(cfg=noc_cfg, msg=msg) tb.log.info(f"src={pkt.src[0]} x={pkt.src[1]} y={pkt.src[2]}") tb.log.info(f"dest={pkt.dest[0]} x={pkt.dest[1]} y={pkt.dest[2]}") write = cocotb.fork(tb.write_pkt(pkt, timeout=noc_const.TIMEOUT_AXI_EXT)) await tb.wait_irq() resp = await tb.read_pkt(pkt, timeout=noc_const.TIMEOUT_AXI_EXT) tb.check_pkt(resp.data,pkt.msg)
async def run_test(dut, config_clk="NoC_slwT_AXI", idle_inserter=None, backpressure_inserter=None): noc_flavor = os.getenv("FLAVOR") noc_cfg = noc_const.NOC_CFG[noc_flavor] # Setup testbench idle = "no_idle" if idle_inserter == None else "w_idle" backp = "no_backpressure" if backpressure_inserter == None else "w_backpressure" tb = Tb(dut, f"sim_{config_clk}_{idle}_{backp}", noc_cfg) tb.set_idle_generator(idle_inserter) tb.set_backpressure_generator(backpressure_inserter) await tb.setup_clks(config_clk) await tb.arst(config_clk) pkt = RaveNoC_pkt(cfg=noc_cfg) write = cocotb.fork(tb.write_pkt(pkt)) await tb.wait_irq() resp = await tb.read_pkt(pkt) tb.check_pkt(resp.data, pkt.msg)
async def run_test(dut, config_clk="NoC_slwT_AXI", idle_inserter=None, backpressure_inserter=None): noc_flavor = os.getenv("FLAVOR") noc_cfg = noc_const.NOC_CFG[noc_flavor] # Setup testbench idle = "no_idle" if idle_inserter == None else "w_idle" backp = "no_backpressure" if backpressure_inserter == None else "w_backpressure" tb = Tb(dut, f"sim_{config_clk}_{idle}_{backp}", noc_cfg) tb.set_idle_generator(idle_inserter) tb.set_backpressure_generator(backpressure_inserter) await tb.setup_clks(config_clk) await tb.arst(config_clk) payload = bytearray("Test", 'utf-8') # Valid write region # Not expecting any error result = await tb.write(sel=randrange(0, noc_cfg['max_nodes']), address=noc_cfg['vc_w_id'][randrange( 0, noc_cfg['n_virt_chn'])], data=payload) assert result.resp == AxiResp.OKAY, "AXI should not raise an error on this txn" # Invalid memory address WR - out of range await tb.arst(config_clk) rand_addr = randrange(0, 2**32) while rand_addr in noc_cfg['vc_w_id']: rand_addr = randrange(0, 2**32) result = await tb.write(sel=randrange(0, noc_cfg['max_nodes']), address=rand_addr, data=payload) assert result.resp == AxiResp.SLVERR, "AXI bus should have raised an error when writing to an invalid region of memory" # Invalid memory address WR - writing in RD buffer await tb.arst(config_clk) result = await tb.write(sel=randrange(0, noc_cfg['max_nodes']), address=noc_cfg['vc_r_id'][randrange( 0, noc_cfg['n_virt_chn'])], data=payload) assert result.resp == AxiResp.SLVERR, "AXI bus should have raised an error when writing to an invalid region of memory" # Invalid burst type await tb.arst(config_clk) result = await tb.write(sel=randrange(0, noc_cfg['max_nodes']), address=noc_cfg['vc_w_id'][randrange( 0, noc_cfg['n_virt_chn'])], burst=AxiBurstType.FIXED, data=payload) assert result.resp == AxiResp.SLVERR, "AXI bus should have raised an error when writing with a not supported burst type" # Invalid memory address RD - reading in WR buffer await tb.arst(config_clk) sel_out = randrange(0, noc_cfg['max_nodes']) sel_in = sel_out while (sel_in == sel_out): sel_in = randrange(0, noc_cfg['max_nodes']) tb.dut.axi_sel_in.setimmediatevalue(sel_in) result = await tb.read(sel=sel_out, address=noc_cfg['vc_w_id'][randrange( 0, noc_cfg['n_virt_chn'])], length=0x1) assert result.resp == AxiResp.SLVERR, "AXI bus should have raised an error when reading to an invalid region of memory" # Invalid memory address RD - reading out of range await tb.arst(config_clk) sel_out = randrange(0, noc_cfg['max_nodes']) tb.dut.axi_sel_in.setimmediatevalue(sel_in) rand_addr = randrange(0, 2**32) while rand_addr in noc_cfg['vc_r_id']: rand_addr = randrange(0, 2**32) result = await tb.read(sel=sel_out, address=rand_addr, length=0x1) assert result.resp == AxiResp.SLVERR, "AXI bus should have raised an error when reading to an invalid region of memory" # Valid read region but empty await tb.arst(config_clk) sel_out = randrange(0, noc_cfg['max_nodes']) sel_in = sel_out while (sel_in == sel_out): sel_in = randrange(0, noc_cfg['max_nodes']) tb.dut.axi_sel_in.setimmediatevalue(sel_in) result = await tb.read(sel=sel_out, address=noc_cfg['vc_r_id'][randrange( 0, noc_cfg['n_virt_chn'])], length=0x1) assert result.resp == AxiResp.SLVERR, "AXI should have raise an error on this txn"
async def run_test(dut, config_clk="NoC_slwT_AXI", idle_inserter=None, backpressure_inserter=None): noc_flavor = os.getenv("FLAVOR") noc_cfg = noc_const.NOC_CFG[noc_flavor] # Setup testbench idle = "no_idle" if idle_inserter == None else "w_idle" backp = "no_backpressure" if backpressure_inserter == None else "w_backpressure" tb = Tb(dut, f"sim_{config_clk}_{idle}_{backp}", noc_cfg) tb.set_idle_generator(idle_inserter) tb.set_backpressure_generator(backpressure_inserter) await tb.setup_clks(config_clk) await tb.arst(config_clk) csr = noc_const.NOC_CSRs encode_mux = {} encode_mux['DEFAULT'] = bytearray(0) encode_mux['MUX_EMPTY_FLAGS'] = bytearray([1, 0, 0, 0]) encode_mux['MUX_FULL_FLAGS'] = bytearray([2, 0, 0, 0]) encode_mux['MUX_COMP_FLAGS'] = bytearray([3, 0, 0, 0]) # Check MUX_EMPTY_FLAGS pkt = RaveNoC_pkt(cfg=noc_cfg, virt_chn_id=0) # First we setup the dest router with the correct switch req = await tb.write(sel=pkt.dest[0], address=csr['IRQ_RD_MUX'], data=encode_mux['MUX_EMPTY_FLAGS'], size=0x2) assert req.resp == AxiResp.OKAY, "AXI bus should not have raised an error here!" await tb.write_pkt(pkt) irq_wait = (2**(pkt.virt_chn_id)) << (pkt.dest[0] * noc_cfg['n_virt_chn']) tb.log.info("IRQ val to wait: %d", irq_wait) await tb.wait_irq_x(irq_wait) # Now we use the mask to disable all the IRQs req = await tb.write(sel=pkt.dest[0], address=csr['IRQ_RD_MASK'], data=bytearray([0, 0, 0, 0]), size=0x2) assert tb.dut.irqs_out.value == 0, "No IRQs should be triggered on this scenario" # ... and we re-enable all the IRQs req = await tb.write(sel=pkt.dest[0], address=csr['IRQ_RD_MASK'], data=bytearray(str(2**32), 'utf-8'), size=0x2) assert tb.dut.irqs_out.value != 0, "IRQs should be triggered on this scenario" # Check MUX_FULL_FLAGS await tb.arst(config_clk) pkt = RaveNoC_pkt(cfg=noc_cfg) pkt_copy = [pkt for i in range(0, buff_rd_vc(pkt.virt_chn_id))] # First we setup the dest router with the correct switch req = await tb.write(sel=pkt.dest[0], address=csr['IRQ_RD_MUX'], data=encode_mux['MUX_FULL_FLAGS'], size=0x2) assert req.resp == AxiResp.OKAY, "AXI bus should not have raised an error here!" await tb.write_pkt(pkt) # Wait some time to ensure the pkt has arrived in the dest await ClockCycles(tb.dut.clk_noc, 15) if (buff_rd_vc(pkt.virt_chn_id) != 1): assert tb.dut.irqs_out.value == 0, "No IRQs should be triggered on this scenario" await tb.read_pkt(pkt) # Now we don't have more pkts for pkt in pkt_copy: await tb.write_pkt(pkt) assert req.resp == AxiResp.OKAY, "AXI bus should not have raised an error here!" irq_wait = (2**(pkt.virt_chn_id)) << (pkt.dest[0] * noc_cfg['n_virt_chn']) tb.log.info("IRQ val to wait: %d", irq_wait) await tb.wait_irq_x(irq_wait) # Now we use the mask to disable all the IRQs req = await tb.write(sel=pkt.dest[0], address=csr['IRQ_RD_MASK'], data=bytearray([0, 0, 0, 0]), size=0x2) assert tb.dut.irqs_out.value == 0, "No IRQs should be triggered on this scenario" # ... and we re-enable all the IRQs req = await tb.write(sel=pkt.dest[0], address=csr['IRQ_RD_MASK'], data=bytearray(str(2**32), 'utf-8'), size=0x2) assert tb.dut.irqs_out.value != 0, "IRQs should be triggered on this scenario" # Check MUX_COMP_FLAGS await tb.arst(config_clk) pkt = RaveNoC_pkt(cfg=noc_cfg) pkt_copy = [pkt for i in range(0, buff_rd_vc(pkt.virt_chn_id))] # First we setup the dest router with the correct switch req = await tb.write(sel=pkt.dest[0], address=csr['IRQ_RD_MUX'], data=encode_mux['MUX_COMP_FLAGS'], size=0x2) assert req.resp == AxiResp.OKAY, "AXI bus should not have raised an error here!" # In COMP mode, MASK will work as ref. for comparison, thus we set it to ZERO, so every buff will trigger it req = await tb.write(sel=pkt.dest[0], address=csr['IRQ_RD_MASK'], data=bytearray([0, 0, 0, 0]), size=0x2) await tb.write_pkt(pkt) await tb.wait_irq() assert tb.dut.irqs_out.value != 0, "IRQs should be triggered on this scenario" if (buff_rd_vc(pkt.virt_chn_id) != 1): # Now we change the comp. to >= 2 req = await tb.write(sel=pkt.dest[0], address=csr['IRQ_RD_MASK'], data=bytearray([2, 0, 0, 0]), size=0x2) assert tb.dut.irqs_out.value == 0, "No IRQs should be triggered on this scenario" #...bc we only sent one pkt # and we send another pkt await tb.write_pkt(pkt) # On this case IRQ should be triggered once we have >= 2 pkt sent await tb.wait_irq()
async def run_test(dut, config_clk="NoC_slwT_AXI", idle_inserter=None, backpressure_inserter=None): noc_flavor = os.getenv("FLAVOR") noc_cfg = noc_const.NOC_CFG[noc_flavor] # Setup testbench idle = "no_idle" if idle_inserter == None else "w_idle" backp = "no_backpressure" if backpressure_inserter == None else "w_backpressure" tb = Tb(dut, f"sim_{config_clk}_{idle}_{backp}", noc_cfg) tb.set_idle_generator(idle_inserter) tb.set_backpressure_generator(backpressure_inserter) await tb.setup_clks(config_clk) await tb.arst(config_clk) csr = noc_const.NOC_CSRs # RaveNoC Version router = randrange(0, noc_cfg['max_nodes']) resp = await tb.read(sel=router, address=csr['RAVENOC_VERSION'], length=4, size=0x2) assert resp.resp == AxiResp.OKAY, "AXI bus should not have raised an error here!" version = resp.data.decode( )[:: -1] # get object data, convert from bytearray to string with decode method and invert it assert version == noc_const.NOC_VERSION, "NoC version not matching with expected!" tb.log.info("NoC Version = %s", version) # Router X,Y coordinates check router = randrange(0, noc_cfg['max_nodes']) ref_pkt = RaveNoC_pkt( cfg=noc_cfg, src_dest=(router, 0 if router != 0 else 1)) # pkt not used, only to compare in the assertion resp_row = await tb.read(sel=router, address=csr['ROUTER_ROW_X_ID'], length=4, size=0x2) resp_col = await tb.read(sel=router, address=csr['ROUTER_COL_Y_ID'], length=4, size=0x2) assert resp_row.resp == AxiResp.OKAY, "AXI bus should not have raised an error here!" assert resp_col.resp == AxiResp.OKAY, "AXI bus should not have raised an error here!" resp_row = int.from_bytes(resp_row.data, byteorder='little', signed=False) resp_col = int.from_bytes(resp_col.data, byteorder='little', signed=False) assert resp_row == ref_pkt.src[1], "NoC CSR - Coordinate ROW not matching" assert resp_col == ref_pkt.src[2], "NoC CSR - Coordinate COL not matching" # IRQ registers router = randrange(0, noc_cfg['max_nodes']) resp = await tb.read(sel=router, address=csr['IRQ_RD_STATUS'], length=4, size=0x2) assert resp.resp == AxiResp.OKAY, "AXI bus should have raised an error here!" irq = resp.data.decode()[::-1] router = randrange(0, noc_cfg['max_nodes']) rand_data = bytearray(tb._get_random_string(length=4), 'utf-8') req = await tb.write(sel=router, address=csr['IRQ_RD_MUX'], data=rand_data, size=0x2) assert req.resp == AxiResp.OKAY, "AXI bus should have not raised an error here!" resp = await tb.read(sel=router, address=csr['IRQ_RD_MUX'], length=4, size=0x2) assert resp.resp == AxiResp.OKAY, "AXI bus should have raised an error here!" data_in = int.from_bytes(rand_data, byteorder='little', signed=False) data_out = int.from_bytes(resp.data, byteorder='little', signed=False) assert data_in == data_out, "NoC CSR, mismatch on IRQ_RD_MUX - Write/Read back" router = randrange(0, noc_cfg['max_nodes']) rand_data = bytearray(tb._get_random_string(length=4), 'utf-8') req = await tb.write(sel=router, address=csr['IRQ_RD_MASK'], data=rand_data, size=0x2) assert req.resp == AxiResp.OKAY, "AXI bus should not have raised an error here!" resp = await tb.read(sel=router, address=csr['IRQ_RD_MASK'], length=4, size=0x2) assert resp.resp == AxiResp.OKAY, "AXI bus should have raised an error here!" data_in = int.from_bytes(rand_data, byteorder='little', signed=False) data_out = int.from_bytes(resp.data, byteorder='little', signed=False) assert data_in == data_out, "NoC CSR, mismatch on IRQ_RD_MASK - Write/Read back" # Illegal operations not_writable = [ csr['RAVENOC_VERSION'], csr['ROUTER_ROW_X_ID'], csr['ROUTER_COL_Y_ID'], csr['IRQ_RD_STATUS'] ] not_writable.extend([(csr['IRQ_RD_MASK'] + 4 + 4 * x) for x in range(noc_cfg['n_virt_chn'])]) router = randrange(0, noc_cfg['max_nodes']) rand_data = bytearray(tb._get_random_string(length=4), 'utf-8') for not_wr in not_writable: req = await tb.write(sel=router, address=not_wr, data=rand_data, size=0x2) assert req.resp == AxiResp.SLVERR, "AXI bus should have raised an error here! ILLEGAL WR CSR:" + hex( not_wr) router = randrange(0, noc_cfg['max_nodes']) if noc_cfg['flit_data_width'] == 64: for i in csr: req = await tb.read(sel=router, address=csr[i], size=0x3) assert req.resp == AxiResp.SLVERR, "AXI bus should have raised an error here!" req = await tb.write(sel=router, address=csr[i], data=rand_data, size=0x3) assert req.resp == AxiResp.SLVERR, "AXI bus should have raised an error here!" # Testing RD_SIZE_VC[0,1,2...]_PKT for vc in range(noc_cfg['n_virt_chn']): await tb.arst(config_clk) msg_size = randrange(5, noc_cfg['max_sz_pkt']) msg = tb._get_random_string(length=msg_size) pkt = RaveNoC_pkt(cfg=noc_cfg, msg=msg, virt_chn_id=vc) write = cocotb.fork( tb.write_pkt(pkt, timeout=noc_const.TIMEOUT_AXI_EXT)) await tb.wait_irq() resp_csr = await tb.read(sel=pkt.dest[0], address=(csr['RD_SIZE_VC_START'] + 4 * vc), length=4, size=0x2) resp_pkt_size = int.from_bytes(resp_csr.data, byteorder='little', signed=False) assert resp_pkt_size == pkt.length_beats, "Mistmatch on CSR pkt size vs pkt sent!" resp = await tb.read_pkt(pkt, timeout=noc_const.TIMEOUT_AXI_EXT) tb.check_pkt(resp.data, pkt.msg)
async def run_test(dut, config_clk="NoC_slwT_AXI", idle_inserter=None, backpressure_inserter=None): noc_flavor = os.getenv("FLAVOR") noc_cfg = noc_const.NOC_CFG[noc_flavor] # Setup testbench idle = "no_idle" if idle_inserter == None else "w_idle" backp = "no_backpressure" if backpressure_inserter == None else "w_backpressure" tb = Tb(dut, f"sim_{config_clk}_{idle}_{backp}", noc_cfg) tb.set_idle_generator(idle_inserter) tb.set_backpressure_generator(backpressure_inserter) await tb.setup_clks(config_clk) await tb.arst(config_clk) # Populate all buffers of all vcs of all routers from router 0 pkts = [] for router in range(1, noc_cfg['max_nodes']): for vc in range(0, noc_cfg['n_virt_chn']): for flit_buff in range( 0, buff_rd_vc(vc) ): # We follow this Equation to discover how many buffs exists in each router / (RD_AXI_BFF(x) x<=2?(1<<x):4) print("Generating pkt - Router dest=%d Vc=%d flit_buff=%d", router, vc, flit_buff) pkts.append( RaveNoC_pkt(cfg=noc_cfg, src_dest=(0, router), virt_chn_id=vc)) for pkt in pkts: await tb.write_pkt(pkt) val = 0 for router in range(1, noc_cfg['max_nodes']): val += ( (2**noc_cfg['n_virt_chn']) - 1) << (router * noc_cfg['n_virt_chn']) # Wait for every pkts to be delivered tb.log.info("IRQs to wait:%d", val) await tb.wait_irq_x(val) for pkt in pkts: resp = await tb.read_pkt(pkt) tb.check_pkt(resp.data, pkt.msg) # Populate all vcs of router 0 from router 1 pkts = [] for vc in range(0, noc_cfg['n_virt_chn']): for flit_buff in range(0, 1 << vc): print("Generating pkt - Router dest=0 Vc=%d flit_buff=%d", vc, flit_buff) pkts.append( RaveNoC_pkt(cfg=noc_cfg, src_dest=(1, 0), virt_chn_id=vc)) for pkt in pkts: await tb.write_pkt(pkt) await tb.wait_irq() for pkt in pkts: resp = await tb.read_pkt(pkt) tb.check_pkt(resp.data, pkt.msg)