import xml.etree.ElementTree as ET import re import sys import os class DramConfigReader: maxValues = {} startBits = {} endBits = {} def __extractAdressEncoding(self, root, elementName): rowElement = root[0].find(elementName) rowBitFrom, rowBitsTo = int( rowElement.attrib['from']), int(rowElement.attrib['to']) rowBitRange = rowBitsTo - rowBitFrom + 1 maxRow = 2 ** rowBitRange - 1 #print('{0}: range {1}..{2}'.format(elementName, 0, maxRow)) self.startBits[elementName] = rowBitFrom self.endBits[elementName] = rowBitsTo self.maxValues[elementName] = maxRow def __init__(self): root = ET.parse( os.path.dirname(os.path.realpath(sys.argv[0])) + '/../configs/addressConfig.xml').getroot() self.__extractAdressEncoding(root, 'channel') self.__extractAdressEncoding(root, 'bank') self.__extractAdressEncoding(root, 'row') self.__extractAdressEncoding(root, 'colum') class StlReader: __dramConfigReader = DramConfigReader() def onesMask(self, numberOfOnes): result = 0 for i in range(numberOfOnes): result = result | 1 << i return result def parseAttributeFromAddress(self, address, element): return address >> self.__dramConfigReader.startBits[element] & self.onesMask(self.__dramConfigReader.endBits[element] - self.__dramConfigReader.startBits[element] + 1) def formatStlLine(self, line): try: found = re.search('0x[0-9,a-f]+', line).group(0) address = int(found, 16) decodedAddress = '[Channel: {0} Bank: {1} Row:{2} Column: {3}]'.format(self.parseAttributeFromAddress(address, 'channel'), self.parseAttributeFromAddress(address, 'bank'), self.parseAttributeFromAddress(address, 'row'), self.parseAttributeFromAddress(address, 'colum')) return line.replace("\n", " ") + decodedAddress except AttributeError: return '' def printStlPretty(self, filename): f = open(filename) for line in f.readlines(): print(self.formatStlLine(line)) class StlGenerator: __actions = [] __time = 0 __dramConfigReader = DramConfigReader() def clear(self): self.__actions = [] self.__time = 0 def setTime(self, time): self.__time = time def addAction(self, bank, row, channel=0, RD_WR='read'): tupel = (self.__time, RD_WR, self.__generateAdress(channel, bank, row)) self.__actions.append(tupel) def setTimeAndAddAction(self, time, bank, row, channel=0, RD_WR='read'): self.setTime(self, time) self.addAction(self, bank, row, channel, RD_WR) def addLoad(self, banks, rows, channel=0, RD_WR='read'): for bank in banks: for row in rows: self.addAction(bank, row, channel, RD_WR) def setTimeAndAddLoad(self, time, banks, rows, channel=0, RD_WR='read'): self.setTime(self, time) self.addLoad(banks, rows, channel, RD_WR) def generateStl(self, filename): f = open(filename, 'w') tmp = [] for tupel in self.__actions: tmp.append('{0}: {1} {2:#x}'.format(tupel[0], tupel[1], tupel[2])) result = '\n'.join(tmp) f.write(result) f.close() print( '<---------------------- Generated stl {0} ---------------------->'.format(filename)) print(result) print( '<---------------------- End generated stl ---------------------->'.format(filename)) def __generateAdress(self, channel, bank, row): if(channel > self.__dramConfigReader.maxValues['channel']): raise(BaseException('Channel argument out of range')) if(bank > self.__dramConfigReader.maxValues['bank']): raise(BaseException('Bank argument out of range')) if(row > self.__dramConfigReader.maxValues['row']): raise(BaseException('Row argument out of range')) return (channel << self.__dramConfigReader.startBits['channel']) | (bank << self.__dramConfigReader.startBits['bank']) | (row << self.__dramConfigReader.startBits['row']) def __init__(self): pass if __name__ == '__main__': if(len(sys.argv) > 1): stlReader = StlReader() for line in sys.argv[1:]: stlReader.printStlPretty(line)