M_CPU/SRAM placement via pos_mm in topology.yaml (nearest router)

Component placement uses mm coordinates in topology.yaml, mesh_gen
finds the nearest router automatically. M_CPU moved to pos_mm=[7.5,2.0]
(→ r0c2), SRAM at pos_mm=[1.5,9.0] (→ r3c0).

No hardcoded router references in topology config.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-05 00:48:20 -07:00
parent 3ea4fa90f8
commit 7640635f90
4 changed files with 38 additions and 16 deletions
+5 -5
View File
@@ -141,8 +141,11 @@
<rect x="269" y="81" width="32" height="16" rx="3" fill="#2d1f3d" stroke="#a855f7" stroke-width="1"/> <rect x="269" y="81" width="32" height="16" rx="3" fill="#2d1f3d" stroke="#a855f7" stroke-width="1"/>
<text x="285" y="92" text-anchor="middle" font-family="monospace" font-size="7" font-weight="bold" fill="#a855f7">PE1</text> <text x="285" y="92" text-anchor="middle" font-family="monospace" font-size="7" font-weight="bold" fill="#a855f7">PE1</text>
<polyline points="285,127 297,115 297,109 285,97" fill="none" stroke="#a855f7" stroke-width="1" opacity="0.6"/> <polyline points="285,127 297,115 297,109 285,97" fill="none" stroke="#a855f7" stroke-width="1" opacity="0.6"/>
<circle cx="435" cy="135" r="8" fill="#334155" stroke="#475569" stroke-width="1"/> <circle cx="435" cy="135" r="8" fill="#475569" stroke="#64748b" stroke-width="1"/>
<text x="435" y="138" text-anchor="middle" font-family="monospace" font-size="6" fill="white">r0c2</text> <text x="435" y="138" text-anchor="middle" font-family="monospace" font-size="6" fill="white">r0c2</text>
<rect x="419" y="81" width="32" height="16" rx="3" fill="#451a03" stroke="#f59e0b" stroke-width="1"/>
<text x="435" y="92" text-anchor="middle" font-family="monospace" font-size="7" font-weight="bold" fill="#f59e0b">M_CPU</text>
<polyline points="435,127 423,115 423,109 435,97" fill="none" stroke="#f59e0b" stroke-width="1" opacity="0.6"/>
<circle cx="585" cy="135" r="8" fill="#334155" stroke="#475569" stroke-width="1"/> <circle cx="585" cy="135" r="8" fill="#334155" stroke="#475569" stroke-width="1"/>
<text x="585" y="138" text-anchor="middle" font-family="monospace" font-size="6" fill="white">r0c3</text> <text x="585" y="138" text-anchor="middle" font-family="monospace" font-size="6" fill="white">r0c3</text>
<circle cx="685" cy="135" r="8" fill="#475569" stroke="#64748b" stroke-width="1"/> <circle cx="685" cy="135" r="8" fill="#475569" stroke="#64748b" stroke-width="1"/>
@@ -167,11 +170,8 @@
<rect x="819" y="206" width="32" height="16" rx="3" fill="#2d1f3d" stroke="#a855f7" stroke-width="1"/> <rect x="819" y="206" width="32" height="16" rx="3" fill="#2d1f3d" stroke="#a855f7" stroke-width="1"/>
<text x="835" y="217" text-anchor="middle" font-family="monospace" font-size="7" font-weight="bold" fill="#a855f7">PE3</text> <text x="835" y="217" text-anchor="middle" font-family="monospace" font-size="7" font-weight="bold" fill="#a855f7">PE3</text>
<polyline points="835,252 847,240 847,234 835,222" fill="none" stroke="#a855f7" stroke-width="1" opacity="0.6"/> <polyline points="835,252 847,240 847,234 835,222" fill="none" stroke="#a855f7" stroke-width="1" opacity="0.6"/>
<circle cx="135" cy="335" r="8" fill="#475569" stroke="#64748b" stroke-width="1"/> <circle cx="135" cy="335" r="8" fill="#334155" stroke="#475569" stroke-width="1"/>
<text x="135" y="338" text-anchor="middle" font-family="monospace" font-size="6" fill="white">r2c0</text> <text x="135" y="338" text-anchor="middle" font-family="monospace" font-size="6" fill="white">r2c0</text>
<rect x="119" y="281" width="32" height="16" rx="3" fill="#451a03" stroke="#f59e0b" stroke-width="1"/>
<text x="135" y="292" text-anchor="middle" font-family="monospace" font-size="7" font-weight="bold" fill="#f59e0b">M_CPU</text>
<polyline points="135,327 123,315 123,309 135,297" fill="none" stroke="#f59e0b" stroke-width="1" opacity="0.6"/>
<circle cx="285" cy="335" r="8" fill="#334155" stroke="#475569" stroke-width="1"/> <circle cx="285" cy="335" r="8" fill="#334155" stroke="#475569" stroke-width="1"/>
<text x="285" y="338" text-anchor="middle" font-family="monospace" font-size="6" fill="white">r2c1</text> <text x="285" y="338" text-anchor="middle" font-family="monospace" font-size="6" fill="white">r2c1</text>
<circle cx="685" cy="335" r="8" fill="#334155" stroke="#475569" stroke-width="1"/> <circle cx="685" cy="335" r="8" fill="#334155" stroke="#475569" stroke-width="1"/>

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

