From 3ac9c7861dd173024cb31c12e9fd3d7a24872b31 Mon Sep 17 00:00:00 2001 From: Paul Matthews Date: Sun, 25 Aug 2024 14:09:58 +0200 Subject: [PATCH 01/12] Initial support for 5A series - .fse file support - .dat file support --- apycula/dat19.py | 35 ++++++++++--- apycula/fuse_h4x.py | 106 +++++++++++++++++++++++++++++----------- apycula/tiled_fuzzer.py | 7 ++- 3 files changed, 110 insertions(+), 38 deletions(-) diff --git a/apycula/dat19.py b/apycula/dat19.py index 19c4a655..cc780fe7 100644 --- a/apycula/dat19.py +++ b/apycula/dat19.py @@ -133,13 +133,14 @@ def read_primitives(self) -> list[Primitive]: def read_grid(self) -> Grid: self._cur = 0x026060 - grid_h = self.read_u16() - grid_w = self.read_u16() - cc_y = self.read_u16() - cc_x = self.read_u16() + grid_h = self.read_u16() # chipRows_ + grid_w = self.read_u16() # chipCols_ + cc_y = self.read_u16() # hiq_ + cc_x = self.read_u16() # viq_ rows = [] grid_mapping = { (0, 0): " ", # empty + (1, 0): "1", # unknown (1, 1): "I", # I/O (2, 1): "L", # LVDS (GW2A* only) (3, 1): "R", # routing? @@ -151,8 +152,12 @@ def read_grid(self) -> Grid: (7, 0): "d", # dsp padding (7, 1): "D", # dsp (8, 0): "p", # pll padding + (10, 0): "2", # unknown (8, 1): "P", # pll (9, 1): "Q", # dll + (10, 1): "3", # unknown + (11, 1): "4", # unknown + (12, 1): "5" # unknown } for y in range(grid_h): row = [] @@ -162,8 +167,8 @@ def read_grid(self) -> Grid: b = self.read_u8_at(125744 + idx) c = grid_mapping[a, b] - if x == cc_x and y == cc_y: - assert c == "b" + #if x == cc_x and y == cc_y: + # assert c == "b" row.append(c) rows.append(row) @@ -252,9 +257,23 @@ def read_portmap(self) -> dict: "MdicIn": self.read_clkins(0x36), "MdicInDlt": self.read_clkins(0x36), "CtrlIn": self.read_mult(0xE), - "CtrlInDlt": self.read_mult(0xE), + "CtrlInDlt": self.read_mult(0xE), + "dsp12x12Ins": self.read_clkins(30), + "dsp12x12Outs": self.read_clkins(24), + "dsp12x12InDlt": self.read_clkins(30), + "dsp12x12OutDlt": self.read_clkins(24), + "dsp12x12SumIns": self.read_arr16(113), + "dsp12x12SumOuts": self.read_arr16(112), + "dsp12x12SumInDlt": self.read_arr16(113), + "dsp12x12SumOutDlt": self.read_arr16(112), + "dsp27x18Ins": self.read_arr16(163), + "dsp27x18Outs": self.read_arr16(139), + "dsp27x18InDlt": self.read_arr16(163), + "dsp27x18OutDlt": self.read_arr16(139), + "dspCtrlIns": self.read_clkins(6), + "dspCtrlInDlt": self.read_clkins(6), } - assert self._cur == 0x58272 + assert self._cur == 0x58c8e return ret def read_io(self): diff --git a/apycula/fuse_h4x.py b/apycula/fuse_h4x.py index 8b895756..df875738 100644 --- a/apycula/fuse_h4x.py +++ b/apycula/fuse_h4x.py @@ -1,79 +1,121 @@ import sys import random +import os from apycula import bitmatrix +gowinhome = os.getenv("GOWINHOME") +if not gowinhome: + raise Exception("GOWINHOME not set") + +# device = os.getenv("DEVICE") +device = sys.argv[1] + def rint(f, w): val = int.from_bytes(f.read(w), 'little', signed=True) return val -def readFse(f): +def readFse(f, device): print("check", rint(f, 4)) tiles = {} ttyp = rint(f, 4) - tiles['header'] = readOneFile(f, ttyp) + tiles['header'] = readOneFile(f, ttyp, device) while True: ttyp = rint(f, 4) if ttyp == 0x9a1d85: break - # print("tile type", ttyp) - tiles[ttyp] = readOneFile(f, ttyp) + print("tile type", ttyp) + tiles[ttyp] = readOneFile(f, ttyp, device) return tiles def readTable(f, size1, size2, w=2): return [[rint(f, w) for j in range(size2)] for i in range(size1)] -def readOneFile(f, fuselength): +def readOneFile(f, tileType, device): tmap = {"height": rint(f, 4), "width": rint(f, 4)} tables = rint(f, 4) + + is5Series = False + if device.lower().startswith("gw5a"): is5Series = True + for i in range(tables): typ = rint(f, 4) size = rint(f, 4) - # print(hex(f.tell()), " Table type", typ, "of size", size) + #print(hex(f.tell()), " Table type", typ, "/", hex(typ), "of size", size) if typ == 61: size2 = rint(f, 4) typn = "grid" + #print("s1: ", size, "s2: ", size2, "total: ", size * size2 * 4); t = readTable(f, size, size2, 4) elif typ == 1: + # Check if the device is 5 series as tile type 1 needs to be read differently typn = "fuse" - t = readTable(f, size, fuselength, 2) - elif typ in {7, 8, 9, 10, 0xb, 0xc, 0xd, 0xe, 0xf, 0x10, - 0x27, 0x31, 0x34, 0x37, 0x39, 0x3b, 0x3e, 0x3f, - 0x41, 0x43, 0x46, 0x48, 0x4a, 0x4c, 0x4e, 0x51, 0x53}: - typn = "logicinfo" - t = readTable(f, size, 3, 2) - elif typ in {2, 0x26, 0x30}: + if is5Series == False: t = readTable(f, size, tileType, 2) + else: t = readTable(f, size, 440, 2) + elif typ in {0x02, 0x26, 0x30, 0x5a, 0x5b}: typn = "wire" - t = readTable(f, size, 8, 2) - elif typ == 3: + if is5Series == False: t = readTable(f, size, 8, 2) + else: t = readTable(f, size, 9, 2) + elif typ == 0x03: typn = "wiresearch" t = readTable(f, size, 3, 2) - elif typ in {5, 0x11, 0x14, 0x15, 0x16, 0x19, 0x1a, 0x1b, + elif typ == 0x04: + typn = "const" + t = readTable(f, size, 1, 2) + elif typ in {0x05, 0x11, 0x14, 0x15, 0x16, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x32, 0x33, 0x38, 0x3c, 0x40, 0x42, 0x44, - 0x47, 0x49, 0x4b, 0x4d, 0x4f, 0x50, 0x52, 0x54}: + 0x47, 0x49, 0x4b, 0x4d, 0x4f, 0x50, 0x52, 0x54, + 0x56, 0x58, 0x59, 0x5d, 0x5e, 0x5f, 0x60, 0x61, + 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, + 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, + 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, + 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, + 0x82, 0x83, 0x84, 0x85, 0x88, 0x89, 0x8a}: typn = "shortval" t = readTable(f, size, 14, 2) elif typ in {6, 0x45}: typn = "alonenode" t = readTable(f, size, 15, 2) + elif typ in {0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, + 0x0f, 0x10, 0x27, 0x31, 0x34, 0x37, 0x39, 0x3b, + 0x3e, 0x3f, 0x41, 0x46, 0x48, 0x4a, 0x4c, 0x4e, + 0x51, 0x53, 0x55, 0x57, 0x5c}: + typn = "logicinfo" + t = readTable(f, size, 3, 2) elif typ in {0x12, 0x13, 0x35, 0x36, 0x3a}: typn = "longfuse" t = readTable(f, size, 17, 2) elif typ in {0x17, 0x18, 0x25, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f}: typn = "longval" t = readTable(f, size, 28, 2) - elif typ == 4: - typn = "const" - t = readTable(f, size, 1, 2) + elif typ == 0x43: + print("deviceType:", device) + if device in {'GW1N-1', 'GW1N-9', 'GW1N-4', 'GW1NS-4' + 'GW2A-18', 'GW2A-18C', 'GW5A-25A', 'GW5AS-25A'}: + typn = "logicinfo" + t = readTable(f, size, 3, 2) + else: # GW1N-9C GW5A-138B GW5AST-138B GW5AT-138 GW5AT-138B GW5AT-75B + typn = "signedlogicinfo" + t = readTable(f, size, 17, 2) + elif typ in {0x86, 0x87}: + typn = "signedlogicinfo" + t = readTable(f, size, 17, 2) + elif typ == 0x8b: + typn = "drpfuse" + t = readTable(f, size, 3, 2) else: raise ValueError("Unknown type {} at {}".format(hex(typ), hex(f.tell()))) tmap.setdefault(typn, {})[typ] = t return tmap -def render_tile(d, ttyp): +def render_tile(d, ttyp, device): w = d[ttyp]['width'] h = d[ttyp]['height'] + print("w:", w,"h:", h) + is5Series = False + if device.lower().startswith("gw5a"): is5Series = True + tile = bitmatrix.zeros(h, w)#+(255-ttyp) for start, table in [(2, 'shortval'), (2, 'wire'), (16, 'longval'), (1, 'longfuse'), (0, 'const')]: @@ -82,9 +124,13 @@ def render_tile(d, ttyp): for i in sinfo: for fuse in i[start:]: if fuse > 0: - num = d['header']['fuse'][1][fuse][ttyp] + if ttyp > 0x400: num = d['header']['fuse'][1][fuse][ttyp - 0x400] + else: num = d['header']['fuse'][1][fuse][ttyp] + row = num // 100 + if is5Series: row = num // 200 col = num % 100 + if table == "wire": if i[0] > 0: if tile[row][col] == 0: @@ -92,7 +138,7 @@ def render_tile(d, ttyp): else: tile[row][col] = (tile[row][col] + (styp + i[1]) % 256) // 2 elif table == "shortval" and styp == 5: - assert tile[row][col] == 0 + #assert tile[row][col] == 0 tile[row][col] = (styp + i[0]) % 256 else: tile[row][col] = styp @@ -100,7 +146,7 @@ def render_tile(d, ttyp): return tile -def render_bitmap(d): +def render_bitmap(d, device): tiles = d['header']['grid'][61] width = sum([d[i]['width'] for i in tiles[0]]) height = sum([d[i[0]]['height'] for i in tiles]) @@ -114,7 +160,7 @@ def render_bitmap(d): h = td['height'] #bitmap[y:y+h,x:x+w] += render_tile(d, typ) #bitmap[y:y+h,x:x+w] = typ - rtile = render_tile(d, typ) + rtile = render_tile(d, typ, device) y0 = y for row in rtile: x0 = x @@ -320,10 +366,12 @@ def reduce_rows(rows, fuses, start=16, tries=1000): return features if __name__ == "__main__": - with open(sys.argv[1], 'rb') as f: - d = readFse(f) - bm = render_bitmap(d) + + with open(f"{gowinhome}/IDE/share/device/{device}/{device}.fse", 'rb') as f: + d = readFse(f, device) + + bm = render_bitmap(d, device) display("fuse.png", bm) - t = render_tile(d, 12) + t = render_tile(d, 50, device) display("tile.png", t) diff --git a/apycula/tiled_fuzzer.py b/apycula/tiled_fuzzer.py index 1f430fa3..b0aa5e31 100644 --- a/apycula/tiled_fuzzer.py +++ b/apycula/tiled_fuzzer.py @@ -76,6 +76,11 @@ "device": "GW2AR-18C", "partnumber": "GW2AR-LV18PG256SC8/I7", }, + "GW5A-25A": { + "package": "MBGA121A", + "device": "GW5A-25A", + "partnumber": "GW5A-LV25MG121NES", + }, }[device] # utils @@ -216,7 +221,7 @@ def fse_iob(fse, db, pin_locations, diff_cap_info, locations): if __name__ == "__main__": with open(f"{gowinhome}/IDE/share/device/{device}/{device}.fse", 'rb') as f: - fse = fuse_h4x.readFse(f) + fse = fuse_h4x.readFse(f, device) dat = dat19.Datfile(Path(f"{gowinhome}/IDE/share/device/{device}/{device}.dat")) From d3a9f7bca7b77f3c437a1f774a542f481ed607ae Mon Sep 17 00:00:00 2001 From: AwooOOoo Date: Mon, 26 Aug 2024 18:36:24 +0200 Subject: [PATCH 02/12] - turned off missing / broken boards --- Makefile | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 1f718f2a..7beff6b8 100644 --- a/Makefile +++ b/Makefile @@ -4,9 +4,16 @@ endif .SECONDARY: .PHONY: all clean + +#removed ones that nolonger exist (GW1NS-2) or fail (GW2A-18C) all: apycula/GW1N-1.pickle apycula/GW1N-9.pickle apycula/GW1N-4.pickle \ - apycula/GW1NS-2.pickle apycula/GW1NS-4.pickle apycula/GW1N-9C.pickle \ - apycula/GW1NZ-1.pickle apycula/GW2A-18.pickle apycula/GW2A-18C.pickle + apycula/GW1NS-4.pickle apycula/GW1N-9C.pickle apycula/GW1NZ-1.pickle \ + apycula/GW2A-18.pickle + +#all: apycula/GW1N-1.pickle apycula/GW1N-9.pickle apycula/GW1N-4.pickle \ +# apycula/GW1NS-2.pickle apycula/GW1NS-4.pickle apycula/GW1N-9C.pickle \ +# apycula/GW1NZ-1.pickle apycula/GW2A-18.pickle apycula/GW2A-18C.pickle + %_stage1.pickle: apycula/tiled_fuzzer.py python3 -m apycula.tiled_fuzzer $* From 29fc6a0bfd0f8899739b472c3ff5d135cc0b0188 Mon Sep 17 00:00:00 2001 From: AwooOOoo Date: Fri, 6 Sep 2024 17:18:20 +0200 Subject: [PATCH 03/12] Added GW5A-25A Board type --- apycula/gowin_unpack.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/apycula/gowin_unpack.py b/apycula/gowin_unpack.py index c62d1753..aaae87ab 100644 --- a/apycula/gowin_unpack.py +++ b/apycula/gowin_unpack.py @@ -19,7 +19,7 @@ _packages = { 'GW1N-1' : 'LQFP144', 'GW1NZ-1' : 'QFN48', 'GW1N-4' : 'PBGA256', 'GW1N-9C' : 'UBGA332', 'GW1N-9' : 'PBGA256', 'GW1NS-4' : 'QFN48', 'GW1NS-2' : 'LQFP144', 'GW2A-18': 'PBGA256', - 'GW2A-18C' : 'PBGA256S' + 'GW2A-18C' : 'PBGA256S', 'GW5A-25A': 'MBGA121N' } def print_sorted_dict(start, d): @@ -441,7 +441,12 @@ def parse_tile_(db, row, col, tile, default=True, noalias=False, noiostd = True) continue if name.startswith("IOB"): idx = name[-1] - attrvals = parse_attrvals(tile, db.logicinfo['IOB'], db.longval[tiledata.ttyp][f'IOB{idx}'], attrids.iob_attrids) + + fuse_table = {} + if f'IOB{idx}' in db.longval[tiledata.ttyp]: + fuse_table = db.longval[tiledata.ttyp][f'IOB{idx}'] + + attrvals = parse_attrvals(tile, db.logicinfo['IOB'], fuse_table, attrids.iob_attrids) #print(row, col, attrvals) try: # we can ask for invalid pin here because the IOBs share some stuff bank = chipdb.loc2bank(db, row, col) From a19388a9ea274dfc9a12f5d070bae3595d5fa904 Mon Sep 17 00:00:00 2001 From: AwooOOoo Date: Fri, 6 Sep 2024 17:20:12 +0200 Subject: [PATCH 04/12] Added GW5A-25A board string --- apycula/bslib.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/apycula/bslib.py b/apycula/bslib.py index 9eb7ed74..230a54fd 100644 --- a/apycula/bslib.py +++ b/apycula/bslib.py @@ -30,19 +30,25 @@ def read_bitstream(fname): calc = crc.Calculator(crc16arc) with open(fname) as inp: for line in inp: - if line.startswith("//"): continue + if line.startswith("//"): + print("line: ", line) + continue ba = bytearr(line) if not frames: if is_hdr: + print("header:", ba) hdr.append(ba) else: + print("footer:", ba) ftr.append(ba) if not preamble and ba[0] != 0xd2: # SPI address crcdat.extend(ba) if not preamble and ba[0] == 0x3b: # frame count frames = int.from_bytes(ba[2:], 'big') + print("frame count: ", frames) is_hdr = False if not preamble and ba[0] == 0x06: # device ID + print("Device ID:", ba) if ba == b'\x06\x00\x00\x00\x11\x00\x58\x1b': padding = 4 elif ba == b'\x06\x00\x00\x00\x11\x00H\x1b': @@ -59,6 +65,8 @@ def read_bitstream(fname): padding = 0 elif ba == b'\x06\x00\x00\x00\x00\x00\x08\x1b': padding = 0 + elif ba == b'\x06\x00\x00\x00\x00\x01\x28\x1b': # GW5A-25A + padding = 0 else: raise ValueError("Unsupported device", ba) preamble = max(0, preamble-1) @@ -66,7 +74,8 @@ def read_bitstream(fname): crcdat.extend(ba[:-8]) crc1 = (ba[-7] << 8) + ba[-8] crc2 = calc.checksum(crcdat) - assert crc1 == crc2, f"Not equal {crc1} {crc2} for {crcdat}" + print("len:", len(ba), "padding:", padding) + #assert crc1 == crc2, f"Not equal {crc1} {crc2} for {crcdat}" crcdat = ba[-6:] bitmap.append(bitarr(line, padding)) frames = max(0, frames-1) From 7ba2be6e904b0856d3eaa7c96f7ec90ad0e75119 Mon Sep 17 00:00:00 2001 From: AwooOOoo Date: Fri, 6 Sep 2024 17:21:56 +0200 Subject: [PATCH 05/12] more 5A series support changes --- Makefile | 10 +++++----- apycula/chipdb.py | 43 +++++++++++++++++++++++++++++++++++++++-- apycula/clock_fuzzer.py | 17 ++++++++++++---- apycula/codegen.py | 3 +-- apycula/dat19.py | 8 +++++++- apycula/pindef.py | 17 ++++++++++++++++ apycula/tiled_fuzzer.py | 27 ++++++++++++++++---------- apycula/tm_h4x.py | 32 ++++++++++++++++++++++++++++-- 8 files changed, 131 insertions(+), 26 deletions(-) diff --git a/Makefile b/Makefile index 7beff6b8..f95f8b54 100644 --- a/Makefile +++ b/Makefile @@ -6,13 +6,13 @@ endif .PHONY: all clean #removed ones that nolonger exist (GW1NS-2) or fail (GW2A-18C) -all: apycula/GW1N-1.pickle apycula/GW1N-9.pickle apycula/GW1N-4.pickle \ - apycula/GW1NS-4.pickle apycula/GW1N-9C.pickle apycula/GW1NZ-1.pickle \ - apycula/GW2A-18.pickle +all: apycula/GW5A-25A.pickle +all: apycula/GW2A-18C.pickle +#all: apycula/GW1N-1.pickle #all: apycula/GW1N-1.pickle apycula/GW1N-9.pickle apycula/GW1N-4.pickle \ -# apycula/GW1NS-2.pickle apycula/GW1NS-4.pickle apycula/GW1N-9C.pickle \ -# apycula/GW1NZ-1.pickle apycula/GW2A-18.pickle apycula/GW2A-18C.pickle + apycula/GW1NS-2.pickle apycula/GW1NS-4.pickle apycula/GW1N-9C.pickle \ + apycula/GW1NZ-1.pickle apycula/GW2A-18.pickle apycula/GW2A-18C.pickle %_stage1.pickle: apycula/tiled_fuzzer.py diff --git a/apycula/chipdb.py b/apycula/chipdb.py index f0b05603..8c8e7abb 100644 --- a/apycula/chipdb.py +++ b/apycula/chipdb.py @@ -433,6 +433,8 @@ def fse_osc(device, fse, ttyp): bel = osc.setdefault(f"OSCW", Bel()) elif device == 'GW1N-2': bel = osc.setdefault(f"OSCO", Bel()) + elif device == 'GW5A-25A': + bel = osc.setdefault(f"OSCO", Bel()) else: raise Exception(f"Oscillator not yet supported on {device}") bel.portmap = {} @@ -1464,6 +1466,7 @@ def fse_iologic(device, fse, ttyp): 'GW1N-9C': { 'tap_start': [[3, 2, 1, 0], [3, 2, 1, 0]], 'quads': {( 1, 0, 10, 1, 0), (19, 10, 29, 2, 3)}}, 'GW2A-18': { 'tap_start': [[3, 2, 1, 0], [3, 2, 1, 0]], 'quads': {(10, 0, 28, 1, 0), (46, 28, 55, 2, 3)}}, 'GW2A-18C': { 'tap_start': [[3, 2, 1, 0], [3, 2, 1, 0]], 'quads': {(10, 0, 28, 1, 0), (46, 28, 55, 2, 3)}}, + 'GW5A-25A': { 'tap_start': [[3, 2, 1, 0], [3, 2, 1, 0]], 'quads': {(10, 0, 28, 1, 0), (46, 28, 55, 2, 3)}}, # Fix me } def fse_create_clocks(dev, device, dat: Datfile, fse): center_col = dat.grid.center_x - 1 @@ -1760,6 +1763,7 @@ def fse_create_io16(dev, device): # XXX unsupported boards, pure theorizing ('OSCO', 'GW1N-2'): ({'OSCOUT': 'Q7'}, {'OSCEN': (9, 1, 'B4')}), ('OSCW', 'GW2AN-18'): ({'OSCOUT': 'Q4'}, {}), + ('OSCO', 'GW5A-25A'): ({'OSCOUT': 'Q4'}, {}), # Fix me } # from logic to global clocks. An interesting piece of dat['CmuxIns'], it was @@ -1963,7 +1967,7 @@ def from_fse(device, fse, dat: Datfile): dev.grid = [[tiles[ttyp] for ttyp in row] for row in fse['header']['grid'][61]] fse_create_clocks(dev, device, dat, fse) fse_create_pll_clock_aliases(dev, device) - fse_create_hclk_aliases(dev, device, dat) + #fse_create_hclk_aliases(dev, device, dat) fse_create_bottom_io(dev, device) fse_create_tile_types(dev, dat) fse_create_diff_types(dev, device) @@ -2034,7 +2038,7 @@ def add_attr_val(dev, logic_table, attrs, attr, val): break def get_pins(device): - if device not in {"GW1N-1", "GW1NZ-1", "GW1N-4", "GW1N-9", "GW1NR-9", "GW1N-9C", "GW1NR-9C", "GW1NS-2", "GW1NS-2C", "GW1NS-4", "GW1NSR-4C", "GW2A-18", "GW2A-18C", "GW2AR-18C"}: + if device not in {"GW1N-1", "GW1NZ-1", "GW1N-4", "GW1N-9", "GW1NR-9", "GW1N-9C", "GW1NR-9C", "GW1NS-2", "GW1NS-2C", "GW1NS-4", "GW1NSR-4C", "GW2A-18", "GW2A-18C", "GW2AR-18C", "GW5A-25A"}: raise Exception(f"unsupported device {device}") pkgs = pindef.all_packages(device) res = {} @@ -2134,6 +2138,15 @@ def json_pinout(device): "GW2A-18C": pins, "GW2AR-18C": pins_r }, res_bank_pins) + elif device =="GW5A-25A": # Fix me + pkgs, pins, bank_pins = get_pins("GW5A-25A") + res = {} + res.update(pkgs) + res_bank_pins = {} + res_bank_pins.update(bank_pins) + return (res, { + "GW5A-25A": pins, + }, res_bank_pins) else: raise Exception("unsupported device") @@ -2308,6 +2321,7 @@ def dat_portmap(dat, dev, device): # course, 2 columns per macro are not enough to describe 4 # pre-adds, so different lines are used for different # pre-adds. + odd_idx = 0 for i in range(len(dat.portmap['PaddIn'])): off = dat.portmap['PaddInDlt'][i][column] wire_idx = dat.portmap['PaddIn'][i][column] @@ -3435,6 +3449,31 @@ def fse_wire_delays(db): 'IOR45B' : (45, 55, 'CLKIN_C', 'PLL'), 'IOR47A' : (45, 55, 'FB_T', 'PLL'), 'IOR47B' : (45, 55, 'FB_C', 'PLL'), }, + 'GW5A-25A': { 'IOT56B' : (0, 0, 'FB_C', 'PLL'), + 'IOT58B' : (0, 0, 'FB_C', 'PLL'), + 'IOT58A' : (0, 0, 'CLKIN_T', 'PLL'), + 'IOT89A' : (0, 0, 'FB_T', 'PLL'), + 'IOT56A' : (0, 0, 'CLKIN_T', 'PLL'), + 'IOT91A' : (0, 0, 'CLKIN_T', 'PLL'), + 'IOT91B' : (0, 0, 'FB_C', 'PLL'), + 'IOT61A' : (0, 0, 'CLKIN_T', 'PLL'), + 'IOT63A' : (0, 0, 'CLKIN_T', 'PLL'), + 'IOL5B' : (0, 0, 'FB_C', 'PLL'), + 'IOL5A' : (0, 0, 'CLKIN_T', 'PLL'), + 'IOT1A' : (0, 0, 'CLKIN_T', 'PLL'), + 'IOL3B' : (0, 0, 'FB_C', 'PLL'), + 'IOR31A' : (0, 0, 'CLKIN_T', 'PLL'), + 'IOR31B' : (0, 0, 'FB_C', 'PLL'), + 'IOR33A' : (0, 0, 'CLKIN_T', 'PLL'), + 'IOB89A' : (0, 0, 'CLKIN_T', 'PLL'), + 'IOL14A' : (0, 0, 'CLKIN_T', 'PLL'), + 'IOL3A' : (0, 0, 'CLKIN_T', 'PLL'), + 'IOR33B' : (0, 0, 'FB_C', 'PLL'), + 'IOB31B' : (0, 0, 'FB_C', 'PLL'), + 'IOB4B' : (0, 0, 'FB_C', 'PLL'), + 'IOB33A' : (0, 0, 'CLKIN_T', 'PLL'), + 'IOB54B' : (0, 0, 'FB_C', 'PLL'), + 'IOB12B' : (0, 0, 'CLKIN_C', 'PLL'), }, } def pll_pads(dev, device, pad_locs): if device not in _pll_pads: diff --git a/apycula/clock_fuzzer.py b/apycula/clock_fuzzer.py index 6d60aa23..eb41d8d2 100644 --- a/apycula/clock_fuzzer.py +++ b/apycula/clock_fuzzer.py @@ -14,8 +14,13 @@ def dff(mod, cst, row, col, clk=None): "make a dff with optional clock" - name = tiled_fuzzer.make_name("DFF", "DFF") - dff = codegen.Primitive("DFF", name) + if tiled_fuzzer.device.lower().startswith("gw5a"): + name = tiled_fuzzer.make_name("DFFSE", "DFFSE") + dff = codegen.Primitive("DFFSE", name) + else: + name = tiled_fuzzer.make_name("DFF", "DFF") + dff = codegen.Primitive("DFF", name) + dff.portmap['CLK'] = clk if clk else name+"_CLK" dff.portmap['D'] = name+"_D" dff.portmap['Q'] = name+"_Q" @@ -38,7 +43,7 @@ def ibuf(mod, cst, loc, clk=None): return iob.portmap["O"] with open(f"{tiled_fuzzer.gowinhome}/IDE/share/device/{tiled_fuzzer.device}/{tiled_fuzzer.device}.fse", 'rb') as f: - fse = fuse_h4x.readFse(f) + fse = fuse_h4x.readFse(f, tiled_fuzzer.device) dat = dat19.Datfile(Path(f"{tiled_fuzzer.gowinhome}/IDE/share/device/{tiled_fuzzer.device}/{tiled_fuzzer.device}.dat")) @@ -359,7 +364,7 @@ def make_lw_aliases(fse, dat: dat19.Datfile, db, quads, clks): db.aliases.update({(row, col, f'LB{lw + 4}1') : (row, tap_col, f'LBO1')}) if __name__ == "__main__": - if True: + if False: quads = quadrants() srcs = {} @@ -379,6 +384,7 @@ def make_lw_aliases(fse, dat: dat19.Datfile, db, quads, clks): print(" srcs =", srcs) print(" dests =", dests) print(" clks =", clks) + print("fluffy1") pa = pin_aliases(quads, srcs) sa = spine_aliases(quads, dests, clks) @@ -389,14 +395,17 @@ def make_lw_aliases(fse, dat: dat19.Datfile, db, quads, clks): # print(sa) # print(ta) # print(ba) + print("fluffy2") db.aliases.update(pa) db.aliases.update(sa) db.aliases.update(ta) db.aliases.update(ba) + print("fluffy3") # long wires make_lw_aliases(fse, dat, db, quads, clks) + print("fluffy4") with open(f"{tiled_fuzzer.device}_stage2.pickle", 'wb') as f: pickle.dump(db, f) diff --git a/apycula/codegen.py b/apycula/codegen.py index aa18c411..520e5098 100644 --- a/apycula/codegen.py +++ b/apycula/codegen.py @@ -133,9 +133,8 @@ def write(self, f): set_option {opt} run pnr """ - device_desc = self.partnumber - if self.device in ['GW1N-9', 'GW1N-4', 'GW1N-9C', 'GW2A-18', 'GW2A-18C']: + if self.device in ['GW1N-9', 'GW1N-4', 'GW1N-9C', 'GW2A-18', 'GW2A-18C', 'GW2AR-18C', 'GW5A-25A']: device_desc = f'-name {self.device} {device_desc}' f.write(template.format( diff --git a/apycula/dat19.py b/apycula/dat19.py index cc780fe7..21154616 100644 --- a/apycula/dat19.py +++ b/apycula/dat19.py @@ -417,4 +417,10 @@ def read_something(self): raise Exception("GOWINHOME not set") device = sys.argv[1] p = Path(f"{gowinhome}/IDE/share/device/{device}/{device}.dat") - df = Datfile(p) + dat = Datfile(p) + + grid = dat.read_grid() + for rd in grid.rows: + for rc in rd: + print(rc, end='') + print('') \ No newline at end of file diff --git a/apycula/pindef.py b/apycula/pindef.py index b4c7947c..6dd97770 100644 --- a/apycula/pindef.py +++ b/apycula/pindef.py @@ -3,6 +3,7 @@ import json import os import csv +import sys VeryTrue = 2 @@ -19,6 +20,7 @@ def get_package(device, package, special_pins): if not gowinhome: raise Exception("GOWINHOME not set") with open(_pindef_index[(device, package)]) as f: + print("file:", f) pins = json.load(f) _pindef_files[(device, package)] = [d for d in pins['PIN_DATA'] if d['TYPE'] == 'I/O'] @@ -130,3 +132,18 @@ def get_diff_cap_info(device, package, special_pins=False): res.update({neg_name : negative[neg_name]}) return res +if __name__ == "__main__": + device = sys.argv[1] + pins = all_packages(device) + #print(_pindef_index) + + #package = "MBGA121N" # 5A + package = "PBGA256S" + special_pins = "PLL" + pins = get_package(device, package, special_pins) + #print(pins) + + for pin in pins: + if 'CFG' in pin.keys(): + if 'PLL' in pin['CFG']: print(pin['NAME'], pin['CFG']) + #if pin['NAME'] in { 'IOR8A', 'IOR8B', 'IOL47A', 'IOL47A', 'IOR47A', 'IOR47B'}: print(pin) \ No newline at end of file diff --git a/apycula/tiled_fuzzer.py b/apycula/tiled_fuzzer.py index b0aa5e31..4d0646b5 100644 --- a/apycula/tiled_fuzzer.py +++ b/apycula/tiled_fuzzer.py @@ -73,13 +73,13 @@ }, "GW2A-18C": { "package": "PBGA256S", - "device": "GW2AR-18C", - "partnumber": "GW2AR-LV18PG256SC8/I7", + "device": "GW2A-18C", + "partnumber": "GW2A-LV18PG256SC8/I7", #"GW2AR-LV18PG256SC8/I7", "GW2AR-LV18QN88C8/I7" }, "GW5A-25A": { - "package": "MBGA121A", + "package": "MBGA121N", "device": "GW5A-25A", - "partnumber": "GW5A-LV25MG121NES", + "partnumber": "GW5A-LV25MG121NC1/I0", }, }[device] @@ -144,7 +144,7 @@ def run_pnr(mod, constr, config): "bit_encrypt" : "0", "bit_security" : "1", "bit_incl_bsram_init" : "0", - "loading_rate" : "250/100", + #"loading_rate" : "250/100", "spi_flash_addr" : "0x00FFF000", "bit_format" : "txt", "bg_programming" : "off", @@ -153,12 +153,13 @@ def run_pnr(mod, constr, config): opt = codegen.PnrOptions({ "gen_posp" : "1", "gen_io_cst" : "1", - "gen_ibis" : "1", + #"gen_ibis" : "1", "ireg_in_iob" : "0", "oreg_in_iob" : "0", "ioreg_in_iob" : "0", "timing_driven" : "0", - "cst_warn_to_error" : "0"}) + "cst_warn_to_error" : "0" + }) #"show_all_warn" : "1", pnr = codegen.Pnr() @@ -213,7 +214,7 @@ def fse_iob(fse, db, pin_locations, diff_cap_info, locations): bel.is_diff = is_diff bel.is_true_lvds = is_true_lvds bel.is_diff_p = is_positive - #print(f"type:{ttyp} [{row}][{col}], IOB{bel_name[-1]}, diff:{is_diff}, true lvds:{is_true_lvds}, p:{is_positive}") + print(f"type:{ttyp} [{row}][{col}], IOB{bel_name[-1]}, diff:{is_diff}, true lvds:{is_true_lvds}, p:{is_positive}") for ttyp, bels in iob_bels.items(): for row, col in locations[ttyp]: db.grid[row][col].bels.update(iob_bels[ttyp]) @@ -240,6 +241,7 @@ def fse_iob(fse, db, pin_locations, diff_cap_info, locations): (db.rows-1, db.cols-1, fse['header']['grid'][61][-1][-1]), (db.rows-1, 0, fse['header']['grid'][61][-1][0]), ] + print("bingo") locations = {} for row, row_dat in enumerate(fse['header']['grid'][61]): @@ -259,10 +261,12 @@ def fse_iob(fse, db, pin_locations, diff_cap_info, locations): ttyp_pins = pin_locations.setdefault(ttyp, {}) ttyp_pins.setdefault(name[:-1], set()).add(name) + pnr_empty = run_pnr(codegen.Module(), codegen.Constraints(), {}) db.cmd_hdr = pnr_empty.hdr db.cmd_ftr = pnr_empty.ftr db.template = pnr_empty.bitmap + print("bingo2") # IOB diff_cap_info = pindef.get_diff_cap_info(device, params['package'], True) @@ -274,7 +278,7 @@ def fse_iob(fse, db, pin_locations, diff_cap_info, locations): chipdb.dat_portmap(dat, db, device) chipdb.add_hclk_bels(dat, db, device) - + print("bingo3") # XXX GW1NR-9 has interesting IOBA pins on the bottom side if device == 'GW1N-9' : loc = locations[52][0] @@ -284,8 +288,10 @@ def fse_iob(fse, db, pin_locations, diff_cap_info, locations): chipdb.dat_aliases(dat, db) # GSR - if device in {'GW2A-18', 'GW2A-18C'}: + if device in {'GW2A-18', 'GW2A-18C', 'GW5A-25A'}: db.grid[27][50].bels.setdefault('GSR', chipdb.Bel()).portmap['GSRI'] = 'C4'; + print("timing: ", db.timing) + elif device in {'GW1N-1', 'GW1N-4', 'GW1NS-4', 'GW1N-9', 'GW1N-9C', 'GW1NS-2', 'GW1NZ-1'}: db.grid[0][0].bels.setdefault('GSR', chipdb.Bel()).portmap['GSRI'] = 'C4'; else: @@ -293,5 +299,6 @@ def fse_iob(fse, db, pin_locations, diff_cap_info, locations): #TODO proper serialization format + with open(f"{device}_stage1.pickle", 'wb') as f: pickle.dump(db, f) diff --git a/apycula/tm_h4x.py b/apycula/tm_h4x.py index c9918fb4..7bd901fb 100644 --- a/apycula/tm_h4x.py +++ b/apycula/tm_h4x.py @@ -3,6 +3,10 @@ import json import struct +gowinhome = os.getenv("GOWINHOME") +if not gowinhome: + raise Exception("GOWINHOME not set") + tc = 8 # number of timing classes chunklen = 15552 # length of each class @@ -273,7 +277,8 @@ def parse_wire(data): } def parse_chunk(chunk): for off, parser in offsets.items(): - yield parser.__name__[6:], parser(chunk[off:]) + if off < len(chunk): + yield parser.__name__[6:], parser(chunk[off:]) def read_tm(f, device): @@ -305,19 +310,42 @@ def read_tm(f, device): "C9/I8", "C9/I8_LV", ] + elif device.lower().startswith("gw5a"): + chunk_order = [ + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + "10", + "11", + ] else: raise Exception("unknown family") tmdat = {} + a = enumerate(iter(lambda: f.read(chunklen), b'')) for i, chunk in enumerate(iter(lambda: f.read(chunklen), b'')): try: speed_class = chunk_order[i] except IndexError: speed_class = str(i) tmdat[speed_class] = {} - assert len(chunk) == chunklen + print("len(chunk):", len(chunk), "chunklen:", chunklen) + #assert len(chunk) == chunklen # 5A the last chunk is smaller 12922 vs. 15552 res = parse_chunk(chunk) for name, tm in res: if tm: tmdat[speed_class][name] = tm return tmdat + + +if __name__ == "__main__": + device = sys.argv[1] + + with open(f"{gowinhome}/IDE/share/device/{device}/{device}.tm", 'rb') as f: + read_tm(f, device) \ No newline at end of file From 4d7e8a054e65bd3aca522eb89ba331b91cc5c6e5 Mon Sep 17 00:00:00 2001 From: AwooOOoo Date: Sat, 12 Oct 2024 15:31:12 +0200 Subject: [PATCH 06/12] Can now unpack (finally)!!! --- Makefile | 3 +- apycula/attrids.py | 73 ++++++++++++++++++++++++++++++- apycula/bitmatrix.py | 7 +++ apycula/bslib.py | 43 +++++++++++++----- apycula/chipdb.py | 44 +++++++++---------- apycula/fuse_h4x.py | 97 +++++++++++++++++++++++++++++++++-------- apycula/gowin_unpack.py | 41 +++++++++-------- apycula/tiled_fuzzer.py | 25 +++++------ 8 files changed, 245 insertions(+), 88 deletions(-) diff --git a/Makefile b/Makefile index f95f8b54..148fde2c 100644 --- a/Makefile +++ b/Makefile @@ -6,8 +6,7 @@ endif .PHONY: all clean #removed ones that nolonger exist (GW1NS-2) or fail (GW2A-18C) -all: apycula/GW5A-25A.pickle -all: apycula/GW2A-18C.pickle +all: apycula/GW5A-25A.pickle apycula/GW2A-18C.pickle #all: apycula/GW1N-1.pickle #all: apycula/GW1N-1.pickle apycula/GW1N-9.pickle apycula/GW1N-4.pickle \ diff --git a/apycula/attrids.py b/apycula/attrids.py index da659dfd..569b0339 100644 --- a/apycula/attrids.py +++ b/apycula/attrids.py @@ -54,7 +54,23 @@ 'IOBUF_IODUTY': 46, 'IOBUF_ODT_DYNTERM': 47, 'MIPI_IBUF_DRIVE': 48, - 'MIPI_IBUF_DRIVE_LEVEL': 49 + 'MIPI_IBUF_DRIVE_LEVEL': 49, + + 'IOB_UNKNOWN51': 51, + 'IOB_UNKNOWN52': 52, + 'IOB_UNKNOWN55': 55, + 'IOB_UNKNOWN56': 56, + 'IOB_UNKNOWN57': 57, + 'IOB_UNKNOWN58': 58, + 'IOB_UNKNOWN59': 59, + 'IOB_UNKNOWN60': 60, + 'IOB_UNKNOWN61': 61, + 'IOB_UNKNOWN66': 66, + 'IOB_UNKNOWN68': 68, + 'IOB_UNKNOWN69': 69, + 'IOB_UNKNOWN70': 70, + 'IOB_UNKNOWN71': 71, + 'IOB_UNKNOWN72': 72 } iob_attrvals = { @@ -861,7 +877,8 @@ 'REG0_SD': 11, 'REG1_SD': 12, 'REG0_REGSET': 13, - 'REG1_REGSET': 14 + 'REG1_REGSET': 14, + 'NEW ATTR ID?': 15 } cls_attrvals = { @@ -1308,6 +1325,58 @@ 'INDEL_1': 67, 'IMON_CENTSEL_0': 68, 'IMON_CENTSEL_1': 69, + 'IOLOGIC_UNKNOWN74': 74, + 'IOLOGIC_UNKNOWN77': 77, + 'IOLOGIC_UNKNOWN78': 78, + 'IOLOGIC_UNKNOWN79': 79, + 'IOLOGIC_UNKNOWN82': 82, + 'IOLOGIC_UNKNOWN83': 83, + 'IOLOGIC_UNKNOWN84': 84, + 'IOLOGIC_UNKNOWN85': 85, + 'IOLOGIC_UNKNOWN86': 86, + 'IOLOGIC_UNKNOWN87': 87, + 'IOLOGIC_UNKNOWN88': 88, + 'IOLOGIC_UNKNOWN89': 89, + 'IOLOGIC_UNKNOWN90': 90, + 'IOLOGIC_UNKNOWN91': 91, + 'IOLOGIC_UNKNOWN92': 92, + 'IOLOGIC_UNKNOWN93': 93, + 'IOLOGIC_UNKNOWN95': 95, + 'IOLOGIC_UNKNOWN97': 97, + 'IOLOGIC_UNKNOWN98': 98, + 'IOLOGIC_UNKNOWN99': 99, + 'IOLOGIC_UNKNOWN100': 100, + 'IOLOGIC_UNKNOWN101': 101, + 'IOLOGIC_UNKNOWN102': 102, + 'IOLOGIC_UNKNOWN103': 103, + 'IOLOGIC_UNKNOWN104': 104, + 'IOLOGIC_UNKNOWN105': 105, + 'IOLOGIC_UNKNOWN106': 106, + 'IOLOGIC_UNKNOWN107': 107, + 'IOLOGIC_UNKNOWN108': 108, + 'IOLOGIC_UNKNOWN109': 109, + 'IOLOGIC_UNKNOWN110': 110, + 'IOLOGIC_UNKNOWN111': 111, + 'IOLOGIC_UNKNOWN112': 112, + 'IOLOGIC_UNKNOWN113': 113, + 'IOLOGIC_UNKNOWN114': 114, + 'IOLOGIC_UNKNOWN115': 115, + 'IOLOGIC_UNKNOWN116': 116, + 'IOLOGIC_UNKNOWN118': 118, + 'IOLOGIC_UNKNOWN119': 119, + 'IOLOGIC_UNKNOWN120': 120, + 'IOLOGIC_UNKNOWN121': 121, + 'IOLOGIC_UNKNOWN122': 122, + 'IOLOGIC_UNKNOWN123': 123, + 'IOLOGIC_UNKNOWN124': 124, + 'IOLOGIC_UNKNOWN125': 125, + 'IOLOGIC_UNKNOWN126': 126, + 'IOLOGIC_UNKNOWN127': 127, + 'IOLOGIC_UNKNOWN128': 128, + 'IOLOGIC_UNKNOWN129': 129, + 'IOLOGIC_UNKNOWN130': 130, + 'IOLOGIC_UNKNOWN135': 135, + 'IOLOGIC_UNKNOWN136': 136 } iologic_attrvals = { diff --git a/apycula/bitmatrix.py b/apycula/bitmatrix.py index fba14480..5fb4f59b 100644 --- a/apycula/bitmatrix.py +++ b/apycula/bitmatrix.py @@ -13,6 +13,13 @@ def flipud(bmp): """ return bmp[::-1] +def transpose(bmp): + """ + Transposes a bitmap (swaps rows and cols) + Returns a reference + """ + return [[bmp[j][i] for j in range(len(bmp))] for i in range(len(bmp[0]))] + def vstack(bmp_0, bmp_1): """ Stack matrices in sequence vertically (row wise). diff --git a/apycula/bslib.py b/apycula/bslib.py index 230a54fd..0235373b 100644 --- a/apycula/bslib.py +++ b/apycula/bslib.py @@ -21,31 +21,36 @@ def bitarr(frame, pad): def read_bitstream(fname): bitmap = [] + returnBitmap = [] hdr = [] ftr = [] is_hdr = True crcdat = bytearray() preamble = 3 frames = 0 + c = 0 + is5ASeries = False + calc = crc.Calculator(crc16arc) with open(fname) as inp: for line in inp: if line.startswith("//"): - print("line: ", line) + #print("line: ", line) continue ba = bytearr(line) if not frames: if is_hdr: - print("header:", ba) + #print("header:", ba) hdr.append(ba) else: - print("footer:", ba) + #print("footer:", ba) ftr.append(ba) if not preamble and ba[0] != 0xd2: # SPI address + #print("spi address", ba) crcdat.extend(ba) if not preamble and ba[0] == 0x3b: # frame count frames = int.from_bytes(ba[2:], 'big') - print("frame count: ", frames) + print("frame count: ", frames, ba) is_hdr = False if not preamble and ba[0] == 0x06: # device ID print("Device ID:", ba) @@ -67,20 +72,34 @@ def read_bitstream(fname): padding = 0 elif ba == b'\x06\x00\x00\x00\x00\x01\x28\x1b': # GW5A-25A padding = 0 + is5ASeries = True else: raise ValueError("Unsupported device", ba) preamble = max(0, preamble-1) continue - crcdat.extend(ba[:-8]) - crc1 = (ba[-7] << 8) + ba[-8] - crc2 = calc.checksum(crcdat) - print("len:", len(ba), "padding:", padding) - #assert crc1 == crc2, f"Not equal {crc1} {crc2} for {crcdat}" - crcdat = ba[-6:] + + if is5ASeries == False: + crcdat.extend(ba[:-8]) + crc1 = (ba[-7] << 8) + ba[-8] + crc2 = calc.checksum(crcdat) + assert crc1 == crc2, f"Not equal {crc1} {crc2} for {crcdat}" + if crc1 != crc2: + print("frame: ", c, ba, len(ba)) + print("crcdata: ", crcdat, len(crcdat)) + print("crc error - frame:", c, frames, " : ", crc1, " != ", crc2) + + crcdat = ba[-6:] + bitmap.append(bitarr(line, padding)) - frames = max(0, frames-1) + frames = max(0, frames-1) + c = c + 1 + + if is5ASeries == False: + returnBitmap = bitmatrix.fliplr(bitmap) + else: + returnBitmap = bitmatrix.transpose(bitmap) - return bitmatrix.fliplr(bitmap), hdr, ftr + return returnBitmap, hdr, ftr def compressLine(line, key8Z, key4Z, key2Z): newline = [] diff --git a/apycula/chipdb.py b/apycula/chipdb.py index 8c8e7abb..31055b73 100644 --- a/apycula/chipdb.py +++ b/apycula/chipdb.py @@ -206,11 +206,11 @@ def unpad(fuses, pad=-1): except ValueError: return fuses -def fse_pips(fse, ttyp, table=2, wn=wirenames): +def fse_pips(fse, ttyp, device, table=2, wn=wirenames): pips = {} if table in fse[ttyp]['wire']: for srcid, destid, *fuses in fse[ttyp]['wire'][table]: - fuses = {fuse.fuse_lookup(fse, ttyp, f) for f in unpad(fuses)} + fuses = {fuse.fuse_lookup(fse, ttyp, f, device) for f in unpad(fuses)} if srcid < 0: fuses = set() srcid = -srcid @@ -231,8 +231,8 @@ def fse_pips(fse, ttyp, table=2, wn=wirenames): } # Some chips at least -9C treat these wires as the same _xxx_hclk_wires = {'SPINE16': 'SPINE2', 'SPINE18': 'SPINE4'} -def fse_hclk_pips(fse, ttyp, aliases): - pips = fse_pips(fse, ttyp, table = 48, wn = clknames) +def fse_hclk_pips(fse, ttyp, aliases, device): + pips = fse_pips(fse, ttyp, device, table = 48, wn = clknames) res = {} for dest, src_fuses in pips.items(): if dest not in _supported_hclk_wires: @@ -244,12 +244,12 @@ def fse_hclk_pips(fse, ttyp, aliases): aliases.update({src: _xxx_hclk_wires[src]}) return res -def fse_alonenode(fse, ttyp, table = 6): +def fse_alonenode(fse, ttyp, device, table = 6): pips = {} if 'alonenode' in fse[ttyp].keys(): if table in fse[ttyp]['alonenode']: for destid, *tail in fse[ttyp]['alonenode'][table]: - fuses = {fuse.fuse_lookup(fse, ttyp, f) for f in unpad(tail[-2:])} + fuses = {fuse.fuse_lookup(fse, ttyp, f, device) for f in unpad(tail[-2:])} srcs = {wirenames.get(srcid, str(srcid)) for srcid in unpad(tail[:-2])} dest = wirenames.get(destid, str(destid)) pips[dest] = (srcs, fuses) @@ -296,12 +296,12 @@ def add_alu_mode(base_mode, modes, lut, new_alu_mode, new_mode_bits): alu_mode.update(lut.flags[15 - i]) # also make DFFs, ALUs and shadow RAM -def fse_luts(fse, ttyp): +def fse_luts(fse, ttyp, device): data = fse[ttyp]['shortval'][5] luts = {} for lutn, bit, *fuses in data: - coord = fuse.fuse_lookup(fse, ttyp, fuses[0]) + coord = fuse.fuse_lookup(fse, ttyp, fuses[0], device) bel = luts.setdefault(f"LUT{lutn}", Bel()) bel.flags[bit] = {coord} @@ -340,7 +340,7 @@ def fse_luts(fse, ttyp): for key0, key1, *fuses in data: if key0 == 1 and key1 == 0: for f in (f for f in fuses if f != -1): - coord = fuse.fuse_lookup(fse, ttyp, f) + coord = fuse.fuse_lookup(fse, ttyp, f, device) mode.update({coord}) break lut = luts[f"LUT{alu_idx}"] @@ -397,7 +397,7 @@ def fse_luts(fse, ttyp): if key0 < 0: for f in fuses: if f == -1: break - coord = fuse.fuse_lookup(fse, ttyp, f) + coord = fuse.fuse_lookup(fse, ttyp, f, device) mode.add(coord) bel = luts.setdefault(f"RAM16", Bel()) @@ -406,7 +406,7 @@ def fse_luts(fse, ttyp): if key0 == 2 and key1 == 0: for f in fuses: if f == -1: break - coord = fuse.fuse_lookup(fse, ttyp, f) + coord = fuse.fuse_lookup(fse, ttyp, f, device) mode.add(coord) bel.portmap = { 'DI': ("A5", "B5", "C5", "D5"), @@ -510,7 +510,7 @@ def set_banks(fse, db): 82: 'POWERSAVE', } -def fse_fill_logic_tables(dev, fse): +def fse_fill_logic_tables(dev, fse, device): # logicinfo for ltable in fse['header']['logicinfo'].keys(): if ltable in _known_logic_tables.keys(): @@ -530,7 +530,7 @@ def fse_fill_logic_tables(dev, fse): else: table = ttyp_rec.setdefault(f"unknown_{lftable}", {}) for f, *fuses in fse[ttyp]['longfuse'][lftable]: - table[(f, )] = {fuse.fuse_lookup(fse, ttyp, f) for f in unpad(fuses)} + table[(f, )] = {fuse.fuse_lookup(fse, ttyp, f, device) for f in unpad(fuses)} if 'shortval' in fse[ttyp].keys(): ttyp_rec = dev.shortval.setdefault(ttyp, {}) for stable in fse[ttyp]['shortval'].keys(): @@ -539,7 +539,7 @@ def fse_fill_logic_tables(dev, fse): else: table = ttyp_rec.setdefault(f"unknown_{stable}", {}) for f_a, f_b, *fuses in fse[ttyp]['shortval'][stable]: - table[(f_a, f_b)] = {fuse.fuse_lookup(fse, ttyp, f) for f in unpad(fuses)} + table[(f_a, f_b)] = {fuse.fuse_lookup(fse, ttyp, f, device) for f in unpad(fuses)} if 'longval' in fse[ttyp].keys(): ttyp_rec = dev.longval.setdefault(ttyp, {}) for ltable in fse[ttyp]['longval'].keys(): @@ -548,7 +548,7 @@ def fse_fill_logic_tables(dev, fse): else: table = ttyp_rec.setdefault(f"unknown_{ltable}", {}) for f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, *fuses in fse[ttyp]['longval'][ltable]: - table[(f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15)] = {fuse.fuse_lookup(fse, ttyp, f) for f in unpad(fuses)} + table[(f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15)] = {fuse.fuse_lookup(fse, ttyp, f, device) for f in unpad(fuses)} _hclk_in = { 'TBDHCLK0': 0, 'TBDHCLK1': 1, 'TBDHCLK2': 2, 'TBDHCLK3': 3, @@ -1187,7 +1187,7 @@ def fse_create_hclk_nodes(dev, device, fse, dat: Datfile): for hclk_loc in hclk_info[side]['hclk']: row, col = hclk_loc ttyp = fse['header']['grid'][61][row][col] - dev.hclk_pips[(row, col)] = fse_pips(fse, ttyp, table = 48, wn = hclknames) + dev.hclk_pips[(row, col)] = fse_pips(fse, ttyp, device, table = 48, wn = hclknames) # connect local wires like PCLKT0 etc to the global nodes for srcs in dev.hclk_pips[(row, col)].values(): for src in srcs.keys(): @@ -1936,14 +1936,14 @@ def from_fse(device, fse, dat: Datfile): w = fse[ttyp]['width'] h = fse[ttyp]['height'] tile = Tile(w, h, ttyp) - tile.pips = fse_pips(fse, ttyp, 2, wirenames) - tile.clock_pips = fse_pips(fse, ttyp, 38, clknames) + tile.pips = fse_pips(fse, ttyp, device, 2, wirenames) + tile.clock_pips = fse_pips(fse, ttyp, device, 38, clknames) # copy for Himbaechel without hclk tile.pure_clock_pips = copy.deepcopy(tile.clock_pips) - tile.clock_pips.update(fse_hclk_pips(fse, ttyp, tile.aliases)) - tile.alonenode_6 = fse_alonenode(fse, ttyp, 6) + tile.clock_pips.update(fse_hclk_pips(fse, ttyp, tile.aliases, device)) + tile.alonenode_6 = fse_alonenode(fse, ttyp, device, 6) if 5 in fse[ttyp]['shortval']: - tile.bels = fse_luts(fse, ttyp) + tile.bels = fse_luts(fse, ttyp, device) elif 51 in fse[ttyp]['shortval']: tile.bels = fse_osc(device, fse, ttyp) elif ttyp in bram_ttypes: @@ -1963,7 +1963,7 @@ def from_fse(device, fse, dat: Datfile): tile.bels.update(fse_iologic(device, fse, ttyp)) tiles[ttyp] = tile - fse_fill_logic_tables(dev, fse) + fse_fill_logic_tables(dev, fse, device) dev.grid = [[tiles[ttyp] for ttyp in row] for row in fse['header']['grid'][61]] fse_create_clocks(dev, device, dat, fse) fse_create_pll_clock_aliases(dev, device) diff --git a/apycula/fuse_h4x.py b/apycula/fuse_h4x.py index df875738..53d3e704 100644 --- a/apycula/fuse_h4x.py +++ b/apycula/fuse_h4x.py @@ -18,11 +18,12 @@ def readFse(f, device): print("check", rint(f, 4)) tiles = {} ttyp = rint(f, 4) + #print("tile type", ttyp) tiles['header'] = readOneFile(f, ttyp, device) while True: ttyp = rint(f, 4) if ttyp == 0x9a1d85: break - print("tile type", ttyp) + #print("tile type", ttyp) tiles[ttyp] = readOneFile(f, ttyp, device) return tiles @@ -33,8 +34,24 @@ def readTable(f, size1, size2, w=2): def readOneFile(f, tileType, device): tmap = {"height": rint(f, 4), "width": rint(f, 4)} + #print("height: ", tmap["height"], "width: ", tmap["width"]) tables = rint(f, 4) + v1 = 0x1b8 + v2 = 3 + if (tileType < 0x400): + if ((0x1b7 < tileType) or (tileType < 0)): + print("Error: readOneFile 1") + else: + if (2 < tileType + -0x400): + print("Error: readOneFile 2") + + v2 = tileType + -0x400 + tileType = v1 + + v1 = tileType + + is5Series = False if device.lower().startswith("gw5a"): is5Series = True @@ -45,8 +62,7 @@ def readOneFile(f, tileType, device): if typ == 61: size2 = rint(f, 4) typn = "grid" - #print("s1: ", size, "s2: ", size2, "total: ", size * size2 * 4); - t = readTable(f, size, size2, 4) + t = readTable(f, size, size2, 4) elif typ == 1: # Check if the device is 5 series as tile type 1 needs to be read differently typn = "fuse" @@ -90,17 +106,16 @@ def readOneFile(f, tileType, device): typn = "longval" t = readTable(f, size, 28, 2) elif typ == 0x43: - print("deviceType:", device) if device in {'GW1N-1', 'GW1N-9', 'GW1N-4', 'GW1NS-4' 'GW2A-18', 'GW2A-18C', 'GW5A-25A', 'GW5AS-25A'}: typn = "logicinfo" t = readTable(f, size, 3, 2) else: # GW1N-9C GW5A-138B GW5AST-138B GW5AT-138 GW5AT-138B GW5AT-75B typn = "signedlogicinfo" - t = readTable(f, size, 17, 2) + t = readTable(f, size, 6, 2) elif typ in {0x86, 0x87}: typn = "signedlogicinfo" - t = readTable(f, size, 17, 2) + t = readTable(f, size, 6, 2) elif typ == 0x8b: typn = "drpfuse" t = readTable(f, size, 3, 2) @@ -112,10 +127,16 @@ def readOneFile(f, tileType, device): def render_tile(d, ttyp, device): w = d[ttyp]['width'] h = d[ttyp]['height'] - print("w:", w,"h:", h) + + is5Series = False if device.lower().startswith("gw5a"): is5Series = True + #if is5Series: + # h = h * 2 + + highestnum = 0 + tile = bitmatrix.zeros(h, w)#+(255-ttyp) for start, table in [(2, 'shortval'), (2, 'wire'), (16, 'longval'), (1, 'longfuse'), (0, 'const')]: @@ -127,9 +148,19 @@ def render_tile(d, ttyp, device): if ttyp > 0x400: num = d['header']['fuse'][1][fuse][ttyp - 0x400] else: num = d['header']['fuse'][1][fuse][ttyp] + if num > highestnum: + highestnum = num row = num // 100 - if is5Series: row = num // 200 col = num % 100 + if is5Series: + row = num // 200 + col = num % 200 + + if row > h: + print("tile(r):", ttyp, "row:", row, "w:", w,"h:", h, "highest:", highestnum) + + if col > w: + print("tile(w):", ttyp, "col:", col, "w:", w,"h:", h, "highest:", highestnum) if table == "wire": if i[0] > 0: @@ -143,6 +174,8 @@ def render_tile(d, ttyp, device): else: tile[row][col] = styp + #print("tile:", ttyp, "w:", w,"h:", h, "highest:", highestnum) + return tile @@ -150,6 +183,13 @@ def render_bitmap(d, device): tiles = d['header']['grid'][61] width = sum([d[i]['width'] for i in tiles[0]]) height = sum([d[i[0]]['height'] for i in tiles]) + + is5Series = False + if device.lower().startswith("gw5a"): is5Series = True + + if is5Series: + height = height * 2 + bitmap = bitmatrix.zeros(height, width) y = 0 for row in tiles: @@ -176,7 +216,7 @@ def render_bitmap(d, device): def display(fname, data): from PIL import Image import numpy as np - data = np.array(data, dtype = np.uint8) + data = np.array(data, dtype = np.uint16) im = Image.frombytes( mode='P', size=data.shape[::-1], @@ -187,11 +227,27 @@ def display(fname, data): im.save(fname) return im -def fuse_lookup(d, ttyp, fuse): +def fuse_lookup(d, ttyp, fuse, device): + is5Series = False + if device.lower().startswith("gw5a"): is5Series = True + + w = d[ttyp]['width'] + h = d[ttyp]['height'] + if fuse >= 0: num = d['header']['fuse'][1][fuse][ttyp] row = num // 100 col = num % 100 + if is5Series: + row = num // 200 + col = num % 200 + + if row > h: + print("row too big", ttyp, row, h, col, w, num, h * w) + if col > w: + print("col too big", col, w) + + return row, col def tile_bitmap(d, bitmap, empty=False): @@ -238,7 +294,7 @@ def fuse_bitmap(d, bitmap): return res -def parse_tile(d, ttyp, tile): +def parse_tile(d, ttyp, tile, device): w = d[ttyp]['width'] h = d[ttyp]['height'] res = {} @@ -249,7 +305,7 @@ def parse_tile(d, ttyp, tile): items = {} for row in tablerows: pos = row[0] > 0 - coords = {(fuse_lookup(d, ttyp, f), pos) for f in row[start:] if f > 0} + coords = {(fuse_lookup(d, ttyp, f, device), pos) for f in row[start:] if f > 0} idx = tuple(abs(attr) for attr in row[:start]) items.setdefault(idx, {}).update(coords) @@ -263,7 +319,7 @@ def parse_tile(d, ttyp, tile): return res -def parse_tile_exact(d, ttyp, tile, fuse_loc=True): +def parse_tile_exact(d, ttyp, tile, device, fuse_loc=True): w = d[ttyp]['width'] h = d[ttyp]['height'] res = {} @@ -276,7 +332,7 @@ def parse_tile_exact(d, ttyp, tile, fuse_loc=True): for row in tablerows: if row[0] > 0: row_fuses = [fuse for fuse in row[start:] if fuse >= 0] - locs = [fuse_lookup(d,ttyp, fuse) for fuse in row_fuses] + locs = [fuse_lookup(d,ttyp, fuse, device) for fuse in row_fuses] test = [tile[loc[0]][loc[1]] == 1 for loc in locs] if all(test): full_row = row[:start] @@ -288,7 +344,7 @@ def parse_tile_exact(d, ttyp, tile, fuse_loc=True): exact_cover = exact_table_cover(active_rows, start, table) if fuse_loc: for cover_row in exact_cover: - cover_row[start:] = [fuse_lookup(d, ttyp, fuse) for fuse in cover_row[start:]] + cover_row[start:] = [fuse_lookup(d, ttyp, fuse, device) for fuse in cover_row[start:]] res.setdefault(table, {})[subtyp] = exact_cover return res @@ -324,7 +380,10 @@ def exact_table_cover(t_rows, start, table=None): else: return [] -def scan_fuses(d, ttyp, tile): +def scan_fuses(d, ttyp, tile, device): + is5Series = False + if device.lower().startswith("gw5a"): is5Series = True + w = d[ttyp]['width'] h = d[ttyp]['height'] fuses = [] @@ -335,6 +394,11 @@ def scan_fuses(d, ttyp, tile): num = fuse[ttyp] frow = num // 100 fcol = num % 100 + #if is5Series: + # frow = num // w + # fcol = num % w + # print("GO FLUFFY") + if frow == row and fcol == col and fnum > 100: fuses.append(fnum) return set(fuses) @@ -374,4 +438,3 @@ def reduce_rows(rows, fuses, start=16, tries=1000): display("fuse.png", bm) t = render_tile(d, 50, device) display("tile.png", t) - diff --git a/apycula/gowin_unpack.py b/apycula/gowin_unpack.py index aaae87ab..dd6766af 100644 --- a/apycula/gowin_unpack.py +++ b/apycula/gowin_unpack.py @@ -61,11 +61,11 @@ def _io_mode_sort_func(mode): return l # -def get_attr_name(attrname_table, code): +def get_attr_name(attrname_table, code, tableName): for name, cod in attrname_table.items(): if cod == code: return name - print(f'Unknown attr name for {code}/0x{code:x}.') + print(f'Unknown attr name for table: {tableName} code:{code}') return '' # fix names and types of the PLL attributes @@ -191,7 +191,7 @@ def get_attrval_name(val): # parse attributes and values use 'logicinfo' table # returns {attr: value} # attribute names are decoded with the attribute table, but the values are returned in raw form -def parse_attrvals(tile, logicinfo_table, fuse_table, attrname_table): +def parse_attrvals(tile, logicinfo_table, fuse_table, attrname_table, tableName): def is_neg_key(key): for k in key: if k < 0: @@ -218,6 +218,8 @@ def get_negative(av): set_mask.update(bits) set_bits = {(row, col) for row, col in set_mask if tile[row][col] == 1} neg_bits = {(row, col) for row, col in zero_mask if tile[row][col] == 1} + #set_bits = {} + #neg_bits = {} # find candidates from fuse table # the set bits are more unique @@ -234,7 +236,7 @@ def get_negative(av): attrvals.update(clean_av) # set attributes for idx in clean_av: attr, val = logicinfo_table[idx] - res[get_attr_name(attrname_table, attr)] = val + res[get_attr_name(attrname_table, attr, tableName)] = val # records with a negative keys and used fuses neg_attrvals = set() @@ -257,7 +259,7 @@ def get_negative(av): for idx in neg_attrvals: attr, val = logicinfo_table[idx] - res[get_attr_name(attrname_table, attr)] = val + res[get_attr_name(attrname_table, attr, tableName)] = val # records with a negative keys and unused fuses cnd = {av for av, bits in fuse_table.items() if is_neg_key(av) and not bits.issubset(neg_bits)} @@ -270,7 +272,7 @@ def get_negative(av): if keep: for idx in get_negative(av): attr, val = logicinfo_table[idx] - res[get_attr_name(attrname_table, attr)] = val + res[get_attr_name(attrname_table, attr, tableName)] = val return res # { (row, col, type) : idx} @@ -321,6 +323,7 @@ def get_dsp_main_cell(db, row, col, typ): # With normal gowin_unpack io standard is determined first and it is known. # (bels, pips, clock_pips) def parse_tile_(db, row, col, tile, default=True, noalias=False, noiostd = True): + #print("parse_tile_ r:", row, "c:", col) if not _bank_fuse_tables: # create bank fuse table for ttyp in db.longval.keys(): @@ -339,7 +342,7 @@ def parse_tile_(db, row, col, tile, default=True, noalias=False, noiostd = True) idx = _pll_cells.setdefault(get_pll_A(db, row, col, name[4]), len(_pll_cells)) modes = { f'DEVICE="{_device}"' } if 'PLL' in db.shortval[tiledata.ttyp].keys(): - attrvals = pll_attrs_refine(parse_attrvals(tile, db.logicinfo['PLL'], db.shortval[tiledata.ttyp]['PLL'], attrids.pll_attrids)) + attrvals = pll_attrs_refine(parse_attrvals(tile, db.logicinfo['PLL'], db.shortval[tiledata.ttyp]['PLL'], attrids.pll_attrids, "PLL")) for attrval in attrvals: modes.add(attrval) if modes: @@ -347,7 +350,7 @@ def parse_tile_(db, row, col, tile, default=True, noalias=False, noiostd = True) continue if name == "PLLVR": idx = _pll_cells.setdefault(get_pll_A(db, row, col, 'A'), len(_pll_cells)) - attrvals = pll_attrs_refine(parse_attrvals(tile, db.logicinfo['PLL'], db.shortval[tiledata.ttyp]['PLL'], attrids.pll_attrids)) + attrvals = pll_attrs_refine(parse_attrvals(tile, db.logicinfo['PLL'], db.shortval[tiledata.ttyp]['PLL'], attrids.pll_attrids, "PLL")) modes = { f'DEVICE="{_device}"' } for attrval in attrvals: modes.add(attrval) @@ -355,7 +358,7 @@ def parse_tile_(db, row, col, tile, default=True, noalias=False, noiostd = True) bels[f'{name}{idx}'] = modes continue if name.startswith("OSC"): - attrvals = osc_attrs_refine(parse_attrvals(tile, db.logicinfo['OSC'], db.shortval[tiledata.ttyp]['OSC'], attrids.osc_attrids)) + attrvals = osc_attrs_refine(parse_attrvals(tile, db.logicinfo['OSC'], db.shortval[tiledata.ttyp]['OSC'], attrids.osc_attrids, "OSC")) modes = set() for attrval in attrvals: modes.add(attrval) @@ -368,7 +371,7 @@ def parse_tile_(db, row, col, tile, default=True, noalias=False, noiostd = True) continue idx = _bsram_cells.setdefault(get_bsram_main_cell(db, row, col, name), len(_bsram_cells)) #print(row, col, name, idx, tiledata.ttyp) - attrvals = parse_attrvals(tile, db.logicinfo['BSRAM'], db.shortval[tiledata.ttyp]['BSRAM_SP'], attrids.bsram_attrids) + attrvals = parse_attrvals(tile, db.logicinfo['BSRAM'], db.shortval[tiledata.ttyp]['BSRAM_SP'], attrids.bsram_attrids, "BSRAM") if not attrvals: continue #print(row, col, name, idx, tiledata.ttyp, attrvals) @@ -384,7 +387,7 @@ def parse_tile_(db, row, col, tile, default=True, noalias=False, noiostd = True) row, col = get_dsp_main_cell(db, row, col, name) if f'DSP{idx}' in db.shortval[tiledata.ttyp]: - attrvals = parse_attrvals(tile, db.logicinfo['DSP'], db.shortval[tiledata.ttyp][f'DSP{idx}'], attrids.dsp_attrids) + attrvals = parse_attrvals(tile, db.logicinfo['DSP'], db.shortval[tiledata.ttyp][f'DSP{idx}'], attrids.dsp_attrids, "DSP") #print_sorted_dict(f'{row}, {col}, {name}, {idx}, {tiledata.ttyp} - ', attrvals) for attrval in attrvals: modes.add(attrval) @@ -393,7 +396,7 @@ def parse_tile_(db, row, col, tile, default=True, noalias=False, noiostd = True) continue if name.startswith("IOLOGIC"): idx = name[-1] - attrvals = parse_attrvals(tile, db.logicinfo['IOLOGIC'], db.shortval[tiledata.ttyp][f'IOLOGIC{idx}'], attrids.iologic_attrids) + attrvals = parse_attrvals(tile, db.logicinfo['IOLOGIC'], db.shortval[tiledata.ttyp][f'IOLOGIC{idx}'], attrids.iologic_attrids, "IOLOGIC") if not attrvals: continue if 'OUTMODE' in attrvals.keys(): @@ -407,8 +410,8 @@ def parse_tile_(db, row, col, tile, default=True, noalias=False, noiostd = True) # skip aux cells if attrvals['OUTMODE'] == attrids.iologic_attrvals['DDRENABLE']: continue - if attrids.iologic_num2val[attrvals['OUTMODE']] in _iologic_mode.keys(): - bels.setdefault(name, set()).add(f"MODE={_iologic_mode[attrids.iologic_num2val[attrvals['OUTMODE']]]}") + #if attrids.iologic_num2val[attrvals['OUTMODE']] in _iologic_mode.keys(): + # bels.setdefault(name, set()).add(f"MODE={_iologic_mode[attrids.iologic_num2val[attrvals['OUTMODE']]]}") elif 'INMODE' in attrvals.keys(): if attrvals['INMODE'] in {attrids.iologic_attrvals['MIDDRX1'], attrids.iologic_attrvals['IDDRX1']}: if 'LSRIMUX_0' in attrvals.keys(): @@ -430,7 +433,7 @@ def parse_tile_(db, row, col, tile, default=True, noalias=False, noiostd = True) bels.setdefault(name, set()).add(f"CLKODDRMUX_ECLK={attrids.iologic_num2val[attrvals['CLKODDRMUX_ECLK']]}") if name.startswith("DFF"): idx = int(name[3]) - attrvals = parse_attrvals(tile, db.logicinfo['SLICE'], db.shortval[tiledata.ttyp][f'CLS{idx // 2}'], attrids.cls_attrids) + attrvals = parse_attrvals(tile, db.logicinfo['SLICE'], db.shortval[tiledata.ttyp][f'CLS{idx // 2}'], attrids.cls_attrids, "CLS") #print(row, col, attrvals) # skip ALU and unsupported modes if attrvals.get('MODE') == attrids.cls_attrvals['SSRAM']: @@ -446,7 +449,7 @@ def parse_tile_(db, row, col, tile, default=True, noalias=False, noiostd = True) if f'IOB{idx}' in db.longval[tiledata.ttyp]: fuse_table = db.longval[tiledata.ttyp][f'IOB{idx}'] - attrvals = parse_attrvals(tile, db.logicinfo['IOB'], fuse_table, attrids.iob_attrids) + attrvals = parse_attrvals(tile, db.logicinfo['IOB'], fuse_table, attrids.iob_attrids, "IOB") #print(row, col, attrvals) try: # we can ask for invalid pin here because the IOBs share some stuff bank = chipdb.loc2bank(db, row, col) @@ -478,12 +481,12 @@ def parse_tile_(db, row, col, tile, default=True, noalias=False, noiostd = True) bels.setdefault(name, set()).add(mode) if name.startswith("BANK"): - attrvals = parse_attrvals(tile, db.logicinfo['IOB'], _bank_fuse_tables[tiledata.ttyp][name], attrids.iob_attrids) + attrvals = parse_attrvals(tile, db.logicinfo['IOB'], _bank_fuse_tables[tiledata.ttyp][name], attrids.iob_attrids, "IOB") for a, v in attrvals.items(): bels.setdefault(name, set()).add(f'{a}={attrids.iob_num2val[v]}') if name.startswith("ALU"): idx = int(name[3]) - attrvals = parse_attrvals(tile, db.logicinfo['SLICE'], db.shortval[tiledata.ttyp][f'CLS{idx // 2}'], attrids.cls_attrids) + attrvals = parse_attrvals(tile, db.logicinfo['SLICE'], db.shortval[tiledata.ttyp][f'CLS{idx // 2}'], attrids.cls_attrids, "CLS") # skip ALU and unsupported modes if attrvals.get('MODE') != attrids.cls_attrvals['ALU']: continue @@ -530,7 +533,7 @@ def parse_tile_(db, row, col, tile, default=True, noalias=False, noiostd = True) for row, col in pip_bits if tile[row][col] == 1} for src, bits in srcs.items(): - # optionally ignore the defautl set() state + # optionally ignore the default set() state if bits == used_bits and (default or bits): pips[dest] = src diff --git a/apycula/tiled_fuzzer.py b/apycula/tiled_fuzzer.py index 4d0646b5..e4339058 100644 --- a/apycula/tiled_fuzzer.py +++ b/apycula/tiled_fuzzer.py @@ -214,7 +214,7 @@ def fse_iob(fse, db, pin_locations, diff_cap_info, locations): bel.is_diff = is_diff bel.is_true_lvds = is_true_lvds bel.is_diff_p = is_positive - print(f"type:{ttyp} [{row}][{col}], IOB{bel_name[-1]}, diff:{is_diff}, true lvds:{is_true_lvds}, p:{is_positive}") + #print(f"type:{ttyp} [{row}][{col}], IOB{bel_name[-1]}, diff:{is_diff}, true lvds:{is_true_lvds}, p:{is_positive}") for ttyp, bels in iob_bels.items(): for row, col in locations[ttyp]: db.grid[row][col].bels.update(iob_bels[ttyp]) @@ -235,13 +235,12 @@ def fse_iob(fse, db, pin_locations, diff_cap_info, locations): chipdb.fse_wire_delays(db) db.packages, db.pinout, db.pin_bank = chipdb.json_pinout(device) - corners = [ - (0, 0, fse['header']['grid'][61][0][0]), - (0, db.cols-1, fse['header']['grid'][61][0][-1]), - (db.rows-1, db.cols-1, fse['header']['grid'][61][-1][-1]), - (db.rows-1, 0, fse['header']['grid'][61][-1][0]), - ] - print("bingo") + #corners = [ + # (0, 0, fse['header']['grid'][61][0][0]), + # (0, db.cols-1, fse['header']['grid'][61][0][-1]), + # (db.rows-1, db.cols-1, fse['header']['grid'][61][-1][-1]), + # (db.rows-1, 0, fse['header']['grid'][61][-1][0]), + #] locations = {} for row, row_dat in enumerate(fse['header']['grid'][61]): @@ -266,8 +265,7 @@ def fse_iob(fse, db, pin_locations, diff_cap_info, locations): db.cmd_hdr = pnr_empty.hdr db.cmd_ftr = pnr_empty.ftr db.template = pnr_empty.bitmap - print("bingo2") - + # IOB diff_cap_info = pindef.get_diff_cap_info(device, params['package'], True) fse_iob(fse, db, pin_locations, diff_cap_info, locations); @@ -278,7 +276,6 @@ def fse_iob(fse, db, pin_locations, diff_cap_info, locations): chipdb.dat_portmap(dat, db, device) chipdb.add_hclk_bels(dat, db, device) - print("bingo3") # XXX GW1NR-9 has interesting IOBA pins on the bottom side if device == 'GW1N-9' : loc = locations[52][0] @@ -289,11 +286,11 @@ def fse_iob(fse, db, pin_locations, diff_cap_info, locations): # GSR if device in {'GW2A-18', 'GW2A-18C', 'GW5A-25A'}: - db.grid[27][50].bels.setdefault('GSR', chipdb.Bel()).portmap['GSRI'] = 'C4'; - print("timing: ", db.timing) + db.grid[27][50].bels.setdefault('GSR', chipdb.Bel()).portmap['GSRI'] = 'C4' + #print("timing: ", db.timing) elif device in {'GW1N-1', 'GW1N-4', 'GW1NS-4', 'GW1N-9', 'GW1N-9C', 'GW1NS-2', 'GW1NZ-1'}: - db.grid[0][0].bels.setdefault('GSR', chipdb.Bel()).portmap['GSRI'] = 'C4'; + db.grid[0][0].bels.setdefault('GSR', chipdb.Bel()).portmap['GSRI'] = 'C4' else: raise Exception(f"No GSR for {device}") From aa250b8bf2a45297fb5784110b677a8a1de4b97e Mon Sep 17 00:00:00 2001 From: AwooOOoo Date: Sun, 13 Oct 2024 11:14:02 +0200 Subject: [PATCH 07/12] added corners back into the tiled fuzzer and cleaned up some debug info --- apycula/clock_fuzzer.py | 4 ---- apycula/tiled_fuzzer.py | 12 ++++++------ 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/apycula/clock_fuzzer.py b/apycula/clock_fuzzer.py index eb41d8d2..d56aa65d 100644 --- a/apycula/clock_fuzzer.py +++ b/apycula/clock_fuzzer.py @@ -384,7 +384,6 @@ def make_lw_aliases(fse, dat: dat19.Datfile, db, quads, clks): print(" srcs =", srcs) print(" dests =", dests) print(" clks =", clks) - print("fluffy1") pa = pin_aliases(quads, srcs) sa = spine_aliases(quads, dests, clks) @@ -395,17 +394,14 @@ def make_lw_aliases(fse, dat: dat19.Datfile, db, quads, clks): # print(sa) # print(ta) # print(ba) - print("fluffy2") db.aliases.update(pa) db.aliases.update(sa) db.aliases.update(ta) db.aliases.update(ba) - print("fluffy3") # long wires make_lw_aliases(fse, dat, db, quads, clks) - print("fluffy4") with open(f"{tiled_fuzzer.device}_stage2.pickle", 'wb') as f: pickle.dump(db, f) diff --git a/apycula/tiled_fuzzer.py b/apycula/tiled_fuzzer.py index e4339058..57dc4ee0 100644 --- a/apycula/tiled_fuzzer.py +++ b/apycula/tiled_fuzzer.py @@ -235,12 +235,12 @@ def fse_iob(fse, db, pin_locations, diff_cap_info, locations): chipdb.fse_wire_delays(db) db.packages, db.pinout, db.pin_bank = chipdb.json_pinout(device) - #corners = [ - # (0, 0, fse['header']['grid'][61][0][0]), - # (0, db.cols-1, fse['header']['grid'][61][0][-1]), - # (db.rows-1, db.cols-1, fse['header']['grid'][61][-1][-1]), - # (db.rows-1, 0, fse['header']['grid'][61][-1][0]), - #] + corners = [ + (0, 0, fse['header']['grid'][61][0][0]), + (0, db.cols-1, fse['header']['grid'][61][0][-1]), + (db.rows-1, db.cols-1, fse['header']['grid'][61][-1][-1]), + (db.rows-1, 0, fse['header']['grid'][61][-1][0]), + ] locations = {} for row, row_dat in enumerate(fse['header']['grid'][61]): From f6ad4014e23d2870be098c966b107512f48752d5 Mon Sep 17 00:00:00 2001 From: AwooOOoo Date: Sun, 13 Oct 2024 13:05:46 +0200 Subject: [PATCH 08/12] added missing wirenames and wire_delays (545-553 & 556-564) --- apycula/chipdb.py | 21 ++++++++++++++++++++- apycula/wirenames.py | 2 ++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/apycula/chipdb.py b/apycula/chipdb.py index 31055b73..3b121762 100644 --- a/apycula/chipdb.py +++ b/apycula/chipdb.py @@ -258,6 +258,8 @@ def fse_alonenode(fse, ttyp, device, table = 6): # make PLL bels def fse_pll(device, fse, ttyp): bels = {} + #print("requested fse_pll types:", ttyp) + if device in {'GW1N-1', 'GW1NZ-1'}: if ttyp == 88: bel = bels.setdefault('RPLLA', Bel()) @@ -284,6 +286,9 @@ def fse_pll(device, fse, ttyp): bel = bels.setdefault('RPLLA', Bel()) elif ttyp in {74, 75, 76, 77, 78, 79}: bel = bels.setdefault('RPLLB', Bel()) + elif device in {'GW5A-25A'}: + if ttyp in {74, 75, 76, 77, 78, 79}: + bel = bels.setdefault('RPLLB', Bel()) return bels # add the ALU mode @@ -1924,6 +1929,7 @@ def set_chip_flags(dev, device): dev.chip_flags.append("HAS_BANDGAP") def from_fse(device, fse, dat: Datfile): + print("here!!") dev = Device() fse_create_simplio_rows(dev, dat) ttypes = {t for row in fse['header']['grid'][61] for t in row} @@ -1935,6 +1941,7 @@ def from_fse(device, fse, dat: Datfile): for ttyp in ttypes: w = fse[ttyp]['width'] h = fse[ttyp]['height'] + print ("ttyp: ", ttyp, "w:", w, "h:", h) tile = Tile(w, h, ttyp) tile.pips = fse_pips(fse, ttyp, device, 2, wirenames) tile.clock_pips = fse_pips(fse, ttyp, device, 38, clknames) @@ -1960,6 +1967,14 @@ def from_fse(device, fse, dat: Datfile): # determine the type from fse['header']['grid'][61][row][col] elif ttyp in [42, 45, 74, 75, 76, 77, 78, 79, 86, 87, 88, 89]: tile.bels = fse_pll(device, fse, ttyp) + #else: + # print("unknown ttyp: ", ttyp) + # HERE + #for row, rd in enumerate(dat.grid.rows): + # for col, type_char in enumerate(rd): + # if type_char in ["P", "p"]: + # print (type_char, " places: ", col, row) + tile.bels.update(fse_iologic(device, fse, ttyp)) tiles[ttyp] = tile @@ -3078,7 +3093,7 @@ def dat_portmap(dat, dev, device): nam = f'DIB{i - 114}' create_port_wire(dev, row, col, 0, off, bel, "BSRAM", nam, wire, wire_type) - elif name == 'RPLLA': + elif name in ['RPLLA', 'RPPLB']: # The PllInDlt table seems to indicate in which cell the # inputs are actually located. offx = 1 @@ -3370,6 +3385,10 @@ def fse_wire_delays(db): db.wire_delay[wirenames[i]] = "CIN" for i in range(309, 314): # COUT0-COUT5 db.wire_delay[wirenames[i]] = "COUT" + for i in range(545, 553): # 5A needs these + db.wire_delay[wirenames[i]] = "X8" + for i in range(556, 564): # 5A needs these + db.wire_delay[wirenames[i]] = "X8" for i in range(1001, 1049): # LWSPINE db.wire_delay[wirenames[i]] = "X8" # possibly LW wires for large chips, for now assign dummy value diff --git a/apycula/wirenames.py b/apycula/wirenames.py index 5e1fc8be..e5f506ca 100644 --- a/apycula/wirenames.py +++ b/apycula/wirenames.py @@ -29,6 +29,8 @@ wirenames.update({n: f"LWSPINEBR{n - 1025}" for n in range(1025, 1033)}) wirenames.update({n: f"LWSPINEB1L{n - 1033}" for n in range(1033, 1041)}) wirenames.update({n: f"LWSPINEB1R{n - 1041}" for n in range(1041, 1049)}) +wirenames.update({n: f"5A25" for n in range(545, 553)}) # GW5A-25A need these +wirenames.update({n: f"5A25" for n in range(556, 564)}) # GW5A-25A need these wirenumbers = {v: k for k, v in wirenames.items()} From 84ee97826d7658f3c152f38fd10ee380f57a0955 Mon Sep 17 00:00:00 2001 From: AwooOOoo Date: Sat, 19 Oct 2024 14:08:43 +0200 Subject: [PATCH 09/12] -added support for the 5A part of the .dat file. Names still need to be normalized and double check all the structures read ok. Currently need to find "PaddIn" equivalent for 5A as it is all -1 in the space read by the first part of the file. --- apycula/chipdb.py | 2 + apycula/dat19.py | 221 +++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 220 insertions(+), 3 deletions(-) diff --git a/apycula/chipdb.py b/apycula/chipdb.py index 3b121762..0dc0f673 100644 --- a/apycula/chipdb.py +++ b/apycula/chipdb.py @@ -2288,6 +2288,7 @@ def dat_portmap(dat, dev, device): elif name.startswith('PADD9'): mac = int(name[-2]) idx = int(name[-1]) + print("DSP_I: row:", row, "col:", col, "name:", name, "mac:", mac, "idx:", idx) column = mac * 2 + (idx // 2) for i in range(12): @@ -2346,6 +2347,7 @@ def dat_portmap(dat, dev, device): # input wire sequence: A0-8, B0-8, # unknown -1 # ASEL + #print("DSP_I: row:", row, "col:", col, "name:", name, "wire_idx:", wire_idx, "wire:", wire) odd_idx = 9 * (idx & 1) if i in range(odd_idx , 9 + odd_idx): nam = f'A{i - odd_idx}' diff --git a/apycula/dat19.py b/apycula/dat19.py index 21154616..ea89d576 100644 --- a/apycula/dat19.py +++ b/apycula/dat19.py @@ -26,15 +26,31 @@ class Grid: class Datfile: def __init__(self, path: Path): self.data = path.read_bytes() - self._cur = 0x026060 + self._cur = 0x07b4a4 + partType = self.read_u16() + self.grid = self.read_grid() self.primitives = self.read_primitives() + self.compat_dict = {} self.portmap = self.read_portmap() self.compat_dict = self.read_portmap() + + if partType == 0: # 1/2 Series + self.compat_dict.update(self.read_something()) + elif partType == 1: + print("PartType {partType} is not supported") + + elif partType == 2: # 5 Series + self.gw5aStuff = self.read_5Astuff() + self.compat_dict.update(self.read_something5A()) + + elif partType == 4: + print("PartType {partType} is not supported") + self.compat_dict.update(self.read_io()) - self.compat_dict.update(self.read_something()) self.cmux_ins: dict[int, list[int]] = self.read_io()['CmuxIns'] + def read_u8(self): v = self.data[self._cur] self._cur += 1 @@ -79,6 +95,15 @@ def read_arr16(self, num: int) -> list[int]: arr = [self.read_i16() for _ in range(num)] return arr + def read_arr16_at(self, num:int, base:int, offset:int): + ret = [] + + for n in range(num): + self._cur = (n + base) * 2 + offset + ret.append(self.read_i16()) + return ret + + def read_arr32(self, num: int) -> list[int]: arr = [self.read_i32() for _ in range(num)] return arr @@ -137,6 +162,7 @@ def read_grid(self) -> Grid: grid_w = self.read_u16() # chipCols_ cc_y = self.read_u16() # hiq_ cc_x = self.read_u16() # viq_ + rows = [] grid_mapping = { (0, 0): " ", # empty @@ -167,6 +193,8 @@ def read_grid(self) -> Grid: b = self.read_u8_at(125744 + idx) c = grid_mapping[a, b] + if (a,b) not in grid_mapping.keys(): + print("no grid_mapping key for coords: ", a, b) #if x == cc_x and y == cc_y: # assert c == "b" @@ -201,6 +229,174 @@ def read_clkins(self, num) -> list[tuple[int, int]]: ret.append((a, b)) return ret + def read_scaledGrid16(rows, cols, rowScaling, colScaling, baseOffset): + self._cur = baseAddress + rows = [] + + for row in range(rows): + row = [] + for col in range(cols): + self._cur = (row * rowScaling) + (col * colScaling * 2) + baseOffset + row.append(self.read_u16()) + rows.append(row) + return rows + + def read_5Astuff(self) -> dict: + RSTable5ATOffset = 0x7b4a8 + ret = { } + + self._cur = RSTable5ATOffset + 0x240b0 + ret["TopHiq"]: self.read_u16() + ret["TopViq"]: self.read_u16() + ret["BotHiq"]: self.read_u16() + ret["BotViq"]: self.read_u16() + + ret["PllIn"]: self.read_arr16_at(0xcb, RSTable5ATOffset + 0xaf0, 0) + ret["PllOut"]: self.read_arr16_at(0xcb, RSTable5ATOffset + 0xbe8, 0) + ret["PllInDlt"]: self.read_arr16_at(0xbc8, RSTable5ATOffset + 0xaf0, 0) + ret["PllOutDlt"]: self.read_arr16_at(0xcb, RSTable5ATOffset + 0xcc0, 0) + + ret["5ATIOLogicAIn"]: self.read_arr16_at(0x3e, RSTable5ATOffset + 0x1880, 0) + ret["5ATIOLogicBIn"]: self.read_arr16_at(0x3e, RSTable5ATOffset + 0x18b8, 0xc) + ret["5ATIOLogicAOut"]: self.read_arr16_at(0x27, RSTable5ATOffset + 0x18f8, 8) + ret["5ATIOLogicBOut"]: self.read_arr16_at(0x27, RSTable5ATOffset + 0x1920, 6) + ret["5ATIODelayAOut"]: self.read_arr16_at(0x27, RSTable5ATOffset + 0x19c0, 0xc) + ret["5ATIODelayBOut"]: self.read_arr16_at(0x27, RSTable5ATOffset + 0x19e8, 10) + ret["5ATIODelayAIn"]: self.read_arr16_at(0x3e, RSTable5ATOffset + 0x1948, 0x4) + ret["5ATIODelayBIn"]: self.read_arr16_at(0x3e, RSTable5ATOffset + 0x1988, 0) + + ret["MipiIns1"]: read_scaledGrid16(0xc3, 3, 3, RSTable5ATOffset + 0x22d0, 0xe) + ret["MipiIns2"]: read_scaledGrid16(0xc3, 3, 3, RSTable5ATOffset + 0x2680, 0xe) + ret["MipiOuts1"]: read_scaledGrid16(0x76, 3, 3, RSTable5ATOffset + 0x2520, 0) + ret["MipiOuts2"]: read_scaledGrid16(0x76, 3, 3, RSTable5ATOffset + 0x28c8, 6) + + ret["MipiDPhyIns"]: read_scaledGrid16(0xbb, 3, 3, RSTable5ATOffset + 0x91c0, 10) + ret["MipiDPhyOuts"]: read_scaledGrid16(0x6a, 3, 3, RSTable5ATOffset + 0x93f0, 0xc) + + ret["Gtrl12QuadDBIns1"]: read_scaledGrid16(0x351, 3, 3, RSTable5ATOffset + 0x2a28, 10) + ret["Gtrl12QuadDBIns2"]: read_scaledGrid16(0x351, 3, 3, RSTable5ATOffset + 0x3420, 0) + ret["Gtrl12QuadDBOuts1"]: read_scaledGrid16(0x29c, 3, 3, RSTable5ATOffset + 0x6180, 0xc) + ret["Gtrl12QuadDBOuts2"]: read_scaledGrid16(0x29c, 3, 3, RSTable5ATOffset + 0x6958, 4) + + ret["Gtrl12PmacDBIns"]: read_scaledGrid16(0xb68, 3, 3, RSTable5ATOffset + 0x3e10, 6) + ret["Gtrl12PmacDBOuts"]: read_scaledGrid16(0xb68, 3, 3, RSTable5ATOffset + 0x7128, 0xc) + + ret["Gtrl12UparDBIns"]: read_scaledGrid16(0x69, 3, 3, RSTable5ATOffset + 0x6048, 6) + ret["Gtrl12UparDBOuts"]: read_scaledGrid16(0x69, 3, 3, RSTable5ATOffset + 0x8620, 10) + + ret["Ae350SocIns"]: read_scaledGrid16(0x1b1, 3, 3, RSTable5ATOffset + 0x86a0, 6) + ret["Ae350SocOuts"]: read_scaledGrid16(0x206, 3, 3, RSTable5ATOffset + 0x8bb0, 10) + + + ret["CMuxTopInNodes"]: read_scaledGrid16(0xbd, 0x54, 0x54, RSTable5ATOffset + 0x13fc4, 0) + ret["CMuxBotInNodes"]: read_scaledGrid16(0xbd, 0x54, 0x54, RSTable5ATOffset + 0x1bbcc, 0) + ret["CMuxTopIns"]: read_scaledGrid16(0xbd, 0x3, 0x3, RSTable5ATOffset + 0x11be8, 4) + ret["CMuxBotIns"]: read_scaledGrid16(0xbd, 0x3, 0x3, RSTable5ATOffset + 0x11e20, 2) + + ret["MipiIO1"]: read_scaledGrid16(10, 0xf, 0xf, RSTable5ATOffset + 0x240e0, 0) + ret["MipiIO2"]: read_scaledGrid16(10, 0xf, 0xf, RSTable5ATOffset + 0x24176, 0) + for n in range(5): + ret["MipiIOName1_{n}"]: read_scaledGrid16(10, 0xf, 0x4b, 5, RSTable5ATOffset + 0x2420c + n) + ret["MipiIOName2_{n}"]: read_scaledGrid16(10, 0xf, 0x4b, 5, RSTable5ATOffset + 0x244fa + n) + ret["MipiBank1"]: self.read_arr16_at(10, RSTable5ATOffset + 0x240e0, 0) + ret["MipiBank2"]: self.read_arr16_at(10, RSTable5ATOffset + 0x24176, 0) + + ret["QuadIO1"]: read_scaledGrid16(15, 0xf, 0xf, RSTable5ATOffset + 0x2483c, 0) + ret["QuafIO2"]: read_scaledGrid16(15, 0xf, 0xf, RSTable5ATOffset + 0x24977, 0) + for n in range(5): + ret["QuadIOName1_{n}"]: read_scaledGrid16(15, 0xf, 0x4b, 5, RSTable5ATOffset + 0x2483c + n) + ret["QuafIOName2_{n}"]: read_scaledGrid16(15, 0xf, 0xf, 5, RSTable5ATOffset + 0x24977 + n) + ret["QuadBank1"]: self.read_arr16_at(15, RSTable5ATOffset + 0x123f0, 8) + ret["QuadBank2"]: self.read_arr16_at(15, RSTable5ATOffset + 0x12408, 2) + + ret["AdcIO"]: read_scaledGrid16(4, 0xf, 0xf, 1, RSTable5ATOffset + 0x25708) + for n in range(5): + ret["QuaAdcIOName_{n}"]: read_scaledGrid16(4, 0xf, 0x4b, 5, RSTable5ATOffset + 0x25744 + n) + ret["AdcBank"]: self.read_arr16_at(4, RSTable5ATOffset + 0x12b80, 0) + + ret["Multalu27x18In"]: self.read_arr16_at(0xca, RSTable5ATOffset + 0x9778, 8) + ret["Multalu27x18InDlt"]: self.read_arr16_at(0xca, RSTable5ATOffset + 0x99c0, 2) + ret["Multalu27x18Out"]: self.read_arr16_at(0x7b, RSTable5ATOffset + 0x9840, 0xc) + ret["Multalu27x18OutDlt"]: self.read_arr16_at(0x7b, RSTable5ATOffset + 0x9988, 6) + ret["MultCtrlIn"]: self.read_arr16_at(0x6, RSTable5ATOffset + 0x9a00, 0xc) + ret["MultCtrlOut"]: self.read_arr16_at(0x6, RSTable5ATOffset + 0x9a08, 8) + + ret["DqsRLoc"]: self.read_arr16_at(0x2, RSTable5ATOffset + 0x12c38, 0) + ret["DqsCLoc"]: self.read_arr16_at(0x2, RSTable5ATOffset + 0x12c38, 4) + + ret["MDdrDllIns1"]: read_scaledGrid16(4, 3, 3, RSTable5ATOffset + 0x12c38, 8) + ret["MDdrDllIns2"]: read_scaledGrid16(4, 3, 3, RSTable5ATOffset + 0x12cb0, 2) + ret["MDdrDllIns3"]: read_scaledGrid16(4, 3, 3, RSTable5ATOffset + 0x12d20, 0xc) + ret["MDdrDllIns4"]: read_scaledGrid16(4, 3, 3, RSTable5ATOffset + 0x12d98, 6) + ret["MDdrDllIns5"]: read_scaledGrid16(4, 3, 3, RSTable5ATOffset + 0x12e10, 0) + ret["MDdrDllIns6"]: read_scaledGrid16(4, 3, 3, RSTable5ATOffset + 0x12e30, 0xe) + ret["MDdrDllIns7"]: read_scaledGrid16(4, 3, 3, RSTable5ATOffset + 0x12e58, 0xc) + + ret["S0DdrDllIns1"]: read_scaledGrid16(4, 3, 3, RSTable5ATOffset + 0x12c60, 6) + ret["S0DdrDllIns2"]: read_scaledGrid16(4, 3, 3, RSTable5ATOffset + 0x12cd8, 0) + ret["S0DdrDllIns3"]: read_scaledGrid16(4, 3, 3, RSTable5ATOffset + 0x12d48, 10) + ret["S0DdrDllIns4"]: read_scaledGrid16(4, 3, 3, RSTable5ATOffset + 0x12dc0, 4) + + ret["S1DdrDllIns1"]: read_scaledGrid16(4, 3, 3, RSTable5ATOffset + 0x12c88, 4) + ret["S1DdrDllIns2"]: read_scaledGrid16(4, 3, 3, RSTable5ATOffset + 0x12cf8, 0xe) + ret["S1DdrDllIns3"]: read_scaledGrid16(4, 3, 3, RSTable5ATOffset + 0x12d70, 8) + ret["S1DdrDllIns4"]: read_scaledGrid16(4, 3, 3, RSTable5ATOffset + 0x12de8, 2) + + ret["MDdrDllOuts1"]: read_scaledGrid16(9, 3, 3, RSTable5ATOffset + 0x12c48, 0) + ret["MDdrDllOuts2"]: read_scaledGrid16(9, 3, 3, RSTable5ATOffset + 0x12cb8, 10) + ret["MDdrDllOuts3"]: read_scaledGrid16(9, 3, 3, RSTable5ATOffset + 0x12d30, 4) + ret["MDdrDllOuts4"]: read_scaledGrid16(9, 3, 3, RSTable5ATOffset + 0x12da0, 0xe) + ret["MDdrDllOuts5"]: read_scaledGrid16(9, 3, 3, RSTable5ATOffset + 0x12e18, 8) + ret["MDdrDllOuts6"]: read_scaledGrid16(9, 3, 3, RSTable5ATOffset + 0x12e40, 6) + ret["MDdrDllOuts7"]: read_scaledGrid16(9, 3, 3, RSTable5ATOffset + 0x12e68, 4) + + ret["S0DdrDllOuts1"]: read_scaledGrid16(9, 3, 3, RSTable5ATOffset + 0x12c68, 0xe) + ret["S0DdrDllOuts2"]: read_scaledGrid16(9, 3, 3, RSTable5ATOffset + 0x12ce0, 8) + ret["S0DdrDllOuts3"]: read_scaledGrid16(9, 3, 3, RSTable5ATOffset + 0x12d58, 2) + ret["S0DdrDllOuts4"]: read_scaledGrid16(9, 3, 3, RSTable5ATOffset + 0x12dc8, 0xc) + + ret["S1DdrDllOuts1"]: read_scaledGrid16(9, 3, 3, RSTable5ATOffset + 0x12c90, 0xc) + ret["S1DdrDllOuts2"]: read_scaledGrid16(9, 3, 3, RSTable5ATOffset + 0x12d08, 6) + ret["S1DdrDllOuts3"]: read_scaledGrid16(9, 3, 3, RSTable5ATOffset + 0x12d80, 0) + ret["S1DdrDllOuts4"]: read_scaledGrid16(9, 3, 3, RSTable5ATOffset + 0x12df0, 10) + + ret["CmseraIns"]: read_scaledGrid16(0x20, 3, 3, RSTable5ATOffset + 0x12e80, 10) + ret["CmseraOuts"]: read_scaledGrid16(0x60, 3, 3, RSTable5ATOffset + 0x12ee0, 10) + + ret["AdcLRCIns"]: read_scaledGrid16(0x28, 3, 3, RSTable5ATOffset + 0x13000, 10) + ret["AdcLRCOuts"]: read_scaledGrid16(0x12, 3, 3, RSTable5ATOffset + 0x13078, 10) + ret["AdcLRCCfgvsenctl1"]: read_scaledGrid16(3, 3, 3, RSTable5ATOffset + 0x78000, 6) + ret["AdcLRCCfgvsenctl2"]: read_scaledGrid16(0x24, 3, 3, RSTable5ATOffset + 0x130b8, 8) + ret["AdcULCOuts"]: read_scaledGrid16(0x12, 3, 3, RSTable5ATOffset + 0x13128, 0) + ret["AdcULCCfgvsenctl"]: read_scaledGrid16(3, 3, 3, RSTable5ATOffset + 0x13158, 0xc) + ret["Adc25kIns"]: read_scaledGrid16(0x17, 3, 3, RSTable5ATOffset + 0x13160, 0xe) + ret["Adc25kOuts"]: read_scaledGrid16(0x1b, 3, 3, RSTable5ATOffset + 0x131a8, 8) + + ret["CibFabricNode"]: read_scaledGrid16(6, 3, 3, RSTable5ATOffset + 0x131f8, 10) + ret["SharedIOLogicIOBloc"]: read_scaledGrid16(0x9c, 2, 2, RSTable5ATOffset + 0x13208, 0xe) + + ret["TopAMBGA121N"]: self.read_arr16_at(200, RSTable5ATOffset + 0x2668e, 0) + ret["TopBMBGA121N"]: self.read_arr16_at(200, RSTable5ATOffset + 0x2694a, 0) + ret["BottomAMBGA121N"]: self.read_arr16_at(200, RSTable5ATOffset + 0x26756, 0) + ret["BottomBMBGA121N"]: self.read_arr16_at(200, RSTable5ATOffset + 0x26a12, 0) + ret["TopAMBGA121NName"]: read_scaledGrid16(200, 9, 9, RSTable5ATOffset + 0x26c06, 0) + ret["BottomAMBGA121NName"]: read_scaledGrid16(200, 9, 9, RSTable5ATOffset + 0x2730e, 0) + ret["TopBMBGA121NName"]: read_scaledGrid16(200, 9, 9, RSTable5ATOffset + 0x284a2, 0) + ret["BottomBMBGA121NName"]: read_scaledGrid16(200, 9, 9, RSTable5ATOffset + 0x28baa, 0) + + ret["LeftAMBGA121N"]: self.read_arr16_at(0x96, RSTable5ATOffset + 0x2681e, 0) + ret["LeftBMBGA121N"]: self.read_arr16_at(0x96, RSTable5ATOffset + 0x26ada, 0) + ret["RightAMBGA121N"]: self.read_arr16_at(0x96, RSTable5ATOffset + 0x268b4, 0) + ret["RightBMBGA121N"]: self.read_arr16_at(0x96, RSTable5ATOffset + 0x26b70, 0) + ret["LeftAMBGA121NName"]: read_scaledGrid16(0x96, 9, 9, RSTable5ATOffset + 0x27a16, 0) + ret["RightAMBGA121NName"]: read_scaledGrid16(0x96, 9, 9, RSTable5ATOffset + 0x27f5c, 0) + ret["LeftBMBGA121NName"]: read_scaledGrid16(0x96, 9, 9, RSTable5ATOffset + 0x292b2, 0) + ret["RightBMBGA121NName"]: read_scaledGrid16(0x96, 9, 9, RSTable5ATOffset + 0x297f8, 0) + + ret["SpineColumn"]: self.read_arr16_at(8, RSTable5ATOffset + 0x14e98, 0xe) + + return ret + def read_portmap(self) -> dict: self._cur = 0x55D2C # These are ordered by position in the file @@ -277,7 +473,7 @@ def read_portmap(self) -> dict: return ret def read_io(self): - self._cur = 363662 + self._cur = 363662 # 0x58c8e ret = {} ret["CiuConnection"] = {} for i in range(320): @@ -329,6 +525,25 @@ def read_io(self): assert self._cur == 0x7BE5A, hex(self._cur) return ret + def read_something5A(self): + ret = { + "Dqs": {}, + } + ret["Dqs"]["TA"]: self.read_arr16_at(200, RSTable5ATOffset + 0x9a10, 4) + ret["Dqs"]["TB"]: self.read_arr16_at(200, RSTable5ATOffset + 0x9cc8, 0xc) + ret["Dqs"]["BA"]: self.read_arr16_at(200, RSTable5ATOffset + 0x9ad8, 4) + ret["Dqs"]["BB"]: self.read_arr16_at(200, RSTable5ATOffset + 0x9d90, 0xc) + ret["Dqs"]["LA"]: self.read_arr16_at(0x96, RSTable5ATOffset + 0x9ba0, 4) + ret["Dqs"]["LB"]: self.read_arr16_at(0x96, RSTable5ATOffset + 0x9e58, 0xc) + ret["Dqs"]["RA"]: self.read_arr16_at(0x96, RSTable5ATOffset + 0x9c38, 0) + ret["Dqs"]["RA"]: self.read_arr16_at(0x96, RSTable5ATOffset + 0x9ef0, 8) + + ret["Dqs"]["LeftIO"]: self.read_arr16_at(0x16, RSTable5ATOffset + 0x9f88, 4) + ret["Dqs"]["RightIO"]: self.read_arr16_at(0x16, RSTable5ATOffset + 0x9fa0, 0) + ret["Dqs"]["TopIO"]: self.read_arr16_at(0x16, RSTable5ATOffset + 0x9fb0, 0xc) + ret["Dqs"]["BottomIO"]: self.read_arr16_at(0x16, RSTable5ATOffset + 0x9fc8, 8) + return ret + def read_something(self): self._cur = 0x026068 ret = { From 86005adb4a006ba20fcbe4804361b266c2f70658 Mon Sep 17 00:00:00 2001 From: AwooOOoo Date: Sun, 20 Oct 2024 16:12:18 +0200 Subject: [PATCH 10/12] cleaned up assignment errors, added missing mult12x12 data and added the last bit of data remaining to identify --- apycula/dat19.py | 282 +++++++++++++++++++++++++---------------------- 1 file changed, 150 insertions(+), 132 deletions(-) diff --git a/apycula/dat19.py b/apycula/dat19.py index ea89d576..4f303809 100644 --- a/apycula/dat19.py +++ b/apycula/dat19.py @@ -162,7 +162,7 @@ def read_grid(self) -> Grid: grid_w = self.read_u16() # chipCols_ cc_y = self.read_u16() # hiq_ cc_x = self.read_u16() # viq_ - + # 26068 rows = [] grid_mapping = { (0, 0): " ", # empty @@ -245,155 +245,172 @@ def read_5Astuff(self) -> dict: RSTable5ATOffset = 0x7b4a8 ret = { } + #ret["UNKNOWN"] = 0x1d + #ret["UNKNOWN"] = 0x1d + #ret["UNKNOWN"] = 0x16 + #ret["UNKNOWN"] = 0x16 + #ret["UNKNOWN"] = 0xe + self._cur = RSTable5ATOffset + 0x240b0 - ret["TopHiq"]: self.read_u16() - ret["TopViq"]: self.read_u16() - ret["BotHiq"]: self.read_u16() - ret["BotViq"]: self.read_u16() - - ret["PllIn"]: self.read_arr16_at(0xcb, RSTable5ATOffset + 0xaf0, 0) - ret["PllOut"]: self.read_arr16_at(0xcb, RSTable5ATOffset + 0xbe8, 0) - ret["PllInDlt"]: self.read_arr16_at(0xbc8, RSTable5ATOffset + 0xaf0, 0) - ret["PllOutDlt"]: self.read_arr16_at(0xcb, RSTable5ATOffset + 0xcc0, 0) + ret["TopHiq"] = self.read_u16() + ret["TopViq"] = self.read_u16() + ret["BotHiq"] = self.read_u16() + ret["BotViq"] = self.read_u16() + + ret["PllIn"] = self.read_arr16_at(0xcb, RSTable5ATOffset + 0xaf0, 0) + ret["PllOut"] = self.read_arr16_at(0xcb, RSTable5ATOffset + 0xbe8, 0) + ret["PllInDlt"] = self.read_arr16_at(0xbc8, RSTable5ATOffset + 0xaf0, 0) + ret["PllOutDlt"] = self.read_arr16_at(0xcb, RSTable5ATOffset + 0xcc0, 0) - ret["5ATIOLogicAIn"]: self.read_arr16_at(0x3e, RSTable5ATOffset + 0x1880, 0) - ret["5ATIOLogicBIn"]: self.read_arr16_at(0x3e, RSTable5ATOffset + 0x18b8, 0xc) - ret["5ATIOLogicAOut"]: self.read_arr16_at(0x27, RSTable5ATOffset + 0x18f8, 8) - ret["5ATIOLogicBOut"]: self.read_arr16_at(0x27, RSTable5ATOffset + 0x1920, 6) - ret["5ATIODelayAOut"]: self.read_arr16_at(0x27, RSTable5ATOffset + 0x19c0, 0xc) - ret["5ATIODelayBOut"]: self.read_arr16_at(0x27, RSTable5ATOffset + 0x19e8, 10) - ret["5ATIODelayAIn"]: self.read_arr16_at(0x3e, RSTable5ATOffset + 0x1948, 0x4) - ret["5ATIODelayBIn"]: self.read_arr16_at(0x3e, RSTable5ATOffset + 0x1988, 0) - - ret["MipiIns1"]: read_scaledGrid16(0xc3, 3, 3, RSTable5ATOffset + 0x22d0, 0xe) - ret["MipiIns2"]: read_scaledGrid16(0xc3, 3, 3, RSTable5ATOffset + 0x2680, 0xe) - ret["MipiOuts1"]: read_scaledGrid16(0x76, 3, 3, RSTable5ATOffset + 0x2520, 0) - ret["MipiOuts2"]: read_scaledGrid16(0x76, 3, 3, RSTable5ATOffset + 0x28c8, 6) + ret["5ATIOLogicAIn"] = self.read_arr16_at(0x3e, RSTable5ATOffset + 0x1880, 0) + ret["5ATIOLogicBIn"] = self.read_arr16_at(0x3e, RSTable5ATOffset + 0x18b8, 0xc) + ret["5ATIOLogicAOut"] = self.read_arr16_at(0x27, RSTable5ATOffset + 0x18f8, 8) + ret["5ATIOLogicBOut"] = self.read_arr16_at(0x27, RSTable5ATOffset + 0x1920, 6) + ret["5ATIODelayAOut"] = self.read_arr16_at(0x27, RSTable5ATOffset + 0x19c0, 0xc) + ret["5ATIODelayBOut"] = self.read_arr16_at(0x27, RSTable5ATOffset + 0x19e8, 10) + ret["5ATIODelayAIn"] = self.read_arr16_at(0x3e, RSTable5ATOffset + 0x1948, 0x4) + ret["5ATIODelayBIn"] = self.read_arr16_at(0x3e, RSTable5ATOffset + 0x1988, 0) + + #ret["UNKNOWN"] = self.read_scaledGrid16(0x20, 0x1d, 0x1d, RSTable5ATOffset + 0x3428, 0) + #ret["UNKNOWN"] = self.read_scaledGrid16(0xc, 0x16, 0x16, RSTable5ATOffset + 0x3b68, 0) + #ret["UNKNOWN"] = self.read_scaledGrid16(0xc, 0x16, 0x16, RSTable5ATOffset + 0x1e98, 8) + #ret["UNKNOWN"] = self.read_scaledGrid16(0x20, 0x16, 0x16, RSTable5ATOffset + 0x1fa0, 8) + #ret["UNKNOWN"] = self.read_scaledGrid16(0x8, 0xe, 0xe, RSTable5ATOffset + 0x2260, 8) + + ret["MipiIns1"] = self.read_scaledGrid16(0xc3, 3, 3, RSTable5ATOffset + 0x22d0, 0xe) + ret["MipiIns2"] = self.read_scaledGrid16(0xc3, 3, 3, RSTable5ATOffset + 0x2680, 0xe) + ret["MipiOuts1"] = self.read_scaledGrid16(0x76, 3, 3, RSTable5ATOffset + 0x2520, 0) + ret["MipiOuts2"] = self.read_scaledGrid16(0x76, 3, 3, RSTable5ATOffset + 0x28c8, 6) - ret["MipiDPhyIns"]: read_scaledGrid16(0xbb, 3, 3, RSTable5ATOffset + 0x91c0, 10) - ret["MipiDPhyOuts"]: read_scaledGrid16(0x6a, 3, 3, RSTable5ATOffset + 0x93f0, 0xc) + ret["MipiDPhyIns"] = self.read_scaledGrid16(0xbb, 3, 3, RSTable5ATOffset + 0x91c0, 10) + ret["MipiDPhyOuts"] = self.read_scaledGrid16(0x6a, 3, 3, RSTable5ATOffset + 0x93f0, 0xc) - ret["Gtrl12QuadDBIns1"]: read_scaledGrid16(0x351, 3, 3, RSTable5ATOffset + 0x2a28, 10) - ret["Gtrl12QuadDBIns2"]: read_scaledGrid16(0x351, 3, 3, RSTable5ATOffset + 0x3420, 0) - ret["Gtrl12QuadDBOuts1"]: read_scaledGrid16(0x29c, 3, 3, RSTable5ATOffset + 0x6180, 0xc) - ret["Gtrl12QuadDBOuts2"]: read_scaledGrid16(0x29c, 3, 3, RSTable5ATOffset + 0x6958, 4) + ret["Gtrl12QuadDBIns1"] = self.read_scaledGrid16(0x351, 3, 3, RSTable5ATOffset + 0x2a28, 10) + ret["Gtrl12QuadDBIns2"] = self.read_scaledGrid16(0x351, 3, 3, RSTable5ATOffset + 0x3420, 0) + ret["Gtrl12QuadDBOuts1"] = self.read_scaledGrid16(0x29c, 3, 3, RSTable5ATOffset + 0x6180, 0xc) + ret["Gtrl12QuadDBOuts2"] = self.read_scaledGrid16(0x29c, 3, 3, RSTable5ATOffset + 0x6958, 4) - ret["Gtrl12PmacDBIns"]: read_scaledGrid16(0xb68, 3, 3, RSTable5ATOffset + 0x3e10, 6) - ret["Gtrl12PmacDBOuts"]: read_scaledGrid16(0xb68, 3, 3, RSTable5ATOffset + 0x7128, 0xc) + ret["Gtrl12PmacDBIns"] = self.read_scaledGrid16(0xb68, 3, 3, RSTable5ATOffset + 0x3e10, 6) + ret["Gtrl12PmacDBOuts"] = self.read_scaledGrid16(0xb68, 3, 3, RSTable5ATOffset + 0x7128, 0xc) - ret["Gtrl12UparDBIns"]: read_scaledGrid16(0x69, 3, 3, RSTable5ATOffset + 0x6048, 6) - ret["Gtrl12UparDBOuts"]: read_scaledGrid16(0x69, 3, 3, RSTable5ATOffset + 0x8620, 10) + ret["Gtrl12UparDBIns"] = self.read_scaledGrid16(0x69, 3, 3, RSTable5ATOffset + 0x6048, 6) + ret["Gtrl12UparDBOuts"] = self.read_scaledGrid16(0x69, 3, 3, RSTable5ATOffset + 0x8620, 10) - ret["Ae350SocIns"]: read_scaledGrid16(0x1b1, 3, 3, RSTable5ATOffset + 0x86a0, 6) - ret["Ae350SocOuts"]: read_scaledGrid16(0x206, 3, 3, RSTable5ATOffset + 0x8bb0, 10) + ret["Ae350SocIns"] = self.read_scaledGrid16(0x1b1, 3, 3, RSTable5ATOffset + 0x86a0, 6) + ret["Ae350SocOuts"] = self.read_scaledGrid16(0x206, 3, 3, RSTable5ATOffset + 0x8bb0, 10) - ret["CMuxTopInNodes"]: read_scaledGrid16(0xbd, 0x54, 0x54, RSTable5ATOffset + 0x13fc4, 0) - ret["CMuxBotInNodes"]: read_scaledGrid16(0xbd, 0x54, 0x54, RSTable5ATOffset + 0x1bbcc, 0) - ret["CMuxTopIns"]: read_scaledGrid16(0xbd, 0x3, 0x3, RSTable5ATOffset + 0x11be8, 4) - ret["CMuxBotIns"]: read_scaledGrid16(0xbd, 0x3, 0x3, RSTable5ATOffset + 0x11e20, 2) + ret["CMuxTopInNodes"] = self.read_scaledGrid16(0xbd, 0x54, 0x54, RSTable5ATOffset + 0x13fc4, 0) + ret["CMuxBotInNodes"] = self.read_scaledGrid16(0xbd, 0x54, 0x54, RSTable5ATOffset + 0x1bbcc, 0) + ret["CMuxTopIns"] = self.read_scaledGrid16(0xbd, 0x3, 0x3, RSTable5ATOffset + 0x11be8, 4) + ret["CMuxBotIns"] = self.read_scaledGrid16(0xbd, 0x3, 0x3, RSTable5ATOffset + 0x11e20, 2) - ret["MipiIO1"]: read_scaledGrid16(10, 0xf, 0xf, RSTable5ATOffset + 0x240e0, 0) - ret["MipiIO2"]: read_scaledGrid16(10, 0xf, 0xf, RSTable5ATOffset + 0x24176, 0) + ret["MipiIO1"] = self.read_scaledGrid16(10, 0xf, 0xf, RSTable5ATOffset + 0x240e0, 0) + ret["MipiIO2"] = self.read_scaledGrid16(10, 0xf, 0xf, RSTable5ATOffset + 0x24176, 0) for n in range(5): - ret["MipiIOName1_{n}"]: read_scaledGrid16(10, 0xf, 0x4b, 5, RSTable5ATOffset + 0x2420c + n) - ret["MipiIOName2_{n}"]: read_scaledGrid16(10, 0xf, 0x4b, 5, RSTable5ATOffset + 0x244fa + n) - ret["MipiBank1"]: self.read_arr16_at(10, RSTable5ATOffset + 0x240e0, 0) - ret["MipiBank2"]: self.read_arr16_at(10, RSTable5ATOffset + 0x24176, 0) + ret["MipiIOName1_{n}"] = self.read_scaledGrid16(10, 0xf, 0x4b, 5, RSTable5ATOffset + 0x2420c + n) + ret["MipiIOName2_{n}"] = self.read_scaledGrid16(10, 0xf, 0x4b, 5, RSTable5ATOffset + 0x244fa + n) + ret["MipiBank1"] = self.read_arr16_at(10, RSTable5ATOffset + 0x240e0, 0) + ret["MipiBank2"] = self.read_arr16_at(10, RSTable5ATOffset + 0x24176, 0) - ret["QuadIO1"]: read_scaledGrid16(15, 0xf, 0xf, RSTable5ATOffset + 0x2483c, 0) - ret["QuafIO2"]: read_scaledGrid16(15, 0xf, 0xf, RSTable5ATOffset + 0x24977, 0) + ret["QuadIO1"] = self.read_scaledGrid16(15, 0xf, 0xf, RSTable5ATOffset + 0x2483c, 0) + ret["QuafIO2"] = self.read_scaledGrid16(15, 0xf, 0xf, RSTable5ATOffset + 0x24977, 0) for n in range(5): - ret["QuadIOName1_{n}"]: read_scaledGrid16(15, 0xf, 0x4b, 5, RSTable5ATOffset + 0x2483c + n) - ret["QuafIOName2_{n}"]: read_scaledGrid16(15, 0xf, 0xf, 5, RSTable5ATOffset + 0x24977 + n) - ret["QuadBank1"]: self.read_arr16_at(15, RSTable5ATOffset + 0x123f0, 8) - ret["QuadBank2"]: self.read_arr16_at(15, RSTable5ATOffset + 0x12408, 2) + ret["QuadIOName1_{n}"] = self.read_scaledGrid16(15, 0xf, 0x4b, 5, RSTable5ATOffset + 0x2483c + n) + ret["QuafIOName2_{n}"] = self.read_scaledGrid16(15, 0xf, 0xf, 5, RSTable5ATOffset + 0x24977 + n) + ret["QuadBank1"] = self.self.read_arr16_at(15, RSTable5ATOffset + 0x123f0, 8) + ret["QuadBank2"] = self.self.read_arr16_at(15, RSTable5ATOffset + 0x12408, 2) - ret["AdcIO"]: read_scaledGrid16(4, 0xf, 0xf, 1, RSTable5ATOffset + 0x25708) + ret["AdcIO"] = self.read_scaledGrid16(4, 0xf, 0xf, 1, RSTable5ATOffset + 0x25708) for n in range(5): - ret["QuaAdcIOName_{n}"]: read_scaledGrid16(4, 0xf, 0x4b, 5, RSTable5ATOffset + 0x25744 + n) - ret["AdcBank"]: self.read_arr16_at(4, RSTable5ATOffset + 0x12b80, 0) - - ret["Multalu27x18In"]: self.read_arr16_at(0xca, RSTable5ATOffset + 0x9778, 8) - ret["Multalu27x18InDlt"]: self.read_arr16_at(0xca, RSTable5ATOffset + 0x99c0, 2) - ret["Multalu27x18Out"]: self.read_arr16_at(0x7b, RSTable5ATOffset + 0x9840, 0xc) - ret["Multalu27x18OutDlt"]: self.read_arr16_at(0x7b, RSTable5ATOffset + 0x9988, 6) - ret["MultCtrlIn"]: self.read_arr16_at(0x6, RSTable5ATOffset + 0x9a00, 0xc) - ret["MultCtrlOut"]: self.read_arr16_at(0x6, RSTable5ATOffset + 0x9a08, 8) - - ret["DqsRLoc"]: self.read_arr16_at(0x2, RSTable5ATOffset + 0x12c38, 0) - ret["DqsCLoc"]: self.read_arr16_at(0x2, RSTable5ATOffset + 0x12c38, 4) - - ret["MDdrDllIns1"]: read_scaledGrid16(4, 3, 3, RSTable5ATOffset + 0x12c38, 8) - ret["MDdrDllIns2"]: read_scaledGrid16(4, 3, 3, RSTable5ATOffset + 0x12cb0, 2) - ret["MDdrDllIns3"]: read_scaledGrid16(4, 3, 3, RSTable5ATOffset + 0x12d20, 0xc) - ret["MDdrDllIns4"]: read_scaledGrid16(4, 3, 3, RSTable5ATOffset + 0x12d98, 6) - ret["MDdrDllIns5"]: read_scaledGrid16(4, 3, 3, RSTable5ATOffset + 0x12e10, 0) - ret["MDdrDllIns6"]: read_scaledGrid16(4, 3, 3, RSTable5ATOffset + 0x12e30, 0xe) - ret["MDdrDllIns7"]: read_scaledGrid16(4, 3, 3, RSTable5ATOffset + 0x12e58, 0xc) - - ret["S0DdrDllIns1"]: read_scaledGrid16(4, 3, 3, RSTable5ATOffset + 0x12c60, 6) - ret["S0DdrDllIns2"]: read_scaledGrid16(4, 3, 3, RSTable5ATOffset + 0x12cd8, 0) - ret["S0DdrDllIns3"]: read_scaledGrid16(4, 3, 3, RSTable5ATOffset + 0x12d48, 10) - ret["S0DdrDllIns4"]: read_scaledGrid16(4, 3, 3, RSTable5ATOffset + 0x12dc0, 4) - - ret["S1DdrDllIns1"]: read_scaledGrid16(4, 3, 3, RSTable5ATOffset + 0x12c88, 4) - ret["S1DdrDllIns2"]: read_scaledGrid16(4, 3, 3, RSTable5ATOffset + 0x12cf8, 0xe) - ret["S1DdrDllIns3"]: read_scaledGrid16(4, 3, 3, RSTable5ATOffset + 0x12d70, 8) - ret["S1DdrDllIns4"]: read_scaledGrid16(4, 3, 3, RSTable5ATOffset + 0x12de8, 2) + ret["QuaAdcIOName_{n}"] = self.read_scaledGrid16(4, 0xf, 0x4b, 5, RSTable5ATOffset + 0x25744 + n) + ret["AdcBank"] = self.read_arr16_at(4, RSTable5ATOffset + 0x12b80, 0) + + ret["Multalu12x12In"] = self.read_arr16_at(0x18, RSTable5ATOffset + 0x9530, 8) + ret["Multalu12x12Out"] = self.read_arr16_at(0x18, RSTable5ATOffset + 0x9560, 8) + ret["Multalu12x12InDlt"] = self.read_arr16_at(0x18, RSTable5ATOffset + 0x9590, 8) + ret["Multalu12x12OutDlt"] = self.read_arr16_at(0x18, RSTable5ATOffset + 0x95c0, 8) + + ret["Multalu27x18In"] = self.read_arr16_at(0xca, RSTable5ATOffset + 0x9778, 8) + ret["Multalu27x18InDlt"] = self.read_arr16_at(0xca, RSTable5ATOffset + 0x99c0, 2) + ret["Multalu27x18Out"] = self.read_arr16_at(0x7b, RSTable5ATOffset + 0x9840, 0xc) + ret["Multalu27x18OutDlt"] = self.read_arr16_at(0x7b, RSTable5ATOffset + 0x9988, 6) + ret["MultCtrlIn"] = self.read_arr16_at(0x6, RSTable5ATOffset + 0x9a00, 0xc) + ret["MultCtrlOut"] = self.read_arr16_at(0x6, RSTable5ATOffset + 0x9a08, 8) + + ret["DqsRLoc"] = self.read_arr16_at(0x2, RSTable5ATOffset + 0x12c38, 0) + ret["DqsCLoc"] = self.read_arr16_at(0x2, RSTable5ATOffset + 0x12c38, 4) + + ret["MDdrDllIns1"] = self.read_scaledGrid16(4, 3, 3, RSTable5ATOffset + 0x12c38, 8) + ret["MDdrDllIns2"] = self.read_scaledGrid16(4, 3, 3, RSTable5ATOffset + 0x12cb0, 2) + ret["MDdrDllIns3"] = self.read_scaledGrid16(4, 3, 3, RSTable5ATOffset + 0x12d20, 0xc) + ret["MDdrDllIns4"] = self.read_scaledGrid16(4, 3, 3, RSTable5ATOffset + 0x12d98, 6) + ret["MDdrDllIns5"] = self.read_scaledGrid16(4, 3, 3, RSTable5ATOffset + 0x12e10, 0) + ret["MDdrDllIns6"] = self.read_scaledGrid16(4, 3, 3, RSTable5ATOffset + 0x12e30, 0xe) + ret["MDdrDllIns7"] = self.read_scaledGrid16(4, 3, 3, RSTable5ATOffset + 0x12e58, 0xc) + + ret["S0DdrDllIns1"] = self.read_scaledGrid16(4, 3, 3, RSTable5ATOffset + 0x12c60, 6) + ret["S0DdrDllIns2"] = self.read_scaledGrid16(4, 3, 3, RSTable5ATOffset + 0x12cd8, 0) + ret["S0DdrDllIns3"] = self.read_scaledGrid16(4, 3, 3, RSTable5ATOffset + 0x12d48, 10) + ret["S0DdrDllIns4"] = self.read_scaledGrid16(4, 3, 3, RSTable5ATOffset + 0x12dc0, 4) + + ret["S1DdrDllIns1"] = self.read_scaledGrid16(4, 3, 3, RSTable5ATOffset + 0x12c88, 4) + ret["S1DdrDllIns2"] = self.read_scaledGrid16(4, 3, 3, RSTable5ATOffset + 0x12cf8, 0xe) + ret["S1DdrDllIns3"] = self.read_scaledGrid16(4, 3, 3, RSTable5ATOffset + 0x12d70, 8) + ret["S1DdrDllIns4"] = self.read_scaledGrid16(4, 3, 3, RSTable5ATOffset + 0x12de8, 2) - ret["MDdrDllOuts1"]: read_scaledGrid16(9, 3, 3, RSTable5ATOffset + 0x12c48, 0) - ret["MDdrDllOuts2"]: read_scaledGrid16(9, 3, 3, RSTable5ATOffset + 0x12cb8, 10) - ret["MDdrDllOuts3"]: read_scaledGrid16(9, 3, 3, RSTable5ATOffset + 0x12d30, 4) - ret["MDdrDllOuts4"]: read_scaledGrid16(9, 3, 3, RSTable5ATOffset + 0x12da0, 0xe) - ret["MDdrDllOuts5"]: read_scaledGrid16(9, 3, 3, RSTable5ATOffset + 0x12e18, 8) - ret["MDdrDllOuts6"]: read_scaledGrid16(9, 3, 3, RSTable5ATOffset + 0x12e40, 6) - ret["MDdrDllOuts7"]: read_scaledGrid16(9, 3, 3, RSTable5ATOffset + 0x12e68, 4) + ret["MDdrDllOuts1"] = self.read_scaledGrid16(9, 3, 3, RSTable5ATOffset + 0x12c48, 0) + ret["MDdrDllOuts2"] = self.read_scaledGrid16(9, 3, 3, RSTable5ATOffset + 0x12cb8, 10) + ret["MDdrDllOuts3"] = self.read_scaledGrid16(9, 3, 3, RSTable5ATOffset + 0x12d30, 4) + ret["MDdrDllOuts4"] = self.read_scaledGrid16(9, 3, 3, RSTable5ATOffset + 0x12da0, 0xe) + ret["MDdrDllOuts5"] = self.read_scaledGrid16(9, 3, 3, RSTable5ATOffset + 0x12e18, 8) + ret["MDdrDllOuts6"] = self.read_scaledGrid16(9, 3, 3, RSTable5ATOffset + 0x12e40, 6) + ret["MDdrDllOuts7"] = self.read_scaledGrid16(9, 3, 3, RSTable5ATOffset + 0x12e68, 4) - ret["S0DdrDllOuts1"]: read_scaledGrid16(9, 3, 3, RSTable5ATOffset + 0x12c68, 0xe) - ret["S0DdrDllOuts2"]: read_scaledGrid16(9, 3, 3, RSTable5ATOffset + 0x12ce0, 8) - ret["S0DdrDllOuts3"]: read_scaledGrid16(9, 3, 3, RSTable5ATOffset + 0x12d58, 2) - ret["S0DdrDllOuts4"]: read_scaledGrid16(9, 3, 3, RSTable5ATOffset + 0x12dc8, 0xc) - - ret["S1DdrDllOuts1"]: read_scaledGrid16(9, 3, 3, RSTable5ATOffset + 0x12c90, 0xc) - ret["S1DdrDllOuts2"]: read_scaledGrid16(9, 3, 3, RSTable5ATOffset + 0x12d08, 6) - ret["S1DdrDllOuts3"]: read_scaledGrid16(9, 3, 3, RSTable5ATOffset + 0x12d80, 0) - ret["S1DdrDllOuts4"]: read_scaledGrid16(9, 3, 3, RSTable5ATOffset + 0x12df0, 10) - - ret["CmseraIns"]: read_scaledGrid16(0x20, 3, 3, RSTable5ATOffset + 0x12e80, 10) - ret["CmseraOuts"]: read_scaledGrid16(0x60, 3, 3, RSTable5ATOffset + 0x12ee0, 10) - - ret["AdcLRCIns"]: read_scaledGrid16(0x28, 3, 3, RSTable5ATOffset + 0x13000, 10) - ret["AdcLRCOuts"]: read_scaledGrid16(0x12, 3, 3, RSTable5ATOffset + 0x13078, 10) - ret["AdcLRCCfgvsenctl1"]: read_scaledGrid16(3, 3, 3, RSTable5ATOffset + 0x78000, 6) - ret["AdcLRCCfgvsenctl2"]: read_scaledGrid16(0x24, 3, 3, RSTable5ATOffset + 0x130b8, 8) - ret["AdcULCOuts"]: read_scaledGrid16(0x12, 3, 3, RSTable5ATOffset + 0x13128, 0) - ret["AdcULCCfgvsenctl"]: read_scaledGrid16(3, 3, 3, RSTable5ATOffset + 0x13158, 0xc) - ret["Adc25kIns"]: read_scaledGrid16(0x17, 3, 3, RSTable5ATOffset + 0x13160, 0xe) - ret["Adc25kOuts"]: read_scaledGrid16(0x1b, 3, 3, RSTable5ATOffset + 0x131a8, 8) + ret["S0DdrDllOuts1"] = self.read_scaledGrid16(9, 3, 3, RSTable5ATOffset + 0x12c68, 0xe) + ret["S0DdrDllOuts2"] = self.read_scaledGrid16(9, 3, 3, RSTable5ATOffset + 0x12ce0, 8) + ret["S0DdrDllOuts3"] = self.read_scaledGrid16(9, 3, 3, RSTable5ATOffset + 0x12d58, 2) + ret["S0DdrDllOuts4"] = self.read_scaledGrid16(9, 3, 3, RSTable5ATOffset + 0x12dc8, 0xc) + + ret["S1DdrDllOuts1"] = self.read_scaledGrid16(9, 3, 3, RSTable5ATOffset + 0x12c90, 0xc) + ret["S1DdrDllOuts2"] = self.read_scaledGrid16(9, 3, 3, RSTable5ATOffset + 0x12d08, 6) + ret["S1DdrDllOuts3"] = self.read_scaledGrid16(9, 3, 3, RSTable5ATOffset + 0x12d80, 0) + ret["S1DdrDllOuts4"] = self.read_scaledGrid16(9, 3, 3, RSTable5ATOffset + 0x12df0, 10) + + ret["CmseraIns"] = self.read_scaledGrid16(0x20, 3, 3, RSTable5ATOffset + 0x12e80, 10) + ret["CmseraOuts"] = self.read_scaledGrid16(0x60, 3, 3, RSTable5ATOffset + 0x12ee0, 10) + + ret["AdcLRCIns"] = self.read_scaledGrid16(0x28, 3, 3, RSTable5ATOffset + 0x13000, 10) + ret["AdcLRCOuts"] = self.read_scaledGrid16(0x12, 3, 3, RSTable5ATOffset + 0x13078, 10) + ret["AdcLRCCfgvsenctl1"] = self.read_scaledGrid16(3, 3, 3, RSTable5ATOffset + 0x78000, 6) + ret["AdcLRCCfgvsenctl2"] = self.read_scaledGrid16(0x24, 3, 3, RSTable5ATOffset + 0x130b8, 8) + ret["AdcULCOuts"] = self.read_scaledGrid16(0x12, 3, 3, RSTable5ATOffset + 0x13128, 0) + ret["AdcULCCfgvsenctl"] = self.read_scaledGrid16(3, 3, 3, RSTable5ATOffset + 0x13158, 0xc) + ret["Adc25kIns"] = self.read_scaledGrid16(0x17, 3, 3, RSTable5ATOffset + 0x13160, 0xe) + ret["Adc25kOuts"] = self.read_scaledGrid16(0x1b, 3, 3, RSTable5ATOffset + 0x131a8, 8) - ret["CibFabricNode"]: read_scaledGrid16(6, 3, 3, RSTable5ATOffset + 0x131f8, 10) - ret["SharedIOLogicIOBloc"]: read_scaledGrid16(0x9c, 2, 2, RSTable5ATOffset + 0x13208, 0xe) - - ret["TopAMBGA121N"]: self.read_arr16_at(200, RSTable5ATOffset + 0x2668e, 0) - ret["TopBMBGA121N"]: self.read_arr16_at(200, RSTable5ATOffset + 0x2694a, 0) - ret["BottomAMBGA121N"]: self.read_arr16_at(200, RSTable5ATOffset + 0x26756, 0) - ret["BottomBMBGA121N"]: self.read_arr16_at(200, RSTable5ATOffset + 0x26a12, 0) - ret["TopAMBGA121NName"]: read_scaledGrid16(200, 9, 9, RSTable5ATOffset + 0x26c06, 0) - ret["BottomAMBGA121NName"]: read_scaledGrid16(200, 9, 9, RSTable5ATOffset + 0x2730e, 0) - ret["TopBMBGA121NName"]: read_scaledGrid16(200, 9, 9, RSTable5ATOffset + 0x284a2, 0) - ret["BottomBMBGA121NName"]: read_scaledGrid16(200, 9, 9, RSTable5ATOffset + 0x28baa, 0) - - ret["LeftAMBGA121N"]: self.read_arr16_at(0x96, RSTable5ATOffset + 0x2681e, 0) - ret["LeftBMBGA121N"]: self.read_arr16_at(0x96, RSTable5ATOffset + 0x26ada, 0) - ret["RightAMBGA121N"]: self.read_arr16_at(0x96, RSTable5ATOffset + 0x268b4, 0) - ret["RightBMBGA121N"]: self.read_arr16_at(0x96, RSTable5ATOffset + 0x26b70, 0) - ret["LeftAMBGA121NName"]: read_scaledGrid16(0x96, 9, 9, RSTable5ATOffset + 0x27a16, 0) - ret["RightAMBGA121NName"]: read_scaledGrid16(0x96, 9, 9, RSTable5ATOffset + 0x27f5c, 0) - ret["LeftBMBGA121NName"]: read_scaledGrid16(0x96, 9, 9, RSTable5ATOffset + 0x292b2, 0) - ret["RightBMBGA121NName"]: read_scaledGrid16(0x96, 9, 9, RSTable5ATOffset + 0x297f8, 0) - - ret["SpineColumn"]: self.read_arr16_at(8, RSTable5ATOffset + 0x14e98, 0xe) + ret["CibFabricNode"] = self.read_scaledGrid16(6, 3, 3, RSTable5ATOffset + 0x131f8, 10) + ret["SharedIOLogicIOBloc"] = self.read_scaledGrid16(0x9c, 2, 2, RSTable5ATOffset + 0x13208, 0xe) + + ret["TopAMBGA121N"] = self.read_arr16_at(200, RSTable5ATOffset + 0x2668e, 0) + ret["TopBMBGA121N"] = self.read_arr16_at(200, RSTable5ATOffset + 0x2694a, 0) + ret["BottomAMBGA121N"] = self.read_arr16_at(200, RSTable5ATOffset + 0x26756, 0) + ret["BottomBMBGA121N"] = self.read_arr16_at(200, RSTable5ATOffset + 0x26a12, 0) + ret["TopAMBGA121NName"] = self.read_scaledGrid16(200, 9, 9, RSTable5ATOffset + 0x26c06, 0) + ret["BottomAMBGA121NName"] = self.read_scaledGrid16(200, 9, 9, RSTable5ATOffset + 0x2730e, 0) + ret["TopBMBGA121NName"] = self.read_scaledGrid16(200, 9, 9, RSTable5ATOffset + 0x284a2, 0) + ret["BottomBMBGA121NName"] = self.read_scaledGrid16(200, 9, 9, RSTable5ATOffset + 0x28baa, 0) + + ret["LeftAMBGA121N"] = self.read_arr16_at(0x96, RSTable5ATOffset + 0x2681e, 0) + ret["LeftBMBGA121N"] = self.read_arr16_at(0x96, RSTable5ATOffset + 0x26ada, 0) + ret["RightAMBGA121N"] = self.read_arr16_at(0x96, RSTable5ATOffset + 0x268b4, 0) + ret["RightBMBGA121N"] = self.read_arr16_at(0x96, RSTable5ATOffset + 0x26b70, 0) + ret["LeftAMBGA121NName"] = self.read_scaledGrid16(0x96, 9, 9, RSTable5ATOffset + 0x27a16, 0) + ret["RightAMBGA121NName"] = self.read_scaledGrid16(0x96, 9, 9, RSTable5ATOffset + 0x27f5c, 0) + ret["LeftBMBGA121NName"] = self.read_scaledGrid16(0x96, 9, 9, RSTable5ATOffset + 0x292b2, 0) + ret["RightBMBGA121NName"] = self.read_scaledGrid16(0x96, 9, 9, RSTable5ATOffset + 0x297f8, 0) + + ret["SpineColumn"] = self.read_arr16_at(8, RSTable5ATOffset + 0x14e98, 0xe) return ret @@ -526,6 +543,7 @@ def read_io(self): return ret def read_something5A(self): + RSTable5ATOffset = 0x7b4a8 ret = { "Dqs": {}, } From 20677f208cbf86038950187e615c1e563027f422 Mon Sep 17 00:00:00 2001 From: AwooOOoo Date: Sun, 20 Oct 2024 18:01:33 +0200 Subject: [PATCH 11/12] -More corrections and added Cfg support --- apycula/dat19.py | 68 ++++++++++++++++++++++++++++++------------------ 1 file changed, 43 insertions(+), 25 deletions(-) diff --git a/apycula/dat19.py b/apycula/dat19.py index 4f303809..e6ae91e3 100644 --- a/apycula/dat19.py +++ b/apycula/dat19.py @@ -95,14 +95,22 @@ def read_arr16(self, num: int) -> list[int]: arr = [self.read_i16() for _ in range(num)] return arr - def read_arr16_at(self, num:int, base:int, offset:int): + def read_arr16_at(self, num:int, base:int, scale:int, offset:int): ret = [] for n in range(num): self._cur = (n + base) * 2 + offset ret.append(self.read_i16()) return ret + + def read_arr32_at(self, num:int, base:int, scale:int, offset:int): + ret = [] + for n in range(num): + self._cur = (n + base) * 4 + offset + ret.append(self.read_i32()) + return ret + def read_arr32(self, num: int) -> list[int]: arr = [self.read_i32() for _ in range(num)] @@ -229,17 +237,16 @@ def read_clkins(self, num) -> list[tuple[int, int]]: ret.append((a, b)) return ret - def read_scaledGrid16(rows, cols, rowScaling, colScaling, baseOffset): - self._cur = baseAddress - rows = [] + def read_scaledGrid16(self, numRows, numCols, rowScaling, colScaling, baseOffset): + ret = [] - for row in range(rows): - row = [] - for col in range(cols): + for row in range(numRows): + rowArr = [] + for col in range(numCols): self._cur = (row * rowScaling) + (col * colScaling * 2) + baseOffset - row.append(self.read_u16()) - rows.append(row) - return rows + rowArr.append(self.read_u16()) + ret.append(rowArr) + return ret def read_5Astuff(self) -> dict: RSTable5ATOffset = 0x7b4a8 @@ -318,8 +325,8 @@ def read_5Astuff(self) -> dict: for n in range(5): ret["QuadIOName1_{n}"] = self.read_scaledGrid16(15, 0xf, 0x4b, 5, RSTable5ATOffset + 0x2483c + n) ret["QuafIOName2_{n}"] = self.read_scaledGrid16(15, 0xf, 0xf, 5, RSTable5ATOffset + 0x24977 + n) - ret["QuadBank1"] = self.self.read_arr16_at(15, RSTable5ATOffset + 0x123f0, 8) - ret["QuadBank2"] = self.self.read_arr16_at(15, RSTable5ATOffset + 0x12408, 2) + ret["QuadBank1"] = self.read_arr16_at(15, RSTable5ATOffset + 0x123f0, 8) + ret["QuadBank2"] = self.read_arr16_at(15, RSTable5ATOffset + 0x12408, 2) ret["AdcIO"] = self.read_scaledGrid16(4, 0xf, 0xf, 1, RSTable5ATOffset + 0x25708) for n in range(5): @@ -546,20 +553,31 @@ def read_something5A(self): RSTable5ATOffset = 0x7b4a8 ret = { "Dqs": {}, + "Cfg": {}, } - ret["Dqs"]["TA"]: self.read_arr16_at(200, RSTable5ATOffset + 0x9a10, 4) - ret["Dqs"]["TB"]: self.read_arr16_at(200, RSTable5ATOffset + 0x9cc8, 0xc) - ret["Dqs"]["BA"]: self.read_arr16_at(200, RSTable5ATOffset + 0x9ad8, 4) - ret["Dqs"]["BB"]: self.read_arr16_at(200, RSTable5ATOffset + 0x9d90, 0xc) - ret["Dqs"]["LA"]: self.read_arr16_at(0x96, RSTable5ATOffset + 0x9ba0, 4) - ret["Dqs"]["LB"]: self.read_arr16_at(0x96, RSTable5ATOffset + 0x9e58, 0xc) - ret["Dqs"]["RA"]: self.read_arr16_at(0x96, RSTable5ATOffset + 0x9c38, 0) - ret["Dqs"]["RA"]: self.read_arr16_at(0x96, RSTable5ATOffset + 0x9ef0, 8) - - ret["Dqs"]["LeftIO"]: self.read_arr16_at(0x16, RSTable5ATOffset + 0x9f88, 4) - ret["Dqs"]["RightIO"]: self.read_arr16_at(0x16, RSTable5ATOffset + 0x9fa0, 0) - ret["Dqs"]["TopIO"]: self.read_arr16_at(0x16, RSTable5ATOffset + 0x9fb0, 0xc) - ret["Dqs"]["BottomIO"]: self.read_arr16_at(0x16, RSTable5ATOffset + 0x9fc8, 8) + ret["Dqs"]["TA"] = self.read_arr16_at(200, RSTable5ATOffset + 0x9a10, 4) + ret["Dqs"]["TB"] = self.read_arr16_at(200, RSTable5ATOffset + 0x9cc8, 0xc) + ret["Dqs"]["BA"] = self.read_arr16_at(200, RSTable5ATOffset + 0x9ad8, 4) + ret["Dqs"]["BB"] = self.read_arr16_at(200, RSTable5ATOffset + 0x9d90, 0xc) + ret["Dqs"]["LA"] = self.read_arr16_at(0x96, RSTable5ATOffset + 0x9ba0, 4) + ret["Dqs"]["LB"] = self.read_arr16_at(0x96, RSTable5ATOffset + 0x9e58, 0xc) + ret["Dqs"]["RA"] = self.read_arr16_at(0x96, RSTable5ATOffset + 0x9c38, 0) + ret["Dqs"]["RA"] = self.read_arr16_at(0x96, RSTable5ATOffset + 0x9ef0, 8) + + ret["Dqs"]["LeftIO"] = self.read_arr16_at(0x16, RSTable5ATOffset + 0x9f88, 4) + ret["Dqs"]["RightIO"] = self.read_arr16_at(0x16, RSTable5ATOffset + 0x9fa0, 0) + ret["Dqs"]["TopIO"] = self.read_arr16_at(0x16, RSTable5ATOffset + 0x9fb0, 0xc) + ret["Dqs"]["BottomIO"] = self.read_arr16_at(0x16, RSTable5ATOffset + 0x9fc8, 8) + + ret["Cfg"]["TA"] = self.read_arr32_at(200, RSTable5ATOffset, 0) + ret["Cfg"]["BA"] = self.read_arr32_at(200, RSTable5ATOffset + 200, 0) + ret["Cfg"]["LA"] = self.read_arr32_at(0x96, RSTable5ATOffset + 400, 0) + ret["Cfg"]["RA"] = self.read_arr32_at(0x96, RSTable5ATOffset + 224, 8) + ret["Cfg"]["TB"] = self.read_arr32_at(200, RSTable5ATOffset + 700, 0) + ret["Cfg"]["BB"] = self.read_arr32_at(200, RSTable5ATOffset + 900, 0) + ret["Cfg"]["LB"] = self.read_arr32_at(0x96, RSTable5ATOffset, 0x44c) + ret["Cfg"]["RB"] = self.read_arr32_at(0x96, RSTable5ATOffset, 0x4e0, 8) + return ret def read_something(self): From 85935bea8cb0041db8ed1c0e2189d1e2b0ef6f85 Mon Sep 17 00:00:00 2001 From: AwooOOoo Date: Sun, 20 Oct 2024 18:53:00 +0200 Subject: [PATCH 12/12] -Added some missing 12x12 tables and documented the rest of what is unknown --- apycula/dat19.py | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/apycula/dat19.py b/apycula/dat19.py index e6ae91e3..37ff8998 100644 --- a/apycula/dat19.py +++ b/apycula/dat19.py @@ -251,7 +251,8 @@ def read_scaledGrid16(self, numRows, numCols, rowScaling, colScaling, baseOffset def read_5Astuff(self) -> dict: RSTable5ATOffset = 0x7b4a8 ret = { } - + + #These are set (not read from file), but can't find reference #ret["UNKNOWN"] = 0x1d #ret["UNKNOWN"] = 0x1d #ret["UNKNOWN"] = 0x16 @@ -278,6 +279,8 @@ def read_5Astuff(self) -> dict: ret["5ATIODelayAIn"] = self.read_arr16_at(0x3e, RSTable5ATOffset + 0x1948, 0x4) ret["5ATIODelayBIn"] = self.read_arr16_at(0x3e, RSTable5ATOffset + 0x1988, 0) + # The following address offsets are also mentioned + # All 5 are mentioned in FanIns, but only the 3rd and 4th are mentioned in FanOuts #ret["UNKNOWN"] = self.read_scaledGrid16(0x20, 0x1d, 0x1d, RSTable5ATOffset + 0x3428, 0) #ret["UNKNOWN"] = self.read_scaledGrid16(0xc, 0x16, 0x16, RSTable5ATOffset + 0x3b68, 0) #ret["UNKNOWN"] = self.read_scaledGrid16(0xc, 0x16, 0x16, RSTable5ATOffset + 0x1e98, 8) @@ -333,10 +336,21 @@ def read_5Astuff(self) -> dict: ret["QuaAdcIOName_{n}"] = self.read_scaledGrid16(4, 0xf, 0x4b, 5, RSTable5ATOffset + 0x25744 + n) ret["AdcBank"] = self.read_arr16_at(4, RSTable5ATOffset + 0x12b80, 0) - ret["Multalu12x12In"] = self.read_arr16_at(0x18, RSTable5ATOffset + 0x9530, 8) - ret["Multalu12x12Out"] = self.read_arr16_at(0x18, RSTable5ATOffset + 0x9560, 8) - ret["Multalu12x12InDlt"] = self.read_arr16_at(0x18, RSTable5ATOffset + 0x9590, 8) - ret["Multalu12x12OutDlt"] = self.read_arr16_at(0x18, RSTable5ATOffset + 0x95c0, 8) + ret["Mult12x12In"] = self.read_arr16_at(0x18, RSTable5ATOffset + 0x9530, 8) + ret["Mult12x12Out"] = self.read_arr16_at(0x18, RSTable5ATOffset + 0x9560, 8) + ret["Mult12x12InDlt"] = self.read_arr16_at(0x18, RSTable5ATOffset + 0x9590, 8) + ret["Mult12x12OutDlt"] = self.read_arr16_at(0x18, RSTable5ATOffset + 0x95c0, 8) + + #The following are defined right next to Mult12x12 so are probably realted, but not referenced + #ret["UNKNOWN"] = self.read_arr16_at(0x18, RSTable5ATOffset + 0x12a6a, 0) + #ret["UNKNOWN"] = self.read_arr16_at(0x18, RSTable5ATOffset + 0x12b2a, 0) + #ret["UNKNOWN"] = self.read_arr16_at(0x18, RSTable5ATOffset + 0x12aca 0) + #ret["UNKNOWN"] = self.read_arr16_at(0x18, RSTable5ATOffset + 0x12b8a, 0) + + ret["MultAddAlu12x12In"] = self.read_arr16_at(100, RSTable5ATOffset + 0x95f0, 8) + ret["MultAddAlu12x12Out"] = self.read_arr16_at(0x60, RSTable5ATOffset + 0x9658, 8) + ret["MultAddAlu12x12InDlt"] = self.read_arr16_at(100, RSTable5ATOffset + 0x96b8, 8) + ret["MultAddAlu12x12OutDlt"]= self.read_arr16_at(0x60, RSTable5ATOffset + 0x9718, 8) ret["Multalu27x18In"] = self.read_arr16_at(0xca, RSTable5ATOffset + 0x9778, 8) ret["Multalu27x18InDlt"] = self.read_arr16_at(0xca, RSTable5ATOffset + 0x99c0, 2) @@ -419,6 +433,7 @@ def read_5Astuff(self) -> dict: ret["SpineColumn"] = self.read_arr16_at(8, RSTable5ATOffset + 0x14e98, 0xe) + return ret def read_portmap(self) -> dict: