Пример #1
0
    def compare(self, got, exp, log, strict_type=True):
        """
        Common function for comparing two transactions.

        Can be re-implemented by a subclass.
        """

        # Compare the types
        if strict_type and type(got) != type(exp):
            self.errors += 1
            log.error("Received transaction is a different type to expected "
                      "transaction")
            log.info("Got: %s but expected %s" %
                     (str(type(got)), str(type(exp))))
            if self._imm:
                raise TestFailure("Received transaction of wrong type")
            return
        # Or convert to a string before comparison
        elif not strict_type:
            got, exp = str(got), str(exp)

        # Compare directly
        if got != exp:
            self.errors += 1

            # Try our best to print out something useful
            strgot, strexp = str(got), str(exp)

            log.error("Received transaction differed from expected output")
            log.info("Expected:\n" + hexdump(strexp))
            if not isinstance(exp, str):
                try:
                    for word in exp:
                        log.info(str(word))
                except:
                    pass
            log.info("Received:\n" + hexdump(strgot))
            if not isinstance(got, str):
                try:
                    for word in got:
                        log.info(str(word))
                except:
                    pass
            log.warning("Difference:\n%s" % hexdiffs(strexp, strgot))
            if self._imm:
                raise TestFailure("Received transaction differed from expected"
                                  "transaction")
        else:
            # Don't want to fail the test
            # if we're passed something without __len__
            try:
                log.debug("Received expected transaction %d bytes" %
                          (len(got)))
                log.debug(repr(got))
            except:
                pass
Пример #2
0
    def compare(self, got, exp, log, strict_type=True):
        """
        Common function for comparing two transactions.

        Can be re-implemented by a subclass.
        """

        # Compare the types
        if strict_type and type(got) != type(exp):
            self.errors += 1
            log.error("Received transaction is a different type to expected "
                      "transaction")
            log.info("Got: %s but expected %s" %
                     (str(type(got)), str(type(exp))))
            if self._imm:
                raise TestFailure("Received transaction of wrong type")
            return
        # Or convert to a string before comparison
        elif not strict_type:
            got, exp = str(got), str(exp)

        # Compare directly
        if got != exp:
            self.errors += 1

            # Try our best to print out something useful
            strgot, strexp = str(got), str(exp)

            log.error("Received transaction differed from expected output")
            log.info("Expected:\n" + hexdump(strexp))
            if not isinstance(exp, str):
                try:
                    for word in exp:
                        log.info(str(word))
                except:
                    pass
            log.info("Received:\n" + hexdump(strgot))
            if not isinstance(got, str):
                try:
                    for word in got:
                        log.info(str(word))
                except:
                    pass
            log.warning("Difference:\n%s" % hexdiffs(strexp, strgot))
            if self._imm:
                raise TestFailure("Received transaction differed from expected"
                                  "transaction")
        else:
            # Don't want to fail the test
            # if we're passed something without __len__
            try:
                log.debug("Received expected transaction %d bytes" %
                          (len(got)))
                log.debug(repr(got))
            except:
                pass
Пример #3
0
    def _monitor_recv(self):
        clk = RisingEdge(self.clock)
        self._pkt = ""

        while True:
            yield clk
            ctrl, bytes = self._get_bytes()

            if ctrl[0] and bytes[0] == _XGMII_START:

                ctrl, bytes = ctrl[1:], bytes[1:]

                while self._add_payload(ctrl, bytes):
                    yield clk
                    ctrl, bytes = self._get_bytes()

            if self._pkt:

                self.log.debug("Received:\n%s" % (hexdump(self._pkt)))

                if len(self._pkt) < 64 + 7:
                    self.log.error("Received a runt frame!")
                if len(self._pkt) < 12:
                    self.log.error("No data to extract")
                    self._pkt = ""
                    continue

                preamble_sfd = self._pkt[0:7]
                crc32 = self._pkt[-4:]
                payload = self._pkt[7:-4]

                if preamble_sfd != _PREAMBLE_SFD:
                    self.log.error("Got a frame with unknown preamble/SFD")
                    self.log.error(hexdump(preamble_sfd))
                    self._pkt = ""
                    continue

                expected_crc = struct.pack("<I",
                                           (zlib.crc32(payload) & 0xFFFFFFFF))

                if crc32 != expected_crc:
                    self.log.error("Incorrect CRC on received packet")
                    self.log.info("Expected: %s" % (hexdump(expected_crc)))
                    self.log.info("Received: %s" % (hexdump(crc32)))

                # Use scapy to decode the packet
                if _have_scapy:
                    p = Ether(payload)
                    self.log.debug("Received decoded packet:\n%s" % p.show2())
                else:
                    p = payload

                self._recv(p)
                self._pkt = ""
