|
|
@ -72,7 +72,7 @@ Cacheable Return Modes:
|
|
|
|
class A2L2Trans(DotMap):
|
|
|
|
class A2L2Trans(DotMap):
|
|
|
|
'''A2L2 Transaction'''
|
|
|
|
'''A2L2 Transaction'''
|
|
|
|
nextID = itertools.count()
|
|
|
|
nextID = itertools.count()
|
|
|
|
def __init__(self, sim, tid, tt, tag=None, addr=None, length=0, wimg=0, cycD=None, be=None, data=None):
|
|
|
|
def __init__(self, sim, tid, tt, tag=None, addr=None, length=0, wimg=0, cycD=None, be=None, data=None, le=False):
|
|
|
|
super().__init__()
|
|
|
|
super().__init__()
|
|
|
|
self.sim = sim
|
|
|
|
self.sim = sim
|
|
|
|
self.id = next(A2L2Trans.nextID)
|
|
|
|
self.id = next(A2L2Trans.nextID)
|
|
|
@ -80,6 +80,15 @@ class A2L2Trans(DotMap):
|
|
|
|
self.tt = tt
|
|
|
|
self.tt = tt
|
|
|
|
self.tag = tag
|
|
|
|
self.tag = tag
|
|
|
|
self.addr = addr
|
|
|
|
self.addr = addr
|
|
|
|
|
|
|
|
if length == 0 or length == 3:
|
|
|
|
|
|
|
|
raise Exception(f'A2L2Trans: bad length encode: {length}')
|
|
|
|
|
|
|
|
elif length == 5:
|
|
|
|
|
|
|
|
self.len = 8
|
|
|
|
|
|
|
|
elif length == 6:
|
|
|
|
|
|
|
|
self.len = 16
|
|
|
|
|
|
|
|
elif length == 7:
|
|
|
|
|
|
|
|
self.len = 32
|
|
|
|
|
|
|
|
else:
|
|
|
|
self.len = length
|
|
|
|
self.len = length
|
|
|
|
self.wimg = wimg
|
|
|
|
self.wimg = wimg
|
|
|
|
self.xfers = 1
|
|
|
|
self.xfers = 1
|
|
|
@ -92,6 +101,7 @@ class A2L2Trans(DotMap):
|
|
|
|
self.cycD = cycD
|
|
|
|
self.cycD = cycD
|
|
|
|
self.be = f'{int(be, 16):032b}' if be is not None else None
|
|
|
|
self.be = f'{int(be, 16):032b}' if be is not None else None
|
|
|
|
self.data = data
|
|
|
|
self.data = data
|
|
|
|
|
|
|
|
self.LE = le
|
|
|
|
self.done = False
|
|
|
|
self.done = False
|
|
|
|
|
|
|
|
|
|
|
|
self.ieq1 = wimg & 0x4 == 0x4
|
|
|
|
self.ieq1 = wimg & 0x4 == 0x4
|
|
|
@ -103,7 +113,7 @@ class A2L2Trans(DotMap):
|
|
|
|
self.addr = self.addr & 0xFFFFFFF0
|
|
|
|
self.addr = self.addr & 0xFFFFFFF0
|
|
|
|
elif self.store:
|
|
|
|
elif self.store:
|
|
|
|
#self.addr = self.addr & 0xFFFFFFE0 #wtf definitely 16B-aligned occurring
|
|
|
|
#self.addr = self.addr & 0xFFFFFFE0 #wtf definitely 16B-aligned occurring
|
|
|
|
self.addr = self.addr & 0xFFFFFFF0
|
|
|
|
#self.addr = self.addr & 0xFFFFFFF0 # keep low bits for 1B and 2B stores
|
|
|
|
if self.be == None or self.data == None:
|
|
|
|
if self.be == None or self.data == None:
|
|
|
|
raise Exception('A2L2Trans: store must have BE and data')
|
|
|
|
raise Exception('A2L2Trans: store must have BE and data')
|
|
|
|
else:
|
|
|
|
else:
|
|
|
@ -147,11 +157,12 @@ class A2L2Trans(DotMap):
|
|
|
|
return w0,w1,w2,w3,beatNum
|
|
|
|
return w0,w1,w2,w3,beatNum
|
|
|
|
|
|
|
|
|
|
|
|
def doStore(self):
|
|
|
|
def doStore(self):
|
|
|
|
addr = ((self.addr + self.storeStart) >> 2) << 2
|
|
|
|
addr = (((self.addr & 0xFFFFFFF0) + self.storeStart) >> 2) << 2 # word-align
|
|
|
|
dataStart = self.storeStart*2
|
|
|
|
dataStart = self.storeStart*2
|
|
|
|
if self.len == 1:
|
|
|
|
if self.len == 1:
|
|
|
|
word = self.sim.mem.read(addr)
|
|
|
|
word = self.sim.mem.read(addr)
|
|
|
|
byte = self.addr & 0x3
|
|
|
|
byte = self.addr & 0x3
|
|
|
|
|
|
|
|
if self.LE:
|
|
|
|
if byte == 0:
|
|
|
|
if byte == 0:
|
|
|
|
mask = 0xFFFFFF00
|
|
|
|
mask = 0xFFFFFF00
|
|
|
|
elif byte == 1:
|
|
|
|
elif byte == 1:
|
|
|
@ -160,33 +171,64 @@ class A2L2Trans(DotMap):
|
|
|
|
mask = 0xFF00FFFF
|
|
|
|
mask = 0xFF00FFFF
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
mask = 0x00FFFFFF
|
|
|
|
mask = 0x00FFFFFF
|
|
|
|
word = (word & mask) | (int(self.data[dataStart:dataStart+2], 16) << (byte*2))
|
|
|
|
word = (word & mask) | (int(self.data[dataStart:dataStart+2], 16) << (byte*8))
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
if byte == 0:
|
|
|
|
|
|
|
|
mask = 0x00FFFFFF
|
|
|
|
|
|
|
|
elif byte == 1:
|
|
|
|
|
|
|
|
mask = 0xFF00FFFF
|
|
|
|
|
|
|
|
elif byte == 2:
|
|
|
|
|
|
|
|
mask = 0xFFFF00FF
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
mask = 0xFFFFFF00
|
|
|
|
|
|
|
|
print(word, mask, dataStart, byte)
|
|
|
|
|
|
|
|
word = (word & mask) | (int(self.data[dataStart:dataStart+2], 16) << ((3-byte)*8))
|
|
|
|
self.sim.mem.write(addr, word)
|
|
|
|
self.sim.mem.write(addr, word)
|
|
|
|
|
|
|
|
print(addr,word)
|
|
|
|
|
|
|
|
#quit()
|
|
|
|
|
|
|
|
|
|
|
|
elif self.len == 2:
|
|
|
|
elif self.len == 2:
|
|
|
|
word = self.sim.mem.read(addr)
|
|
|
|
word = self.sim.mem.read(addr)
|
|
|
|
hw = (self.addr & 0x2) >> 1
|
|
|
|
hw = (self.addr & 0x2) >> 1
|
|
|
|
|
|
|
|
if self.LE:
|
|
|
|
if hw == 0:
|
|
|
|
if hw == 0:
|
|
|
|
mask = 0xFFFF0000
|
|
|
|
mask = 0xFFFF0000
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
mask = 0x0000FFFF
|
|
|
|
mask = 0x0000FFFF
|
|
|
|
word = (word & mask) | (int(self.data[dataStart:dataStart+4], 16) << (hw*4))
|
|
|
|
word = (word & mask) | (int(self.data[dataStart:dataStart+4], 16) << (hw*16))
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
if hw == 0:
|
|
|
|
|
|
|
|
mask = 0x0000FFFF
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
mask = 0xFFFF0000
|
|
|
|
|
|
|
|
word = (word & mask) | (int(self.data[dataStart:dataStart+4], 16) << ((1-hw)*16))
|
|
|
|
self.sim.mem.write(addr, word)
|
|
|
|
self.sim.mem.write(addr, word)
|
|
|
|
|
|
|
|
|
|
|
|
elif self.len == 4:
|
|
|
|
elif self.len == 4:
|
|
|
|
self.sim.mem.write(addr, int(self.data[dataStart:dataStart+8], 16))
|
|
|
|
self.sim.mem.write(addr, int(self.data[dataStart:dataStart+8], 16))
|
|
|
|
|
|
|
|
|
|
|
|
elif self.len == 8:
|
|
|
|
elif self.len == 8:
|
|
|
|
|
|
|
|
if self.LE:
|
|
|
|
self.sim.mem.write(addr, int(self.data[dataStart:dataStart+16], 16))
|
|
|
|
self.sim.mem.write(addr, int(self.data[dataStart:dataStart+16], 16))
|
|
|
|
self.sim.mem.write(addr+4, int(self.data[dataStart+16:dataStart+32], 16))
|
|
|
|
self.sim.mem.write(addr+4, int(self.data[dataStart+16:dataStart+32], 16))
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
self.sim.mem.write(addr+4, int(self.data[dataStart:dataStart+16], 16))
|
|
|
|
|
|
|
|
self.sim.mem.write(addr, int(self.data[dataStart+16:dataStart+32], 16))
|
|
|
|
|
|
|
|
|
|
|
|
elif self.len == 16:
|
|
|
|
elif self.len == 16:
|
|
|
|
|
|
|
|
if self.LE:
|
|
|
|
self.sim.mem.write(addr, int(self.data[0:8], 16))
|
|
|
|
self.sim.mem.write(addr, int(self.data[0:8], 16))
|
|
|
|
self.sim.mem.write(addr+4, int(self.data[8:16], 16))
|
|
|
|
self.sim.mem.write(addr+4, int(self.data[8:16], 16))
|
|
|
|
self.sim.mem.write(addr+8, int(self.data[16:24], 16))
|
|
|
|
self.sim.mem.write(addr+8, int(self.data[16:24], 16))
|
|
|
|
self.sim.mem.write(addr+12, int(self.data[24:32], 16))
|
|
|
|
self.sim.mem.write(addr+12, int(self.data[24:32], 16))
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
self.sim.mem.write(addr+12, int(self.data[0:8], 16))
|
|
|
|
|
|
|
|
self.sim.mem.write(addr+8, int(self.data[8:16], 16))
|
|
|
|
|
|
|
|
self.sim.mem.write(addr+4, int(self.data[16:24], 16))
|
|
|
|
|
|
|
|
self.sim.mem.write(addr, int(self.data[24:32], 16))
|
|
|
|
|
|
|
|
|
|
|
|
elif self.len == 32:
|
|
|
|
elif self.len == 32:
|
|
|
|
|
|
|
|
if self.LE:
|
|
|
|
self.sim.mem.write(addr, int(self.data[0:8], 16))
|
|
|
|
self.sim.mem.write(addr, int(self.data[0:8], 16))
|
|
|
|
self.sim.mem.write(addr+4, int(self.data[8:16], 16))
|
|
|
|
self.sim.mem.write(addr+4, int(self.data[8:16], 16))
|
|
|
|
self.sim.mem.write(addr+8, int(self.data[16:24], 16))
|
|
|
|
self.sim.mem.write(addr+8, int(self.data[16:24], 16))
|
|
|
@ -195,6 +237,15 @@ class A2L2Trans(DotMap):
|
|
|
|
self.sim.mem.write(addr+20, int(self.data[40:48], 16))
|
|
|
|
self.sim.mem.write(addr+20, int(self.data[40:48], 16))
|
|
|
|
self.sim.mem.write(addr+24, int(self.data[48:56], 16))
|
|
|
|
self.sim.mem.write(addr+24, int(self.data[48:56], 16))
|
|
|
|
self.sim.mem.write(addr+28, int(self.data[56:64], 16))
|
|
|
|
self.sim.mem.write(addr+28, int(self.data[56:64], 16))
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
self.sim.mem.write(addr+28, int(self.data[0:8], 16))
|
|
|
|
|
|
|
|
self.sim.mem.write(addr+24, int(self.data[8:16], 16))
|
|
|
|
|
|
|
|
self.sim.mem.write(addr+20, int(self.data[16:24], 16))
|
|
|
|
|
|
|
|
self.sim.mem.write(addr+16, int(self.data[24:32], 16))
|
|
|
|
|
|
|
|
self.sim.mem.write(addr+12, int(self.data[32:40], 16))
|
|
|
|
|
|
|
|
self.sim.mem.write(addr+8, int(self.data[40:48], 16))
|
|
|
|
|
|
|
|
self.sim.mem.write(addr+4, int(self.data[48:56], 16))
|
|
|
|
|
|
|
|
self.sim.mem.write(addr, int(self.data[56:64], 16))
|
|
|
|
|
|
|
|
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
raise Exception(f'A2L2Trans: unsupported store len={self.len}')
|
|
|
|
raise Exception(f'A2L2Trans: unsupported store len={self.len}')
|
|
|
@ -293,14 +344,14 @@ async def A2L2Driver(dut, sim):
|
|
|
|
reldCyc = sim.cycle + 6 # const for now
|
|
|
|
reldCyc = sim.cycle + 6 # const for now
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
reldCyc = readPending[-1].cycD + 4 # worst-case const for now
|
|
|
|
reldCyc = readPending[-1].cycD + 4 # worst-case const for now
|
|
|
|
trans = A2L2Trans(sim, tid, int(tt, 16), int(tag, 16), int(ra, 16), int(lenEnc, 16), wimg, reldCyc)
|
|
|
|
trans = A2L2Trans(sim, tid, int(tt, 16), int(tag, 16), int(ra, 16), int(lenEnc, 16), wimg, reldCyc, le=le)
|
|
|
|
readPending.append(trans)
|
|
|
|
readPending.append(trans)
|
|
|
|
sim.msg(f'T{tid} {transType} {ra} tag={tag} len={trans.len} {le}WIMG:{wimg:X} reld data:{trans.cycD}')
|
|
|
|
sim.msg(f'T{tid} {transType} {ra} tag={tag} len={trans.len} {le}WIMG:{wimg:X} reld data:{trans.cycD}')
|
|
|
|
elif transType == 'STORE':
|
|
|
|
elif transType == 'STORE':
|
|
|
|
# should verify st_data_pwr_token prev cycle
|
|
|
|
# should verify st_data_pwr_token prev cycle
|
|
|
|
be = hex(dut.ac_an_st_byte_enbl, 8)
|
|
|
|
be = hex(dut.ac_an_st_byte_enbl, 8)
|
|
|
|
data = hex(dut.ac_an_st_data, 64)
|
|
|
|
data = hex(dut.ac_an_st_data, 64)
|
|
|
|
trans = A2L2Trans(sim, tid, int(tt, 16), int(tag, 16), int(ra, 16), int(lenEnc, 16), wimg, None, be=be, data=data)
|
|
|
|
trans = A2L2Trans(sim, tid, int(tt, 16), int(tag, 16), int(ra, 16), int(lenEnc, 16), wimg, None, be=be, data=data, le=le)
|
|
|
|
sim.msg(f'T{tid} {transType} {ra} tag={tag} len={trans.len} be={be} data={data} {le}WIMG:{wimg:X}')
|
|
|
|
sim.msg(f'T{tid} {transType} {ra} tag={tag} len={trans.len} be={be} data={data} {le}WIMG:{wimg:X}')
|
|
|
|
trans.doStore()
|
|
|
|
trans.doStore()
|
|
|
|
dut.an_ac_req_st_pop.value = 1 #wtf can randomize, etc.
|
|
|
|
dut.an_ac_req_st_pop.value = 1 #wtf can randomize, etc.
|
|
|
|