Skip to content

Commit 52d3776

Browse files
update
1 parent 454cada commit 52d3776

36 files changed

+17844
-11269
lines changed

FABulous/FABulous.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ def main():
146146

147147
args = parser.parse_args()
148148

149-
setup_logger(args.verbose)
149+
setup_logger(args.verbose, True)
150150

151151
setup_global_env_vars(args)
152152

FABulous/FABulous_CLI/helper.py

Lines changed: 39 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -13,35 +13,51 @@
1313

1414
MAX_BITBYTES = 16384
1515

16+
def setup_logger(verbosity: int, debug: bool, log_file: Path = Path()):
17+
# Remove the default logger to avoid duplicate logs
18+
logger.remove()
1619

17-
def error_callback(msg):
18-
raise Exception
20+
# Define a custom formatting function that has access to 'verbosity'
21+
def custom_format_function(record):
22+
# Construct the standard part of the log message based on verbosity
23+
level = f"<level>{record['level'].name}</level> | "
24+
time = f"<cyan>[{record['time']:DD-MM-YYYY HH:mm:ss}]</cyan> | "
25+
name = f"<green>[{record['name']}</green>"
26+
func = f"<green>{record['function']}</green>"
27+
line = f"<green>{record['line']}</green>"
28+
msg = f"<level>{record['message']}</level>"
29+
exc = (
30+
f"<bg red><white>{record['exception'].type.__name__}</white></bg red> | "
31+
if record["exception"]
32+
else ""
33+
)
1934

35+
if verbosity >= 1:
36+
final_log = f"{level}{time}{name}:{func}:{line} - {exc}{msg}\n"
37+
else:
38+
final_log = f"{level}{exc}{msg}\n"
2039

21-
def setup_logger(verbosity: int):
22-
# Remove the default logger to avoid duplicate logs
23-
logger.remove()
40+
if os.getenv("FABULOUS_TESTING", None):
41+
final_log = f"{record['level'].name}: {record['message']}\n"
42+
43+
return final_log
44+
45+
# Determine the log level for the sink
46+
log_level_to_set = "DEBUG" if debug else "INFO"
2447

