Skip to content
Closed
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
10 changes: 9 additions & 1 deletion src/dbSta/test/cpp/TestLambertW.cc
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,15 @@ TEST_F(TestLambertW, ValidateRandomPImodels)
std::uniform_real_distribution<float> dis_c1(1e-15f, 50e-15f);
std::uniform_real_distribution<float> dis_slew(0.01e-9f, 0.5e-9f);

const Net* net = db_network_->net(drvr_pin);
// The net the parasitics store keys drvr_pin's network by.
const Net* net = db_network_->highestConnectedNet(db_network_->net(drvr_pin));
// OpenSTA's lock-free parasitics store needs an entry for the driver
// before a network is made; older OpenSTA has no such call.
[&]<typename P>(P* p) {
if constexpr (requires { p->ensureParasitics(drvr_pin); }) {
p->ensureParasitics(drvr_pin);
}
}(parasitics);
ASSERT_NE(net, nullptr);

static constexpr int kNumSamples = 10000;
Expand Down
1 change: 1 addition & 0 deletions src/est/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ cc_library(
"src/AbstractSteinerRenderer.h",
"src/MakeWireParasitics.h",
"src/OdbCallBack.h",
"src/StaParasiticsEntries.h",
],
copts = [
"-fopenmp",
Expand Down
2 changes: 2 additions & 0 deletions src/est/include/est/EstimateParasitics.h
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,8 @@ class EstimateParasitics : public sta::dbStaState, public ParasiticsService
template <typename T>
const std::vector<T>& resolveWireRC(std::vector<T> WireRC::*category) const;
void ensureParasitics();
// Give each driver of net an entry in every scene's parasitics.
void makeParasiticsEntries(const sta::Net* net);
bool isSkipPin(const sta::Pin* pin) const;
bool hasIdealClocks(const sta::Mode* mode) const;
bool hasIdealClocks() const;
Expand Down
27 changes: 25 additions & 2 deletions src/est/src/EstimateParasitics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "AbstractSteinerRenderer.h"
#include "MakeWireParasitics.h"
#include "OdbCallBack.h"
#include "StaParasiticsEntries.h"
#include "db_sta/SpefWriter.hh"
#include "db_sta/dbNetwork.hh"
#include "db_sta/dbSta.hh"
Expand Down Expand Up @@ -160,6 +161,7 @@ void EstimateParasitics::updateGlobalRouteParasitics(odb::dbNet* db_net,
if (db_net == nullptr || route.empty()) {
return;
}
makeParasiticsEntries(db_network_->dbToSta(db_net));
estimateGlobalRouteParasitics(db_net, route);
// Annotating parasitics alone leaves stale cached delays in the timer.
sta_->delaysInvalidFromFanin(db_network_->dbToSta(db_net));
Expand Down Expand Up @@ -653,6 +655,7 @@ void EstimateParasitics::ensureWireParasitic(const sta::Pin* drvr_pin)
void EstimateParasitics::ensureWireParasitic(const sta::Pin* drvr_pin,
const sta::Net* net)
{
makeParasiticsEntries(net);
// Sufficient to check for parasitic for one corner because
// they are all made at the same time.
const Scene* corner = sta_->scenes().front();
Expand Down Expand Up @@ -686,6 +689,7 @@ void EstimateParasitics::estimateGlobalRouteRC(sta::SpefWriter* spef_writer)
for (Scene* scene : scenes_) {
Parasitics* parasitics = sta_->makeConcreteParasitics(scene->name(), "");
scene->setParasitics(parasitics, sta::MinMaxAll::minMax());
est::makeParasiticsEntries(parasitics);
}

auto& routes = global_router_->getRoutes();
Expand Down Expand Up @@ -715,6 +719,7 @@ void EstimateParasitics::estimateGlobalRouteRC(sta::SpefWriter* spef_writer)

void EstimateParasitics::estimateGlobalRouteRC(odb::dbNet* db_net)
{
makeParasiticsEntries(db_network_->dbToSta(db_net));
MakeWireParasitics builder(
logger_, this, sta_, block_->getTech(), block_, global_router_);
auto& routes = global_router_->getRoutes();
Expand All @@ -735,6 +740,7 @@ void EstimateParasitics::estimateGlobalRouteParasitics(odb::dbNet* net,
return;
}
initBlock();
makeParasiticsEntries(db_network_->dbToSta(net));
MakeWireParasitics builder(
logger_, this, sta_, block_->getTech(), block_, global_router_);

Expand Down Expand Up @@ -768,6 +774,7 @@ void EstimateParasitics::estimateWireParasitics(sta::SpefWriter* spef_writer)
for (Scene* scene : scenes_) {
Parasitics* parasitics = sta_->makeConcreteParasitics(scene->name(), "");
scene->setParasitics(parasitics, sta::MinMaxAll::minMax());
est::makeParasiticsEntries(parasitics);
}

sta::LibertyLibrary* default_lib = network_->defaultLibertyLibrary();
Expand Down Expand Up @@ -829,6 +836,7 @@ void EstimateParasitics::estimateWireParasitic(const sta::Net* net,
{
PinSet* drivers = network_->drivers(net);
if (drivers && !drivers->empty()) {
makeParasiticsEntries(net);
const Pin* drvr_pin = *drivers->begin();
estimateWireParasitic(drvr_pin, net, spef_writer);
}
Expand Down Expand Up @@ -863,6 +871,7 @@ void EstimateParasitics::makeWireParasitic(sta::Net* net,
const Scene* corner)
{
sta::Parasitics* parasitics = corner->parasitics(max_);
est::makeParasiticsEntry(parasitics, drvr_pin);
sta::Parasitic* parasitic = parasitics->makeParasiticNetwork(net, false);
sta::ParasiticNode* n1
= parasitics->ensureParasiticNode(parasitic, drvr_pin, network_);
Expand Down Expand Up @@ -1354,6 +1363,19 @@ bool EstimateParasitics::isPad(const sta::Instance* inst) const
return false;
}

void EstimateParasitics::makeParasiticsEntries(const sta::Net* net)
{
PinSet* drivers = network_->drivers(net);
if (drivers == nullptr) {
return;
}
Comment thread
oharboe marked this conversation as resolved.
for (const sta::Scene* scene : sta_->scenes()) {
for (const sta::Pin* drvr_pin : *drivers) {
est::makeParasiticsEntry(scene->parasitics(max_), drvr_pin);
}
}
}

bool EstimateParasitics::isSkipPin(const sta::Pin* pin) const
{
// A pin can be skipped when its parasitics never affect timing in any mode.
Expand Down Expand Up @@ -1485,11 +1507,12 @@ void EstimateParasitics::eraseParasitics(const sta::Net* net)
//
// deleteParasiticNetwork() and not deleteParasitics(): the latter resolves
// drivers(net), which by now has no driver and would cache an empty entry
// keyed on a dbNet about to be freed.
// keyed on a dbNet about to be freed. A net with no entry has nothing to
// delete, and OpenSTA's deleteParasiticNetwork needs the entry to exist.
for (Scene* scene : scenes_) {
for (const sta::MinMax* mm : sta::MinMax::range()) {
Parasitics* parasitics = scene->parasitics(mm);
if (parasitics) {
if (parasitics && parasitics->findParasiticNetwork(net)) {
Comment thread
oharboe marked this conversation as resolved.
parasitics->deleteParasiticNetwork(net);
}
}
Expand Down
2 changes: 2 additions & 0 deletions src/est/src/MakeWireParasitics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <string>
#include <vector>

#include "StaParasiticsEntries.h"
#include "db_sta/SpefWriter.hh"
#include "db_sta/dbNetwork.hh"
#include "db_sta/dbSta.hh"
Expand Down Expand Up @@ -153,6 +154,7 @@ void MakeWireParasitics::clearParasitics()
for (Scene* scene : sta_->scenes()) {
Parasitics* parasitics = sta_->makeConcreteParasitics(scene->name(), "");
scene->setParasitics(parasitics, sta::MinMaxAll::minMax());
makeParasiticsEntries(parasitics);
}
}

Expand Down
32 changes: 32 additions & 0 deletions src/est/src/StaParasiticsEntries.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// SPDX-License-Identifier: BSD-3-Clause
// Copyright (c) 2026, The OpenROAD Authors

#pragma once

#include "sta/NetworkClass.hh"
#include "sta/Parasitics.hh"

namespace est {

// OpenSTA's parasitics store finds and makes parasitics without a lock
// once every driver and its net have an entry, and makeParasiticNetwork
// no longer adds the entry itself. OpenSTA before that change has
// neither call and adds the entry under its own lock, so there is
// nothing to do. Call these only where no other thread uses the store.
template <typename Parasitics = sta::Parasitics>
void makeParasiticsEntries(Parasitics* parasitics)
{
if constexpr (requires { parasitics->ensureParasitics(); }) {
parasitics->ensureParasitics();
}
}
Comment thread
oharboe marked this conversation as resolved.

template <typename Parasitics = sta::Parasitics>
void makeParasiticsEntry(Parasitics* parasitics, const sta::Pin* drvr_pin)
{
if constexpr (requires { parasitics->ensureParasitics(drvr_pin); }) {
parasitics->ensureParasitics(drvr_pin);
}
}
Comment thread
oharboe marked this conversation as resolved.

} // namespace est
Loading