Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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" \
Comment thread
simi1505 marked this conversation as resolved.
Outdated
{ (-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."
}
Comment on lines +309 to +314

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Why use two different idioms and different words (Either vs Exactly one) for the same one-hot style check?

# Default action is to disable auto-taper.
set disable [expr { ![info exists flags(-enable)] }]
set block [ord::get_db_block]
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
}
}
}

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
6 changes: 6 additions & 0 deletions src/drt/src/db/drObj/drNet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "db/obj/frBTerm.h"
#include "db/obj/frBlockObject.h"
#include "db/obj/frInstTerm.h"
#include "db/obj/frNet.h"
#include "distributed/frArchive.h"
#include "dr/FlexDR.h"
#include "frBaseTypes.h"
Expand Down Expand Up @@ -106,6 +107,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

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.

I'm not sure about this one. Does that mean that, as soon as an instance is connected to a net with auto-taper disabled, that the entire instance has auto taper disabled?

Also, why not use isNDRInst(inst) instead of net->getNondefaultRule() as in the original code?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

isNDRInst(inst) only tells us whether the instance touches some NDR net. It reduces the per-terminal information to a single bool, so it can't tell us whether the same net is both NDR and has auto-taper suppressed.

Here I need that conjunction on one net. Take an instance with net A (NDR, taper enabled) and net B (auto-taper disabled, but no NDR): isNDRInst(inst) would be true (because of A) and "the instance has an auto-taper-disabled net" would also be true (because of B), yet no single net qualifies. So the instance should not be treated as no-auto-taper. Auto-taper only affects NDR nets, so the per-net flag is only meaningful when the same net also carries an NDR.

That's why the loop checks net->getNondefaultRule() && (!AUTO_TAPER_NDR_NETS || net->isAutoTaperDisabled()) together per terminal, rather than combining two instance-level predicates.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

However, the condition was duplicated. I've factored it into frNet::isAutoTaperSuppressed(bool auto_taper_enabled) and reused it at all three sites. Here in isNoAutoTaperNDRInst, and the two in FlexPA_acc_point. So the predicate now lives in one place. Behaviour is unchanged. See commit e638dd6

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

To your other question, "Does that mean that, as soon as an instance is connected to a net with auto-taper disabled, that the entire instance has auto taper disabled?":
Yes, for pin-access purposes, if an instance touches at least one NDR net whose auto-taper is suppressed, the whole instance gets its own unique class. That's intentional and matches the pre-existing behaviour: the line this replaced was if (!AUTO_TAPER_NDR_NETS && isNDRInst(inst)), which likewise classified the entire instance. Pin-access patterns are computed per unique-instance-class, so a no-taper NDR instance needs its own class to get access points computed against the untapered (full-width NDR) geometry. The actual tapering still happens per-net/per-pin during routing. This only affects how instances are grouped for pin access.

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.

Alright. So as long as you can have instances with both non-NDR nets and NDR nets connected to them, it with tapering individually enabled, this should be fine.

{
// 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