コード例 #1
0
ファイル: test.py プロジェクト: l-n-x/fejkon
class Thing:
    def __init__(self, dut):
        self.dut = dut
        self.st_in = AvalonSTDriver(dut, 'st_in', dut.clk)
        self.st_out = AvalonSTMonitor(dut, 'st_out', dut.clk)
        self.csr = AvalonMaster(dut, 'csr', dut.clk)
        self.st_in_recovered = AvalonSTMonitor(dut,
                                               'st_in',
                                               dut.clk,
                                               callback=self.model)
        self.expected_output = []
        self.scoreboard = Scoreboard(dut)
        self.scoreboard.add_interface(self.st_out, self.expected_output)

    def model(self, transaction):
        """Model the DUT based on the input transaction."""
        self.expected_output.append(transaction)
        self.st_in_recovered.log.info(hexdump(transaction))

    async def reset(self):
        self.dut.reset <= 1
        await Timer(50, units='us')
        self.dut.reset <= 0
        self.dut.st_out_ready <= 1
        self.dut.reset._log.debug('Reset complete')
コード例 #2
0
class TB(object):
    def __init__(self, dut):
        # Some internal state
        self.dut = dut
        self.stopped = False

        # 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.Zybo_Example_sw_in, clk=dut.clk,
                                    callback=self.model)

        # Create input driver and output monitor
        self.input_drv = BitDriver(signal=dut.Zybo_Example_sw_in, clk=dut.clk, generator=input_gen())
        self.output_mon = BitMonitor(name="output", signal=dut.Zybo_Example_leds_out, clk=dut.clk)

        # Create a scoreboard on the outputs
        self.expected_output = []
        self.scoreboard = Scoreboard(dut)
        self.scoreboard.add_interface(self.output_mon, self.expected_output)

    def model(self, transaction):
        if not self.stopped:
            self.expected_output.append(transaction)

    def start(self):
        self.input_drv.start()

    def stop(self):
        self.input_drv.stop()
        self.stopped = True
コード例 #3
0
class Thing:
    """Commmon test logic for all tests."""
    def __init__(self, dut):
        self.dut = dut
        # TODO: See https://github.com/cocotb/cocotb/issues/2051 for Verilator freeze bug
        self.userrx = AvalonSTMonitor(dut, 'userrx', dut.rx_clk)
        self.tx_csr = AvalonMaster(dut, 'tx_mm', dut.tx_clk)
        self.rx_csr = AvalonMaster(dut, 'rx_mm', dut.rx_clk)
        self.expected_output = []
        self.scoreboard = Scoreboard(dut)
        self.scoreboard.add_interface(self.userrx, self.expected_output)

    @staticmethod
    async def new(dut):
        rx_clock = Clock(dut.rx_clk, 10, units='us')
        tx_clock = Clock(dut.tx_clk, 10, units='us')
        cocotb.fork(rx_clock.start())
        cocotb.fork(tx_clock.start())
        # Ensure the bus is in a known and quiet state before starting the monitors
        await Thing.reset(dut)
        return Thing(dut)

    @staticmethod
    async def reset(dut):
        dut.reset <= 1
        await Timer(30, units='us')
        dut.reset <= 0
        dut.avtx_ready <= 1
        dut.reset._log.info('Reset complete')
コード例 #4
0
ファイル: test_avalon_stream.py プロジェクト: rami0r/cocotb
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)

    @cocotb.coroutine
    def initialise(self):
        self.dut.reset <= 0
        cocotb.fork(Clock(self.dut.clk, 10).start())
        for _ in range(3):
            yield self.clkedge
        self.dut.reset <= 1
        yield self.clkedge

    @cocotb.coroutine
    def send_data(self, data):
        exp_data = struct.pack("B", data)
        self.expected_output.append(exp_data)
        yield self.stream_in.send(data)
コード例 #5
0
async def test_tdata(dut, packets_num=5, packet_size=(10, 100), delay=-1, consecutive_transfers=0):
    """Test TDATA"""

    tdata_width = dut.C_S_AXIS_TDATA_WIDTH.value.integer

    axis_m = Axi4StreamMaster(dut, "s_axis", dut.aclk)
    axis_s = Axi4StreamSlave(dut, "m_axis", dut.aclk, delay, consecutive_transfers)
    axis_monitor = Axi4Stream(dut, "m_axis", dut.aclk, data_type="integer", packets=True)

    await setup_dut(dut)

    input = []
    output = []

    # Build the input and output packets
    for i in range(packets_num):
        input.append([randint(0, 2**tdata_width - 1) for i in range(randint(*packet_size))])
        output.append([word ^ 2**tdata_width - 1 for word in input[-1]])

    scoreboard = Scoreboard(dut)
    scoreboard.add_interface(axis_monitor, output)

    # Write the input packets
    for packet in input:
        await axis_m.write(packet)

    # Wait until output is empty (so, all the packets have been received)
    while output:
        await RisingEdge(dut.aclk)

    await RisingEdge(dut.aclk)
コード例 #6
0
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
コード例 #7
0
ファイル: test.py プロジェクト: bluecmd/fejkon
class Thing:
    """Commmon test logic for all tests."""
    def __init__(self, dut):
        self.dut = dut
        self.st_in = AvalonSTDriver(dut, 'st_in', dut.clk)
        self.st_out = AvalonSTMonitor(dut, 'st_out', dut.clk)
        self.csr = AvalonMaster(dut, 'csr', dut.clk)
        self.st_in_recovered = AvalonSTMonitor(dut,
                                               'st_in',
                                               dut.clk,
                                               callback=self.model)
        self.expected_output = []
        self.scoreboard = Scoreboard(dut)
        self.scoreboard.add_interface(self.st_out, self.expected_output)

    @staticmethod
    async def new(dut):
        # Ensure the bus is in a known and quiet state before starting the monitors
        await Thing.reset(dut)
        return Thing(dut)

    @staticmethod
    async def reset(dut):
        dut.reset <= 1
        await Timer(50, units='us')
        dut.reset <= 0
        dut.st_out_ready <= 1
        dut.reset._log.debug('Reset complete')

    def model(self, transaction):
        """Model the DUT based on the input transaction."""
        self.expected_output.append(transaction)
        self.st_in_recovered.log.info(hexdump(transaction))