Пример #4
0
    def _monitor_recv(self):
        clk = RisingEdge(self.clock)
        self._pkt = ""

        while True:
            yield clk
            ctrl, bytes = self._get_bytes()

            if ctrl[0] and bytes[0] == _XGMII_START:

                ctrl, bytes = ctrl[1:], bytes[1:]

                while self._add_payload(ctrl, bytes):
                    yield clk
                    ctrl, bytes = self._get_bytes()

            if self._pkt:

                self.log.debug("Received:\n%s" % (hexdump(self._pkt)))

                if len(self._pkt) < 64 + 7:
                    self.log.error("Received a runt frame!")
                if len(self._pkt) < 12:
                    self.log.error("No data to extract")
                    self._pkt = ""
                    continue

                preamble_sfd = self._pkt[0:7]
                crc32 = self._pkt[-4:]
                payload = self._pkt[7:-4]

                if preamble_sfd != _PREAMBLE_SFD:
                    self.log.error("Got a frame with unknown preamble/SFD")
                    self.log.error(hexdump(preamble_sfd))
                    self._pkt = ""
                    continue

                expected_crc = struct.pack("<I",
                                           (zlib.crc32(payload) & 0xFFFFFFFF))

                if crc32 != expected_crc:
                    self.log.error("Incorrect CRC on received packet")
                    self.log.info("Expected: %s" % (hexdump(expected_crc)))
                    self.log.info("Received: %s" % (hexdump(crc32)))

                # Use scapy to decode the packet
                if _have_scapy:
                    p = Ether(payload)
                    self.log.debug("Received decoded packet:\n%s" % p.show2())
                else:
                    p = payload

                self._recv(p)
                self._pkt = ""
Пример #5
0
    def result(self):
        """Determine the test result, do we have any pending data remaining?

        Returns:
            :any:`TestFailure`: If not all expected output was received or
            error were recorded during the test.
        """
        fail = False
        for monitor, expected_output in self.expected.items():
            if callable(expected_output):
                self.log.debug("Can't check all data returned for %s since "
                               "expected output is callable function rather "
                               "than a list" % str(monitor))
                continue
            if len(expected_output):
                self.log.warn("Still expecting %d transactions on %s" %
                              (len(expected_output), str(monitor)))
                for index, transaction in enumerate(expected_output):
                    self.log.info("Expecting %d:\n%s" %
                                  (index, hexdump(str(transaction))))
                    if index > 5:
                        self.log.info("... and %d more to come" %
                                      (len(expected_output) - index - 1))
                        break
                fail = True
        if fail:
            return TestFailure("Not all expected output was received")
        if self.errors:
            return TestFailure("Errors were recorded during the test")
        return TestSuccess()
Пример #6
0
        def check_received_transaction(transaction):
            """Called back by the monitor when a new transaction has been
            received"""

            log = logging.getLogger(self.log.name + '.' + monitor.name)

            if callable(expected_output):
                exp = expected_output(transaction)

            elif len(expected_output):
                for i in range(min((reorder_depth + 1), len(expected_output))):
                    if expected_output[i] == transaction:
                        break
                else:
                    i = 0
                exp = expected_output.pop(i)
            else:
                self.errors += 1
                log.error("Received a transaction but wasn't expecting "
                          "anything")
                log.info("Got: %s" % (hexdump(str(transaction))))
                if self._imm:
                    raise TestFailure("Received a transaction but wasn't "
                                      "expecting anything")
                return

            self.compare(transaction, exp, log, strict_type=strict_type)
