@@ -1219,5 +1219,62 @@ TEST_F(TileGeneratorTest, SerializeTechResponseContainsBlockName)
12191219 << " tech response missing block name value \" top\" ; got: " << json;
12201220}
12211221
1222+ TEST_F (TileGeneratorTest, LayerHierarchyBacksideCategory)
1223+ {
1224+ odb::dbTech* tech = getDb ()->getTech ();
1225+
1226+ // Mark metal1 and via1 as backside.
1227+ tech->findLayer (" metal1" )->setBackside (true );
1228+ tech->findLayer (" via1" )->setBackside (true );
1229+
1230+ makeTileGen ();
1231+ const auto resp = serializeTechResponse (*tile_gen_);
1232+ ASSERT_TRUE (resp.contains (" layer_hierarchy" ));
1233+ const auto & hier = resp.at (" layer_hierarchy" ).as_object ();
1234+
1235+ // Top-level layers should NOT contain the backside layers.
1236+ const auto & top_layers = hier.at (" layers" ).as_array ();
1237+ for (const auto & l : top_layers) {
1238+ const auto & name = l.as_object ().at (" name" ).as_string ();
1239+ EXPECT_NE (name, " metal1" ) << " backside metal1 should not be at top level" ;
1240+ EXPECT_NE (name, " via1" ) << " backside via1 should not be at top level" ;
1241+ }
1242+
1243+ // A "Backside" category node should exist in instances.
1244+ const auto & instances = hier.at (" instances" ).as_array ();
1245+ const boost::json::object* backside_node = nullptr ;
1246+ for (const auto & inst : instances) {
1247+ const auto & obj = inst.as_object ();
1248+ if (obj.at (" name" ).as_string () == " Backside" ) {
1249+ backside_node = &obj;
1250+ break ;
1251+ }
1252+ }
1253+ ASSERT_NE (backside_node, nullptr )
1254+ << " layer_hierarchy missing Backside category node" ;
1255+ EXPECT_EQ (backside_node->at (" type" ).as_string (), " category" );
1256+
1257+ // The backside node should contain exactly metal1 and via1.
1258+ const auto & bs_layers = backside_node->at (" layers" ).as_array ();
1259+ std::set<std::string> bs_names;
1260+ for (const auto & l : bs_layers) {
1261+ bs_names.insert (std::string (l.as_object ().at (" name" ).as_string ()));
1262+ }
1263+ EXPECT_EQ (bs_names, (std::set<std::string>{" metal1" , " via1" }));
1264+ }
1265+
1266+ TEST_F (TileGeneratorTest, LayerHierarchyNoBacksideCategory)
1267+ {
1268+ // No layers marked backside — there should be no Backside category.
1269+ makeTileGen ();
1270+ const auto resp = serializeTechResponse (*tile_gen_);
1271+ const auto & hier = resp.at (" layer_hierarchy" ).as_object ();
1272+ const auto & instances = hier.at (" instances" ).as_array ();
1273+ for (const auto & inst : instances) {
1274+ EXPECT_NE (inst.as_object ().at (" name" ).as_string (), " Backside" )
1275+ << " Backside category should not appear when no layers are backside" ;
1276+ }
1277+ }
1278+
12221279} // namespace
12231280} // namespace web
0 commit comments