25-
# Define logger format
26-
if verbosity >= 1:
27-
log_format = (
28-
"<level>{level:}</level> | "
29-
"<cyan>[{time:DD-MM-YYYY HH:mm:ss]}</cyan> | "
30-
"<green>[{name}</green>:<green>{function}</green>:<green>{line}]</green> - "
31-
"<level>{message}</level>"
48+
# Add logger to write logs to stdout using the custom formatter
49+
if log_file != Path():
50+
logger.add(
51+
log_file, format=custom_format_function, level=log_level_to_set, catch=False
3252
)
3353
else:
34-
log_format = "<level>{level:}</level> | <level>{message}</level>"
35-
36-
# Add logger to write logs to stdout
37-
logger.add(sys.stdout, format=log_format, level="DEBUG", colorize=True, catch=False)
38-
logger.add(
39-
error_callback,
40-
format=log_format,
41-
colorize=True,
42-
catch=False,
43-
filter=lambda msg: msg["level"].name == "ERROR",
44-
)
54+
logger.add(
55+
sys.stdout,
56+
format=custom_format_function,
57+
level=log_level_to_set,
58+
colorize=True,
59+
catch=False,
60+
)
4561

4662

4763
def setup_global_env_vars(args: argparse.Namespace) -> None:

FABulous/fabric_cad/chip_database_generator.py

Lines changed: 37 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from collections import defaultdict
12
from itertools import islice
23
from pathlib import Path
34
from subprocess import run
@@ -11,6 +12,7 @@
1112
from FABulous.fabric_cad.chip_database.database_timing import TimingValue
1213
from FABulous.fabric_cad.chip_database.define import NodeWire, PinType
1314
from FABulous.fabric_cad.graph_draw import genRoutingResourceGraph
15+
from FABulous.fabric_definition.Wire import WireType
1416
from FABulous.fabric_definition.define import IO, Loc
1517
from FABulous.fabric_definition.Fabric import Fabric
1618
from FABulous.fabric_definition.Port import BelPort, TilePort
@@ -249,37 +251,52 @@ def genTile(tile: Tile, subTile: str, chip: Chip, context=1) -> TileType:
249251
return tt
250252

251253

252-
# change to base on wire type
254+
# TODO: fix for terminal ports
253255
def genFabric(fabric: Fabric, chip: Chip, context=1):
254256
def clipX(value):
255257
return max(0, min(value, fabric.width - 1))
256258

257259
def clipY(value):
258260
return max(0, min(value, fabric.height - 1))
259-
260-
# TODO fix terminal ports
261-
for (x, y), wires in fabric.wireDict.items():
262-
if not wires:
261+
262+
for (x, y), tileName in fabric.tileNames_iter():
263+
if tileName is None:
263264
continue
264-
for c in range(context):
265-
for wire in wires:
266-
for src, dst in zip(wire.source.expand(), wire.destination.expand()):
267-
node = [
268-
NodeWire(
265+
266+
tile = fabric.getTileByName(tileName)
267+
print(tileName)
268+
shareDest:dict[TilePort | BelPort, list[WireType]] = defaultdict(list)
269+
for wireType in tile.wireTypes[tileName]:
270+
assert wireType.destinationPort.width == wireType.sourcePort.width
271+
shareDest[wireType.sourcePort].append(wireType)
272+
273+
print(shareDest)
274+
for src, destList in shareDest.items():
275+
nodes = []
276+
for c in range(context):
277+
for n in src.expand():
278+
nodes.append(
279+
[NodeWire(
269280
clipX(x),
270281
clipY(y),
271-
f"c{c}.{src}",
272-
),
273-
NodeWire(
274-
clipX(x + wire.xOffset),
275-
clipY(y + wire.yOffset),
276-
f"c{c}.{dst}",
277-
),
278-
]
279-
chip.add_node(node, "DEFAULT")
282+
f"c{c}.{n}",
283+
)]
284+
)
285+
print(destList)
286+
for dest in destList:
287+
for i, n in enumerate(dest.destinationPort.expand()):
288+
nodes[i].append(
289+
NodeWire(
290+
clipX(x + dest.offsetX),
291+
clipY(y + dest.offsetY),
292+
f"c{c}.{n}",
293+
)
294+
)
295+
for node in nodes:
296+
print(node)
297+
chip.add_node(node, "DEFAULT")
280298
setTiming(chip)
281299

282-
283300
def setTiming(chip: Chip):
284301
speed = "DEFAULT"
285302
tmg = chip.set_speed_grades([speed])

FABulous/fabric_definition/Fabric.py

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ class Fabric:
7878
superTileDict: dict[str, SuperTile] = field(default_factory=dict)
7979
wireDict: dict[Loc, list[Wire]] = field(default_factory=dict)
8080

81+
_subTileToTile: dict[str, Tile] = field(init=False, default_factory=dict)
82+
8183
def __post_init__(self):
8284
for t in self.tileDict.values():
8385
if (
@@ -87,11 +89,24 @@ def __post_init__(self):
8789
raise ValueError(
8890
f"Tile {t.name} has too many config bits. Tile have {self.frameBitsPerRow * self.maxFramesPerCol} but requires {t.configBits*self.contextCount}"
8991
)
92+
93+
for t in self.tileDict.values():
94+
for subTile in t.getSubTiles():
95+
if subTile not in self._subTileToTile:
96+
self._subTileToTile[subTile] = t
97+
else:
98+
raise ValueError(
99+
f"Subtile {subTile} is defined in multiple tiles: {self._subTileToTile[subTile].name} and {t.name}"
100+
)
90101

91102
def __getitem__(self, index: Any) -> Tile | None:
92103
if isinstance(index, tuple):
93104
if t := self.tiles[index[1]][index[0]]:
94-
return self.tileDict[t]
105+
if t in self.tileDict:
106+
return self.tileDict[t]
107+
else:
108+
return self._subTileToTile[t]
109+
95110
return None
96111
if isinstance(index, str):
97112
if index in self.tileDict:
@@ -210,6 +225,18 @@ def getBelByBelPort(self, p: BelPort) -> Bel:
210225
if tile.isPortInTile(p):
211226
return tile.getBelByBelPort(p)
212227
raise ValueError(f"BelPort {p} not found in any tile")
228+
229+
def isSubTile(self, name: str) -> bool:
230+
"""Check if the given name is a sub-tile in the fabric."""
231+
return name in self._subTileToTile
232+
233+
def isRootTile(self, name: str) -> bool:
234+
for tile in self.tileDict.values():
235+
if tile is not None and tile.partOfTile(name):
236+
return tile.isRootTile(name)
237+
return False
238+
239+
213240

214241

215242
# def getFlattenFabric(self) -> Generator[tuple[Loc, Tile | None], None, None]:

0 commit comments

Comments
 (0)