Skip to content
Merged
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
15 changes: 15 additions & 0 deletions docs/agents/coding.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,21 @@
### Null Safety
- Avoid adding too defensive null checks if the object cannot be null

## Service Interfaces

Abstract interfaces published through `utl::ServiceRegistry` use the
`Service` suffix (e.g. `est::ParasiticsService`, `drt::PinAccessService`).
Each interface lives in its owning module's public `include/<module>/`
directory and is exposed as a small header-only Bazel target that
consumers can depend on without pulling in the full implementation
library. This keeps module dependency graphs acyclic and the decoupling
visible at the build layer.

Note that this is distinct from the `Abstract*` prefix used for
graphics/visualization mock-swappable classes (e.g.
`AbstractSteinerRenderer`); those are inherited for test/headless modes
rather than looked up through a registry.

## Common Coding Mistakes

### OpenROAD Message ID Duplicate Checker
Expand Down
6 changes: 3 additions & 3 deletions include/ord/OpenRoad.hh
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ class ICeWall;

namespace utl {
class Logger;
class CallBackHandler;
class ServiceRegistry;
} // namespace utl

namespace dst {
Expand Down Expand Up @@ -151,7 +151,7 @@ class OpenRoad

Tcl_Interp* tclInterp() { return tcl_interp_; }
utl::Logger* getLogger() { return logger_; }
utl::CallBackHandler* getCallBackHandler() { return callback_handler_; }
utl::ServiceRegistry* getServiceRegistry() { return service_registry_; }
odb::dbDatabase* getDb() { return db_; }
sta::dbSta* getSta() { return sta_; }
sta::dbNetwork* getDbNetwork();
Expand Down Expand Up @@ -288,7 +288,7 @@ class OpenRoad
dft::Dft* dft_ = nullptr;
est::EstimateParasitics* estimate_parasitics_ = nullptr;
web::WebServer* web_server_ = nullptr;
utl::CallBackHandler* callback_handler_ = nullptr;
utl::ServiceRegistry* service_registry_ = nullptr;

int threads_ = 1;

Expand Down
12 changes: 6 additions & 6 deletions src/OpenRoad.cc
Original file line number Diff line number Diff line change
Expand Up @@ -83,11 +83,11 @@
#include "tap/MakeTapcell.h"
#include "tap/tapcell.h"
#include "upf/MakeUpf.h"
#include "utl/CallBackHandler.h"
#include "utl/Logger.h"
#include "utl/MakeLogger.h"
#include "utl/Progress.h"
#include "utl/ScopedTemporaryFile.h"
#include "utl/ServiceRegistry.h"
#include "utl/decode.h"
#include "web/MakeWeb.h"
#include "web/web.h"
Expand Down Expand Up @@ -150,7 +150,7 @@ OpenRoad::~OpenRoad()
delete web_server_;
delete logger_;
delete verilog_reader_;
delete callback_handler_;
delete service_registry_;
}

