Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions src/OpenRoad.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,40 @@ proc assign_ndr { args } {
}
}

sta::define_cmd_args "set_routing_disable_auto_taper" \
{ (-net name | -all_clocks) [-disable] [-enable] }

# Per-net control of the detailed router's auto-taper behavior. By default
# the detailed router tapers NDR (wide) nets down to minimum width near pin
# connections. Some nets (e.g. wide analog/NDR traces) must keep their full
# width all the way to the pin; use -disable to suppress auto-taper for those
# nets without recompiling. Use -enable to restore the default behavior.
proc set_routing_disable_auto_taper { args } {
sta::parse_key_args "set_routing_disable_auto_taper" args \
keys {-net} flags {-all_clocks -disable -enable}
if { !([info exists keys(-net)] ^ [info exists flags(-all_clocks)]) } {
utl::error ORD 1016 "Either -net or -all_clocks need to be defined."
}
if { [info exists flags(-disable)] && [info exists flags(-enable)] } {
utl::error ORD 1017 "Only one of -disable or -enable may be specified."
}
# Default action is to disable auto-taper.
set disable [expr { ![info exists flags(-enable)] }]
set block [[[ord::get_db] getChip] getBlock]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Chaining [[[ord::get_db] getChip] getBlock] can throw a Tcl error if no design or chip is loaded. It is safer to use the standard ord::get_db_block helper and check if the returned block is valid.

  set block [ord::get_db_block]
  if { $block == "NULL" } {
    utl::error ORD 1019 "No design block found."
  }

if { [info exists keys(-net)] } {
set netName $keys(-net)
set net [$block findNet $netName]
if { $net == "NULL" } {
utl::error ORD 1018 "No net named ${netName} found."
}
$net setDisableAutoTaper $disable
} else {
foreach net [sta::find_all_clk_nets] {
$net setDisableAutoTaper $disable
}
Comment on lines +326 to +328

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

sta::find_all_clk_nets returns a list of OpenSTA net objects (sta::Net*), not odb::dbNet* objects. Calling setDisableAutoTaper directly on them will result in a Tcl runtime error. You should convert the OpenSTA net to a dbNet using ord::sta_to_db_net first. Note that this path was not covered by the new integration test ndr_no_auto_taper.tcl, which is why the test passed locally.

    foreach sta_net [sta::find_all_clk_nets] {
      set db_net [ord::sta_to_db_net $sta_net]
      if { $db_net != "NULL" } {
        $db_net setDisableAutoTaper $disable
      }
    }

}
}

sta::define_cmd_args "set_debug_level" { tool group level }
proc set_debug_level { args } {
sta::check_argc_eq3 "set_debug_level" $args
Expand Down
29 changes: 28 additions & 1 deletion src/drt/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,13 +98,40 @@ detailed_route

#### Developer arguments

Some arguments that are helpful for developers are listed here.
Some arguments that are helpful for developers are listed here.

| Switch Name | Description |
| ----- | ----- |
| `-or_seed` | Random seed for the order of nets to reroute. The default value is `-1`, and the allowed values are integers `[0, MAX_INT]`. |
| `-or_k` | Number of swaps is given by $k * sizeof(rerouteNets)$. The default value is `0`, and the allowed values are integers `[0, MAX_INT]`. |

### Disable Auto-Taper Per Net

By default the detailed router tapers non-default-rule (NDR, i.e. wide)
nets down to minimum width near pin connections so that they fit the pin
access geometry. For some nets (for example wide analog/NDR traces) this
tapering is undesirable and the net must keep its full NDR width all the
way to the pin. The following command disables auto-taper on a per-net
basis, without recompiling. The global default behavior (auto-taper
enabled) is unchanged for all other nets.

```tcl
set_routing_disable_auto_taper
(-net name | -all_clocks)
[-disable]
[-enable]
```

#### Options

| Switch Name | Description |
| ----- | ----- |
| `-net` | Name of the net to mark. Mutually exclusive with `-all_clocks`. |
| `-all_clocks` | Apply to all clock nets. Mutually exclusive with `-net`. |
| `-disable` | Disable auto-taper for the selected net(s). This is the default action if neither `-disable` nor `-enable` is given. |
| `-enable` | Re-enable auto-taper for the selected net(s), restoring the default behavior. |


### Detailed Route Debugging

The following command and arguments are useful when debugging error
Expand Down
7 changes: 6 additions & 1 deletion src/drt/src/db/drObj/drNet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
#include "db/obj/frAccess.h"
#include "db/obj/frBTerm.h"
#include "db/obj/frBlockObject.h"
#include "db/obj/frInstTerm.h"
#include "db/obj/frNet.h" #include "db/obj/frInstTerm.h"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

The two #include directives are on the same line, which will cause a compilation error. They should be placed on separate lines.

Suggested change
#include "db/obj/frNet.h" #include "db/obj/frInstTerm.h"
#include "db/obj/frNet.h"
#include "db/obj/frInstTerm.h"

#include "distributed/frArchive.h"
#include "dr/FlexDR.h"
#include "frBaseTypes.h"
Expand Down Expand Up @@ -106,6 +106,11 @@ bool drNet::hasNDR() const
return getFrNet()->getNondefaultRule() != nullptr;
}