Пример #7
0
    async def _driver_send(self,
                           pkt: Union[bytes, Iterable],
                           sync: bool = True,
                           channel: Optional[int] = None):
        """Send a packet over the bus.

        Args:
            pkt: Packet to drive onto the bus.
            channel: Channel attributed to the packet.

        If ``pkt`` is a string, we simply send it word by word

        If ``pkt`` is an iterable, it's assumed to yield objects with
        attributes matching the signal names.
        """

        # Avoid spurious object creation by recycling
        if isinstance(pkt, bytes):
            self.log.debug("Sending packet of length %d bytes", len(pkt))
            self.log.debug(hexdump(pkt))
            await self._send_string(pkt, sync=sync, channel=channel)
            self.log.debug("Successfully sent packet of length %d bytes",
                           len(pkt))
        elif isinstance(pkt, str):
            raise TypeError("pkt must be a bytestring, not a unicode string")
        else:
            if channel is not None:
                self.log.warning(
                    "%s is ignoring channel=%d because pkt is an iterable",
                    self.name, channel)
            await self._send_iterable(pkt, sync=sync)
Пример #8
0
 def result(self):
     """Determine the test result, do we have any pending data remaining?"""
     fail = False
     for monitor, expected_output in self.expected.items():
         if callable(expected_output):
             self.log.debug("Can't check all data returned for %s since "
                            "expected output is callable function rather "
                            "than a list" % str(monitor))
             continue
         if len(expected_output):
             self.log.warn("Still expecting %d transactions on %s" %
                           (len(expected_output), str(monitor)))
             for index, transaction in enumerate(expected_output):
                 self.log.info("Expecting %d:\n%s" %
                               (index, hexdump(str(transaction))))
                 if index > 5:
                     self.log.info("... and %d more to come" %
                                   (len(expected_output) - index - 1))
                     break
             fail = True
     if fail:
         return TestFailure("Not all expected output was received")
     if self.errors:
         return TestFailure("Errors were recorded during the test")
     return TestSuccess()
Пример #9
0
        def check_received_transaction(transaction):
            """Called back by the monitor when a new transaction has been
            received"""

            if monitor.name:
                log_name = self.log.name + '.' + monitor.name
            else:
                log_name = self.log.name + '.' + monitor.__class__.__name__

            log = logging.getLogger(log_name)

            if callable(expected_output):
                exp = expected_output(transaction)

            elif len(expected_output):
                for i in range(min((reorder_depth + 1), len(expected_output))):
                    if expected_output[i] == transaction:
                        break
                else:
                    i = 0
                exp = expected_output.pop(i)
            else:
                self.errors += 1
                log.error("Received a transaction but wasn't expecting "
                          "anything")
                log.info("Got: %s" % (hexdump(str(transaction))))
                if self._imm:
                    raise TestFailure("Received a transaction but wasn't "
                                      "expecting anything")
                return

            self.compare(transaction, exp, log, strict_type=strict_type)
Пример #10
0
    def _driver_send(self, pkt, sync=True, channel=None):
        """Send a packet over the bus.

        Args:
            pkt (str or iterable): Packet to drive onto the bus.
            channel (None or int): Channel attributed to the packet.

        If ``pkt`` is a string, we simply send it word by word

        If ``pkt`` is an iterable, it's assumed to yield objects with
        attributes matching the signal names.
        """

        # Avoid spurious object creation by recycling
        if isinstance(pkt, str):
            self.log.debug("Sending packet of length %d bytes", len(pkt))
            self.log.debug(hexdump(pkt))
            yield self._send_string(pkt, sync=sync, channel=channel)
            self.log.debug("Successfully sent packet of length %d bytes",
                           len(pkt))
        else:
            if channel is not None:
                self.log.warning(
                    "%s is ignoring channel=%d because pkt is an iterable",
                    self.name, channel)
            yield self._send_iterable(pkt, sync=sync)