コード例 #8
0
def mean_mdv_test(dut):
    """ Test using functional coverage measurements and 
        Constrained-Random mechanisms. Generates random transactions
        until coverage defined in Driver reaches 100% """

    dut_out = StreamBusMonitor(dut, "o", dut.clk)
    dut_in = StreamBusDriver(dut, "i", dut.clk)

    exp_out = []
    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_gen(dut.clk, period=clock_period))

    dut.rst <= 1
    for i in range(bus_width):
        dut.i_data[i] = 0
    dut.i_valid <= 0
    yield RisingEdge(dut.clk)
    yield RisingEdge(dut.clk)
    dut.rst <= 0

    coverage1_hits = []
    coverageN_hits = []

    #define a constraint function, which prevents from picking already covered data
    def data_constraint(data):
        return (not data[0] in coverage1_hits) & (not data[bus_width - 1]
                                                  in coverageN_hits)

    coverage = 0
    xaction = StreamTransaction(bus_width, data_width)
    while coverage < 100:

        #randomize without constraint
        #xaction.randomize()

        #randomize with constraint
        if not "top.data1" in cocotb.coverage.coverage_db:
            xaction.randomize()
        else:
            coverage1_new_bins = cocotb.coverage.coverage_db[
                "top.data1"].new_hits
            coverageN_new_bins = cocotb.coverage.coverage_db[
                "top.dataN"].new_hits
            coverage1_hits.extend(coverage1_new_bins)
            coverageN_hits.extend(coverageN_new_bins)
            xaction.randomize_with(data_constraint)

        yield dut_in.send(xaction)
        exp_out.append(xaction.mean_value())
        coverage = cocotb.coverage.coverage_db[
            "top"].coverage * 100 / cocotb.coverage.coverage_db["top"].size
        dut._log.info("Current Coverage = %d %%", coverage)
コード例 #9
0
class HashEngineTB(object):
    def __init__(self, dut, codec, debug=False):
        dut._log.info(
            f"Preparing tb for hashing-engine, codec={Sha.resolve_name(codec)}"
        )
        self.dut = dut
        self.codec = codec  # sha_type_actual
        self.sha = Sha.get_method(codec)

        self.s_axis = AXIS_Driver(dut, "s_axis", dut.axis_aclk)
        self.backpressure = BitDriver(dut.m_axis_tready, dut.axis_aclk)
        self.m_axis = AXIS_Monitor(dut, "m_axis", dut.axis_aclk)

        self.expected_output = []

        # Create a scoreboard on the m_axis bus
        with warnings.catch_warnings():
            warnings.simplefilter("ignore")
            self.scoreboard = Scoreboard(dut)
        self.scoreboard.add_interface(self.m_axis, self.expected_output)

        # Reconstrut the input transactions
        self.s_axis_recovered = AXIS_Monitor(dut,
                                             "s_axis",
                                             dut.axis_aclk,
                                             callback=self.model)

        level = logging.DEBUG if debug else logging.WARNING
        self.s_axis.log.setLevel(level)
        self.s_axis_recovered.log.setLevel(level)

    async def reset(self, duration=2):
        self.dut._log.debug("Resetting DUT")
        self.dut.axis_resetn <= 0
        await Timer(duration, units='ns')
        await RisingEdge(self.dut.axis_aclk)
        self.dut.axis_resetn <= 1
        self.dut._log.debug("Out of reset")

    def model(self, transaction):
        message = transaction['data']
        self.dut._log.debug(f'Incoming message={message}')
        self.dut._log.debug(f'Length={len(message)}')

        # sha = hashlib.sha256()
        # sha.update(message)
        # digest = sha.digest()
        self.sha.init()
        self.sha.padder(message)
        self.sha.wt_transaction()
        digest = self.sha.digest()

        self.expected_output.append({
            'data':
            digest,
            'user':
            80 * '0' + little_endian_codec(self.codec) + 32 * '0'
        })
コード例 #10
0
ファイル: DspBlockTB.py プロジェクト: grebe/adi-bbp
class DspBlockTB(object):
    def __init__(self, dut, debug=False):
        self.dut = dut
        self.stream_in = STDriver(dut,
                                  "ValNamein_0",
                                  dut.clock,
                                  name_map=axi4stream_chisel_name_map)
        self.backpressure = BitDriver(self.dut.out_0_ready, self.dut.clock)
        self.stream_out = STMonitor(dut,
                                    "out_0",
                                    dut.clock,
                                    name_map=axi4stream_chisel_name_map)

        self.csr = MemMaster(dut,
                             "ValNameioMem_0",
                             dut.clock,
                             name_map=axi4_chisel_name_map)
        self.set_rotation(0)

        # Reconstruct the input transactions from the pins
        # and send them to our 'model'
        self.stream_in_recovered = STMonitor(
            dut,
            "ValNamein_0",
            dut.clock,
            callback=self.model,
            name_map=axi4stream_chisel_name_map)

        # Create a scoreboard on the stream_out bus
        self.pkts_sent = 0
        self.expected_output = []
        self.scoreboard = Scoreboard(dut)
        self.scoreboard.add_interface(self.stream_out, self.expected_output)

        # 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 set_rotation(self, rotation):
        self.rotation = rotation
        return self.csr.write(0, self.rotation)

    def model(self, transaction):
        """Model the DUT based on the input transaction"""
        ## TODO apply rotation
        self.expected_output.append(transaction)
        self.pkts_sent += 1

    @cocotb.coroutine
    def reset(self, duration=10):
        self.dut._log.debug("Resetting DUT")
        self.dut.reset <= 1
        self.stream_in.bus.TVALID <= 0
        yield Timer(duration, units='ns')
        yield RisingEdge(self.dut.clock)
        self.dut.reset <= 0
        self.dut._log.debug("Out of reset")