bool drNet::autoTaperEnabled(bool global_enabled) const
{
return global_enabled && !fNet_->isAutoTaperDisabled();
}

bool drNet::isClockNet() const
{
return fNet_->isClock();
Expand Down
4 changes: 4 additions & 0 deletions src/drt/src/db/drObj/drNet.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ class drNet : public drBlockObject
void clearRouteConnFigs() { routeConnFigs_.clear(); }
frNet* getFrNet() const { return fNet_; }
void setFrNet(frNet* net) { fNet_ = net; }
// True when this net should still be auto-tapered to min width near pins.
// Honors both the global AUTO_TAPER_NDR_NETS config and the per-net
// disable flag carried on the frNet.
bool autoTaperEnabled(bool global_enabled) const;
const frOrderedIdSet<frBlockObject*>& getFrNetTerms() const
{
return fNetTerms_;
Expand Down
7 changes: 7 additions & 0 deletions src/drt/src/db/obj/frNet.h
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,10 @@ class frNet : public frBlockObject
bool hasJumpers() { return has_jumpers_; }
void setToBeDeleted(bool to_be_deleted) { to_be_deleted_ = to_be_deleted; }
bool toBeDeleted() { return to_be_deleted_; }
// When true, DRT must not auto-taper this net to minimum width near pin
// connections (per-net override of router_cfg_->AUTO_TAPER_NDR_NETS).
void setDisableAutoTaper(bool in) { disable_auto_taper_ = in; }
bool isAutoTaperDisabled() const { return disable_auto_taper_; }

protected:
frString name_;
Expand Down Expand Up @@ -194,5 +198,8 @@ class frNet : public frBlockObject
bool has_jumpers_{false};
std::vector<frPinFig*> all_pinfigs_;
bool to_be_deleted_{false};
// Per-net override: when true, auto-taper to min width near pins is
// suppressed for this net even if AUTO_TAPER_NDR_NETS is globally enabled.
bool disable_auto_taper_{false};
};
} // namespace drt
8 changes: 5 additions & 3 deletions src/drt/src/dr/FlexDR_maze.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2229,7 +2229,7 @@ void FlexDRWorker::routeNet_prep(
}
unConnPins.insert(pin.get());
if (gridGraph_.getNDR()) {
if (router_cfg_->AUTO_TAPER_NDR_NETS
if (net->autoTaperEnabled(router_cfg_->AUTO_TAPER_NDR_NETS)
&& pin->isInstPin()) { // create a taper box for each pin
auto [l, h] = pin->getAPBbox();
frCoord pitch
Expand Down Expand Up @@ -2648,7 +2648,8 @@ void FlexDRWorker::routeNet_postAstarWritePath(
via = net_ndr->getPrefVia(startLayerNum / 2 - 1);
}
auto currVia = std::make_unique<drVia>(via);
if (net->hasNDR() && router_cfg_->AUTO_TAPER_NDR_NETS) {
if (net->hasNDR()
&& net->autoTaperEnabled(router_cfg_->AUTO_TAPER_NDR_NETS)) {
if (isInsideTaperBox(endX, endY, startZ, endZ, mazeIdx2TaperBox)) {
currVia->setTapered(true);
}
Expand Down Expand Up @@ -2818,7 +2819,8 @@ bool FlexDRWorker::splitPathSeg(frMIdx& midX,
drNet* net)
{
taperFirstPiece = false;
if (!net->hasNDR() || !router_cfg_->AUTO_TAPER_NDR_NETS) {
if (!net->hasNDR()
|| !net->autoTaperEnabled(router_cfg_->AUTO_TAPER_NDR_NETS)) {
return false;
}
frBox3D* bx = nullptr;
Expand Down
1 change: 1 addition & 0 deletions src/drt/src/io/io.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1053,6 +1053,7 @@ frNet* io::Parser::addNet(odb::dbNet* db_net)
}
net_in->setHasJumpers(has_jumpers);
net_in->setIsConnectedByAbutment(is_abuted);
net_in->setDisableAutoTaper(db_net->disableAutoTaper());
updateNetRouting(net_in.get(), db_net);
net_in->setType(db_net->getSigType());
frNet* raw_net_in = net_in.get();
Expand Down
9 changes: 6 additions & 3 deletions src/drt/src/pa/FlexPA_acc_point.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1059,13 +1059,16 @@ bool FlexPA::isViaViolationFree(frAccessPoint* ap,
design_rule_checker.setExtBox(ext_box);
design_rule_checker.setDrcBox(ext_box);
if (inst_term) {
if (!inst_term->getNet() || !inst_term->getNet()->getNondefaultRule()
|| router_cfg_->AUTO_TAPER_NDR_NETS) {
auto* it_net = inst_term->getNet();
if (!it_net || !it_net->getNondefaultRule()
|| (router_cfg_->AUTO_TAPER_NDR_NETS
&& !it_net->isAutoTaperDisabled())) {
design_rule_checker.addTargetObj(inst_term->getInst());
}
} else {
if (!pin_net || !pin_net->getNondefaultRule()
|| router_cfg_->AUTO_TAPER_NDR_NETS) {
|| (router_cfg_->AUTO_TAPER_NDR_NETS
&& !pin_net->isAutoTaperDisabled())) {
design_rule_checker.addTargetObj(pin_term);
}
}
Expand Down
17 changes: 16 additions & 1 deletion src/drt/src/pa/FlexPA_unique.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,21 @@ bool UniqueInsts::isNDRInst(frInst* inst) const
return false;
}

bool UniqueInsts::isNoAutoTaperNDRInst(frInst* inst) const
{
// An instance whose pin access must be computed without auto-taper:
// it touches an NDR net for which tapering is suppressed, either
// globally (!AUTO_TAPER_NDR_NETS) or per-net (disable_auto_taper).
for (const auto& a : inst->getInstTerms()) {
auto* net = a->getNet();
if (net && net->getNondefaultRule()
&& (!router_cfg_->AUTO_TAPER_NDR_NETS || net->isAutoTaperDisabled())) {
return true;
}
}
return false;
}

UniqueClassKey UniqueInsts::computeUniqueClassKey(frInst* inst) const
{
const odb::Point origin = inst->getOrigin();
Expand Down Expand Up @@ -196,7 +211,7 @@ UniqueClassKey UniqueInsts::computeUniqueClassKey(frInst* inst) const
}
// Special case for NDR instances, create a separate unique class for them
frInst* ndr_inst = nullptr;
if (!router_cfg_->AUTO_TAPER_NDR_NETS && isNDRInst(inst)) {
if (isNoAutoTaperNDRInst(inst)) {
ndr_inst = inst;
}
std::set<frTerm*> stubborn_terms;
Expand Down
1 change: 1 addition & 0 deletions src/drt/src/pa/FlexPA_unique.h
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@ class UniqueInsts
* terminal.
*/
bool isNDRInst(frInst* inst) const;
bool isNoAutoTaperNDRInst(frInst* inst) const;
bool hasTrackPattern(frTrackPattern* tp, const odb::Rect& box) const;

/**
Expand Down
2 changes: 2 additions & 0 deletions src/drt/test/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ COMPULSORY_TESTS = [
"ndr_vias1",
"ndr_vias2",
"ndr_vias3",
"ndr_no_auto_taper",
"obstruction",
"single_step",
"ta_ap_aligned",
Expand All @@ -36,6 +37,7 @@ ALL_TESTS = COMPULSORY_TESTS + PASSFAIL_TESTS
BIG_TESTS = [
"ndr_vias1",
"ndr_vias2",
"ndr_no_auto_taper",
]

PY_TESTS = [
Expand Down
2 changes: 2 additions & 0 deletions src/drt/test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ or_integration_tests(
ndr_vias1
ndr_vias2
ndr_vias3
ndr_no_auto_taper
obstruction
single_step
ta_ap_aligned
Expand All @@ -22,5 +23,6 @@ or_integration_tests(
set_tests_properties(
drt.ndr_vias1.tcl
drt.ndr_vias2.tcl
drt.ndr_no_auto_taper.tcl
PROPERTIES TIMEOUT 900
)
Loading