Пример #11
0
        def check_received_transaction(transaction):
            """Called back by the monitor when a new transaction has been
            received."""

            if monitor.name:
                log_name = self.log.name + '.' + monitor.name
            else:
                log_name = self.log.name + '.' + type(monitor).__qualname__

            log = logging.getLogger(log_name)

            if callable(expected_output):
                exp = expected_output(transaction)

            elif len(expected_output):  # we expect something
                for i in range(min((reorder_depth + 1), len(expected_output))):
                    if expected_output[i] == transaction:
                        break  # break out of enclosing for loop
                else:  # run when for loop is exhausted (but no break occurs)
                    i = 0
                exp = expected_output.pop(i)
            else:
                self.errors += 1
                log.error("Received a transaction but wasn't expecting "
                          "anything")
                log.info("Got: %s" % (hexdump(str(transaction))))
                if self._imm:
                    raise TestFailure("Received a transaction but wasn't "
                                      "expecting anything")
                return

            self.compare(transaction, exp, log, strict_type=strict_type)
Пример #12
0
    def _monitor_recv(self):
        """Watch the pins and reconstruct transactions"""

        # Avoid spurious object creation by recycling
        clkedge = RisingEdge(self.clock)
        rdonly = ReadOnly()
        pkt = ""
        in_pkt = False
        invalid_cyclecount = 0

        def valid():
            if hasattr(self.bus, 'ready'):
                return self.bus.valid.value and self.bus.ready.value
            return self.bus.valid.value

        while True:
            yield clkedge
            yield rdonly

            if self.in_reset:
                continue

            if valid():
                invalid_cyclecount = 0

                if self.bus.startofpacket.value:
                    if pkt:
                        raise AvalonProtocolError(
                            "Duplicate start-of-packet received on %s" % (
                                str(self.bus.startofpacket)))
                    pkt = ""
                    in_pkt = True

                if not in_pkt:
                    raise AvalonProtocolError("Data transfer outside of "
                                              "packet")

                vec = self.bus.data.value
                vec.big_endian = self.config['firstSymbolInHighOrderBits']
                pkt += vec.buff

                if self.bus.endofpacket.value:
                    # Truncate the empty bits
                    if (self.config["useEmpty"] and
                       self.bus.empty.value.integer):
                        pkt = pkt[:-self.bus.empty.value.integer]
                    self.log.info("Received a packet of %d bytes" % len(pkt))
                    self.log.debug(hexdump(str((pkt))))
                    self._recv(pkt)
                    pkt = ""
                    in_pkt = False
            else :                
                if in_pkt :
                    invalid_cyclecount += 1
                    if self.config["invalidTimeout"] :
                        if invalid_cyclecount >= self.config["invalidTimeout"] :
                            raise AvalonProtocolError(
                                "In-Packet Timeout. Didn't receive any valid data for %d cycles!" %
                                invalid_cyclecount)
Пример #13
0
        def check_received_transaction(transaction):
            """Called back by the monitor when a new transaction has been received"""

            log = logging.getLogger(self.log.name + '.' + monitor.name)

            if callable(expected_output):
                exp = expected_output(transaction)
            elif len(expected_output):
                exp = expected_output.pop(0)
            else:
                self.errors += 1
                log.error("Received a transaction but wasn't expecting anything")
                log.info("Got: %s" % (hexdump(str(transaction))))
                if self._imm: raise TestFailure("Received a transaction but wasn't expecting anything")
                return

            if type(transaction) != type(exp):
                self.errors += 1
                log.error("Received transaction is a different type to expected transaction")
                log.info("Got: %s but expected %s" % (str(type(transaction)), str(type(exp))))
                if self._imm: raise TestFailure("Received transaction of wrong type")
                return

            if transaction != exp:
                self.errors += 1
                log.error("Received transaction differed from expected output")
                log.info("Expected:\n" + hexdump(exp))
                if not isinstance(exp, str):
                    try:
                        for word in exp: self.log.info(str(word))
                    except: pass
                log.info("Received:\n" + hexdump(transaction))
                if not isinstance(transaction, str):
                    try:
                        for word in transaction: self.log.info(str(word))
                    except: pass
                log.warning("Difference:\n%s" % hexdiffs(exp, transaction))
                if self._imm: raise TestFailure("Received transaction differed from expected transaction")
            else:
                # Don't want to fail the test if we're passed something without __len__
                try:
                    log.debug("Received expected transaction %d bytes" % (len(transaction)))
                    log.debug(repr(transaction))
                except: pass
