def __init__(self, dut, init_val): """ Setup the testbench. *init_val* signifies the ``BinaryValue`` which must be captured by the output monitor with the first rising clock edge. This must match the initial state of the D flip-flop in RTL. """ # Some internal state self.dut = dut self.stopped = False # Create input driver and output monitor self.input_drv = BitDriver(signal=dut.d, clk=dut.c, generator=input_gen()) self.output_mon = BitMonitor(name="output", signal=dut.q, clk=dut.c) # Create a scoreboard on the outputs self.expected_output = [init_val ] # a list with init_val as the first element with warnings.catch_warnings(): warnings.simplefilter("ignore") self.scoreboard = Scoreboard(dut) self.scoreboard.add_interface(self.output_mon, self.expected_output) # Use the input monitor to reconstruct the transactions from the pins # and send them to our 'model' of the design. self.input_mon = BitMonitor(name="input", signal=dut.d, clk=dut.c, callback=self.model)
def __init__(self, dut, debug=False): self.dut = dut self.stream_in = AvalonSTDriver(dut, "stream_in", dut.clk) self.backpressure = BitDriver(self.dut.stream_out_ready, self.dut.clk) self.stream_out = AvalonSTMonitor( dut, "stream_out", dut.clk, config={'firstSymbolInHighOrderBits': True}) self.csr = AvalonMaster(dut, "csr", dut.clk) cocotb.fork( stream_out_config_setter(dut, self.stream_out, self.stream_in)) # Create a scoreboard on the stream_out bus self.pkts_sent = 0 self.expected_output = [] with warnings.catch_warnings(): warnings.simplefilter("ignore") self.scoreboard = Scoreboard(dut) self.scoreboard.add_interface(self.stream_out, self.expected_output) # Reconstruct the input transactions from the pins # and send them to our 'model' self.stream_in_recovered = AvalonSTMonitor(dut, "stream_in", dut.clk, callback=self.model) # Set verbosity on our various interfaces level = logging.DEBUG if debug else logging.WARNING self.stream_in.log.setLevel(level) self.stream_in_recovered.log.setLevel(level)
class DFF_TB(object): def __init__(self, dut, init_val): """ Setup the testbench. *init_val* signifies the ``BinaryValue`` which must be captured by the output monitor with the first rising clock edge. This must match the initial state of the D flip-flop in RTL. """ # Some internal state self.dut = dut self.stopped = False # Create input driver and output monitor self.input_drv = BitDriver(signal=dut.d, clk=dut.c, generator=input_gen()) self.output_mon = BitMonitor(name="output", signal=dut.q, clk=dut.c) # Create a scoreboard on the outputs self.expected_output = [init_val ] # a list with init_val as the first element with warnings.catch_warnings(): warnings.simplefilter("ignore") self.scoreboard = Scoreboard(dut) self.scoreboard.add_interface(self.output_mon, self.expected_output) # Use the input monitor to reconstruct the transactions from the pins # and send them to our 'model' of the design. self.input_mon = BitMonitor(name="input", signal=dut.d, clk=dut.c, callback=self.model) def model(self, transaction): """Model the DUT based on the input *transaction*. For a D flip-flop, what goes in at ``d`` comes out on ``q``, so the value on ``d`` (put into *transaction* by our ``input_mon``) can be used as expected output without change. Thus we can directly append *transaction* to the ``expected_output`` list, except for the very last clock cycle of the simulation (that is, after ``stop()`` has been called). """ if not self.stopped: self.expected_output.append(transaction) def start(self): """Start generating input data.""" self.input_drv.start() def stop(self): """Stop generating input data. Also stop generation of expected output transactions. One more clock cycle must be executed afterwards so that the output of the D flip-flop can be checked. """ self.input_drv.stop() self.stopped = True
class AvalonSTTB(object): """Testbench for avalon basic stream""" def __init__(self, dut): self.dut = dut self.clkedge = RisingEdge(dut.clk) self.stream_in = AvalonSTDriver(self.dut, "asi", dut.clk) self.stream_out = AvalonSTMonitor(self.dut, "aso", dut.clk) with warnings.catch_warnings(): warnings.simplefilter("ignore") self.scoreboard = Scoreboard(self.dut, fail_immediately=True) self.expected_output = [] self.scoreboard.add_interface(self.stream_out, self.expected_output) self.backpressure = BitDriver(self.dut.aso_ready, self.dut.clk) async def initialise(self): self.dut.reset.value = 0 cocotb.fork(Clock(self.dut.clk, 10).start()) for _ in range(3): await self.clkedge self.dut.reset.value = 1 await self.clkedge async def send_data(self, data): exp_data = struct.pack("B",data) self.expected_output.append(exp_data) await self.stream_in.send(data)
def __init__(self, dut, clkperiod=6.4): self.dut = dut dut._discover_all() # scan all signals on the design dut._log.setLevel(logging.INFO) fork(Clock(dut.clk, clkperiod, 'ns').start()) self.payload_in = AXI4STPKts(dut, "payload_in", dut.clk) self.stream_out = AXI4STMonitor(dut, "packet_out", dut.clk, callback=self.print_trans) self.scoreboard = Scoreboard(dut, fail_immediately=False) self.expected_output = [] self.scoreboard.add_interface(self.stream_out, self.expected_output) self.nb_frame = 0 self.packet = BinaryValue()
class EndianSwapperTB(object): def __init__(self, dut, debug=False): self.dut = dut self.stream_in = AvalonSTDriver(dut, "stream_in", dut.clk) self.backpressure = BitDriver(self.dut.stream_out_ready, self.dut.clk) self.stream_out = AvalonSTMonitor( dut, "stream_out", dut.clk, config={'firstSymbolInHighOrderBits': True}) self.csr = AvalonMaster(dut, "csr", dut.clk) cocotb.fork( stream_out_config_setter(dut, self.stream_out, self.stream_in)) # Create a scoreboard on the stream_out bus self.pkts_sent = 0 self.expected_output = [] with warnings.catch_warnings(): warnings.simplefilter("ignore") self.scoreboard = Scoreboard(dut) self.scoreboard.add_interface(self.stream_out, self.expected_output) # Reconstruct the input transactions from the pins # and send them to our 'model' self.stream_in_recovered = AvalonSTMonitor(dut, "stream_in", dut.clk, callback=self.model) # Set verbosity on our various interfaces level = logging.DEBUG if debug else logging.WARNING self.stream_in.log.setLevel(level) self.stream_in_recovered.log.setLevel(level) def model(self, transaction): """Model the DUT based on the input transaction""" self.expected_output.append(transaction) self.pkts_sent += 1 async def reset(self, duration=20): self.dut._log.debug("Resetting DUT") self.dut.reset_n <= 0 self.stream_in.bus.valid <= 0 await Timer(duration, units='ns') await RisingEdge(self.dut.clk) self.dut.reset_n <= 1 self.dut._log.debug("Out of reset")
def __init__(self, dut): self.dut = dut self.clkedge = RisingEdge(dut.clk) self.stream_in = AvalonSTDriver(self.dut, "asi", dut.clk) self.stream_out = AvalonSTMonitor(self.dut, "aso", dut.clk) with warnings.catch_warnings(): warnings.simplefilter("ignore") self.scoreboard = Scoreboard(self.dut, fail_immediately=True) self.expected_output = [] self.scoreboard.add_interface(self.stream_out, self.expected_output) self.backpressure = BitDriver(self.dut.aso_ready, self.dut.clk)
async def mean_randomised_test(dut): """Test mean of random numbers multiple times""" # dut_in = StreamBusMonitor(dut, "i", dut.clk) # this doesn't work: # VPI Error vpi_get_value(): # ERROR - Cannot get a value for an object of type vpiArrayVar. dut_out = StreamBusMonitor(dut, "o", dut.clk) exp_out = [] with warnings.catch_warnings(): warnings.simplefilter("ignore") scoreboard = Scoreboard(dut) scoreboard.add_interface(dut_out, exp_out) DATA_WIDTH = int(dut.DATA_WIDTH.value) BUS_WIDTH = int(dut.BUS_WIDTH.value) dut._log.info('Detected DATA_WIDTH = %d, BUS_WIDTH = %d' % (DATA_WIDTH, BUS_WIDTH)) cocotb.fork(Clock(dut.clk, CLK_PERIOD_NS, units='ns').start()) dut.rst <= 1 for i in range(BUS_WIDTH): dut.i_data[i] <= 0 dut.i_valid <= 0 await RisingEdge(dut.clk) await RisingEdge(dut.clk) dut.rst <= 0 for j in range(10): nums = [] for i in range(BUS_WIDTH): x = random.randint(0, 2**DATA_WIDTH - 1) dut.i_data[i] <= x nums.append(x) dut.i_valid <= 1 nums_mean = sum(nums) // BUS_WIDTH exp_out.append(nums_mean) await RisingEdge(dut.clk) dut.i_valid <= 0 await RisingEdge(dut.clk) await RisingEdge(dut.clk)
def __init__( self, dut, test_name, expected_regfile_read=None, expected_regfile_write=None, expected_data_read=None, expected_data_write=None, instruction_memory=None, data_memory=None, enable_self_checking=True, pass_fail_address=None, pass_fail_values=None, output_address=None, timer_address=None, ): self.log = SimLog('cocotb.' + __name__ + '.' + self.__class__.__name__) self.test_name = test_name self.dut = dut self.clock = self.dut.clk self.reset_n = self.dut.rst core = self.dut self.reset_n.setimmediatevalue(0) self.pass_fail_address = pass_fail_address self.pass_fail_values = pass_fail_values self.output_address = output_address self.fake_uart = [] self.timer_counter = 0 self.timer_address = timer_address if self.timer_address is not None: cocotb.fork(self.timer()) self.end_test = Event() ## Process parameters self.memory = {**instruction_memory, **data_memory} if 'debug_test' in cocotb.plusargs: csv_path = Path(test_name + '_memory.csv') self.log.debug( f"Dumping initial memory content to {csv_path.resolve()}") memory = [(f'0x{k:X}', f'0x{v:X}') for k, v in self.memory.items()] csv_path.write_text( tabulate(memory, ['address', 'value'], tablefmt="plain")) self.end_i_address = None if enable_self_checking: self.end_i_address = max(instruction_memory.keys()) self.expected_regfile_read = [ RegFileReadTransaction.from_string(t) for t in expected_regfile_read ] self.expected_regfile_write = [ RegFileWriteTransaction.from_string(t) for t in expected_regfile_write ] self.expected_data_read = [ BusReadTransaction.from_string(t) for t in expected_data_read ] self.expected_data_write = [ BusWriteTransaction.from_string(t) for t in expected_data_write ] #self.log.debug(f"Instruction memory: {instruction_memory}") #self.log.debug(f"Data memory: {data_memory}") #self.log.debug(f"Memory: {self.memory}") ## Bus functional models prefix = None if not cocotb.plusargs.get('dut_copperv1', False): prefix = "bus_" self.bus_bfm = CoppervBusBfm(clock=self.clock, reset_n=self.reset_n, entity=self.dut, prefix=prefix) regfile_bfm = RegFileBfm(clock=self.clock, reset_n=self.reset_n, entity=core.regfile, signals=RegFileBfm.Signals( rd_en="rd_en", rd_addr="rd", rd_data="rd_din", rs1_en="rs1_en", rs1_addr="rs1", rs1_data="rs1_dout", rs2_en="rs2_en", rs2_addr="rs2", rs2_data="rs2_dout", )) ## Instruction read self.bus_ir_driver = BusSourceDriver("bus_ir", BusReadTransaction, self.bus_bfm.ir_send_response, self.bus_bfm.ir_drive_ready) self.bus_ir_monitor = BusMonitor("bus_ir", BusReadTransaction, self.bus_bfm.ir_get_request, self.bus_bfm.ir_get_response) self.bus_ir_req_monitor = BusMonitor("bus_ir_req", BusReadTransaction, self.bus_bfm.ir_get_request, callback=self.memory_callback, bus_name="bus_ir") ## Data read self.bus_dr_driver = BusSourceDriver("bus_dr", BusReadTransaction, self.bus_bfm.dr_send_response, self.bus_bfm.dr_drive_ready) self.bus_dr_monitor = BusMonitor("bus_dr", BusReadTransaction, self.bus_bfm.dr_get_request, self.bus_bfm.dr_get_response) self.bus_dr_req_monitor = BusMonitor("bus_dr_req", BusReadTransaction, self.bus_bfm.dr_get_request, callback=self.memory_callback, bus_name="bus_dr") ## Data write self.bus_dw_driver = BusSourceDriver("bus_dw", BusWriteTransaction, self.bus_bfm.dw_send_response, self.bus_bfm.dw_drive_ready) self.bus_dw_monitor = BusMonitor("bus_dw", BusWriteTransaction, self.bus_bfm.dw_get_request, self.bus_bfm.dw_get_response) self.bus_dw_req_monitor = BusMonitor("bus_dw_req", BusWriteTransaction, self.bus_bfm.dw_get_request, callback=self.memory_callback, bus_name="bus_dw") ## Regfile self.regfile_write_monitor = RegFileWriteMonitor( "regfile_write", regfile_bfm) self.regfile_read_monitor = RegFileReadMonitor("regfile_read", regfile_bfm) ## Stack Monitor #StackMonitor(self.regfile_write_monitor) if enable_self_checking: ## Self checking self.scoreboard = Scoreboard(dut) self.scoreboard.add_interface(self.regfile_write_monitor, self.expected_regfile_write) self.scoreboard.add_interface(self.regfile_read_monitor, self.expected_regfile_read) self.scoreboard.add_interface(self.bus_dr_monitor, self.expected_data_read) self.scoreboard.add_interface(self.bus_dw_monitor, self.expected_data_write)
class Testbench(): def __init__( self, dut, test_name, expected_regfile_read=None, expected_regfile_write=None, expected_data_read=None, expected_data_write=None, instruction_memory=None, data_memory=None, enable_self_checking=True, pass_fail_address=None, pass_fail_values=None, output_address=None, timer_address=None, ): self.log = SimLog('cocotb.' + __name__ + '.' + self.__class__.__name__) self.test_name = test_name self.dut = dut self.clock = self.dut.clk self.reset_n = self.dut.rst core = self.dut self.reset_n.setimmediatevalue(0) self.pass_fail_address = pass_fail_address self.pass_fail_values = pass_fail_values self.output_address = output_address self.fake_uart = [] self.timer_counter = 0 self.timer_address = timer_address if self.timer_address is not None: cocotb.fork(self.timer()) self.end_test = Event() ## Process parameters self.memory = {**instruction_memory, **data_memory} if 'debug_test' in cocotb.plusargs: csv_path = Path(test_name + '_memory.csv') self.log.debug( f"Dumping initial memory content to {csv_path.resolve()}") memory = [(f'0x{k:X}', f'0x{v:X}') for k, v in self.memory.items()] csv_path.write_text( tabulate(memory, ['address', 'value'], tablefmt="plain")) self.end_i_address = None if enable_self_checking: self.end_i_address = max(instruction_memory.keys()) self.expected_regfile_read = [ RegFileReadTransaction.from_string(t) for t in expected_regfile_read ] self.expected_regfile_write = [ RegFileWriteTransaction.from_string(t) for t in expected_regfile_write ] self.expected_data_read = [ BusReadTransaction.from_string(t) for t in expected_data_read ] self.expected_data_write = [ BusWriteTransaction.from_string(t) for t in expected_data_write ] #self.log.debug(f"Instruction memory: {instruction_memory}") #self.log.debug(f"Data memory: {data_memory}") #self.log.debug(f"Memory: {self.memory}") ## Bus functional models prefix = None if not cocotb.plusargs.get('dut_copperv1', False): prefix = "bus_" self.bus_bfm = CoppervBusBfm(clock=self.clock, reset_n=self.reset_n, entity=self.dut, prefix=prefix) regfile_bfm = RegFileBfm(clock=self.clock, reset_n=self.reset_n, entity=core.regfile, signals=RegFileBfm.Signals( rd_en="rd_en", rd_addr="rd", rd_data="rd_din", rs1_en="rs1_en", rs1_addr="rs1", rs1_data="rs1_dout", rs2_en="rs2_en", rs2_addr="rs2", rs2_data="rs2_dout", )) ## Instruction read self.bus_ir_driver = BusSourceDriver("bus_ir", BusReadTransaction, self.bus_bfm.ir_send_response, self.bus_bfm.ir_drive_ready) self.bus_ir_monitor = BusMonitor("bus_ir", BusReadTransaction, self.bus_bfm.ir_get_request, self.bus_bfm.ir_get_response) self.bus_ir_req_monitor = BusMonitor("bus_ir_req", BusReadTransaction, self.bus_bfm.ir_get_request, callback=self.memory_callback, bus_name="bus_ir") ## Data read self.bus_dr_driver = BusSourceDriver("bus_dr", BusReadTransaction, self.bus_bfm.dr_send_response, self.bus_bfm.dr_drive_ready) self.bus_dr_monitor = BusMonitor("bus_dr", BusReadTransaction, self.bus_bfm.dr_get_request, self.bus_bfm.dr_get_response) self.bus_dr_req_monitor = BusMonitor("bus_dr_req", BusReadTransaction, self.bus_bfm.dr_get_request, callback=self.memory_callback, bus_name="bus_dr") ## Data write self.bus_dw_driver = BusSourceDriver("bus_dw", BusWriteTransaction, self.bus_bfm.dw_send_response, self.bus_bfm.dw_drive_ready) self.bus_dw_monitor = BusMonitor("bus_dw", BusWriteTransaction, self.bus_bfm.dw_get_request, self.bus_bfm.dw_get_response) self.bus_dw_req_monitor = BusMonitor("bus_dw_req", BusWriteTransaction, self.bus_bfm.dw_get_request, callback=self.memory_callback, bus_name="bus_dw") ## Regfile self.regfile_write_monitor = RegFileWriteMonitor( "regfile_write", regfile_bfm) self.regfile_read_monitor = RegFileReadMonitor("regfile_read", regfile_bfm) ## Stack Monitor #StackMonitor(self.regfile_write_monitor) if enable_self_checking: ## Self checking self.scoreboard = Scoreboard(dut) self.scoreboard.add_interface(self.regfile_write_monitor, self.expected_regfile_write) self.scoreboard.add_interface(self.regfile_read_monitor, self.expected_regfile_read) self.scoreboard.add_interface(self.bus_dr_monitor, self.expected_data_read) self.scoreboard.add_interface(self.bus_dw_monitor, self.expected_data_write) async def timer(self): while True: await RisingEdge(self.clock) self.timer_counter += 1 def memory_callback(self, transaction): self.log.debug(f"Memory callback {transaction}") if isinstance(transaction, BusReadTransaction) and transaction.bus_name == 'bus_ir': driver_transaction = "deassert_ready" if self.end_i_address is None or ( self.end_i_address is not None and transaction.addr < self.end_i_address): driver_transaction = BusReadTransaction( bus_name=transaction.bus_name, data=from_array(self.memory, transaction.addr), addr=transaction.addr) self.bus_ir_driver.append(driver_transaction) #self.log.debug('instruction_read_callback transaction: %s driver_transaction %s', # transaction,driver_transaction) elif isinstance( transaction, BusReadTransaction) and transaction.bus_name == 'bus_dr': driver_transaction = BusReadTransaction( bus_name=transaction.bus_name, data=self.handle_data_read(transaction), addr=transaction.addr, ) self.bus_dr_driver.append(driver_transaction) #self.log.debug('data_read_callback transaction: %s driver_transaction %s', # transaction,driver_transaction) elif isinstance(transaction, BusWriteTransaction): self.handle_data_write(transaction) driver_transaction = BusWriteTransaction( bus_name=transaction.bus_name, data=transaction.data, addr=transaction.addr, strobe=transaction.strobe, response=1, ) self.bus_dw_driver.append(driver_transaction) #self.log.debug('data_write_callback transaction: %s driver_transaction %s', # transaction,driver_transaction) else: raise ValueError(f"Unsupported transaction type: {transaction}") def handle_data_write(self, transaction): if self.pass_fail_address is not None and self.pass_fail_address == transaction.addr: if len(self.fake_uart) > 0: self.log.info("Fake UART output:\n%s", ''.join(self.fake_uart)) assert self.pass_fail_values[ transaction.data] == True, "Received test fail from bus" self.log.debug("Received test pass from bus") self.end_test.set() elif self.output_address is not None and self.output_address == transaction.addr: recv = chr(transaction.data) self.fake_uart.append(recv) self.log.info('Fake UART received: %s', repr(recv)) else: mask = f"{transaction.strobe:04b}" #self.log.debug('write start: %X mask: %s',from_array(self.memory,transaction.addr),mask) for i in range(4): if int(mask[3 - i]): #self.log.debug('writing %X -> %X',transaction.addr+i,to_bytes(transaction.data)[i]) self.memory[transaction.addr + i] = to_bytes( transaction.data)[i] #self.log.debug('write finished: %X',from_array(self.memory,transaction.addr)) def handle_data_read(self, transaction): value = None if self.timer_address is not None and self.timer_address == transaction.addr: value = self.timer_counter else: value = from_array(self.memory, transaction.addr) return value @cocotb.coroutine async def finish(self): last_pending = "" while True: if all([ len(expected) == 0 for expected in self.scoreboard.expected.values() ]): break pending = repr({ k.name: [str(i) for i in v] for k, v in self.scoreboard.expected.items() }) if last_pending != pending: self.log.debug(f"Pending transactions: {pending}") last_pending = pending await RisingEdge(self.clock) await ClockCycles(self.clock, 2)
def test_dut(dut): ''' The testbench: * binds the interfaces * Loads the Key * Loads the IV in the ICB * Sends the AAD data through the pipeline * Sends the PT data through the pipeline * Checks the CT and the MAC match the model ''' # Create the lists of transactions aad_tran = [] pt_tran = [] aad_model_tran = [] pt_model_tran = [] tb = gcm_gctr(dut) # Open config file with open('./tmp/' + str(cocotb.RANDOM_SEED) + '.json', 'r') as config_file: tb.config = dict(json.load(config_file)) # Generate configuration data tb.config_data() # Initialise GCM model dut_model = gcm_model.gcm(tb.data['key'], tb.data['iv']) # Create drivers pkt_drv = pkt_driver(dut.clk_i, dut.aes_gcm_ghash_pkt_val_i) aad_drv = aad_driver(dut.clk_i, dut.aes_gcm_ghash_aad_bval_i, dut.aes_gcm_ghash_aad_i) pt_drv = pt_driver(dut.clk_i, dut.aes_gcm_plain_text_bval_i, dut.aes_gcm_plain_text_i, dut.aes_gcm_cipher_ready_o) # Create delay function delay = wait_for(dut.clk_i, RisingEdge) # Get the AES mode dut._log.info('AES mode: ' + tb.config['aes_mode']) # Get AES key size dut._log.info('AES size: ' + tb.config['aes_size']) # Release the Reset cocotb.fork(tb.release_rst(RST_WINDOW)) # Start the Clock cocotb.fork(Clock(dut.clk_i, CLK_PERIOD, 'ns').start()) # Wait for the Reset falling edge event yield FallingEdge(dut.rst_i) # Wait few clocks yield ClockCycles(dut.clk_i, random.randint(10, 20)) # Create the sequencer seq = sequencer(pkt_drv, aad_drv, pt_drv, delay.n_clk, tb.data, str(tb.config['seed']), aad_tran, pt_tran) # Create monitors mon_aad = gcm_AAD_monitor("Get AAD", dut, dut_model.load_aad) mon_pt = gcm_PT_monitor("Get PT", dut, dut_model.load_plain_text) mon_ct = gcm_CT_monitor("Get CT", dut) mon_tag = gcm_TAG_monitor("Get TAG", dut, dut_model.get_tag) # Create scoreboard scoreboard = Scoreboard(dut) # Add scoreboard interfaces scoreboard.add_interface(mon_aad, aad_model_tran) scoreboard.add_interface(mon_pt, pt_model_tran) scoreboard.add_interface(mon_ct, dut_model.ct) scoreboard.add_interface(mon_tag, dut_model.tag) # Set AES key mode yield tb.aes_set_mode() # Load the KEY if (tb.config['key_pre_exp'] == True): yield tb.load_pre_exp_key(tb.data['key']) else: yield tb.load_key(tb.data['key']) # Load the ICB yield tb.load_iv(tb.data['iv']) # Start The ICB yield tb.start_icb() # Wait the AES to produce cipher data yield tb.cipher_is_ready() # Set the number of AAD transactions n_transaction = tb.data['aad_n_bytes'] >> 4 if tb.data['aad_n_bytes'] & 0xF: n_transaction += 1 dut._log.info('\n' + str(n_transaction) + " AAD transactions to read") # Set the number of PT transactions n_transaction = tb.data['pt_n_bytes'] >> 4 if tb.data['pt_n_bytes'] & 0xF: n_transaction += 1 dut._log.info(str(n_transaction) + " PT transactions to read\n") # Start the sequencer seq.start_sequencer() # Encrypt data yield tb.encrypt_data(tb.data['aad_n_bytes'], tb.data['pt_n_bytes'], aad_tran, pt_tran, aad_model_tran, pt_model_tran) # Wait for the test to finish while dut.aes_gcm_ghash_tag_val_o.value == 0: yield RisingEdge(dut.clk_i) last_cycles = ClockCycles(dut.clk_i, 20) yield last_cycles
class deparser_TB(object): def __init__(self, dut, clkperiod=6.4): self.dut = dut dut._discover_all() # scan all signals on the design dut._log.setLevel(logging.INFO) fork(Clock(dut.clk, clkperiod, 'ns').start()) self.payload_in = AXI4STPKts(dut, "payload_in", dut.clk) self.stream_out = AXI4STMonitor(dut, "packet_out", dut.clk, callback=self.print_trans) self.scoreboard = Scoreboard(dut, fail_immediately=False) self.expected_output = [] self.scoreboard.add_interface(self.stream_out, self.expected_output) self.nb_frame = 0 self.packet = BinaryValue() """ Dictionnary to convert scapy name to VHDL. structure : scapyName: [VHDLname, length in bits] """ name_to_VHDL = { "Ether": ["ethernet", 112], "IP": ["ipv4", 160], "TCP": ["tcp", 160], "UDP": ["udp", 64], "IPv6": ["ipv6", 320]} @coroutine def async_rst(self): """ This function execute the reset_n for 40ns it also set all input signals to default value """ self.dut._log.info("begin Rst") for n, t in self.dut._sub_handles.items(): if isinstance(t, handle.ModifiableObject): t.value = 0 yield Timer(40, 'ns') self.dut.reset_n.value = 1 yield Timer(15, 'ns') self.dut._log.info("end Rst") def print_trans(self, transaction): self.dut._log.info("Frame : {}, {}B:{}".format(self.nb_frame, len(transaction.buff), transaction)) self.packet.buff += transaction.buff self.nb_frame += 1 if self.dut.packet_out_tlast == 1: print(self.packet.buff) if len(self.packet.binstr) < 6*8: self.dut._log.warning("received packet lesser than 6Bytes\n" "received :\n{}".format(self.packet.binstr)) else: print("received :\n{}".format(raw(BinaryValue_to_scapy(self.packet)))) self.packet = BinaryValue() # BinaryValue_to_scapy(self.packet).display() # self.dut._log.info("received {}B : {}".format( # len(self.packet.buff), # self.packet.binstr)) def set_PHV(self, pkt, payload=None): """ set PHV for deparser """ scap_to_PHV(self.dut, pkt, self.name_to_VHDL) full_hdr = scapy_to_BinaryValue(pkt) print("emitted {} bytes : \n {}".format(len(raw(pkt)), raw(pkt))) self.dut._log.info("send {}B : {}".format(len(full_hdr.buff), full_hdr.binstr)) new_output = PHVDeparser(len(self.dut.packet_out_tdata), full_hdr) self.expected_output.extend(new_output)