コード例 #11
0
ファイル: FFTTB.py プロジェクト: grebe/adi-bbp
class FFTTB:
    def __init__(self, dut, debug: bool = False):
        self._dut = dut
        self._fft_in = DecoupledDriver(self._dut, "in", self._dut.clock)
        self._fft_mon = FFTMonitor(self._dut, self._dut.clock)
        self._backpressure = BitDriver(self._dut.out_ready, self._dut.clock)

        self._scoreboard = Scoreboard(self._dut)
        self._scoreboard.add_interface(self._fft_mon._mon_out,
                                       self._fft_mon._expected_output)
コード例 #12
0
class axistream_fifo_TB(object):
    def __init__(self, dut):
        self.dut = dut
        self.stream_in = AXI4ST_driver(dut, "stream_in", dut.clk)
        #self.stream_in.log.setLevel(logging.DEBUG)
        self.stream_out = AXI4STMonitor(dut,
                                        "stream_out",
                                        dut.clk,
                                        callback=self.print_trans)
        self.expected_output = []
        self.overrideModel = False  # temp help to differentiate scapy to other send
        self.scoreboard = Scoreboard(dut, fail_immediately=False)
        self.scoreboard.add_interface(self.stream_out, self.expected_output)
        self.stream_in_recovered = AXI4STMonitor(dut,
                                                 "stream_in",
                                                 dut.clk,
                                                 callback=self.model)

    def print_trans(self, transaction):
        #        pkt = BinaryValue_to_scapy(transaction)
        print("received transaction {}".format(transaction))


#        pkt_buf = scapy_to_BinaryValue(pkt)
#        print("from packet {}".format(pkt_buf))
#        pkt.display()

    def model(self, transaction):
        """ Model the expected output based on input
        """
        if not self.overrideModel:
            self.expected_output.append(transaction)

    def send(self, pkt):
        if isinstance(pkt, scapy_pkt):
            self.overrideModel = True
            self.expected_output.append(scapy_to_BinaryValue(pkt))
        self.stream_in.append(pkt)
        self.overrideModel = False

    @cocotb.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")
        self.dut.reset_n <= 0
        self.dut.stream_in_tdata <= 0
        self.dut.stream_in_tlast <= 0
        self.dut.stream_in_tvalid <= 0
        self.dut.stream_out_tready <= 0
        yield Timer(40, 'ns')
        self.dut.reset_n <= 1
        yield Timer(15, 'ns')
        self.dut._log.info("end Rst")
コード例 #13
0
class PadderTB(object):
    def __init__(self, dut, codec, debug=False):
        dut._log.info("Preparing tb for padder, codec={codec}")
        self.dut = dut
        self.codec = codec  # sha_type_actual
        self.sha = Sha.get_method(codec=codec)

        self.s_axis = AXIS_Driver(dut, "s_axis", dut.axis_aclk)
        self.backpressure = BitDriver(dut.m_axis_tready, dut.axis_aclk)
        self.m_axis = AXIS_Monitor(dut, "m_axis", dut.axis_aclk)

        self.expected_output = []

        # Create a scoreboard on the m_axis bus
        with warnings.catch_warnings():
            warnings.simplefilter("ignore")
            self.scoreboard = Scoreboard(dut)
        self.scoreboard.add_interface(self.m_axis, self.expected_output)

        # Reconstrut the input transactions
        self.s_axis_recovered = AXIS_Monitor(dut,
                                             "s_axis",
                                             dut.axis_aclk,
                                             callback=self.model)

        level = logging.DEBUG if debug else logging.WARNING
        self.s_axis.log.setLevel(level)
        self.s_axis_recovered.log.setLevel(level)

    async def reset(self, duration=2):
        self.dut._log.debug("Resetting DUT")
        self.dut.axis_resetn <= 0
        await Timer(duration, units='ns')
        await RisingEdge(self.dut.axis_aclk)
        self.dut.axis_resetn <= 1
        self.dut._log.debug("Out of reset")

    def model(self, transaction):
        message = transaction['data']
        self.dut._log.debug(f'Incoming message={message}')
        self.dut._log.debug(f'Length={len(message)}')

        self.sha.init()
        message = self.sha.padder(message)
        self.expected_output.append({
            'data':
            message,
            'user':
            80 * '0' + little_endian_codec(self.codec) + 32 * '0'
        })

        while message:
            self.dut._log.debug("Message block to be received: {}".format(
                message[0:DATA_BYTE_WIDTH]))
            message = message[DATA_BYTE_WIDTH:]
コード例 #14
0
class DigestTB(object):
    def __init__(self, dut, codec, debug=False):
        self.dut = dut
        self.codec = codec
        self.sha = Sha.get_method(codec)

        self.dut._log.info("Configure driver, monitors and scoreboard")
        self.s_axis = AXIS_Driver(dut,
                                  "s_axis",
                                  dut.axis_aclk,
                                  lsb_first=False)
        self.backpressure = BitDriver(dut.m_axis_tready, dut.axis_aclk)
        self.m_axis = AXIS_Monitor(dut, "m_axis", dut.axis_aclk)

        self.expected_output = []

        # Create a scoreboard on the m_axis bus
        with warnings.catch_warnings():
            warnings.simplefilter("ignore")
            self.scoreboard = Scoreboard(dut)
        self.scoreboard.add_interface(self.m_axis, self.expected_output)

        # Reconstrut the input transactions
        self.s_axis_recovered = AXIS_Monitor(dut,
                                             "s_axis",
                                             dut.axis_aclk,
                                             callback=self.model,
                                             lsb_first=False)

        level = logging.DEBUG if debug else logging.WARNING
        self.s_axis.log.setLevel(level)
        self.s_axis_recovered.log.setLevel(level)

    async def reset(self, duration=2):
        self.dut._log.debug("Resetting DUT")
        self.dut.axis_resetn <= 0
        await Timer(duration, units='ns')
        await RisingEdge(self.dut.axis_aclk)
        self.dut.axis_resetn <= 1
        self.dut._log.debug("Out of reset")

    def model(self, transaction):
        message = transaction['data']
        #print(f'Transaction = {transaction}')
        print(message)
        self.sha.init()
        digest = self.sha.digest(message)
        self.expected_output.append({
            'data':
            digest,
            'user':
            80 * '0' + little_endian_codec(self.codec) + 32 * '0'
        })
