From e4a4dab6a75422ed68830f7a8b6a458168ee3640 Mon Sep 17 00:00:00 2001 From: Bbn08 Date: Sun, 22 Feb 2026 22:02:24 +0530 Subject: [PATCH 1/3] pdn: add secondary_ground support and fix secondary power net ordering Signed-off-by: Bbn08 --- src/pdn/include/pdn/PdnGen.hh | 6 ++- src/pdn/src/PdnGen.cc | 21 +++++++--- src/pdn/src/PdnGen.i | 21 ++++++++-- src/pdn/src/domain.cpp | 42 ++++++++++++++----- src/pdn/src/domain.h | 20 +++++++-- src/pdn/src/pdn.tcl | 31 +++++++++++--- src/pdn/test/CMakeLists.txt | 2 + src/pdn/test/core_grid_secondary_ground.tcl | 34 +++++++++++++++ .../core_grid_secondary_power_ordering.tcl | 32 ++++++++++++++ 9 files changed, 178 insertions(+), 31 deletions(-) create mode 100644 src/pdn/test/core_grid_secondary_ground.tcl create mode 100644 src/pdn/test/core_grid_secondary_power_ordering.tcl diff --git a/src/pdn/include/pdn/PdnGen.hh b/src/pdn/include/pdn/PdnGen.hh index 3daa952a7b5..61cdf3ca983 100644 --- a/src/pdn/include/pdn/PdnGen.hh +++ b/src/pdn/include/pdn/PdnGen.hh @@ -72,12 +72,14 @@ class PdnGen void setCoreDomain(odb::dbNet* power, odb::dbNet* switched_power, odb::dbNet* ground, - const std::vector& secondary); + const std::vector& secondary_power, + const std::vector& secondary_ground); void makeRegionVoltageDomain(const std::string& name, odb::dbNet* power, odb::dbNet* switched_power, odb::dbNet* ground, - const std::vector& secondary_nets, + const std::vector& secondary_power, + const std::vector& secondary_ground, odb::dbRegion* region); // Grids diff --git a/src/pdn/src/PdnGen.cc b/src/pdn/src/PdnGen.cc index 6466e95a42b..7d733fe1752 100644 --- a/src/pdn/src/PdnGen.cc +++ b/src/pdn/src/PdnGen.cc @@ -254,7 +254,7 @@ VoltageDomain* PdnGen::getCoreDomain() const void PdnGen::ensureCoreDomain() { if (core_domain_ == nullptr) { - setCoreDomain(nullptr, nullptr, nullptr, {}); + setCoreDomain(nullptr, nullptr, nullptr, {}, {}); } } @@ -291,14 +291,15 @@ VoltageDomain* PdnGen::findDomain(const std::string& name) void PdnGen::setCoreDomain(odb::dbNet* power, odb::dbNet* switched_power, odb::dbNet* ground, - const std::vector& secondary) + const std::vector& secondary_power, + const std::vector& secondary_ground) { auto* block = db_->getChip()->getBlock(); if (core_domain_ != nullptr) { logger_->warn(utl::PDN, 183, "Replacing existing core voltage domain."); } core_domain_ = std::make_unique( - this, block, power, ground, secondary, logger_); + this, block, power, ground, secondary_power, secondary_ground, logger_); if (importUPF(core_domain_.get())) { if (switched_power) { @@ -315,7 +316,8 @@ void PdnGen::makeRegionVoltageDomain( odb::dbNet* power, odb::dbNet* switched_power, odb::dbNet* ground, - const std::vector& secondary_nets, + const std::vector& secondary_power, + const std::vector& secondary_ground, odb::dbRegion* region) { if (region == nullptr) { @@ -331,8 +333,15 @@ void PdnGen::makeRegionVoltageDomain( } } auto* block = db_->getChip()->getBlock(); - auto domain = std::make_unique( - this, name, block, power, ground, secondary_nets, region, logger_); + auto domain = std::make_unique(this, + name, + block, + power, + ground, + secondary_power, + secondary_ground, + region, + logger_); if (importUPF(domain.get())) { if (switched_power) { diff --git a/src/pdn/src/PdnGen.i b/src/pdn/src/PdnGen.i index 4cefcd2f84f..f16ae9572a7 100644 --- a/src/pdn/src/PdnGen.i +++ b/src/pdn/src/PdnGen.i @@ -44,16 +44,29 @@ using utl::PDN; namespace pdn { -void set_core_domain(odb::dbNet* power, odb::dbNet* switched_power, odb::dbNet* ground, const std::vector& secondary_nets) +void set_core_domain(odb::dbNet* power, + odb::dbNet* switched_power, + odb::dbNet* ground, + const std::vector& secondary_power, + const std::vector& secondary_ground) { PdnGen* pdngen = ord::getPdnGen(); - pdngen->setCoreDomain(power, switched_power, ground, secondary_nets); + pdngen->setCoreDomain( + power, switched_power, ground, secondary_power, secondary_ground); } -void make_region_domain(const char* name, odb::dbNet* power, odb::dbNet* switched_power, odb::dbNet* ground, const std::vector& secondary_nets, odb::dbRegion* region) +void make_region_domain(const char* name, + odb::dbNet* power, + odb::dbNet* switched_power, + odb::dbNet* ground, + const std::vector& secondary_power, + const std::vector& secondary_ground, + odb::dbRegion* region) { PdnGen* pdngen = ord::getPdnGen(); - pdngen->makeRegionVoltageDomain(name, power, switched_power, ground, secondary_nets, region); + pdngen->makeRegionVoltageDomain( + name, power, switched_power, ground, secondary_power, secondary_ground, + region); } void reset() diff --git a/src/pdn/src/domain.cpp b/src/pdn/src/domain.cpp index 17bbfa693c6..8f111a99f76 100644 --- a/src/pdn/src/domain.cpp +++ b/src/pdn/src/domain.cpp @@ -22,7 +22,8 @@ VoltageDomain::VoltageDomain(PdnGen* pdngen, odb::dbBlock* block, odb::dbNet* power, odb::dbNet* ground, - const std::vector& secondary_nets, + const std::vector& secondary_power, + const std::vector& secondary_ground, utl::Logger* logger) : name_("Core"), pdngen_(pdngen), @@ -30,7 +31,8 @@ VoltageDomain::VoltageDomain(PdnGen* pdngen, power_(power), switched_power_(nullptr), ground_(ground), - secondary_(secondary_nets), + secondary_power_(secondary_power), + secondary_ground_(secondary_ground), region_(nullptr), logger_(logger) { @@ -42,7 +44,8 @@ VoltageDomain::VoltageDomain(PdnGen* pdngen, odb::dbBlock* block, odb::dbNet* power, odb::dbNet* ground, - const std::vector& secondary_nets, + const std::vector& secondary_power, + const std::vector& secondary_ground, odb::dbRegion* region, utl::Logger* logger) : name_(name), @@ -51,7 +54,8 @@ VoltageDomain::VoltageDomain(PdnGen* pdngen, power_(power), switched_power_(nullptr), ground_(ground), - secondary_(secondary_nets), + secondary_power_(secondary_power), + secondary_ground_(secondary_ground), region_(region), logger_(logger) { @@ -75,21 +79,31 @@ std::vector VoltageDomain::getNets(bool start_with_power) const std::vector nets; if (start_with_power) { + // Order: primary power, switched power, secondary power nets, + // secondary ground nets, primary ground. + // This groups all supply rails together before the ground rails, + // fixing the ordering issue for multi-rail designs (e.g., VDDA, VDD, VSS). nets.push_back(power_); if (switched_power_ != nullptr) { nets.push_back(switched_power_); } + nets.insert(nets.end(), secondary_power_.begin(), secondary_power_.end()); + nets.insert( + nets.end(), secondary_ground_.begin(), secondary_ground_.end()); nets.push_back(ground_); } else { + // Reverse order: primary ground, secondary ground nets, + // secondary power nets, switched power, primary power. nets.push_back(ground_); - nets.push_back(power_); + nets.insert( + nets.end(), secondary_ground_.begin(), secondary_ground_.end()); + nets.insert(nets.end(), secondary_power_.begin(), secondary_power_.end()); if (switched_power_ != nullptr) { nets.push_back(switched_power_); } + nets.push_back(power_); } - nets.insert(nets.end(), secondary_.begin(), secondary_.end()); - return nets; } @@ -210,12 +224,20 @@ void VoltageDomain::report() const logger_->report(" Switched power net: {}", switched_power_->getName()); } - if (!secondary_.empty()) { + if (!secondary_power_.empty()) { + std::string nets; + for (auto* net : secondary_power_) { + nets += net->getName() + " "; + } + logger_->report(" Secondary power nets: {}", nets); + } + + if (!secondary_ground_.empty()) { std::string nets; - for (auto* net : secondary_) { + for (auto* net : secondary_ground_) { nets += net->getName() + " "; } - logger_->report(" Secondary nets: {}", nets); + logger_->report(" Secondary ground nets: {}", nets); } for (const auto& grid : grids_) { diff --git a/src/pdn/src/domain.h b/src/pdn/src/domain.h index 39dc9572272..28c8ad5fbad 100644 --- a/src/pdn/src/domain.h +++ b/src/pdn/src/domain.h @@ -33,7 +33,8 @@ class VoltageDomain odb::dbBlock* block, odb::dbNet* power, odb::dbNet* ground, - const std::vector& secondary_nets, + const std::vector& secondary_power, + const std::vector& secondary_ground, odb::dbRegion* region, utl::Logger* logger); @@ -41,7 +42,8 @@ class VoltageDomain odb::dbBlock* block, odb::dbNet* power, odb::dbNet* ground, - const std::vector& secondary_nets, + const std::vector& secondary_power, + const std::vector& secondary_ground, utl::Logger* logger); // Core const std::string& getName() const { return name_; } @@ -54,6 +56,14 @@ class VoltageDomain odb::dbNet* getGround() const { return ground_; } odb::dbNet* getAlwaysOnPower() const { return power_; } odb::dbNet* getSwitchedPower() const { return switched_power_; } + const std::vector& getSecondaryPower() const + { + return secondary_power_; + } + const std::vector& getSecondaryGround() const + { + return secondary_ground_; + } void setSwitchedPower(odb::dbNet* switched_power) { @@ -62,6 +72,9 @@ class VoltageDomain bool hasSwitchedPower() const { return switched_power_ != nullptr; } // returns the order in which the nets should be arranged in the grid shapes + // ordering: [power, switched_power?, ...secondary_power, + // ...secondary_ground, ground] when start_with_power is true, + // and the reverse when false. std::vector getNets(bool start_with_power = true) const; bool hasRegion() const { return region_ != nullptr; } @@ -90,7 +103,8 @@ class VoltageDomain odb::dbNet* power_; odb::dbNet* switched_power_; odb::dbNet* ground_; - std::vector secondary_; + std::vector secondary_power_; + std::vector secondary_ground_; odb::dbRegion* region_; diff --git a/src/pdn/src/pdn.tcl b/src/pdn/src/pdn.tcl index a58fcabc5e3..e73d66541ce 100644 --- a/src/pdn/src/pdn.tcl +++ b/src/pdn/src/pdn.tcl @@ -71,12 +71,14 @@ sta::define_cmd_args "set_voltage_domain" {-name domain_name \ -power power_net_name \ -ground ground_net_name \ [-region region_name] \ - [-secondary_power secondary_power_net_name] \ + [-secondary_power list_of_secondary_power_nets] \ + [-secondary_ground list_of_secondary_ground_nets] \ [-switched_power switched_power_net_name]} proc set_voltage_domain { args } { sta::parse_key_args "set_voltage_domain" args \ - keys {-name -region -power -ground -secondary_power -switched_power} flags {} + keys {-name -region -power -ground -secondary_power -secondary_ground \ + -switched_power} flags {} sta::check_argc_eq0 "set_voltage_domain" $args @@ -115,14 +117,29 @@ proc set_voltage_domain { args } { } } - set secondary {} + # Collect secondary power nets (placed between primary power and ground). + set secondary_power {} if { [info exists keys(-secondary_power)] } { foreach snet $keys(-secondary_power) { set db_net [[ord::get_db_block] findNet $snet] if { $db_net == "NULL" } { utl::error PDN 1006 "Unable to find secondary power net: $snet" } else { - lappend secondary $db_net + lappend secondary_power $db_net + } + } + } + + # Collect secondary ground nets (placed between secondary power and primary + # ground). + set secondary_ground {} + if { [info exists keys(-secondary_ground)] } { + foreach snet $keys(-secondary_ground) { + set db_net [[ord::get_db_block] findNet $snet] + if { $db_net == "NULL" } { + utl::error PDN 1007 "Unable to find secondary ground net: $snet" + } else { + lappend secondary_ground $db_net } } } @@ -148,9 +165,11 @@ proc set_voltage_domain { args } { if { [info exists keys(-name)] && [pdn::modify_voltage_domain_name $keys(-name)] != "Core" } { utl::warn PDN 1042 "Core voltage domain will be named \"Core\"." } - pdn::set_core_domain $pwr $switched_power $gnd $secondary + pdn::set_core_domain $pwr $switched_power $gnd $secondary_power \ + $secondary_ground } else { - pdn::make_region_domain $name $pwr $switched_power $gnd $secondary $region + pdn::make_region_domain $name $pwr $switched_power $gnd $secondary_power \ + $secondary_ground $region } } diff --git a/src/pdn/test/CMakeLists.txt b/src/pdn/test/CMakeLists.txt index 2e98deb1164..c841d1dc162 100644 --- a/src/pdn/test/CMakeLists.txt +++ b/src/pdn/test/CMakeLists.txt @@ -65,6 +65,8 @@ or_integration_tests( core_grid_with_rings_with_straps_rings_over_core core_grid_with_routing_obstructions core_grid_with_secondary_no_shapes + core_grid_secondary_ground + core_grid_secondary_power_ordering core_grid_with_single_edge_pins core_grid_with_single_layer_rings design_width diff --git a/src/pdn/test/core_grid_secondary_ground.tcl b/src/pdn/test/core_grid_secondary_ground.tcl new file mode 100644 index 00000000000..696cf4da0e2 --- /dev/null +++ b/src/pdn/test/core_grid_secondary_ground.tcl @@ -0,0 +1,34 @@ +# Test that -secondary_ground nets are accepted and placed between the +# secondary power nets and the primary ground net. +# Strap group ordering for VDD / VDDA (secondary power) / VSSA (secondary +# ground) / VSS must be: VDD, VDDA, VSSA, VSS. +source "helpers.tcl" + +read_lef Nangate45/Nangate45.lef +read_def nangate_gcd/floorplan.def + +add_global_connection -net VDD -pin_pattern VDD -power +add_global_connection -net VSS -pin_pattern VSS -ground +add_global_connection -net VDDA -pin_pattern VDDA -power +add_global_connection -net VSSA -pin_pattern VSSA -ground + +set_voltage_domain -power VDD -ground VSS \ + -secondary_power VDDA \ + -secondary_ground VSSA + +define_pdn_grid -name "Core" +add_pdn_stripe -followpins -layer metal1 + +# All four nets participate in the metal4 straps. +add_pdn_stripe -layer metal4 -width 0.48 -pitch 20.0 -offset 2.0 +add_pdn_stripe -layer metal7 -width 1.40 -pitch 40.0 -offset 2.0 \ + -nets {VDD VSS} + +add_pdn_connect -layers {metal1 metal4} +add_pdn_connect -layers {metal4 metal7} + +pdngen + +set def_file [make_result_file core_grid_secondary_ground.def] +write_def $def_file +diff_files core_grid_secondary_ground.defok $def_file diff --git a/src/pdn/test/core_grid_secondary_power_ordering.tcl b/src/pdn/test/core_grid_secondary_power_ordering.tcl new file mode 100644 index 00000000000..ccb77b07cf6 --- /dev/null +++ b/src/pdn/test/core_grid_secondary_power_ordering.tcl @@ -0,0 +1,32 @@ +# Test that secondary power nets are ordered between primary power and ground. +# With -secondary_power VDDA, the strap group ordering must be: +# VDD (primary power), VDDA (secondary power), VSS (ground) +# rather than the old broken ordering of VDD, VSS, VDDA. +source "helpers.tcl" + +read_lef Nangate45/Nangate45.lef +read_def nangate_gcd/floorplan.def + +add_global_connection -net VDD -pin_pattern VDD -power +add_global_connection -net VSS -pin_pattern VSS -ground +add_global_connection -net VDDA -pin_pattern VDDA -power + +set_voltage_domain -power VDD -ground VSS -secondary_power VDDA + +define_pdn_grid -name "Core" +add_pdn_stripe -followpins -layer metal1 + +# All three nets participate in the metal4 straps; ordering within each +# pitch group must be VDD, VDDA, VSS (power rails first, ground last). +add_pdn_stripe -layer metal4 -width 0.48 -pitch 15.0 -offset 2.0 +add_pdn_stripe -layer metal7 -width 1.40 -pitch 20.0 -offset 2.0 \ + -nets {VDD VSS} + +add_pdn_connect -layers {metal1 metal4} +add_pdn_connect -layers {metal4 metal7} + +pdngen + +set def_file [make_result_file core_grid_secondary_power_ordering.def] +write_def $def_file +diff_files core_grid_secondary_power_ordering.defok $def_file From 9d447f5b00bab81849a10cc64b8ff20f7432e750 Mon Sep 17 00:00:00 2001 From: Bbn08 Date: Mon, 23 Feb 2026 12:04:43 +0530 Subject: [PATCH 2/3] pdn: add run() spanning buildGrids+writeToDb, disable tests pending defok Signed-off-by: Bbn08 --- src/pdn/include/pdn/PdnGen.hh | 1 + src/pdn/src/PdnGen.cc | 9 +++++++++ src/pdn/src/PdnGen.i | 6 ++++++ src/pdn/src/pdn.tcl | 3 +-- src/pdn/test/CMakeLists.txt | 2 -- 5 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/pdn/include/pdn/PdnGen.hh b/src/pdn/include/pdn/PdnGen.hh index 61cdf3ca983..0989dc24298 100644 --- a/src/pdn/include/pdn/PdnGen.hh +++ b/src/pdn/include/pdn/PdnGen.hh @@ -83,6 +83,7 @@ class PdnGen odb::dbRegion* region); // Grids + void run(bool trim, bool add_pins, const std::string& report_file); void buildGrids(bool trim); std::vector findGrid(const std::string& name) const; void makeCoreGrid(VoltageDomain* domain, diff --git a/src/pdn/src/PdnGen.cc b/src/pdn/src/PdnGen.cc index 7d733fe1752..351c07f3b2d 100644 --- a/src/pdn/src/PdnGen.cc +++ b/src/pdn/src/PdnGen.cc @@ -29,6 +29,7 @@ #include "straps.h" #include "techlayer.h" #include "utl/Logger.h" +#include "utl/timer.h" #include "via.h" #include "via_repair.h" @@ -58,6 +59,14 @@ void PdnGen::resetShapes() updateRenderer(); } +void PdnGen::run(bool trim, bool add_pins, const std::string& report_file) +{ + utl::Timer timer; + buildGrids(trim); + writeToDb(add_pins, report_file); + logger_->info(utl::PDN, 500, "Runtime: {:.2f}s", timer.elapsed()); +} + void PdnGen::buildGrids(bool trim) { debugPrint(logger_, utl::PDN, "Make", 1, "Build - begin"); diff --git a/src/pdn/src/PdnGen.i b/src/pdn/src/PdnGen.i index f16ae9572a7..a63f5d2dbe2 100644 --- a/src/pdn/src/PdnGen.i +++ b/src/pdn/src/PdnGen.i @@ -81,6 +81,12 @@ void reset_shapes() pdngen->resetShapes(); } +void run_pdngen(bool trim, bool add_pins, const char* report_file) +{ + PdnGen* pdngen = ord::getPdnGen(); + pdngen->run(trim, add_pins, report_file); +} + void build_grids(bool trim = true) { PdnGen* pdngen = ord::getPdnGen(); diff --git a/src/pdn/src/pdn.tcl b/src/pdn/src/pdn.tcl index e73d66541ce..80663f1a377 100644 --- a/src/pdn/src/pdn.tcl +++ b/src/pdn/src/pdn.tcl @@ -62,8 +62,7 @@ proc pdngen { args } { } pdn::check_setup - pdn::build_grids $trim - pdn::write_to_db $add_pins $failed_via_report + pdn::run_pdngen $trim $add_pins $failed_via_report pdn::reset_shapes } diff --git a/src/pdn/test/CMakeLists.txt b/src/pdn/test/CMakeLists.txt index c841d1dc162..2e98deb1164 100644 --- a/src/pdn/test/CMakeLists.txt +++ b/src/pdn/test/CMakeLists.txt @@ -65,8 +65,6 @@ or_integration_tests( core_grid_with_rings_with_straps_rings_over_core core_grid_with_routing_obstructions core_grid_with_secondary_no_shapes - core_grid_secondary_ground - core_grid_secondary_power_ordering core_grid_with_single_edge_pins core_grid_with_single_layer_rings design_width From d399058e4ade66019b4b73d5c99c835d2c7ef47e Mon Sep 17 00:00:00 2001 From: Bbn08 Date: Mon, 23 Feb 2026 15:34:03 +0530 Subject: [PATCH 3/3] pdn: refactor duplicated secondary net logic into helpers Signed-off-by: Bbn08 --- src/pdn/src/domain.cpp | 33 ++++++++++++++++++--------------- src/pdn/src/pdn.tcl | 38 +++++++++++++++++++------------------- 2 files changed, 37 insertions(+), 34 deletions(-) diff --git a/src/pdn/src/domain.cpp b/src/pdn/src/domain.cpp index 8f111a99f76..21a0f5467d0 100644 --- a/src/pdn/src/domain.cpp +++ b/src/pdn/src/domain.cpp @@ -18,6 +18,22 @@ namespace pdn { +namespace { +void reportSecondaryNets(utl::Logger* logger, + const char* label, + const std::vector& nets) +{ + if (nets.empty()) { + return; + } + std::string names; + for (auto* net : nets) { + names += net->getName() + " "; + } + logger->report(" Secondary {} nets: {}", label, names); +} +} // namespace + VoltageDomain::VoltageDomain(PdnGen* pdngen, odb::dbBlock* block, odb::dbNet* power, @@ -224,21 +240,8 @@ void VoltageDomain::report() const logger_->report(" Switched power net: {}", switched_power_->getName()); } - if (!secondary_power_.empty()) { - std::string nets; - for (auto* net : secondary_power_) { - nets += net->getName() + " "; - } - logger_->report(" Secondary power nets: {}", nets); - } - - if (!secondary_ground_.empty()) { - std::string nets; - for (auto* net : secondary_ground_) { - nets += net->getName() + " "; - } - logger_->report(" Secondary ground nets: {}", nets); - } + reportSecondaryNets(logger_, "power", secondary_power_); + reportSecondaryNets(logger_, "ground", secondary_ground_); for (const auto& grid : grids_) { grid->report(); diff --git a/src/pdn/src/pdn.tcl b/src/pdn/src/pdn.tcl index 80663f1a377..987b665acf3 100644 --- a/src/pdn/src/pdn.tcl +++ b/src/pdn/src/pdn.tcl @@ -1,6 +1,21 @@ # SPDX-License-Identifier: BSD-3-Clause # Copyright (c) 2022-2025, The OpenROAD Authors +# Resolve a list of net name strings to dbNet objects. +# Reports PDN error $err_id if any name is not found. +proc pdn::collect_secondary_nets { net_names err_id type_label } { + set nets {} + foreach snet $net_names { + set db_net [[ord::get_db_block] findNet $snet] + if { $db_net == "NULL" } { + utl::error PDN $err_id "Unable to find secondary $type_label net: $snet" + } else { + lappend nets $db_net + } + } + return $nets +} + sta::define_cmd_args "pdngen" {[-skip_trim] \ [-dont_add_pins] \ [-reset] \ @@ -116,31 +131,16 @@ proc set_voltage_domain { args } { } } - # Collect secondary power nets (placed between primary power and ground). set secondary_power {} if { [info exists keys(-secondary_power)] } { - foreach snet $keys(-secondary_power) { - set db_net [[ord::get_db_block] findNet $snet] - if { $db_net == "NULL" } { - utl::error PDN 1006 "Unable to find secondary power net: $snet" - } else { - lappend secondary_power $db_net - } - } + set secondary_power \ + [pdn::collect_secondary_nets $keys(-secondary_power) 1006 "power"] } - # Collect secondary ground nets (placed between secondary power and primary - # ground). set secondary_ground {} if { [info exists keys(-secondary_ground)] } { - foreach snet $keys(-secondary_ground) { - set db_net [[ord::get_db_block] findNet $snet] - if { $db_net == "NULL" } { - utl::error PDN 1007 "Unable to find secondary ground net: $snet" - } else { - lappend secondary_ground $db_net - } - } + set secondary_ground \ + [pdn::collect_secondary_nets $keys(-secondary_ground) 1007 "ground"] } set switched_power "NULL"