Пример #14
0
    async def _driver_send(self, pkt: bytes, sync: bool = True) -> None:
        """Send a packet over the bus.

        Args:
            pkt: The Ethernet packet to drive onto the bus.
        """
        pkt = self.layer1(bytes(pkt))

        self.log.debug("Sending packet of length %d bytes" % len(pkt))
        self.log.debug(hexdump(pkt))

        clkedge = RisingEdge(self.clock)
        if sync:
            await clkedge

        self.bus[0] = (_XGMII_START, True)

        for i in range(1, len(self.bus)):
            self.bus[i] = (pkt[i - 1], False)

        pkt = pkt[len(self.bus) - 1:]
        self.signal.value = self.bus.value
        await clkedge

        done = False

        while pkt:

            for i in range(len(self.bus)):
                if i == len(pkt):
                    self.terminate(i)
                    pkt = b""
                    done = True
                    break
                self.bus[i] = (pkt[i], False)

            self.signal.value = self.bus.value
            await clkedge
            pkt = pkt[len(self.bus):]

        if not done:
            self.terminate(0)
            self.signal.value = self.bus.value
            await clkedge

        self.idle()
        await clkedge
        self.log.debug("Successfully sent packet")
Пример #15
0
    def _driver_send(self, pkt, sync=True):
        """Send a packet over the bus

        Args:
            pkt (str): Ethernet packet to drive onto the bus
        """
        pkt = self.layer1(str(pkt))

        self.log.debug("Sending packet of length %d bytes" % len(pkt))
        self.log.debug(hexdump(pkt))

        clkedge = RisingEdge(self.clock)
        if sync:
            yield clkedge

        self.bus[0] = (_XGMII_START, True)

        for i in range(1, len(self.bus)):
            self.bus[i] = (pkt[i - 1], False)

        pkt = pkt[len(self.bus) - 1 :]
        self.signal <= self.bus.value
        yield clkedge

        done = False

        while pkt:

            for i in range(len(self.bus)):
                if i == len(pkt):
                    self.terminate(i)
                    pkt = ""
                    done = True
                    break
                self.bus[i] = (pkt[i], False)

            self.signal <= self.bus.value
            yield clkedge
            pkt = pkt[len(self.bus) :]

        if not done:
            self.terminate(0)
            self.signal <= self.bus.value
            yield clkedge

        self.idle()
        yield clkedge
        self.log.debug("Successfully sent packet")
Пример #16
0
    def _driver_send(self, pkt, sync=True):
        """Send a packet over the bus

        Args:
            pkt (str): Ethernet packet to drive onto the bus
        """
        pkt = self.layer1(str(pkt))

        self.log.debug("Sending packet of length %d bytes" % len(pkt))
        self.log.debug(hexdump(pkt))

        clkedge = RisingEdge(self.clock)
        if sync:
            yield clkedge

        self.bus[0] = (_XGMII_START, True)

        for i in range(1, len(self.bus)):
            self.bus[i] = (pkt[i - 1], False)

        pkt = pkt[len(self.bus) - 1:]
        self.signal <= self.bus.value
        yield clkedge

        done = False

        while pkt:

            for i in range(len(self.bus)):
                if i == len(pkt):
                    self.terminate(i)
                    pkt = ""
                    done = True
                    break
                self.bus[i] = (pkt[i], False)

            self.signal <= self.bus.value
            yield clkedge
            pkt = pkt[len(self.bus):]

        if not done:
            self.terminate(0)
            self.signal <= self.bus.value
            yield clkedge

        self.idle()
        yield clkedge
        self.log.debug("Successfully sent packet")
Пример #17
0
    def _driver_send(self, pkt, sync=True):
        """Send a packet over the bus

        Args:
            pkt (str or iterable): packet to drive onto the bus

        If pkt is a string, we simply send it word by word

        If pkt is an iterable, it's assumed to yield objects with attributes
        matching the signal names
        """

        # Avoid spurious object creation by recycling

        if isinstance(pkt, str):
            self.log.debug("Sending packet of length %d bytes" % len(pkt))
            self.log.debug(hexdump(pkt))
            yield self._send_string(pkt, sync=sync)
            self.log.info("Sucessfully sent packet of length %d bytes" %
                          len(pkt))
        else:
            yield self._send_iterable(pkt, sync=sync)
