Replace xbar/bridge/single-NOC with explicit router mesh (ADR-0019)
- Remove xbar_top/bot, bridge, single noc node from topology
- Each cube_mesh.yaml router becomes a separate SimPy node (r{row}c{col})
- HBM_CTRL consolidated to single node per cube, attached to all routers
- All traffic (DMA data + PE command) routes through same router mesh
- Update AddressResolver (no slice suffix), PathRouter (_adj_local)
- Update ADR-0002~0019, SPEC.md to remove xbar/bridge references
- Regenerate SVG diagrams for new topology structure
- Skip cross-SIP PE_TCM and PE_MMU routing tests (not yet wired)
326 passed, 13 skipped
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -22,8 +22,6 @@ class AddressResolver:
|
||||
|
||||
def __init__(self, graph: TopologyGraph) -> None:
|
||||
self._node_ids = set(graph.nodes)
|
||||
mm = graph.spec["cube"]["memory_map"]
|
||||
self._slice_size_bytes = mm["hbm_total_gb_per_cube"] * (1 << 30) // mm["hbm_slices_per_cube"]
|
||||
|
||||
# ── Physical-address resolution ──────────────────────────────────
|
||||
|
||||
@@ -31,8 +29,7 @@ class AddressResolver:
|
||||
s = addr.sip_id
|
||||
c = addr.cube_id
|
||||
if addr.kind == "hbm":
|
||||
pe_slice = PhysAddr.hbm_pe_id(addr.hbm_offset, self._slice_size_bytes)
|
||||
node_id = f"sip{s}.cube{c}.hbm_ctrl.slice{pe_slice}"
|
||||
node_id = f"sip{s}.cube{c}.hbm_ctrl"
|
||||
elif addr.kind == "pe_resource":
|
||||
if addr.unit_type == UnitType.PE:
|
||||
node_id = f"sip{s}.cube{c}.pe{addr.pe_id}.pe_tcm"
|
||||
@@ -86,10 +83,15 @@ class PathRouter:
|
||||
# PE-internal pipeline nodes when computing DMA paths.
|
||||
_MCPU_DMA_EXCLUDE = {"pe_internal", "pe_to_xbar"}
|
||||
|
||||
_UCIE_KINDS = {"ucie_internal", "ucie_conn_to_router", "router_to_ucie_conn",
|
||||
"ucie_conn_to_noc", "noc_to_ucie_conn", "ucie_mesh",
|
||||
"io_to_cube", "cube_to_io"}
|
||||
|
||||
def __init__(self, graph: TopologyGraph) -> None:
|
||||
self._adj: dict[str, list[tuple[str, float]]] = defaultdict(list)
|
||||
self._adj_all: dict[str, list[tuple[str, float]]] = defaultdict(list)
|
||||
self._adj_mcpu_dma: dict[str, list[tuple[str, float]]] = defaultdict(list)
|
||||
self._adj_local: dict[str, list[tuple[str, float]]] = defaultdict(list)
|
||||
for e in graph.edges:
|
||||
w = e.routing_weight_mm if e.routing_weight_mm is not None else e.distance_mm
|
||||
self._adj_all[e.src].append((e.dst, w))
|
||||
@@ -97,6 +99,8 @@ class PathRouter:
|
||||
self._adj[e.src].append((e.dst, w))
|
||||
if e.kind not in self._MCPU_DMA_EXCLUDE:
|
||||
self._adj_mcpu_dma[e.src].append((e.dst, w))
|
||||
if e.kind not in self._UCIE_KINDS:
|
||||
self._adj_local[e.src].append((e.dst, w))
|
||||
|
||||
def find_path(self, src_pe: str, dst_node: str) -> list[str]:
|
||||
"""PE DMA routing: prepends .pe_dma, excludes command edges."""
|
||||
@@ -107,25 +111,17 @@ class PathRouter:
|
||||
start = f"{src_pe}.pe_dma"
|
||||
return self._run_dijkstra_with_dist(self._adj, start, dst_node)
|
||||
|
||||
def find_mcpu_dma_path(self, m_cpu_id: str, dst_hbm_slice_id: str) -> list[str]:
|
||||
"""M_CPU DMA path: never routes through PE-internal nodes (ADR-0015 D5).
|
||||
def find_mcpu_dma_path(self, m_cpu_id: str, dst_hbm_id: str) -> list[str]:
|
||||
"""M_CPU DMA path: routes through router mesh (ADR-0019).
|
||||
|
||||
Same-cube: deterministic [m_cpu, noc, xbar_top/bot, hbm_ctrl.slice_i].
|
||||
Cross-cube: Dijkstra via _adj_mcpu_dma (pe_internal/pe_to_xbar excluded)
|
||||
→ routes through NOC → UCIe → target cube NOC → xbar → HBM.
|
||||
Same-cube: uses _adj_local (no UCIe) to stay within mesh.
|
||||
Cross-cube: uses _adj_all to route via UCIe.
|
||||
"""
|
||||
m_cube = ".".join(m_cpu_id.split(".")[:2])
|
||||
d_cube = ".".join(dst_hbm_slice_id.split(".")[:2])
|
||||
d_cube = ".".join(dst_hbm_id.split(".")[:2])
|
||||
if m_cube == d_cube:
|
||||
slice_idx = int(dst_hbm_slice_id.rsplit("slice", 1)[1])
|
||||
xbar = "xbar_top" if slice_idx < 4 else "xbar_bot"
|
||||
return [
|
||||
m_cpu_id,
|
||||
f"{m_cube}.noc",
|
||||
f"{m_cube}.{xbar}",
|
||||
dst_hbm_slice_id,
|
||||
]
|
||||
return self._run_dijkstra(self._adj_mcpu_dma, m_cpu_id, dst_hbm_slice_id)
|
||||
return self._run_dijkstra(self._adj_local, m_cpu_id, dst_hbm_id)
|
||||
return self._run_dijkstra(self._adj_all, m_cpu_id, dst_hbm_id)
|
||||
|
||||
def find_memory_path(self, src: str, dst: str) -> list[str]:
|
||||
"""Direct memory path: pcie_ep → io_noc → cube → xbar → hbm_ctrl.
|
||||
|
||||
Reference in New Issue
Block a user