コード例 #15
0
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")
コード例 #16
0
class HcuTb(object):
    def __init__(self, dut, codec, debug=False):
        dut._log.info(f"Setting up test bench object with codec={codec}")
        self.dut = dut
        self.codec = codec
        self.sha = Sha.get_method(codec=codec)

        self.dut._log.info(f"Configure driver, monitors and scoreboard for {self.sha.sha_name}")
        self.s_axis = AXIS_Driver(dut, "s_axis", dut.axis_aclk, lsb_first=False)
        self.m_axis = AXIS_Monitor(dut, "m_axis", dut.axis_aclk, lsb_first=False)

        self.expected_output = []
        
        # Create a scoreboard on the m_axis bus
        with warnings.catch_warnings():
            warnings.simplefilter("ignore")
            self.scoreboard = Scoreboard(dut)
        self.scoreboard.add_interface(self.m_axis, self.expected_output)  

        # Reconstrut the input transactions
        self.s_axis_recovered = AXIS_Monitor(dut, "s_axis", dut.axis_aclk, callback=self.model, lsb_first=False)

        level = logging.DEBUG if debug else logging.WARNING
        self.s_axis.log.setLevel(level)
        self.s_axis_recovered.log.setLevel(level)

    async def reset(self,duration = 2):
        self.dut._log.debug("Resetting DUT")
        self.dut.axis_resetn <= 0
        await Timer(duration, units='ns')
        await RisingEdge(self.dut.axis_aclk)
        self.dut.axis_resetn <= 1
        self.dut._log.debug("Out of reset")    
    
    def model(self, transaction):
        self.dut._log.debug(f'Transaction = {transaction}')
        message = transaction['data']
        # print(f'Length or received tansaction = {len(message)}')
        self.sha.init()
        words_block = self.sha.wt_iters
        while(message):
            for i in range(words_block):
                # print(f'Word to unpack: {message[i*BYTE_WIDTH_WORDS:(i+1)*BYTE_WIDTH_WORDS]}')
                w_temp, = struct.unpack('!Q', message[i*BYTE_WIDTH_WORDS:(i+1)*BYTE_WIDTH_WORDS])
                self.sha.update(w_temp)
            message = message[BYTE_WIDTH_WORDS*words_block:]
        
        self.dut._log.debug(f'Hash Computed = {[hex(reg) for  reg in self.sha.get_hash()]}')
        self.expected_output.append({'data': self.sha.get_bytes_hash(), 'user':80*'0'+little_endian_codec(self.codec)+32*'0'})
コード例 #17
0
ファイル: sort_lru_cache_cocotb.py プロジェクト: Paebbels/PoC
class Testbench(object):
	def __init__(self, dut):
		self.dut = dut
		self.stopped = False
		elements = dut.ELEMENTS.value;
		self.lru = LeastRecentlyUsedDict(size_limit=elements)

		# initial state of LRU list
		for keyin in range(elements-1, -1, -1):
			self.lru[keyin] = 1

		init_val = elements-1

		self.input_drv = InputDriver(dut)
		self.output_mon = OutputMonitor(dut)

		# Create a scoreboard on the outputs
		self.expected_output = [ init_val ]
		self.scoreboard = Scoreboard(dut)
		self.scoreboard.add_interface(self.output_mon, self.expected_output)

		# Reconstruct the input transactions from the pins
		# and send them to our 'model'
		self.input_mon = InputMonitor(dut, callback=self.model)

	def model(self, transaction):
		'''Model the DUT based on the input transaction.'''
		insert, free, keyin = transaction
		#print "=== model called with stopped=%r, Insert=%d, Free=%d, KeyIn=%d" % (self.stopped, insert, free, keyin)
		if not self.stopped:
			if insert == 1:
				self.lru[keyin] = 1
			elif free == 1:
				self.lru.moveLRU(keyin)

			#print "=== model: lru=%s" % self.lru.items()
			keyout = self.lru.iterkeys().next()
			#print "=== model: KeyOut=%d" % keyout
			self.expected_output.append(keyout)

	def stop(self):
		"""
		Stop generation of expected output transactions.
		One more clock cycle must be executed afterwards, so that, output of
		D-FF can be checked.
		"""
		self.stopped = True
