File size: 4,881 Bytes
fe51a63
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
diff --git a/tt_metal/hw/toolchain/main.ld b/tt_metal/hw/toolchain/main.ld
index 8cee67693d8..03732862192 100644
--- a/tt_metal/hw/toolchain/main.ld
+++ b/tt_metal/hw/toolchain/main.ld
@@ -306,7 +306,8 @@ SECTIONS
     LONG(TEXT_SIZE
 #if defined(TYPE_KERNEL) && !(defined(COMPILE_FOR_NCRISC) && defined(ARCH_WORMHOLE)) \
     && !defined(COMPILE_FOR_AERISC) && !defined(COMPILE_FOR_SUBORDINATE_AERISC) \
-    && !defined(COMPILE_FOR_MAIN_AERISC)
+    && !defined(COMPILE_FOR_MAIN_AERISC) \
+    && !(defined(ARCH_BLACKHOLE) && (defined(COMPILE_FOR_IERISC) || defined(COMPILE_FOR_SUBORDINATE_IERISC)))
          - (__fw_export_text_end - TEXT_START)
 #endif
          )
diff --git a/tt_metal/impl/dispatch/dispatch_query_manager.cpp b/tt_metal/impl/dispatch/dispatch_query_manager.cpp
index 38c31376178..fef7bafe6cd 100644
--- a/tt_metal/impl/dispatch/dispatch_query_manager.cpp
+++ b/tt_metal/impl/dispatch/dispatch_query_manager.cpp
@@ -148,6 +148,15 @@ void DispatchQueryManager::reset(DispatchCoreConfig& dispatch_core_config, uint8
             (num_hw_cqs == 1 or dispatch_core_config_.get_dispatch_core_type() == DispatchCoreType::WORKER);
         distributed_dispatcher_ =
             (num_hw_cqs == 1 and dispatch_core_config_.get_dispatch_core_type() == DispatchCoreType::ETH);
+        // Blackhole ETH dispatch with 1 CQ needs 3 idle ETH cores (prefetch, dispatch, dispatch_s).
+        // Galaxy BH chips only have 2 idle ETH cores (the rest are trained links), so fall back to
+        // running without dispatch_s (dispatch_d sends go signals), which needs only 2 cores.
+        if (arch == tt::ARCH::BLACKHOLE and num_hw_cqs == 1 and
+            dispatch_core_config_.get_dispatch_core_type() == DispatchCoreType::ETH and
+            populate_all_logical_dispatch_cores(env_, num_hw_cqs_, dispatch_core_config_).size() < 3) {
+            dispatch_s_enabled_ = false;
+            distributed_dispatcher_ = false;
+        }
     }
 
     go_signal_noc_ = (dispatch_s_enabled_ and arch != tt::ARCH::QUASAR) ? NOC::NOC_1 : NOC::NOC_0;
diff --git a/tt_metal/impl/dispatch/topology.cpp b/tt_metal/impl/dispatch/topology.cpp
index 3dc6377b652..813787a2bf5 100644
--- a/tt_metal/impl/dispatch/topology.cpp
+++ b/tt_metal/impl/dispatch/topology.cpp
@@ -130,6 +130,12 @@ static const std::vector<DispatchKernelNode> single_chip_arch_1cq = {
     {2, 0, 0, 0, DISPATCH_S, {0, x, x, x}, {1, x, x, x}, k_dispatcher_s_noc},
 };
 
+// 1 CQ without dispatch_s (used for Blackhole ETH dispatch when only 2 idle ETH cores exist)
+static const std::vector<DispatchKernelNode> single_chip_arch_1cq_no_dispatch_s = {
+    {0, 0, 0, 0, PREFETCH_HD, {x, x, x, x}, {1, x, x, x}, k_prefetcher_noc},
+    {1, 0, 0, 0, DISPATCH_HD, {0, x, x, x}, {x, x, x, x}, k_dispatcher_noc},
+};
+
 static const std::vector<DispatchKernelNode> single_chip_arch_2cq = {
     {0, 0, 0, 0, PREFETCH_HD, {x, x, x, x}, {2, x, x, x}, k_prefetcher_noc},
     {1, 0, 0, 1, PREFETCH_HD, {x, x, x, x}, {3, x, x, x}, k_prefetcher_noc},
@@ -464,7 +470,13 @@ std::vector<DispatchKernelNode> DispatchTopology::generate_nodes(
     auto populate_single_device = [&]() {
         const bool is_quasar = this->descriptor_.cluster().arch() == tt::ARCH::QUASAR;
         if (num_hw_cqs == 1) {
-            return is_quasar ? quasar_single_chip_1cq : single_chip_arch_1cq;
+            if (is_quasar) {
+                return quasar_single_chip_1cq;
+            }
+            if (!this->get_dispatch_query_manager_().dispatch_s_enabled()) {
+                return single_chip_arch_1cq_no_dispatch_s;
+            }
+            return single_chip_arch_1cq;
         }
         if (is_quasar) {
             return quasar_single_chip_2cq;
diff --git a/tt_metal/llrt/core_descriptor.cpp b/tt_metal/llrt/core_descriptor.cpp
index 0ada4eff2f0..1a2358d6cf7 100644
--- a/tt_metal/llrt/core_descriptor.cpp
+++ b/tt_metal/llrt/core_descriptor.cpp
@@ -290,6 +290,13 @@ const tt::core_descriptor_t& MetalEnvImpl::get_core_descriptor_config(
             coord = RelativeCoreCoord({.x = core_node[0].as<int>(), .y = core_node[1].as<int>()});
             if (get_core_type_from_config(dispatch_core_config) == CoreType::ETH) {
                 auto logical_coord = get_core_coord_from_relative(coord, grid_size);
+                // Skip ETH dispatch entries that do not exist on this chip (harvested ETH cores, e.g.
+                // Blackhole Galaxy chips expose fewer than the 14 ETH cores listed in the YAML).
+                const size_t num_logical_eth_cores =
+                    get_cluster().get_soc_desc(device_id).get_cores(CoreType::ETH, CoordSystem::LOGICAL).size();
+                if (logical_coord.y >= num_logical_eth_cores) {
+                    continue;
+                }
                 if (logical_active_eth_cores.contains(logical_coord)) {
                     continue;
                 }