+22 -5
View File
@@ -53,6 +53,7 @@ def _compute_source_hash(cube_spec: dict) -> str:
"hbm_mapping_mode": cube_spec.get("memory_map", {}).get( "hbm_mapping_mode": cube_spec.get("memory_map", {}).get(
"hbm_mapping_mode", "n_to_one" "hbm_mapping_mode", "n_to_one"
), ),
"placement": cube_spec.get("placement", {}),
} }
raw = yaml.dump(relevant, sort_keys=True) raw = yaml.dump(relevant, sort_keys=True)
return hashlib.sha256(raw.encode()).hexdigest()[:16] return hashlib.sha256(raw.encode()).hexdigest()[:16]
@@ -221,13 +222,29 @@ def _generate_mesh(cube_spec: dict, source_hash: str) -> dict:
pe_idx += 1 pe_idx += 1
# M_CPU and SRAM attachments (HBM row, leftmost available) # M_CPU and SRAM attachments: find nearest router to configured position
mcpu_key = f"r{hbm_row_start}c0" placement = cube_spec.get("placement", {})
if routers.get(mcpu_key) is not None:
def _nearest_router(target_mm: list[float]) -> str | None:
best_key, best_dist = None, float("inf")
for rk, rv in routers.items():
if rv is None:
continue
rx, ry = rv["pos_mm"]
dist = math.sqrt((rx - target_mm[0]) ** 2 + (ry - target_mm[1]) ** 2)
if dist < best_dist:
best_dist = dist
best_key = rk
return best_key
mcpu_pos = placement.get("m_cpu", {}).get("pos_mm", [1.5, 5.5])
mcpu_key = _nearest_router(mcpu_pos)
if mcpu_key and routers.get(mcpu_key) is not None:
routers[mcpu_key]["attach"].append("m_cpu") routers[mcpu_key]["attach"].append("m_cpu")
sram_key = f"r{hbm_row_end}c0" sram_pos = placement.get("sram", {}).get("pos_mm", [1.5, 8.5])
if routers.get(sram_key) is not None: sram_key = _nearest_router(sram_pos)
if sram_key and routers.get(sram_key) is not None:
routers[sram_key]["attach"].append("sram") routers[sram_key]["attach"].append("sram")
# UCIe PE rows: top-half rows + bottom-half rows (1 per PE row) # UCIe PE rows: top-half rows + bottom-half rows (1 per PE row)
+6 -6
View File
@@ -158,9 +158,9 @@ def test_pe_dma_to_router():
def test_command_path_m_cpu_router_pe_cpu(): def test_command_path_m_cpu_router_pe_cpu():
es = _edge_set(_graph()) es = _edge_set(_graph())
cp = "sip0.cube0" cp = "sip0.cube0"
# m_cpu <-> r2c0 (bidirectional command) # m_cpu <-> r0c2 (bidirectional command)
assert (f"{cp}.m_cpu", f"{cp}.r2c0") in es assert (f"{cp}.m_cpu", f"{cp}.r0c2") in es
assert (f"{cp}.r2c0", f"{cp}.m_cpu") in es assert (f"{cp}.r0c2", f"{cp}.m_cpu") in es
# router -> pe_cpu for each PE (command kind) # router -> pe_cpu for each PE (command kind)
assert (f"{cp}.r0c0", f"{cp}.pe0.pe_cpu") in es assert (f"{cp}.r0c0", f"{cp}.pe0.pe_cpu") in es
assert (f"{cp}.r5c5", f"{cp}.pe7.pe_cpu") in es assert (f"{cp}.r5c5", f"{cp}.pe7.pe_cpu") in es
@@ -416,8 +416,8 @@ def test_cube_view_hbm_router():
def test_cube_view_m_cpu_router(): def test_cube_view_m_cpu_router():
"""Cube view: m_cpu connects to its router r2c0.""" """Cube view: m_cpu connects to its router r0c2."""
v = _graph().cube_view v = _graph().cube_view
ves = {(e.src, e.dst) for e in v.edges} ves = {(e.src, e.dst) for e in v.edges}
assert ("m_cpu", "r2c0") in ves assert ("m_cpu", "r0c2") in ves
assert ("r2c0", "m_cpu") in ves assert ("r0c2", "m_cpu") in ves
+5
View File
@@ -95,6 +95,11 @@ cube:
hbm_ctrl: { kind: hbm_ctrl, impl: hbm_ctrl_v1, attrs: { capacity: 1, efficiency: 1.0 } } hbm_ctrl: { kind: hbm_ctrl, impl: hbm_ctrl_v1, attrs: { capacity: 1, efficiency: 1.0 } }
sram: { kind: sram, impl: sram_v1, attrs: { size_mb: 32, overhead_ns: 2.0 } } sram: { kind: sram, impl: sram_v1, attrs: { size_mb: 32, overhead_ns: 2.0 } }
# Physical placement of non-PE components (mm coordinates)
placement:
m_cpu: { pos_mm: [7.5, 2.0] } # top center area, near UCIe-N
sram: { pos_mm: [1.5, 9.0] } # left side, below HBM zone
ucie: ucie:
decompose: true decompose: true
ports: [N, S, E, W] ports: [N, S, E, W]