コード例 #18
0
ファイル: sort_lru_cache_cocotb.py プロジェクト: zwl1671/PoC
class Testbench(object):
    def __init__(self, dut):
        self.dut = dut
        self.stopped = False
        elements = dut.ELEMENTS.value
        self.lru = LeastRecentlyUsedDict(size_limit=elements)

        # initial state of LRU list
        for keyin in range(elements - 1, -1, -1):
            self.lru[keyin] = 1

        init_val = elements - 1

        self.input_drv = InputDriver(dut)
        self.output_mon = OutputMonitor(dut)

        # Create a scoreboard on the outputs
        self.expected_output = [init_val]
        self.scoreboard = Scoreboard(dut)
        self.scoreboard.add_interface(self.output_mon, self.expected_output)

        # Reconstruct the input transactions from the pins
        # and send them to our 'model'
        self.input_mon = InputMonitor(dut, callback=self.model)

    def model(self, transaction):
        '''Model the DUT based on the input transaction.'''
        insert, free, keyin = transaction
        #print "=== model called with stopped=%r, Insert=%d, Free=%d, KeyIn=%d" % (self.stopped, insert, free, keyin)
        if not self.stopped:
            if insert == 1:
                self.lru[keyin] = 1
            elif free == 1:
                self.lru.moveLRU(keyin)

            #print "=== model: lru=%s" % self.lru.items()
            keyout = self.lru.iterkeys().next()
            #print "=== model: KeyOut=%d" % keyout
            self.expected_output.append(keyout)

    def stop(self):
        """
		Stop generation of expected output transactions.
		One more clock cycle must be executed afterwards, so that, output of
		D-FF can be checked.
		"""
        self.stopped = True
コード例 #19
0
class DFF_TB(object):
    def __init__(self, dut, init_val):
        """
        Setup testbench.

        init_val signifies the BinaryValue which must be captured by the
        output monitor with the first risign edge. This is actually the initial 
        state of the flip-flop.
        """
        # Some internal state
        self.dut = dut
        self.stopped = False

        # Create input driver and output monitor
        self.input_drv = BitDriver(dut.d, dut.c, input_gen())
        self.output_mon = BitMonitor("output", dut.q, dut.c)
        
        # Create a scoreboard on the outputs
        self.expected_output = [ init_val ]
        self.scoreboard = Scoreboard(dut)
        self.scoreboard.add_interface(self.output_mon, self.expected_output)

        # Reconstruct the input transactions from the pins
        # and send them to our 'model'
        self.input_mon = BitMonitor("input", dut.d, dut.c,
                                    callback=self.model)

    def model(self, transaction):
        """Model the DUT based on the input transaction."""
        # Do not append an output transaction for the 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 generation of input data."""
        self.input_drv.start()

    def stop(self):
        """
        Stop generation of input data. 
        Also stop generation of expected output transactions.
        One more clock cycle must be executed afterwards, so that, output of
        D-FF can be checked.
        """
        self.input_drv.stop()
        self.stopped = True
コード例 #20
0
class axistream_fifo_TB(object):
    def __init__(self, dut):
        self.dut = dut
        self.stream_in = AXI4ST(dut, "stream_in", dut.clk)
        self.stream_out = AXI4STMonitor(dut, "stream_out", dut.clk,
                                        callback=self.print_trans)
        self.expected_output = []
        self.scoreboard = Scoreboard(dut, fail_immediately=True)
        self.scoreboard.add_interface(self.stream_out, self.expected_output)
        self.stream_in_recovered = AXI4STMonitor(dut, "stream_in", dut.clk,
                                                 callback=self.model)
        self.stream_in_recovered.log.setLevel(30)
        self.stream_out.log.setLevel(30)

    def print_trans(self, transaction):
        # print(transaction)
        pass

    def model(self, transaction):
        """ Model the expected output based on input
        """
        self.expected_output.append(transaction)
        # print(self.expected_output)

    def insertContinuousBatch(self, nb, base):
        """
        Insert nb element in the stream_in with base as first value
        """
        for i in range(nb):
            self.stream_in.append(base+i)

    @cocotb.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")
        self.dut.reset_n <= 0
        self.dut.stream_in_tdata <= 0
        self.dut.stream_in_tlast <= 0
        self.dut.stream_in_tvalid <= 0
        self.dut.stream_out_tready <= 0
        yield Timer(40, 'ns')
        self.dut.reset_n <= 1
        yield Timer(15, 'ns')
        self.dut._log.info("end Rst")
コード例 #21
0
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)
コード例 #22
0
ファイル: test_endian_swapper.py プロジェクト: Martoni/cocotb
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 = []
        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

    @cocotb.coroutine
    def reset(self, duration=10000):
        self.dut._log.debug("Resetting DUT")
        self.dut.reset_n <= 0
        self.stream_in.bus.valid <= 0
        yield Timer(duration)
        yield RisingEdge(self.dut.clk)
        self.dut.reset_n <= 1
        self.dut._log.debug("Out of reset")
コード例 #23
0
class BaseTest:
    """Common test logic and resource for all tests."""

    def __init__(self, dut):
        self.dut = dut
        self.tlp_tx_st = AvalonSTMonitor(dut, 'tlp_tx_multiplexer_out', dut.clk)
        self.tlp_tx_recovered = AvalonSTMonitor(dut, 'tlp_tx_multiplexer_out', dut.clk,
                callback=self.tx_model)
        self.csr = AvalonMaster(dut, 'csr', dut.clk)
        self.expected_output = []
        self.scoreboard = Scoreboard(dut)
        self.scoreboard.add_interface(self.tlp_tx_st, self.expected_output)

    async def reset(self):
        self.dut.reset <= 1
        await Timer(50, units='ns')
        self.dut.reset <= 0
        await Timer(100, units='ns')
        self.dut.tlp_tx_multiplexer_out_ready <= 1
        self.dut.rx_st_bar <= 1
        self.dut.reset._log.debug('Reset complete')

    def expect_memwrite(self, address, data):
        exp = pcie.TLP()
        exp.requester_id = pcie.PcieId(bus=0xb3, device=0)
        exp.set_be(address, len(data))
        exp.fmt_type = pcie.TLP_MEM_WRITE
        exp.set_data(data)
        exp.byte_count = len(data)
        self.expected_output.append(exp.intel_pack())

    def expect_cmpld(self, address, data):
        exp = pcie.TLP()
        exp.completer_id = pcie.PcieId(bus=0xb3, device=0)
        exp.set_be(address, len(data))
        exp.fmt_type = pcie.TLP_CPL_DATA
        exp.set_data(data)
        exp.byte_count = len(data)
        self.expected_output.append(exp.intel_pack())

    def tx_model(self, transaction):
        """Log TLPs received from DUT."""
        tlp = pcie.TLP()
        tlp.intel_unpack(transaction)
        self.tlp_tx_recovered.log.info("TLP from DUT: " + repr(tlp))