Пример #18
0
    def _driver_send(self, pkt, sync=True):
        """Send a packet over the bus

        Args:
            pkt (str or iterable): packet to drive onto the bus

        If pkt is a string, we simply send it word by word

        If pkt is an iterable, it's assumed to yield objects with attributes
        matching the signal names
        """

        # Avoid spurious object creation by recycling


        if isinstance(pkt, str):
            self.log.debug("Sending packet of length %d bytes" % len(pkt))
            self.log.debug(hexdump(pkt))
            yield self._send_string(pkt, sync=sync)
            self.log.info("Sucessfully sent packet of length %d bytes" % len(pkt))
        else:
            yield self._send_iterable(pkt, sync=sync)
Пример #19
0
    def _driver_send(self, pkt, sync=True, channel=None):
        """Send a packet over the bus.

        Args:
            pkt (str or iterable): Packet to drive onto the bus.
            channel (None or int): Channel attributed to the packet.

        If ``pkt`` is a string, we simply send it word by word

        If ``pkt`` is an iterable, it's assumed to yield objects with 
        attributes matching the signal names.
        """

        # Avoid spurious object creation by recycling
        if isinstance(pkt, str):
            self.log.debug("Sending packet of length %d bytes" % len(pkt))
            self.log.debug(hexdump(pkt))
            yield self._send_string(pkt, sync=sync, channel=channel)
            self.log.debug("Successfully sent packet of length %d bytes" % len(pkt))
        else:
            if channel is not None:
                self.log.warning("%s is ignoring channel=%d because pkt is an iterable" % (self.name, channel))
            yield self._send_iterable(pkt, sync=sync)
Пример #20
0
    def _monitor_recv(self):
        """Watch the pins and reconstruct transactions"""

        # Avoid spurious object creation by recycling
        clkedge = RisingEdge(self.clock)
        rdonly  = ReadOnly()
        pkt = ""

        def valid():
            if hasattr(self.bus, 'ready'):
                return self.bus.valid.value and self.bus.ready.value
            return self.bus.valid.value

        while True:
            yield clkedge
            yield rdonly

            if valid():
                if self.bus.startofpacket.value:
                    if pkt:
                        raise AvalonProtocolError(
                            "Duplicate start-of-packet received on %s" % (
                                str(self.bus.startofpacket)))
                    pkt = ""

                vec = self.bus.data.value
                vec.big_endian = self.config['firstSymbolInHighOrderBits']
                pkt += vec.buff

                if self.bus.endofpacket.value:
                    # Truncate the empty bits
                    if self.bus.empty.value.integer:
                        pkt = pkt[:-self.bus.empty.value.integer]
                    self.log.info("Received a packet of %d bytes" % len(pkt))
                    self.log.debug(hexdump(str((pkt))))
                    self._recv(pkt)
                    pkt = ""
Пример #21
0
                       for x, y in zip(self._h, [a, b, c, d, e, f, g, h])]

    def digest(self):
        return b''.join(
            [struct.pack('!L', i) for i in self._h[:self._output_size]])

    def hexdigest(self):
        return self.digest().hex()

    def compute(self):
        w = True
        while w:
            w = self.NextWords()
        self._sha256_process()


mess = b'8U\xa3@\x9a\xb3\x94\xd2\xcb\x9a5\xa3\xd7\xba\x00\x87\xc2py\xc8\xb1M\xa5M\xb6\x94f#\xfc4\xe0\x12.\x8ey\xc6;8\x8dz|\x80\xb5\n\xcc\xb8.\xe1\x88\x08u/H\xdb9\xd1\xaen\x01QC\x91\x9b\xbd\xf1m\x9b\x8a\xb4gL\xb1+p\xd1"\x9f\x86\x9c\x92\xbb\xfb\xc7\xee\xce\xc8\xc1m\xf1\xb3\x9f\xc7\xd8\xe1\xfb\xca\x991\xae<\xda\xbf!9\x8bk(\xdb}\x82\xbb\x92}z3.\x1et\xbaC\xdd|\x91COpu\xc9'
print(mess[0:64])
sha2 = SHA256(mess)
#print(sha2.padding())
eom = False
while not eom:
    w_bytes = b''.join([struct.pack('!L', w) for w in sha2.NextWords()])
    if w_bytes != b'':
        print(hexdump(w_bytes))
    else:
        eom = True
