blob: fe3483cf8f54cd0a5ddc32a959b58681741b24d9 [file] [log] [blame]
#
# Copyright (c) 2010-2023 Antmicro
#
# This file is licensed under the MIT License.
# Full license text is available in 'licenses/MIT.txt'.
#
from struct import *
class BaseEntry(Struct):
def __init__(self, format):
super(BaseEntry, self).__init__(format)
self.realTime = 0
self.virtualTime = 0
self.entryType = -1
class MetricsParser:
def __init__(self, filePath):
self.filePath = filePath
def get_instructions_entries(self):
with open(self.filePath, "rb") as f:
cpus, _ = self._parseHeader(f)
return cpus, self._parse(f, b'\x00', '<cQ')
def get_memory_entries(self):
with open(self.filePath, "rb") as f:
_, _ = self._parseHeader(f)
return self._parse(f, b'\x01', 'c')
def get_peripheral_entries(self):
with open(self.filePath, "rb") as f:
_, peripherals = self._parseHeader(f)
return peripherals, self._parse(f, b'\x02', '<cQ')
def get_exceptions_entries(self):
with open(self.filePath, "rb") as f:
_, _ = self._parseHeader(f)
return self._parse(f, b'\x03', 'Q')
def _parse(self, f, entryType, format):
startTime = 0
entries = []
entry = BaseEntry('<qdc')
while True:
entryHeader = f.read(entry.size)
if not entryHeader:
break
realTime, entry.virtualTime, entry.entryType = entry.unpack(entryHeader)
if startTime == 0:
startTime = realTime
entry.realTime = (realTime - startTime) / 10000
if entry.entryType == entryType:
result = [entry.realTime, entry.virtualTime]
for data in self._read(format, f):
result.append(data)
entries.append(result)
else:
self._ignore(entry.entryType, f)
return entries
def _parseHeader(self, f):
cpus = {}
peripherals = {}
numberOfCpus = self._read('i', f)[0]
for x in range(numberOfCpus):
cpuId = self._read('i', f)[0]
cpuNameLength = self._read('i', f)[0]
cpus[cpuId] = self._read('{}s'.format(cpuNameLength), f)[0].decode()
numberOfPeripherals = self._read('i', f)[0]
for x in range(numberOfPeripherals):
peripheralNameLength = self._read('i', f)[0]
peripheralName = self._read('{}s'.format(peripheralNameLength), f)[0].decode()
peripheralStartAddress, peripheralEndAddress = self._read('2Q', f)
peripherals[peripheralName] = [peripheralStartAddress, peripheralEndAddress]
return cpus, peripherals
def _ignore(self, entryType, f):
if entryType == b'\x00':
self._read('<cQ', f)
if entryType == b'\x01':
self._read('c', f)
if entryType == b'\x02':
self._read('<cQ', f)
if entryType == b'\x03':
self._read('<Q', f)
def _read(self, format, file):
return unpack(format, file.read(calcsize(format)))