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
2 changes: 2 additions & 0 deletions src/odb/include/odb/db.h
Original file line number Diff line number Diff line change
Expand Up @@ -7540,6 +7540,8 @@ class dbChipNet : public dbObject

dbSet<dbChipCapNode> getChipCapNodes() const;

float getTotalCapacitance() const;

dbSet<dbChipRSeg> getChipRSegs() const;

uint32_t getNumBumpInsts() const;
Expand Down
11 changes: 11 additions & 0 deletions src/odb/src/db/dbChipNet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,17 @@ dbSet<dbChipCapNode> dbChipNet::getChipCapNodes() const
return dbSet<dbChipCapNode>(chip_net, chip->chip_net_cap_node_itr_);
}

float dbChipNet::getTotalCapacitance() const
{
float total_capacitance = 0.0;

for (odb::dbChipCapNode* cap_node : getChipCapNodes()) {
total_capacitance += cap_node->getCapacitance();
}

return total_capacitance;
}

dbSet<dbChipRSeg> dbChipNet::getChipRSegs() const
{
_dbChipNet* chip_net = (_dbChipNet*) this;
Expand Down
2 changes: 2 additions & 0 deletions src/rcx/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ cc_library(
"src/grids.cpp",
"src/gs.cpp",
"src/gseq.h",
"src/interChipModel.cpp",
"src/multiChipExtractor.cpp",
"src/multiChipSpefWriter.cpp",
"src/name.cpp",
Expand Down Expand Up @@ -86,6 +87,7 @@ cc_library(
"include/rcx/ext_options.h",
"include/rcx/extprocess.h",
"include/rcx/grids.h",
"include/rcx/interChipModel.h",
"include/rcx/multiChipExtractor.h",
"include/rcx/multiChipSpefWriter.h",
"include/rcx/rcx.h",
Expand Down
11 changes: 11 additions & 0 deletions src/rcx/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,13 @@ The `extract_parasitics` command performs parasitic extraction based on the
routed design. If there are no information on routed design, no parasitics are
returned.

For a 3D design, the command extracts each die using the extraction rules
set for its technology and then extracts the inter-chip parasitics using the
assembly design kit rules (see `set_extraction_rules_file`). Each bond
between two dies is modeled as a resistor connecting the boundary terminals
of the bonded bumps. 3D extraction supports only the v1 RC flow and a single
process corner.

```tcl
extract_parasitics
[-ext_model_file filename]
Expand Down Expand Up @@ -112,6 +119,10 @@ extract_parasitics
The `write_spef` command writes the `.spef` output of the parasitics stored
in the database.

For a 3D design, the command writes one file per die, appending the chip
name to the given filename (e.g., `design.chip_name.spef`), and one
additional file with the inter-chip parasitics (`design.bonds.spef`).

```tcl
write_spef
[-net_id net_id]
Expand Down
15 changes: 12 additions & 3 deletions src/rcx/include/rcx/extRCap.h
Original file line number Diff line number Diff line change
Expand Up @@ -1869,7 +1869,7 @@ class extMain
int _metal_flag_22; // dkf: 06242024
uint32_t _wire_extracted_progress_count; // dkf: 06242024

bool _v2; // new flow dkf: 10302023
bool _v2{false}; // new flow dkf: 10302023

void skip_via_wires(bool v) { _skip_via_wires = v; };
void printUpdateCoup(uint32_t netId1,
Expand Down Expand Up @@ -2131,8 +2131,6 @@ class extMain

void setCornerCount();

Array1D<extCorner*>* getProcessCornerTable() { return _processCornerTable; }

uint32_t getShortSrcJid(uint32_t jid);
void make1stRSeg(odb::dbNet* net,
odb::dbWirePath& path,
Expand Down Expand Up @@ -2669,6 +2667,16 @@ class extMain

utl::Logger* getLogger() { return logger_; }

const Array1D<extCorner*>* getProcessCornerTable() const
{
return _processCornerTable;
}

void setDeleteModelAtExtraction(bool delete_model_at_extraction)
{
delete_model_at_extraction_ = delete_model_at_extraction;
}

private:
utl::Logger* logger_;

Expand All @@ -2679,6 +2687,7 @@ class extMain
Array1D<extCorner*>* _scaledCornerTable = nullptr;

Array1D<extRCModel*>* _modelTable;
bool delete_model_at_extraction_{true};
Array1D<uint32_t> _modelMap; // TO_TEST
Array1D<extMetRCTable*> _metRCTable;
double _resistanceTable[20][20];
Expand Down
20 changes: 20 additions & 0 deletions src/rcx/include/rcx/interChipModel.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// SPDX-License-Identifier: BSD-3-Clause
// Copyright (c) 2019-2025, The OpenROAD Authors

#pragma once

#include <string>

#include "utl/Logger.h"

namespace rcx {

struct InterChipModel
{
double resistance{0.0}; // In Ohms.
};

InterChipModel parseInterChipRules(const std::string& rules_file_path,
utl::Logger* logger);

} // namespace rcx
15 changes: 15 additions & 0 deletions src/rcx/include/rcx/multiChipExtractor.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@

#pragma once

#include <memory>
#include <string>

#include "odb/PtrSetMap.h"
#include "odb/db.h"
#include "rcx/extRCap.h"
#include "rcx/ext_options.h"
#include "rcx/interChipModel.h"
#include "utl/Logger.h"

namespace rcx {
Expand All @@ -25,11 +28,23 @@ class MultiChipExtractor
const std::string& assembly_extraction_rules_file);

private:
void loadRules();
void extractChipParasitics(odb::dbChip* chip, const ExtractOptions& options);
void extractInterChipParasitics();

odb::dbDatabase* db_{nullptr};
utl::Logger* logger_{nullptr};

// Rules' files paths.
odb::PtrMap<odb::dbTech, std::string> extraction_rules_files_;
std::string assembly_extraction_rules_file_;

// Rules' models i.e., the structures populated with rules file data.
odb::PtrMap<odb::dbTech, std::unique_ptr<extRCModel>> tech_to_rules_model_;
InterChipModel inter_chip_model_;

const int corner_index_{0};
const std::string corner_name_{"Typical"};
};

} // namespace rcx
19 changes: 18 additions & 1 deletion src/rcx/include/rcx/multiChipSpefWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@

#pragma once

#include <string>

#include "odb/db.h"
#include "rcx/extSpef.h"
#include "rcx/ext_options.h"
#include "utl/Logger.h"

Expand All @@ -12,13 +15,27 @@ namespace rcx {
class MultiChipSpefWriter
{
public:
MultiChipSpefWriter(odb::dbDatabase* db, utl::Logger* logger);
MultiChipSpefWriter(odb::dbDatabase* db,
utl::Logger* logger,
const std::string& spef_version);

void run(const SpefOptions& options);

private:
void setUnits(const SpefOptions& options);

void writeChipSpef(odb::dbChip* chip, const SpefOptions& options);
void writeInterChipSpef();
std::string chipNetSpefString(odb::dbChipNet* chip_net);
std::string bondNodeName(odb::dbChipCapNode* cap_node);

odb::dbDatabase* db_{nullptr};
utl::Logger* logger_{nullptr};

std::string file_base_name_;
SpefHeader spef_header_;

ScaleFactors scale_factors_;
};

} // namespace rcx
1 change: 1 addition & 0 deletions src/rcx/src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ add_library(rcx_lib
find_some_net.cpp
multiChipExtractor.cpp
multiChipSpefWriter.cpp
interChipModel.cpp
)

target_include_directories(rcx_lib
Expand Down
3 changes: 2 additions & 1 deletion src/rcx/src/ext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ Ext::Ext(odb::dbDatabase* db, Logger* logger, const char* spef_version)
logger_(logger),
spef_version_(spef_version),
multi_chip_extractor_(std::make_unique<MultiChipExtractor>(db, logger)),
multi_chip_spef_writer_(std::make_unique<MultiChipSpefWriter>(db, logger))
multi_chip_spef_writer_(
std::make_unique<MultiChipSpefWriter>(db, logger, spef_version))
{
_ext->init(db, logger);
}
Expand Down
10 changes: 9 additions & 1 deletion src/rcx/src/ext.i
Original file line number Diff line number Diff line change
Expand Up @@ -121,11 +121,19 @@ extract(const char* ext_model_file,
opts._dbg= dbg;

odb::dbChip* top_chip = ord::getOpenRoad()->getDb()->getChip();

if (!top_chip) {
getLogger()->error(utl::RCX, 517, "No design is loaded.");
}

if (top_chip->getChipType() == odb::dbChip::ChipType::HIER) {
if (opts._v2) {
getLogger()->error(utl::RCX,
515,
"Multi-chip (3D) parasitic extraction supports only the v1 "
"RC flow; the v2 flow (-version >= 2.0) is not supported.");
}

ext->extractMultiChip(opts);
return;
}
Expand All @@ -148,7 +156,7 @@ write_spef(const char* file,
opts.nets = nets;
opts.net_id = net_id;
opts.coordinates= coordinates;
if (coordinates) {
if (coordinates) {
opts.N = "Y";
}

Expand Down
80 changes: 80 additions & 0 deletions src/rcx/src/interChipModel.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
// SPDX-License-Identifier: BSD-3-Clause
// Copyright (c) 2019-2025, The OpenROAD Authors

#include "rcx/interChipModel.h"

#include <fstream>
#include <sstream>
#include <string>
#include <string_view>

#include "utl/Logger.h"

namespace {

constexpr std::string_view kHybridBondVia = "HBV";
constexpr std::string_view kViaResistanceTable = "VIA_RESISTANCE";
constexpr std::string_view kTableEnd = "END";

} // namespace

namespace rcx {

InterChipModel parseInterChipRules(const std::string& rules_file_path,
utl::Logger* logger)
{
std::ifstream file(rules_file_path);

if (!file.is_open()) {
logger->error(utl::RCX,
516,
"Could not open assembly rules file {}.",
rules_file_path);
}
Comment thread
AcKoucher marked this conversation as resolved.

InterChipModel inter_chip_model;
bool found_hybrid_bond_via = false;
bool inside_via_resistance_table = false;

std::string line;
while (std::getline(file, line)) {
line = line.substr(0, line.find('#'));

std::istringstream line_stream(line);
std::string token;
if (!(line_stream >> token)) {
continue;
}

if (token == kViaResistanceTable) {
inside_via_resistance_table = true;
continue;
}

if (!inside_via_resistance_table) {
continue;
}

if (token == kTableEnd) {
break;
}

if (token == kHybridBondVia) {
line_stream >> inter_chip_model.resistance;
found_hybrid_bond_via = true;
break;
}
Comment thread
AcKoucher marked this conversation as resolved.
}

if (!found_hybrid_bond_via) {
logger->error(
utl::RCX,
538,
"Could not find HBV via resistance in assembly rules file {}.",
rules_file_path);
}

return inter_chip_model;
}

} // namespace rcx
Loading
Loading