# print([struct.pack('!L', w) for w in sha2.NextWords()])
sha2.compute()
print(sha2.hexdigest())
#print([struct.pack('!Q', w) for w in sha2.NextWords()])
Пример #22
0
 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))
Пример #23
0
    def _monitor_recv(self):
        """Watch the pins and reconstruct transactions."""

        # Avoid spurious object creation by recycling
        clkedge = RisingEdge(self.clock)
        rdonly = ReadOnly()
        pkt = ""
        in_pkt = False
        invalid_cyclecount = 0
        channel = None

        def valid():
            if hasattr(self.bus, 'ready'):
                return self.bus.valid.value and self.bus.ready.value
            return self.bus.valid.value

        while True:
            yield clkedge
            yield rdonly

            if self.in_reset:
                continue

            if valid():
                invalid_cyclecount = 0

                if self.bus.startofpacket.value:
                    if pkt:
                        raise AvalonProtocolError(
                            "Duplicate start-of-packet received on %s" %
                            str(self.bus.startofpacket))
                    pkt = ""
                    in_pkt = True

                if not in_pkt:
                    raise AvalonProtocolError("Data transfer outside of "
                                              "packet")

                # Handle empty and X's in empty / data
                vec = BinaryValue()
                if not self.bus.endofpacket.value:
                    vec = self.bus.data.value
                else:
                    value = self.bus.data.value.get_binstr()
                    if self.config["useEmpty"] and self.bus.empty.value.integer:
                        empty = self.bus.empty.value.integer * self.config[
                            "dataBitsPerSymbol"]
                        if self.config["firstSymbolInHighOrderBits"]:
                            value = value[:-empty]
                        else:
                            value = value[empty:]
                    vec.assign(value)
                    if not vec.is_resolvable:
                        raise AvalonProtocolError(
                            "After empty masking value is still bad?  "
                            "Had empty {:d}, got value {:s}".format(
                                empty, self.bus.data.value.get_binstr()))

                vec.big_endian = self.config['firstSymbolInHighOrderBits']
                pkt += vec.buff

                if hasattr(self.bus, 'channel'):
                    if channel is None:
                        channel = self.bus.channel.value.integer
                        if channel > self.config["maxChannel"]:
                            raise AvalonProtocolError(
                                "Channel value (%d) is greater than maxChannel (%d)"
                                % (channel, self.config["maxChannel"]))
                    elif self.bus.channel.value.integer != channel:
                        raise AvalonProtocolError(
                            "Channel value changed during packet")

                if self.bus.endofpacket.value:
                    self.log.info("Received a packet of %d bytes", len(pkt))
                    self.log.debug(hexdump(str((pkt))))
                    self.channel = channel
                    if self.report_channel:
                        self._recv({"data": pkt, "channel": channel})
                    else:
                        self._recv(pkt)
                    pkt = ""
                    in_pkt = False
                    channel = None
            else:
                if in_pkt:
                    invalid_cyclecount += 1
                    if self.config["invalidTimeout"]:
                        if invalid_cyclecount >= self.config["invalidTimeout"]:
                            raise AvalonProtocolError(
                                "In-Packet Timeout. Didn't receive any valid data for %d cycles!"
                                % invalid_cyclecount)
