prjpeppercorn/gatemate/chip.py

176 lines
6.2 KiB
Python
Raw Normal View History

2024-12-27 09:01:22 +01:00
#
# prjpeppercorn -- GateMate FPGAs Bitstream Documentation and Tools
#
# Copyright (C) 2024 The Project Peppercorn Authors.
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#
import die
2024-12-27 10:42:38 +01:00
from die import Die
2024-12-27 09:01:22 +01:00
from dataclasses import dataclass
2024-12-27 14:33:52 +01:00
from typing import List, Dict
2024-12-27 09:01:22 +01:00
2025-01-14 15:15:40 +01:00
@dataclass(eq=True, order=True)
2024-12-27 10:03:19 +01:00
class Pad:
x : int
y : int
name : str
bel : str
function : str
bank : int
2024-12-27 14:33:52 +01:00
@dataclass
class Bank:
die : str
bank: str
2024-12-27 09:01:22 +01:00
@dataclass
class Chip:
name : str
die_width : int
die_height : int
2024-12-27 14:33:52 +01:00
dies : Dict[str,Die]
packages: Dict[str,Dict[str, List[Bank]]]
not_exist: Dict[str,List[str]]
2024-12-27 09:01:22 +01:00
def max_row(self):
return self.die_height * die.num_rows() - 3
def max_col(self):
return self.die_width * die.num_cols() - 3
def get_tile_types(self,x,y):
x_pos = (x + 2) % die.num_cols() - 2
y_pos = (y + 2) % die.num_rows() - 2
return die.get_tile_types(x_pos,y_pos)
2024-12-27 10:03:19 +01:00
def get_tile_type(self,x,y):
x_pos = (x + 2) % die.num_cols() - 2
y_pos = (y + 2) % die.num_rows() - 2
return die.get_tile_type(x_pos,y_pos)
2025-01-23 12:52:36 +01:00
def get_tile_info(self,x,y):
x_pos = (x + 2) % die.num_cols() - 2
y_pos = (y + 2) % die.num_rows() - 2
x_die = (x + 2) // die.num_cols()
y_die = (y + 2) // die.num_rows()
die_num = x_die + y_die * self.die_width
return die.get_tile_info(die_num, x_pos, y_pos)
2024-12-27 10:03:19 +01:00
def get_connections(self):
2024-12-27 10:42:38 +01:00
conn = dict()
2024-12-27 14:33:52 +01:00
for d in self.dies.values():
2024-12-27 10:42:38 +01:00
d.create_in_die_connections(conn)
return conn.items()
2024-12-27 10:03:19 +01:00
2024-12-27 14:33:52 +01:00
def get_packages(self):
return self.packages
2025-03-13 12:12:40 +01:00
def get_bank_number(self, bank):
match bank:
case 'N1' : return 0
case 'N2' : return 1
case 'E1' : return 2
case 'E2' : return 3
case 'W1' : return 4
case 'W2' : return 5
case 'S1' : return 6
case 'S2' : return 7
case 'S3' : return 8
case _ : return -1
2024-12-27 14:33:52 +01:00
def get_package_pads(self, package):
2024-12-27 10:03:19 +01:00
pads = []
2024-12-27 14:33:52 +01:00
pkg = self.packages[package]
not_exist = self.not_exist[package]
for name, banks in pkg.items():
for bank in banks:
for p in ["A","B"]:
for num in range(9):
2025-02-06 08:56:32 +01:00
d = self.dies[bank.die]
loc = d.io_pad_names[bank.bank][p][num]
2024-12-27 14:33:52 +01:00
pad_name = f"IO_{name}_{p}{num}"
if pad_name not in not_exist:
2025-03-13 12:12:40 +01:00
pads.append(Pad(loc.x + d.offset_x,loc.y + d.offset_y,pad_name,"GPIO","",self.get_bank_number(bank.bank)))
2024-12-27 10:03:19 +01:00
return pads
2024-12-27 09:01:22 +01:00
CCGM1_DEVICES = {
2024-12-27 14:33:52 +01:00
"CCGM1A1": Chip("CCGM1A1", 1, 1, {
"1A" : Die("1A", 0, 0)
}, {
"FBGA324" : {
"EA" : [ Bank("1A", "N1") ],
"EB" : [ Bank("1A", "N2") ],
"NA" : [ Bank("1A", "E1") ],
"NB" : [ Bank("1A", "E2") ],
"WA" : [ Bank("1A", "S3") ],
"WB" : [ Bank("1A", "S1") ],
"WC" : [ Bank("1A", "S2") ],
"SA" : [ Bank("1A", "W1") ],
"SB" : [ Bank("1A", "W2") ]
}
}, { # non existing pins
"FBGA324" : []
}),
"CCGM1A2": Chip("CCGM1A2", 1, 2, {
"1A" : Die("1A", 0, 0),
"1B" : Die("1B", 0, 1)
}, {
"FBGA324" : {
"EA" : [ Bank("1B", "N1") ],
"EB" : [ Bank("1B", "N2") ],
"NA" : [ Bank("1A", "E1"), Bank("1B", "E1") ],
"NB" : [ Bank("1A", "E2") ],
"WA" : [ Bank("1A", "S3") ],
"WB" : [ Bank("1A", "S1"), Bank("1B", "S1") ],
"WC" : [ Bank("1A", "S2") ],
"SA" : [ Bank("1A", "W1") ],
"SB" : [ Bank("1A", "W2"), Bank("1B", "W2") ]
}
}, { # non existing pins
"FBGA324" : []
}),
"CCGM1A4": Chip("CCGM1A4", 2, 2, {
"1A" : Die("1A", 0, 0),
"1B" : Die("1B", 0, 1),
"2A" : Die("2A", 1, 0),
"2B" : Die("2B", 1, 1)
}, {
"FBGA324" : {
"EA" : [ Bank("1B", "N1") ],
"EB" : [ Bank("1B", "N2") ],
"NA" : [ Bank("1A", "E1"), Bank("1B", "E1"), Bank("2A", "E1"), Bank("2B", "E1") ],
"NB" : [ Bank("2A", "N1"), Bank("2B", "S1") ],
"WA" : [ Bank("1A", "S3") ],
"WB" : [ Bank("1A", "N1"), Bank("1B", "S1") ],
"WC" : [ Bank("1A", "S2") ],
"SA" : [ Bank("1A", "W1") ],
"SB" : [ Bank("1A", "W2"), Bank("1B", "W2"), Bank("2A", "W2"), Bank("2B", "W2") ]
}
}, { # non existing pins
"FBGA324" : [
"IO_SB_A0","IO_SB_B0",
"IO_SB_A1","IO_SB_B1",
"IO_SB_A2","IO_SB_B2",
"IO_SB_A3","IO_SB_B3"
]
}),
2024-12-27 09:01:22 +01:00
}
def get_all_devices():
return CCGM1_DEVICES
def get_device(name):
return CCGM1_DEVICES[name]