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
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 = ""
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()
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)
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)
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()
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)
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)
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)
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)
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
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")
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")
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")
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)
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)
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 = ""
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()])
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))
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)
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)
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