Пример #24
0
    def _monitor_recv(self):
        """Watch the pins and reconstruct transactions."""

        # Avoid spurious object creation by recycling
        clkedge = RisingEdge(self.clock)
        rdonly = ReadOnly()
        pkt = ""
        in_pkt = False
        invalid_cyclecount = 0
        channel = None

        def valid():
            if hasattr(self.bus, 'ready'):
                return self.bus.valid.value and self.bus.ready.value
            return self.bus.valid.value

        while True:
            yield clkedge
            yield rdonly

            if self.in_reset:
                continue

            if valid():
                invalid_cyclecount = 0

                if self.bus.startofpacket.value:
                    if pkt and self.config['fail_immediately']:
                        raise AvalonProtocolError(
                            "Duplicate start-of-packet received on %s" % (
                                str(self.bus.startofpacket)))
                    pkt = ""
                    in_pkt = True

                if not in_pkt and self.config['fail_immediately']:
                    raise AvalonProtocolError("Data transfer outside of "
                                              "packet")

                # Handle empty and X's in empty / data
                vec = BinaryValue()
                if not self.bus.endofpacket.value:
                    vec = self.bus.data.value
                else:
                    value = self.bus.data.value.get_binstr()
                    if self.config["useEmpty"] and self.bus.empty.value.integer:
                        empty = self.bus.empty.value.integer * self.config["dataBitsPerSymbol"]
                        if self.config["firstSymbolInHighOrderBits"]:
                            value = value[:-empty]
                        else:
                            value = value[empty:]
                    vec.assign(value)
                    if not vec.is_resolvable:
                        raise AvalonProtocolError("After empty masking value is still bad?  Had empty {:d}, got value {:s}".format(empty, self.bus.data.value.get_binstr()))

                vec.big_endian = self.config['firstSymbolInHighOrderBits']
                pkt += vec.buff

                if hasattr(self.bus, 'channel'):
                    if channel is None:
                        channel = self.bus.channel.value.integer
                        if channel > self.config["maxChannel"]:
                            raise AvalonProtocolError("Channel value (%d) is greater than maxChannel (%d)" % (channel,self.config["maxChannel"]))
                    elif self.bus.channel.value.integer != channel:
                        raise AvalonProtocolError("Channel value changed during packet")

                if self.bus.endofpacket.value:
                    self.log.info("Received a packet of %d bytes" % len(pkt))
                    self.log.debug(hexdump(str((pkt))))
                    self.channel = channel
                    self._recv(pkt)
                    pkt = ""
                    in_pkt = False
                    channel = None
            else :
                if in_pkt :
                    invalid_cyclecount += 1
                    if self.config["invalidTimeout"] :
                        if invalid_cyclecount >= self.config["invalidTimeout"] :
                            raise AvalonProtocolError(
                                "In-Packet Timeout. Didn't receive any valid data for %d cycles!" %
                                invalid_cyclecount)
Пример #25
0
    def compare(self, got, exp, log, strict_type=True):
        """Common function for comparing two transactions.

        Can be re-implemented by a sub-class.

        Args:
            got: The received transaction.
            exp: The expected transaction.
            log: The logger for reporting messages.
            strict_type (bool, optional): Require transaction type to match
                exactly if ``True``, otherwise compare its string representation.

        Raises:
            :any:`TestFailure`: If received transaction differed from
                expected transaction when :attr:`fail_immediately` is ``True``.
                If *strict_type* is ``True``,
                also the transaction type must match.
        """

        # Compare the types
        if strict_type and type(got) != type(exp):
            self.errors += 1
            log.error("Received transaction type is different than expected")
            log.info("Received: %s but expected %s" %
                     (str(type(got)), str(type(exp))))
            if self._imm:
                raise TestFailure("Received transaction of wrong type. "
                                  "Set strict_type=False to avoid this.")
            return
        # Or convert to a string before comparison
        elif not strict_type:
            got, exp = str(got), str(exp)

        # Compare directly
        if got != exp:
            self.errors += 1

            # Try our best to print out something useful
            strgot, strexp = str(got), str(exp)

            log.error("Received transaction differed from expected output")
            if not strict_type:
                log.info("Expected:\n" + hexdump(strexp))
            else:
                log.info("Expected:\n" + repr(exp))
            if not isinstance(exp, str):
                try:
                    for word in exp:
                        log.info(str(word))
                except Exception:
                    pass
            if not strict_type:
                log.info("Received:\n" + hexdump(strgot))
            else:
                log.info("Received:\n" + repr(got))
            if not isinstance(got, str):
                try:
                    for word in got:
                        log.info(str(word))
                except Exception:
                    pass
            log.warning("Difference:\n%s" % hexdiffs(strexp, strgot))
            if self._imm:
                raise TestFailure(
                    "Received transaction differed from expected "
                    "transaction")
        else:
            # Don't want to fail the test
            # if we're passed something without __len__
            try:
                log.debug("Received expected transaction %d bytes" %
                          (len(got)))
                log.debug(repr(got))
            except Exception:
                pass