コード例 #24
0
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 = []
    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_gen(dut.clk, period=clock_period))

    dut.rst <= 1
    for i in range(bus_width):
        dut.i_data[i] = 0
    dut.i_valid <= 0
    yield RisingEdge(dut.clk)
    yield 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)
        yield RisingEdge(dut.clk)
        dut.i_valid <= 0
コード例 #25
0
async def test_multiply(dut, a_data, b_data):
    """Test multiplication of many matrices."""

    cocotb.fork(Clock(dut.clk_i, 10, units='ns').start())

    # Configure Scoreboard to compare module results to expected
    expected_output = []

    in_monitor = MatrixInMonitor(dut, callback=expected_output.append)
    out_monitor = MatrixOutMonitor(dut)

    scoreboard = Scoreboard(dut)
    scoreboard.add_interface(out_monitor, expected_output)

    # Initial values
    dut.valid_i <= 0
    dut.a_i <= create_a(lambda x: 0)
    dut.b_i <= create_b(lambda x: 0)

    # Reset DUT
    dut.reset_i <= 1
    for _ in range(3):
        await RisingEdge(dut.clk_i)
    dut.reset_i <= 0

    # Do multiplication operations
    for A, B in zip(a_data(), b_data()):
        await RisingEdge(dut.clk_i)
        dut.a_i <= A
        dut.b_i <= B
        dut.valid_i <= 1

        await RisingEdge(dut.clk_i)
        dut.valid_i <= 0

    await RisingEdge(dut.clk_i)

    raise scoreboard.result
コード例 #26
0
class TB(object):
    def __init__(self, dut):
        self.dut = dut
        # Reconstruct the input transactions from the pins
        # and send them to our 'model'
        input_mon = InputMonitor("input",
                                 dut.A,
                                 dut.B,
                                 dut.clk,
                                 callback=self.adder_modelD)
        # Output monitor
        self.output_mon = OutMonitor("output", dut.X, dut.clk)
        # Create a scoreboard on the outputs
        self.expected_output = []
        self.scoreboard = Scoreboard(dut)
        self.scoreboard.add_interface(self.output_mon, self.expected_output)

    def adder_modelD(self, transaction):
        result = adder_model(transaction[0], transaction[1])
        self.expected_output.append(
            BinaryValue(value=result,
                        n_bits=int(self.dut.DATA_WIDTH),
                        bigEndian=False))
コード例 #27
0
ファイル: test_mean.py プロジェクト: johnjohnlin/cocotb
def value_test(dut):
    scb = Scoreboard(dut)
    data_width = int(dut.B)
    bus_width = int(dut.N)
    n_test = 100
    cocotb.fork(clock_gen(dut.clk, period=clock_period))

    exp1 = list()
    exp2 = list()
    c1 = VectorCollector([[bus_width]], n_test)
    c2 = VectorCollector([[]], n_test)
    master = ValidMaster(dut, 'i', dut.clk, ['i_data'])
    m1 = ValidMonitor(dut, 'i', dut.clk, ['i_data'], collector=c1)
    m2 = ValidMonitor(dut, 'o', dut.clk, ['o_data'], collector=c2)
    scb.add_interface(m1, exp1)
    scb.add_interface(m2, exp2)

    for i in range(10):
        yield RisingEdge(dut.clk)

    idat = np.random.randint(1<<data_width, size=(n_test,bus_width)).astype(np.int32)
    odat = np.sum(idat, axis=1)/bus_width
    exp1.append(CompareWrap((idat,), verbose=True))
    # wrong answer
    # exp2.append(CompareWrap((odat+1,), verbose=True))
    exp2.append(CompareWrap((odat,), verbose=True))

    ibus = master.create_data()
    for n in range(n_test):
        for i in range(bus_width):
            ibus.i_data[i].integer = idat[n,i]
        yield master.send(ibus, 3)

    yield Timer(10)
    assert c1.clean and c2.clean
    raise scb.result
コード例 #28
0
ファイル: deparser_v1.py プロジェクト: mxy0091/deparser
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(30)
        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 <= 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)
