From 3d3039e25c2981a0d16e8cff079315da57c637c8 Mon Sep 17 00:00:00 2001 From: YRabbit Date: Wed, 12 Jul 2023 19:36:03 +1000 Subject: [PATCH] gowin: Himbaechel. Add bundle data generation. The pin data is only being populated so far, but not used. Signed-off-by: YRabbit --- himbaechel/himbaechel_dbgen/chip.py | 61 ++++++++++++++++++++++-- himbaechel/uarch/gowin/gowin_arch_gen.py | 39 +++++++++++++++ 2 files changed, 97 insertions(+), 3 deletions(-) diff --git a/himbaechel/himbaechel_dbgen/chip.py b/himbaechel/himbaechel_dbgen/chip.py index c3e4a8ae..4f16b831 100644 --- a/himbaechel/himbaechel_dbgen/chip.py +++ b/himbaechel/himbaechel_dbgen/chip.py @@ -371,6 +371,56 @@ class TileInst(BBAStruct): bba.ref(f"{context}_extra_data") else: bba.u32(0) + +@dataclass +class PadInfo(BBAStruct): + # package pin name + package_pin: IdString + # reference to corresponding bel + tile: IdString + bel: IdString + # function name + pad_function: IdString + # index of pin bank + pad_bank: int + # extra pad flags + flags: int + extra_data: object = None + + def serialise_lists(self, context: str, bba: BBAWriter): + pass + def serialise(self, context: str, bba: BBAWriter): + bba.u32(self.package_pin.index) + bba.u32(self.tile.index) + bba.u32(self.bel.index) + bba.u32(self.pad_function.index) + bba.u32(self.pad_bank) + bba.u32(self.flags) + if self.extra_data is not None: + bba.ref(f"{context}_extra_data") + else: + bba.u32(0) + +@dataclass +class PackageInfo(BBAStruct): + strs: StringPool + name: IdString + pads: list[int] = field(default_factory=list) + + def create_pad(self, package_pin: str, tile: str, bel: str, pad_function: str, pad_bank: int, flags: int = 0): + pad = PadInfo(package_pin = self.strs.id(package_pin), tile = self.strs.id(tile), bel = self.strs.id(bel), + pad_function = self.strs.id(pad_function), pad_bank = pad_bank, flags = flags) + self.pads.append(pad) + return pad + + def serialise_lists(self, context: str, bba: BBAWriter): + for i, pad in enumerate(self.pad): + bel.serialise_lists(f"{context}_pad{i}", pad) + + def serialise(self, context: str, bba: BBAWriter): + bba.u32(self.name.index) + bba.slice(f"{context}_pads", len(self.pads)) + class Chip: def __init__(self, uarch: str, name: str, width: int, height: int): self.strs = StringPool() @@ -385,6 +435,7 @@ class Chip: self.node_shape_idx = dict() self.tile_shapes = [] self.tile_shapes_idx = dict() + self.packages = [] self.extra_data = None def create_tile_type(self, name: str): tt = TileType(self.strs, self.strs.id(name)) @@ -449,6 +500,11 @@ class Chip: self.tile_shapes_idx[key] = tile.shape_idx print(f"{len(self.tile_shapes)} unique tile routing shapes") + def create_package(self, name: str): + pkg = PackageInfo(self.strs, self.strs.id(name)) + self.packages.append(pkg) + return pkg + def serialise(self, bba: BBAWriter): self.flatten_tile_shapes() # TODO: preface, etc @@ -496,9 +552,8 @@ class Chip: bba.slice("tile_insts", self.width*self.height) bba.slice("node_shapes", len(self.node_shapes)) bba.slice("tile_shapes", len(self.tile_shapes)) - # packages: not yet used - bba.u32(0) - bba.u32(0) + # packages + bba.slice("packages", len(self.packages)) # speed grades: not yet used bba.u32(0) bba.u32(0) diff --git a/himbaechel/uarch/gowin/gowin_arch_gen.py b/himbaechel/uarch/gowin/gowin_arch_gen.py index 2c631908..191268ce 100644 --- a/himbaechel/uarch/gowin/gowin_arch_gen.py +++ b/himbaechel/uarch/gowin/gowin_arch_gen.py @@ -329,6 +329,42 @@ def create_ssram_tiletype(chip: Chip, db: chipdb, x: int, y: int, ttyp: int): tt.add_bel_pin(ff, f"WRE", "LSR2", PinType.INPUT) return (ttyp, tt) +_tbrlre = re.compile(r"IO([TBRL])(\d+)(\w)") +def create_packages(chip: Chip, db: chipdb): + def ioloc_to_tile_bel(ioloc): + side, num, bel_idx = _tbrlre.match(ioloc).groups() + if side == 'T': + row = 0 + col = int(num) - 1 + elif side == 'B': + row = db.rows - 1 + col = int(num) - 1 + elif side == 'L': + row = int(num) - 1 + col = 0 + elif side == 'R': + row = int(num) - 1 + col = db.cols - 1 + return (f'X{col}Y{row}', f'IOB{bel_idx}') + + created_pkgs = set() + for partno_spd, partdata in db.packages.items(): + pkgname, variant, spd = partdata + partno = partno_spd.removesuffix(spd) # drop SPEED like 'C7/I6' + if partno in created_pkgs: + continue + pkg = chip.create_package(partno) + print(partno) + for pinno, pininfo in db.pinout[variant][pkgname].items(): + io_loc, cfgs = pininfo + tile, bel = ioloc_to_tile_bel(io_loc) + pad_func = "" + for cfg in cfgs: + pad_func += cfg + "/" + pad_func = pad_func.rstrip('/') + bank = int(db.pin_bank[io_loc]) + pad = pkg.create_pad(pinno, tile, bel, pad_func, bank) + def main(): parser = argparse.ArgumentParser(description='Make Gowin BBA') parser.add_argument('-d', '--device', required=True) @@ -348,6 +384,9 @@ def main(): # Init constant ids ch.strs.read_constids(path.join(path.dirname(__file__), "constids.inc")) + # packages from parntnumbers + create_packages(ch, db) + # The manufacturer distinguishes by externally identical tiles, so keep # these differences (in case it turns out later that there is a slightly # different routing or something like that).