2015-04-17 07:45:01 -04:00
|
|
|
from misoclib.com.litepcie.common import *
|
|
|
|
from misoclib.com.litepcie.core.packet.common import *
|
|
|
|
|
|
|
|
|
|
|
|
# TLP Layer model
|
|
|
|
def get_field_data(field, dwords):
|
2015-04-27 08:59:29 -04:00
|
|
|
return (dwords[field.byte//4] >> field.offset) & (2**field.width-1)
|
2015-04-17 07:45:01 -04:00
|
|
|
|
|
|
|
tlp_headers_dict = {
|
|
|
|
"RD32": tlp_request_header,
|
|
|
|
"WR32": tlp_request_header,
|
|
|
|
"CPLD": tlp_completion_header,
|
|
|
|
"CPL": tlp_completion_header
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
class TLP():
|
|
|
|
def __init__(self, name, dwords=[0, 0, 0]):
|
|
|
|
self.name = name
|
|
|
|
self.header = dwords[:3]
|
|
|
|
self.data = dwords[3:]
|
|
|
|
self.dwords = self.header + self.data
|
|
|
|
self.decode_dwords()
|
|
|
|
|
|
|
|
def decode_dwords(self):
|
2015-04-27 08:59:29 -04:00
|
|
|
for k, v in tlp_headers_dict[self.name].fields.items():
|
2015-04-17 07:45:01 -04:00
|
|
|
setattr(self, k, get_field_data(v, self.header))
|
|
|
|
|
|
|
|
def encode_dwords(self, data=[]):
|
|
|
|
self.header = [0, 0, 0]
|
2015-04-27 08:59:29 -04:00
|
|
|
for k, v in tlp_headers_dict[self.name].fields.items():
|
|
|
|
field = tlp_headers_dict[self.name].fields[k]
|
|
|
|
self.header[field.byte//4] |= (getattr(self, k) << field.offset)
|
2015-04-17 07:45:01 -04:00
|
|
|
self.data = data
|
|
|
|
self.dwords = self.header + self.data
|
|
|
|
return self.dwords
|
|
|
|
|
|
|
|
def __repr__(self):
|
|
|
|
r = self.name + "\n"
|
|
|
|
r += "--------\n"
|
|
|
|
for k in sorted(tlp_headers_dict[self.name].keys()):
|
|
|
|
r += k + " : 0x{:x}".format(getattr(self, k) + "\n")
|
|
|
|
if len(self.data) != 0:
|
|
|
|
r += "data:\n"
|
|
|
|
for d in self.data:
|
|
|
|
r += "{:08x}\n".format(d)
|
|
|
|
return r
|
|
|
|
|
|
|
|
|
|
|
|
class RD32(TLP):
|
|
|
|
def __init__(self, dwords=[0, 0, 0]):
|
|
|
|
TLP.__init__(self, "RD32", dwords)
|
|
|
|
|
|
|
|
|
|
|
|
class WR32(TLP):
|
|
|
|
def __init__(self, dwords=[0, 0, 0]):
|
|
|
|
TLP.__init__(self, "WR32", dwords)
|
|
|
|
|
|
|
|
|
|
|
|
class CPLD(TLP):
|
|
|
|
def __init__(self, dwords=[0, 0, 0]):
|
|
|
|
TLP.__init__(self, "CPLD", dwords)
|
|
|
|
|
|
|
|
|
|
|
|
class CPL():
|
|
|
|
def __init__(self, dwords=[0, 0, 0]):
|
|
|
|
TLP.__init__(self, "CPL", dwords)
|
|
|
|
|
|
|
|
|
|
|
|
class Unknown():
|
|
|
|
def __repr__(self):
|
|
|
|
r = "UNKNOWN\n"
|
|
|
|
return r
|
|
|
|
|
|
|
|
fmt_type_dict = {
|
|
|
|
fmt_type_dict["mem_rd32"]: (RD32, 3),
|
|
|
|
fmt_type_dict["mem_wr32"]: (WR32, 4),
|
|
|
|
fmt_type_dict["cpld"]: (CPLD, 4),
|
|
|
|
fmt_type_dict["cpl"]: (CPL, 3)
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
def parse_dwords(dwords):
|
2015-04-27 08:59:29 -04:00
|
|
|
f = get_field_data(tlp_common_header.fields["fmt"], dwords)
|
|
|
|
t = get_field_data(tlp_common_header.fields["type"], dwords)
|
2015-04-17 07:45:01 -04:00
|
|
|
fmt_type = (f << 5) | t
|
|
|
|
try:
|
|
|
|
tlp, min_len = fmt_type_dict[fmt_type]
|
|
|
|
if len(dwords) >= min_len:
|
|
|
|
return tlp(dwords)
|
|
|
|
else:
|
|
|
|
return Unknown()
|
|
|
|
except:
|
|
|
|
return Unknown()
|