コード例 #29
0
class uart_tx_tb(object):
    def __init__(self, dut):
        self.dut = dut
        self.output_mon = UartTxOMonitor(dut,
                                         "o",
                                         dut.clk,
                                         int(self.dut.BAUD),
                                         reset_n=dut.rstn)
        self.input_mon = UartTxIMonitor(dut,
                                        "i",
                                        dut.clk,
                                        int(self.dut.BAUD),
                                        reset_n=dut.rstn,
                                        callback=self.tx_model)
        self.input_drv = UartTxDriver(dut, "i", dut.clk)  #initializer only
        self.etx = BinaryValue(1)
        self.eready = BinaryValue(0)
        self.output_expected = [{
            'tx': self.etx,
            'ready': self.eready
        }]  #i don't think this should be necessary...
        self.scoreboard = Scoreboard(dut)

        #self.output_mon.log.setLevel(logging.DEBUG)

        #scoreboard is where results are checked. On each transaction of the output_mon, it'll compare against the
        #next transaction in the list output_expected. Output_expected gets updated by the tx_model. tx_model is the
        #callback function of the input monitor. So the expected output gets appended to when the input changes.
        # its not obvious if on the same simulation cycle you can force the tx_model to get called before the
        # scoreboard gets called on
        self.scoreboard.add_interface(self.output_mon, self.output_expected)
        self.baud_rate = int(self.dut.BAUD) - 1
        self.baud_count = 0
        self.shifter = 0

    def tx_model(self, transaction):
        # shift data (transaction second field) out 1 bit at a time
        # at the baud rate
        # adding start and stop bits to the expected values.
        if self.input_mon.transmitting:
            #print ("tx model call -- character %d:%d" % (self.input_mon.bits,len(self.output_expected)))
            #print (self.output_expected)
            if self.input_mon.bits == 0:
                self.output_expected.pop(
                )  #ugh. are we putting in expectations for this cycle, or next?
                self.etx <= 0
                self.eready <= 0
                self.output_expected.append({
                    'tx': self.etx,
                    'ready': self.eready
                })  #start bit
                self.shifter = self.input_mon.start_data
                #print ("transaction - %s,%s" %(transaction[0],transaction[1]))
            if self.input_mon.bits < 8:
                self.output_expected.append({
                    'tx': self.shifter % 2,
                    'ready': 0
                })
                self.shifter = self.shifter >> 1
            else:
                self.output_expected.append({'tx': 1, 'ready': 0})  #stop bit
        else:
            #print ("tx model call -- idle :%d" % len(self.output_expected))
            if self.input_mon.in_reset:
                self.etx <= 1
                self.eready <= 0
                self.output_expected.append({
                    'tx': self.etx,
                    'ready': self.eready
                })
            else:
                self.etx <= 1
                self.eready <= 1
                self.output_expected.append({
                    'tx': self.etx,
                    'ready': self.eready
                })

    @cocotb.coroutine
    def reset_dut(self, reset, duration):
        reset <= 0
        yield Timer(duration)
        reset <= 1
        self.dut._log.info("reset complete")

    @cocotb.coroutine
    def set_char(self, char):
        yield RisingEdge(self.dut.clk)
        self.dut.i_data <= ord(char)
        self.dut.i_start <= 1
        yield RisingEdge(self.dut.clk)
        self.dut.i_start <= 0
        self.dut._log.info("sent char %s" % char)
コード例 #30
0
async def run_test(dut):

    en_gpio_loopback_test = True
    en_spi_test = True


    clk = Clock(dut.clk, 10, units="ns")  # Create a 10us period clock on port clk
    cocotb.fork(clk.start())  # Start the clock

    dut.uart_txd = 0
    await FallingEdge(dut.clk)

    ### =============================================================================================================
    ### GPIO LOOPBACK TEST

    if en_gpio_loopback_test:
        dv = DVTest(dut, "GPIO Loopback", msg_lvl="All")
        dv.info("GPIO Loopback Test")
        for i in range(20000):
            await FallingEdge(dut.clk)
            dut.P2_in <= dut.P1_out.value
            try:
                gpio_value = int(dut.P1_out.value.binstr,2)
                loop_done = True if gpio_value == 0xff else False
            except ValueError:
                gpio_value = 0
                loop_done = False
            if (i+1) % 1000 == 0:
                dv.info("clock = " + str(i+1) +": P1_out = " + str(gpio_value) )
            if loop_done: break

        await Edge(dut.P1_out)

        gpio_result = int(dut.P1_out.value.binstr,2)
        dv.eq(gpio_result, 0, "Error count from DUT")
        dut.P1_in = 0
        await ClockCycles(dut.clk,100)
        dv.done()


    ### =============================================================================================================
    ### SPI TEST


    spi_peripheral = SPIPeripheralMonitor(
        dut=dut,
        cfg = {
            'name' : "SPI Monitor",
            'size' : 8, # bits
            'mode' : 0,
            'lsb_first' : False,
        },
        io = {
            'sclk' : dut.spi_sclk,
            'cs_n' : dut.spi_cs,
            'sdi'  : dut.spi_mosi,
            'sdo'  : dut.spi_miso,
        }
    )

#        spi_peripheral_expect.append( random.randint(0, 127) )
#        spi_peripheral_response.append( random.randint(0, 127) )



    if en_spi_test:

        dv.info("SPI Test (random modes and speeds)")

        spi_n = 15
        spi_peripheral_expect = []
        spi_scoreboard_expect = []
        spi_peripheral_response = []
        for i in range(spi_n):
           val = i
           spi_peripheral_expect.append( val )
           spi_scoreboard_expect.append( val )
           spi_peripheral_response.append( val )

        spi_peripheral.start(spi_peripheral_expect, spi_peripheral_response)

        scoreboard = Scoreboard(dut)
        scoreboard.add_interface(spi_peripheral, spi_scoreboard_expect, strict_type=False)
        random.seed(42)
        err_cnt = 0
        toggle = 0
        for iiii in range(spi_n):

            # SEND BYTE-VALUE TO SEND OVER SPI TO Z80 USING BPIO p2[7:0]
            dut.P2_in.value = spi_peripheral_expect[iiii]

            # SEND MODE AND CLKDIV TO Z80 OVER GPIO P1[7:0]
            # Bit [1:0] mode
            # Bit [2]   toggle (ensure p1_in changes)
            # Bit [6:3] clkdiv (div sys clk)
            # Bit [7]   done
            spi_peripheral.mode = random.randrange(4) # i % 4
            clkdiv = random.randrange(0, 16, 2)
            toggle = (toggle + 4) & 0x04
            P1_in = (clkdiv << 3) | toggle | spi_peripheral.mode
            dut.P1_in.value = P1_in

            # WAIT FOR Z80 TO SEND SPI MESSAGE AND COMPARE WITH EXPECETD VALUE
            dv.info("Waiting for SPI Peripheral ({})".format(iiii))
            await spi_peripheral.peripheral_monitor()

        spi_peripheral.stop()
        dut.P1_in.value = 0x80
        if err_cnt == 0:
            dv.info("SPI Test Passed")
        else:
            dv.info("SPI Test Failed - Error Count = " + str(err_cnt) )

        await ClockCycles(dut.clk,100)

        # Print result of scoreboard.
        dv.is_true(scoreboard.result, "SPI Test Scoreboard")
