190 lines
4.9 KiB
Python
190 lines
4.9 KiB
Python
from __future__ import annotations
|
|
|
|
from dataclasses import dataclass
|
|
|
|
from typing import Dict, Any, List, Optional, Tuple
|
|
from enum import Enum
|
|
|
|
|
|
@dataclass
|
|
class TracerVConfig:
|
|
enable: bool
|
|
select: str
|
|
start: str
|
|
end: str
|
|
output_format: str
|
|
|
|
def __init__(self, args: Dict[str, Any]) -> None:
|
|
self.enable = args.get("enable", False) == True
|
|
self.select = args.get("selector", "0")
|
|
self.start = args.get("start", "0")
|
|
self.end = args.get("end", "-1")
|
|
self.output_format = args.get("output_format", "0")
|
|
|
|
|
|
@dataclass
|
|
class AutoCounterConfig:
|
|
readrate: int
|
|
|
|
def __init__(self, args: Dict[str, Any]) -> None:
|
|
self.readrate = int(args.get("read_rate", "0"))
|
|
|
|
|
|
@dataclass
|
|
class HostDebugConfig:
|
|
zero_out_dram: bool
|
|
disable_synth_asserts: bool
|
|
|
|
def __init__(self, args: Dict[str, Any]) -> None:
|
|
self.zero_out_dram = args.get("zero_out_dram", False) == True
|
|
self.disable_synth_asserts = args.get("disable_synth_asserts", False) == True
|
|
|
|
|
|
@dataclass
|
|
class SynthPrintConfig:
|
|
start: str
|
|
end: str
|
|
cycle_prefix: bool
|
|
|
|
def __init__(self, args: Dict[str, Any]) -> None:
|
|
self.start = args.get("start", "0")
|
|
self.end = args.get("end", "-1")
|
|
self.cycle_prefix = args.get("cycle_prefix", True) == True
|
|
|
|
|
|
class FireAxeNodeBridgePair:
|
|
"""
|
|
pidx : partition index of the node
|
|
bidx : bridge index
|
|
"""
|
|
|
|
pidx: int
|
|
bidx: int
|
|
|
|
def __init__(self, pidx: int, bidx: int) -> None:
|
|
self.pidx = pidx
|
|
self.bidx = bidx
|
|
|
|
|
|
class FireAxeEdge:
|
|
"""
|
|
Connects two `FireAxeNodeBridgePair`s u, v
|
|
"""
|
|
|
|
u: FireAxeNodeBridgePair
|
|
v: FireAxeNodeBridgePair
|
|
|
|
def __init__(self, u: FireAxeNodeBridgePair, v: FireAxeNodeBridgePair) -> None:
|
|
self.u = u
|
|
self.v = v
|
|
|
|
|
|
class PartitionMode(Enum):
|
|
FAST_MODE = 0
|
|
EXACT_MODE = 1
|
|
NOC_MODE = 2
|
|
|
|
|
|
class PartitionNode:
|
|
"""
|
|
Partitioning information for a single FireSimServerNode
|
|
hwdb : FireSimHWDB
|
|
pidx : partition index
|
|
edges : my_bridge -> (neighbor_bridge, neighbor_node)
|
|
"""
|
|
|
|
hwdb: str
|
|
pidx: int
|
|
edges: Dict[int, Tuple[int, PartitionNode]]
|
|
|
|
def __init__(self, hwdb: str, pidx: int) -> None:
|
|
self.hwdb = hwdb
|
|
self.pidx = pidx
|
|
self.edges = dict()
|
|
|
|
def sort_edges_by_bridge_idx(self) -> None:
|
|
self.edges = dict(sorted(self.edges.items()))
|
|
|
|
def add_edge(self, bidx: int, nbidx: int, node: PartitionNode) -> None:
|
|
self.edges[bidx] = (nbidx, node)
|
|
self.sort_edges_by_bridge_idx()
|
|
|
|
|
|
@dataclass
|
|
class PartitionConfig:
|
|
"""
|
|
Provides information to a FireSimServerNode about the global partitioning topology
|
|
"""
|
|
|
|
node: Optional[PartitionNode]
|
|
fpga_cnt: int
|
|
pidx_to_slotid: Dict[int, int]
|
|
pcim_slot_offset: List[Tuple[int, int]] # slotid, bridge offset of neighbor
|
|
mode: PartitionMode
|
|
|
|
def __init__(
|
|
self,
|
|
node: Optional[PartitionNode] = None,
|
|
pidx_to_slotid: Dict[int, int] = dict(),
|
|
mode: PartitionMode = PartitionMode.FAST_MODE,
|
|
) -> None:
|
|
self.node = node
|
|
self.fpga_cnt = max(len(pidx_to_slotid.keys()), 1)
|
|
self.pidx_to_slotid = pidx_to_slotid
|
|
self.pcim_slot_offset = list()
|
|
self.mode = mode
|
|
|
|
def get_hwdb(self) -> str:
|
|
assert self.node is not None
|
|
return self.node.hwdb
|
|
|
|
def get_edges(self) -> Dict[int, Tuple[int, PartitionNode]]:
|
|
assert self.node is not None
|
|
return self.node.edges
|
|
|
|
def add_pcim_slot_offset(self, slot: int, offset: int) -> None:
|
|
self.pcim_slot_offset.append((slot, offset))
|
|
|
|
def is_base(self) -> bool:
|
|
if self.node is None:
|
|
return True
|
|
else:
|
|
return self.node.pidx == (self.fpga_cnt - 1)
|
|
|
|
def is_partitioned(self) -> bool:
|
|
return self.fpga_cnt > 1
|
|
|
|
def batch_size(self) -> int:
|
|
if self.mode == PartitionMode.FAST_MODE:
|
|
return 1
|
|
elif (self.mode == PartitionMode.EXACT_MODE) or (
|
|
self.mode == PartitionMode.NOC_MODE
|
|
):
|
|
return 0
|
|
else:
|
|
print(f"Unrecognized partition mode {self.mode}")
|
|
exit(1)
|
|
|
|
def metasim_partition_topo_args(self) -> int:
|
|
if (
|
|
(self.mode == PartitionMode.FAST_MODE)
|
|
or (self.mode == PartitionMode.EXACT_MODE)
|
|
or (self.mode == PartitionMode.NOC_MODE)
|
|
):
|
|
return self.mode.value
|
|
else:
|
|
print("Unrecognized topology")
|
|
exit(1)
|
|
|
|
def mac_address_assignable(self) -> bool:
|
|
return (not self.is_partitioned()) or (self.is_partitioned() and self.is_base())
|
|
|
|
def leaf_partition(self) -> bool:
|
|
return self.is_partitioned() and (not self.is_base())
|
|
|
|
def get_pcim_slot_and_bridge_offsets(self) -> List[str]:
|
|
return [
|
|
f"{slotid},{bridgeoffset}"
|
|
for (slotid, bridgeoffset) in self.pcim_slot_offset
|
|
]
|