sta::dbNetwork* OpenRoad::getDbNetwork()
Expand Down Expand Up @@ -195,7 +195,7 @@ void OpenRoad::init(Tcl_Interp* tcl_interp,
// Make components.
utl::Progress::setBatchMode(batch_mode);
logger_ = new utl::Logger(log_filename, metrics_filename);
callback_handler_ = new utl::CallBackHandler(logger_);
service_registry_ = new utl::ServiceRegistry(logger_);
db_->setLogger(logger_);
sta_ = new sta::dbSta(tcl_interp, db_, logger_);
verilog_network_ = new dbVerilogNetwork(sta_);
Expand All @@ -204,7 +204,7 @@ void OpenRoad::init(Tcl_Interp* tcl_interp,
antenna_checker_ = new ant::AntennaChecker(db_, logger_);
opendp_ = new dpl::Opendp(db_, logger_);
global_router_ = new grt::GlobalRouter(logger_,
callback_handler_,
service_registry_,
stt_builder_,
db_,
sta_,
Expand All @@ -213,7 +213,7 @@ void OpenRoad::init(Tcl_Interp* tcl_interp,
grt::initGui(global_router_, db_, logger_);

estimate_parasitics_ = new est::EstimateParasitics(
logger_, callback_handler_, db_, sta_, stt_builder_, global_router_);
logger_, service_registry_, db_, sta_, stt_builder_, global_router_);
est::initGui(estimate_parasitics_);

resizer_ = new rsz::Resizer(logger_,
Expand All @@ -240,7 +240,7 @@ void OpenRoad::init(Tcl_Interp* tcl_interp,
extractor_ = new rcx::Ext(db_, logger_, getVersion());
distributer_ = new dst::Distributed(logger_);
detailed_router_ = new drt::TritonRoute(
db_, logger_, callback_handler_, distributer_, stt_builder_);
db_, logger_, service_registry_, distributer_, stt_builder_);
drt::initGui(detailed_router_);

replace_ = new gpl::Replace(db_, sta_, resizer_, global_router_, logger_);
Expand Down
12 changes: 11 additions & 1 deletion src/drt/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,15 @@ package(
features = ["layering_check"],
)

# Abstract service interface published through utl::ServiceRegistry.
# Consumers depend only on this target, not on //src/drt, which keeps
# them free of the full drt implementation surface.
cc_library(
name = "pin_access_service",
hdrs = ["include/drt/PinAccessService.h"],
includes = ["include"],
)

cc_library(
name = "db_hdrs",
hdrs = [
Expand Down Expand Up @@ -79,7 +88,6 @@ cc_library(
"src/AbstractGraphicsFactory.h",
"src/DesignCallBack.cpp",
"src/DesignCallBack.h",
"src/PACallBack.h",
"src/TritonRoute.cpp",
"src/db/drObj/drAccessPattern.cpp",
"src/db/drObj/drNet.cpp",
Expand Down Expand Up @@ -181,6 +189,7 @@ cc_library(
],
deps = [
":db_hdrs",
":pin_access_service",
"//src/dst",
"//src/odb",
"//src/stt",
Expand Down Expand Up @@ -245,6 +254,7 @@ cc_library(
deps = [
":db_hdrs",
":drt",
":pin_access_service",
"//:ord",
"//src/dst",
"//src/gui",
Expand Down
20 changes: 20 additions & 0 deletions src/drt/include/drt/PinAccessService.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// SPDX-License-Identifier: BSD-3-Clause
// Copyright (c) 2026-2026, The OpenROAD Authors

#pragma once

namespace drt {

// Service interface published by the detailed router. Consumers look
// it up through utl::ServiceRegistry and do not depend on the concrete
// drt::TritonRoute type.
class PinAccessService
{
public:
virtual ~PinAccessService() = default;

// Recompute pin access for any instances that have become dirty.
virtual void updateDirtyPinAccess() = 0;
};

} // namespace drt
14 changes: 8 additions & 6 deletions src/drt/include/drt/TritonRoute.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

#include "absl/synchronization/mutex.h"
#include "boost/asio/thread_pool.hpp"
#include "drt/PinAccessService.h"
#include "odb/geom.h"

namespace odb {
Expand All @@ -27,7 +28,7 @@ class dbWire;

namespace utl {
class Logger;
class CallBackHandler;
class ServiceRegistry;
} // namespace utl

namespace stt {
Expand All @@ -43,7 +44,6 @@ namespace drt {
class frDesign;
class frInst;
class DesignCallBack;
class PACallBack;
class FlexDR;
class FlexPA;
class FlexTA;
Expand Down Expand Up @@ -80,15 +80,17 @@ struct ParamStruct
int num_threads = 1;
};

class TritonRoute
class TritonRoute : public PinAccessService
{
public:
TritonRoute(odb::dbDatabase* db,
utl::Logger* logger,
utl::CallBackHandler* callback_handler,
utl::ServiceRegistry* service_registry,
dst::Distributed* dist,
stt::SteinerTreeBuilder* stt_builder);
~TritonRoute();
~TritonRoute() override;

void updateDirtyPinAccess() override;

void initGraphics(std::unique_ptr<AbstractGraphicsFactory> graphics_factory);

Expand Down Expand Up @@ -191,10 +193,10 @@ class TritonRoute
std::unique_ptr<frDesign> design_;
std::unique_ptr<frDebugSettings> debug_;
std::unique_ptr<DesignCallBack> db_callback_;
std::unique_ptr<PACallBack> pa_callback_;
std::unique_ptr<RouterConfiguration> router_cfg_;
odb::dbDatabase* db_{nullptr};
utl::Logger* logger_{nullptr};
utl::ServiceRegistry* service_registry_{nullptr};
std::unique_ptr<FlexDR> dr_; // kept for single stepping
stt::SteinerTreeBuilder* stt_builder_{nullptr};
int num_drvs_{-1};
Expand Down
35 changes: 0 additions & 35 deletions src/drt/src/PACallBack.h

This file was deleted.

23 changes: 17 additions & 6 deletions src/drt/src/TritonRoute.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@

#include "AbstractGraphicsFactory.h"
#include "DesignCallBack.h"
#include "PACallBack.h"
#include "absl/synchronization/mutex.h"
#include "boost/asio/post.hpp"
#include "boost/bind/bind.hpp"
Expand All @@ -35,6 +34,7 @@
#include "distributed/frArchive.h"
#include "dr/AbstractDRGraphics.h"
#include "dr/FlexDR.h"
#include "drt/PinAccessService.h"
#include "dst/Distributed.h"
#include "dst/JobMessage.h"
#include "frBaseTypes.h"
Expand All @@ -57,36 +57,47 @@
#include "stt/SteinerTreeBuilder.h"
#include "ta/AbstractTAGraphics.h"
#include "ta/FlexTA.h"
#include "utl/CallBackHandler.h"
#include "utl/Logger.h"
#include "utl/ScopedTemporaryFile.h"
#include "utl/ServiceRegistry.h"

using odb::dbTechLayerType;

namespace drt {
TritonRoute::TritonRoute(odb::dbDatabase* db,
utl::Logger* logger,
utl::CallBackHandler* callback_handler,
utl::ServiceRegistry* service_registry,
dst::Distributed* dist,
stt::SteinerTreeBuilder* stt_builder)
: debug_(std::make_unique<frDebugSettings>()),
db_callback_(std::make_unique<DesignCallBack>(this)),
pa_callback_(std::make_unique<PACallBack>(this)),
router_cfg_(std::make_unique<RouterConfiguration>())
{
if (distributed_) {
dist_pool_.emplace(1);
}
db_ = db;
logger_ = logger;
service_registry_ = service_registry;
dist_ = dist;
stt_builder_ = stt_builder;
design_ = std::make_unique<frDesign>(logger_, router_cfg_.get());
dist->addCallBack(new RoutingCallBack(this, dist, logger));
pa_callback_->setOwner(callback_handler);
service_registry_->provide<PinAccessService>(this);
}

TritonRoute::~TritonRoute() = default;
TritonRoute::~TritonRoute()
{
service_registry_->withdraw<PinAccessService>(this);
}

void TritonRoute::updateDirtyPinAccess()
{
if (design_ == nullptr || design_->getTopBlock() == nullptr) {
return;
}
updateDirtyPAData();
}

void TritonRoute::initGraphics(
std::unique_ptr<AbstractGraphicsFactory> graphics_factory)
Expand Down
12 changes: 10 additions & 2 deletions src/est/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ cc_library(
name = "private_hdrs",
hdrs = [
"src/AbstractSteinerRenderer.h",
"src/EstimateParasiticsCallBack.h",
"src/MakeWireParasitics.h",
"src/OdbCallBack.h",
"src/SteinerRenderer.h",
Expand All @@ -26,11 +25,19 @@ cc_library(
],
)

# Abstract service interface published through utl::ServiceRegistry.
# Consumers depend only on this target, not on //src/est, which keeps
# them free of the full est implementation surface.
cc_library(
name = "parasitics_service",
hdrs = ["include/est/ParasiticsService.h"],
includes = ["include"],
)

cc_library(
name = "est",
srcs = [
"src/EstimateParasitics.cpp",
"src/EstimateParasiticsCallBack.cpp",
"src/MakeWireParasitics.cpp",
"src/OdbCallBack.cpp",
"src/SteinerTree.cpp",
Expand All @@ -43,6 +50,7 @@ cc_library(
"include",
],
deps = [
":parasitics_service",
":private_hdrs",
"//src/dbSta",
"//src/dbSta:SpefWriter",
Expand Down
Loading
Loading