コード例 #31
0
async def test_aux(dut, packets_num=5, packet_size=(10, 100), delay=-1, consecutive_transfers=0):
    """Test all the auxiliary AXI4-Stream signals"""

    tdata_width = dut.C_S_AXIS_TDATA_WIDTH.value.integer
    tdest_width = dut.C_S_AXIS_TDEST_WIDTH.value.integer
    tid_width = dut.C_S_AXIS_TID_WIDTH.value.integer
    tuser_width = dut.C_S_AXIS_TUSER_WIDTH.value.integer

    axis_m = Axi4StreamMaster(dut, "s_axis", dut.aclk)
    axis_s = Axi4StreamSlave(dut, "m_axis", dut.aclk, delay, consecutive_transfers)
    axis_monitor = Axi4Stream(dut, "m_axis", dut.aclk, data_type="integer", packets=True, aux_signals=True)

    await setup_dut(dut)

    input = []
    output = []

    # Build the input and output packets
    for i in range(packets_num):
        first_word = {
            "TDATA": randint(0, 2**tdata_width - 1),
            "TSTRB": randint(0, 2**(tdata_width // 8) - 1),
            "TKEEP": 2**(tdata_width // 8) - 1,
            "TDEST": randint(0, 2**tdest_width - 1),
            "TID": randint(0, 2**tid_width - 1),
            "TUSER": randint(0, 2**tuser_width - 1),
        }
        second_word = {
            "TDATA": randint(0, 2**tdata_width - 1),
            "TSTRB": 2**(tdata_width // 8) - 1
        }
        input.append(
            [first_word, second_word] +
            [randint(0, 2**tdata_width - 1) for i in range(randint(*packet_size))])

        output.append([])
        for input_word in input[-1]:
            output[-1].append({})
            for signal in ("TDATA", "TSTRB", "TKEEP", "TDEST", "TID", "TUSER"):
                if signal == "TDATA" and isinstance(input_word, int):
                    output[-1][-1]["TDATA"] = input_word
                else:
                    try:
                        # If input_word has that signal, copy it, ...
                        output[-1][-1][signal] = input_word[signal]
                    except (KeyError, TypeError):
                        # ...if not, use the last value
                        output[-1][-1][signal] = output[-1][-2][signal]

        for output_word in output[-1]:
            # Flip TDATA and TUSER
            output_word["TDATA"] ^= 2**tdata_width - 1
            output_word["TUSER"] ^= 2**tuser_width - 1

    scoreboard = Scoreboard(dut)
    scoreboard.add_interface(axis_monitor, output)

    # Write the input packets
    for packet in input:
        await axis_m.write(packet)

    # Wait until output_tdata is empty (so, all the packets have been received)
    while output:
        await RisingEdge(dut.aclk)
コード例 #32
0
def rob_simple_test(dut):

    # TB_ARGS parser

    parser = ArgumentParser(description='Arguments for test')

    parser.add_argument("-len",
                        "--length",
                        dest="length",
                        type=int,
                        default=32)
    parser.add_argument("-dhreq",
                        "--max_delay_host_req",
                        dest="dhreq",
                        type=int,
                        default=0)
    parser.add_argument("-dhrsp",
                        "--max_delay_host_rsp",
                        dest="dhrsp",
                        type=int,
                        default=0)
    parser.add_argument("-dmreq",
                        "--max_delay_mem_req",
                        dest="dmreq",
                        type=int,
                        default=0)
    parser.add_argument("-dmrsp",
                        "--max_delay_mem_rsp",
                        dest="dmrsp",
                        type=int,
                        default=0)
    parser.add_argument("-id",
                        "--id_width",
                        dest="id_width",
                        type=int,
                        default=4)

    argument_list = shlex.split(os.environ["PY_TB_ARGS"])

    args = parser.parse_args(argument_list)

    # Setup CLK and Reset

    vr_in = vr.vr_master(dut,
                         name="bug_host_req_i",
                         clock=dut.clk,
                         bus_separator=".",
                         valid_max_delay=args.dhreq)
    vr_out = vr.vr_slave(dut,
                         name="bug_host_rsp_o",
                         clock=dut.clk,
                         bus_separator=".",
                         ready_max_delay=args.dhrsp)

    mem_req = vr.vr_slave(dut,
                          name="bug_mem_req_o",
                          clock=dut.clk,
                          bus_separator=".",
                          ready_max_delay=args.dmreq)
    mem_rsp = vr.vr_master(dut,
                           name="bug_mem_rsp_i",
                           clock=dut.clk,
                           bus_separator=".",
                           valid_max_delay=args.dmrsp)

    vr_out_mon = vr.vr_monitor(dut,
                               name="bug_host_rsp_o",
                               clock=dut.clk,
                               bus_separator=".")

    setup_clk(dut)

    dut.rstn <= 0

    yield Timer(CLK_PERIOD * 10, units='ns')

    dut.rstn <= 1

    # Init interfaces

    memory = vr_mem.vr_mem_cl(mem_req, mem_rsp, permutation=True)

    packet = packet_generate(args, random.randint(1, args.length))

    with open("./ref.dat", "w") as f:
        for i in packet:
            f.write(str(i) + '\n')

    scoreboard = Scoreboard(dut)
    scoreboard.add_interface(vr_out_mon, packet)

    cocotb.fork(vr_out.receive_packet(len(packet)))
    cocotb.fork(vr_in.write_packet(packet))

    while (vr_in.busy):
        yield RisingEdge(dut.clk)

    memory.th = 0  # flush buffer

    while (vr_out.wait):
        yield RisingEdge(dut.clk)

    yield Timer(CLK_PERIOD, units='ns')

    packet_out = list(map(int, vr_out.get_packet(clean=True)))

    with open("./out.dat", "w") as f:
        for i in packet_out:
            f.write(str(i) + '\n')