Skip to content

Commit 0f6757d

Browse files
committed
Merge remote-tracking branch 'private/master' into gpl-new-regions
2 parents 2a77daa + 2292048 commit 0f6757d

34 files changed

+118107
-391
lines changed

Jenkinsfile

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
@Library('[email protected]') _
22

3+
def logHostname() {
4+
sh label: "Running on ${env.NODE_NAME}", script: "echo 'Node context established.'"
5+
}
6+
37
def baseTests(String image) {
48
Map base_tests = [failFast: false];
59

@@ -43,6 +47,7 @@ def baseTests(String image) {
4347
flow_tests.each { current_test ->
4448
base_tests["Flow Test - ${current_test}"] = {
4549
node {
50+
logHostname()
4651
withDockerContainer(args: '-u root', image: image) {
4752
stage("Setup ${current_test}") {
4853
sh label: 'Configure git', script: "git config --system --add safe.directory '*'";
@@ -78,6 +83,7 @@ def getParallelTests(String image) {
7883
def ret = [
7984
'Docs Tester': {
8085
node {
86+
logHostname()
8187
withDockerContainer(args: '-u root', image: image) {
8288
stage('Setup Docs Test') {
8389
echo "Setting up Docs Tester environment in ${image}";
@@ -101,6 +107,7 @@ def getParallelTests(String image) {
101107

102108
'Build without GUI': {
103109
node {
110+
logHostname()
104111
withDockerContainer(args: '-u root', image: image) {
105112
stage('Setup no-GUI Build') {
106113
echo "Build without GUI";
@@ -118,6 +125,7 @@ def getParallelTests(String image) {
118125

119126
'Build without Test': {
120127
node {
128+
logHostname()
121129
withDockerContainer(args: '-u root', image: image) {
122130
stage('Setup no-test Build') {
123131
echo "Build without Tests";
@@ -139,6 +147,7 @@ def getParallelTests(String image) {
139147

140148
'Build on RHEL8': {
141149
node ('rhel8') {
150+
logHostname()
142151
stage('Setup RHEL8 Build') {
143152
checkout scm;
144153
}
@@ -172,6 +181,7 @@ def getParallelTests(String image) {
172181

173182
'Unit Tests Ninja': {
174183
node {
184+
logHostname()
175185
withDockerContainer(args: '-u root', image: image) {
176186
stage('Setup Ninja Tests') {
177187
sh label: 'Configure git', script: "git config --system --add safe.directory '*'";
@@ -195,6 +205,7 @@ def getParallelTests(String image) {
195205

196206
'Compile with C++20': {
197207
node {
208+
logHostname()
198209
withDockerContainer(args: '-u root', image: image) {
199210
stage('Setup C++20 Compile') {
200211
sh label: 'Configure git', script: "git config --system --add safe.directory '*'";
@@ -213,6 +224,7 @@ def getParallelTests(String image) {
213224

214225
def bazelTest = {
215226
node {
227+
logHostname()
216228
stage('Setup') {
217229
checkout scm;
218230
sh label: 'Setup Docker Image', script: 'docker build -f docker/Dockerfile.bazel -t openroad/bazel-ci .';
@@ -265,6 +277,7 @@ def dockerTests = {
265277
test_os.each { os ->
266278
build_docker_images["Test Installer - ${os.name}"] = {
267279
node {
280+
logHostname()
268281
checkout scm;
269282
sh label: 'Build Docker image', script: "./etc/DockerHelper.sh create -target=builder -os=${os.image}";
270283
sh label: 'Test Docker image', script: "./etc/DockerHelper.sh test -target=builder -os=${os.image} -smoke";

src/dbSta/include/db_sta/dbNetwork.hh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,14 +72,14 @@ class dbNetwork : public ConcreteNetwork
7272
CellPortIterator* portIterator(const Cell* cell) const override;
7373

7474
// sanity checkers
75-
void checkAxioms() const;
75+
void checkAxioms(odb::dbObject* obj = nullptr) const;
7676
void checkSanityModBTerms() const;
7777
void checkSanityModITerms() const;
7878
void checkSanityModuleInsts() const;
7979
void checkSanityModInstTerms() const;
8080
void checkSanityUnusedModules() const;
8181
void checkSanityTermConnectivity() const;
82-
void checkSanityNetConnectivity() const;
82+
void checkSanityNetConnectivity(odb::dbObject* obj = nullptr) const;
8383
void checkSanityInstNames() const;
8484
void checkSanityNetNames() const;
8585
void checkSanityModNetNamesInModule(odb::dbModule* module) const;

src/dbSta/src/dbNetwork.cc

Lines changed: 82 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ Recommended conclusion: use map for concrete cells. They are invariant.
6565
#include "odb/dbSet.h"
6666
#include "odb/dbTypes.h"
6767
#include "sta/Liberty.hh"
68+
#include "sta/Network.hh"
6869
#include "sta/NetworkClass.hh"
6970
#include "sta/PatternMatch.hh"
7071
#include "sta/PortDirection.hh"
@@ -4130,8 +4131,15 @@ void dbNetwork::accumulateFlatLoadPinsOnNet(
41304131
}
41314132

41324133
// Use this API to check if flat & hier connectivities are ok
4133-
void dbNetwork::checkAxioms() const
4134+
void dbNetwork::checkAxioms(odb::dbObject* obj) const
41344135
{
4136+
// Check with an object if provided
4137+
if (obj != nullptr) {
4138+
checkSanityNetConnectivity(obj);
4139+
return;
4140+
}
4141+
4142+
// Otherwise, check the whole design
41354143
checkSanityModBTerms();
41364144
checkSanityModITerms();
41374145
checkSanityModInstTerms();
@@ -4458,79 +4466,90 @@ void dbNetwork::checkSanityTermConnectivity() const
44584466
}
44594467
}
44604468

4461-
void dbNetwork::checkSanityNetConnectivity() const
4469+
void dbNetwork::checkSanityNetConnectivity(odb::dbObject* obj) const
44624470
{
4463-
// Check for hier net and flat net connectivity
4464-
dbSet<dbModNet> mod_nets = block()->getModNets();
4465-
for (dbModNet* mod_net : mod_nets) {
4466-
findRelatedDbNet(mod_net);
4467-
}
4468-
4469-
// Check for incomplete flat net connections
4470-
for (odb::dbNet* net_db : block_->getNets()) {
4471-
// Check for multiple drivers.
4472-
Net* net = dbToSta(net_db);
4473-
PinSeq loads;
4474-
PinSeq drvrs;
4475-
PinSet visited_drvrs(this);
4476-
FindNetDrvrLoads visitor(nullptr, visited_drvrs, loads, drvrs, this);
4477-
NetSet visited_nets(this);
4478-
visitConnectedPins(net, visitor, visited_nets);
4479-
4480-
if (drvrs.size() > 1) {
4481-
bool all_tristate = true;
4482-
for (const Pin* drvr : drvrs) {
4483-
LibertyPort* port = libertyPort(drvr);
4484-
if (!port || !port->direction()->isAnyTristate()) {
4485-
all_tristate = false;
4486-
break;
4471+
//
4472+
// Check for a specific object if provided
4473+
//
4474+
if (obj != nullptr) {
4475+
// Collect relevant nets from the provided object
4476+
std::set<odb::dbNet*> nets_to_check;
4477+
std::set<odb::dbModNet*> mod_nets_to_check;
4478+
4479+
auto const obj_type = obj->getObjectType();
4480+
if (obj_type == odb::dbNetObj) {
4481+
nets_to_check.insert(static_cast<odb::dbNet*>(obj));
4482+
} else if (obj_type == odb::dbModNetObj) {
4483+
mod_nets_to_check.insert(static_cast<odb::dbModNet*>(obj));
4484+
} else if (obj_type == odb::dbInstObj) {
4485+
auto inst = static_cast<odb::dbInst*>(obj);
4486+
for (auto iterm : inst->getITerms()) {
4487+
if (iterm->getNet() != nullptr) {
4488+
nets_to_check.insert(iterm->getNet());
4489+
}
4490+
if (iterm->getModNet() != nullptr) {
4491+
mod_nets_to_check.insert(iterm->getModNet());
44874492
}
44884493
}
4489-
4490-
if (!all_tristate) {
4491-
std::string drivers_str;
4492-
for (const Pin* drvr : drvrs) {
4493-
drivers_str += " " + std::string(pathName(drvr));
4494+
} else if (obj_type == odb::dbModInstObj) {
4495+
auto mod_inst = static_cast<odb::dbModInst*>(obj);
4496+
for (auto mod_iterm : mod_inst->getModITerms()) {
4497+
if (mod_iterm->getModNet() != nullptr) {
4498+
mod_nets_to_check.insert(mod_iterm->getModNet());
44944499
}
4495-
logger_->error(
4496-
ORD,
4497-
2049,
4498-
"SanityCheck: Net '{}' has multiple non-tristate drivers:{}",
4499-
name(net),
4500-
drivers_str);
45014500
}
4502-
}
4503-
const uint iterm_count = net_db->getITerms().size();
4504-
const uint bterm_count = net_db->getBTerms().size();
4505-
if (iterm_count + bterm_count >= 2) {
4506-
continue;
4501+
} else if (obj_type == odb::dbITermObj) {
4502+
auto iterm = static_cast<odb::dbITerm*>(obj);
4503+
if (iterm->getNet() != nullptr) {
4504+
nets_to_check.insert(iterm->getNet());
4505+
}
4506+
if (iterm->getModNet() != nullptr) {
4507+
mod_nets_to_check.insert(iterm->getModNet());
4508+
}
4509+
} else if (obj_type == odb::dbBTermObj) {
4510+
auto bterm = static_cast<odb::dbBTerm*>(obj);
4511+
if (bterm->getNet() != nullptr) {
4512+
nets_to_check.insert(bterm->getNet());
4513+
}
4514+
if (bterm->getModNet() != nullptr) {
4515+
mod_nets_to_check.insert(bterm->getModNet());
4516+
}
4517+
} else if (obj_type == odb::dbModITermObj) {
4518+
auto mod_iterm = static_cast<odb::dbModITerm*>(obj);
4519+
if (mod_iterm->getModNet() != nullptr) {
4520+
mod_nets_to_check.insert(mod_iterm->getModNet());
4521+
}
4522+
} else if (obj_type == odb::dbModBTermObj) {
4523+
auto mod_bterm = static_cast<odb::dbModBTerm*>(obj);
4524+
if (mod_bterm->getModNet() != nullptr) {
4525+
mod_nets_to_check.insert(mod_bterm->getModNet());
4526+
}
45074527
}
45084528

4509-
// Skip power/ground net
4510-
if (net_db->getSigType().isSupply()) {
4511-
continue; // OK: Unconnected power/ground net
4529+
// Now run checks on the collected nets.
4530+
for (odb::dbModNet* mod_net : mod_nets_to_check) {
4531+
findRelatedDbNet(mod_net);
45124532
}
45134533

4514-
// A net connected to 1 terminal
4515-
if (iterm_count == 1) {
4516-
odb::dbITerm* iterm = *(net_db->getITerms().begin());
4517-
if (iterm->getIoType() == odb::dbIoType::OUTPUT) {
4518-
continue; // OK: Unconnected output pin
4519-
}
4520-
} else if (bterm_count == 1) { // This is a top level port
4521-
odb::dbBTerm* bterm = *(net_db->getBTerms().begin());
4522-
if (bterm->getIoType() == odb::dbIoType::INPUT) {
4523-
continue; // OK: Unconnected input port
4524-
}
4534+
for (odb::dbNet* net_db : nets_to_check) {
4535+
net_db->checkSanity();
45254536
}
4537+
return;
4538+
}
45264539

4527-
logger_->warn(ORD,
4528-
2039,
4529-
"SanityCheck: Net '{}' has less than 2 connections (# of "
4530-
"ITerms = {}, # of BTerms = {}).",
4531-
net_db->getName(),
4532-
iterm_count,
4533-
bterm_count);
4540+
//
4541+
// Check for all nets in the design
4542+
//
4543+
4544+
// Check for hier net and flat net connectivity
4545+
dbSet<dbModNet> mod_nets = block()->getModNets();
4546+
for (dbModNet* mod_net : mod_nets) {
4547+
findRelatedDbNet(mod_net);
4548+
}
4549+
4550+
// Check for incomplete flat net connections
4551+
for (odb::dbNet* net_db : block()->getNets()) {
4552+
net_db->checkSanity();
45344553
}
45354554
}
45364555

src/dbSta/test/check_axioms.ok

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
[INFO ODB-0227] LEF file: Nangate45/Nangate45.lef, created 22 layers, 27 vias, 135 library cells
2-
[WARNING ORD-2039] SanityCheck: Net 'out_unconnected' has less than 2 connections (# of ITerms = 0, # of BTerms = 1).
3-
[WARNING ORD-2039] SanityCheck: Net 'single_conn_wire' has less than 2 connections (# of ITerms = 0, # of BTerms = 0).
4-
[WARNING ORD-2039] SanityCheck: Net 'w2' has less than 2 connections (# of ITerms = 0, # of BTerms = 1).
2+
[WARNING ORD-0011] Hierarchical flow (-hier) is currently in development and may cause multiple issues. Do not use in production environments.
3+
[WARNING ODB-0050] SanityCheck: dbNet 'out_unconnected' has no driver.
4+
[WARNING ODB-0051] SanityCheck: dbNet 'out_unconnected' is dangling. It has less than 2 connections (# of ITerms = 0, # of BTerms = 1).
5+
[WARNING ODB-0051] SanityCheck: dbNet 'single_conn_wire' is dangling. It has less than 2 connections (# of ITerms = 0, # of BTerms = 0).
6+
[WARNING ODB-0050] SanityCheck: dbNet 'w2' has no driver.
7+
[WARNING ODB-0051] SanityCheck: dbNet 'w2' is dangling. It has less than 2 connections (# of ITerms = 0, # of BTerms = 1).
58
[WARNING ORD-2038] SanityCheck: Module 'i_empty' has no instances.
69
[WARNING ORD-2038] SanityCheck: Module 'u1' has no instances.
710
[WARNING ORD-2038] SanityCheck: Module 'u2' has no instances.

src/dbSta/test/check_axioms.tcl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ source "helpers.tcl"
55
read_liberty Nangate45/Nangate45_typ.lib
66
read_lef Nangate45/Nangate45.lef
77
read_verilog check_axioms.v
8-
link_design top
8+
link_design top -hier
99

1010
# Run the checks and capture output.
1111
# The 'catch' command is used because sta::check_axioms will exit with an

src/dbSta/test/check_axioms.v

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
// A standard cell definition for the test.
2-
// Defined as a blackbox to prevent yosys from optimizing it away.
32
module and2 (input A, input B, output Z);
43
endmodule
54

@@ -19,18 +18,19 @@ module top (
1918
output out_unconnected // For ORD-2040
2019
);
2120

22-
// For ORD-2038: An instance of a module that has no instances inside.
21+
// [WARNING ORD-2038] SanityCheck: Module 'i_empty' has no instances.
2322
empty_module i_empty();
2423

25-
// For ORD-2041: non-output ITerm not connected.
24+
// [ODB-0050] SanityCheck: 'w2' has no driver.
25+
// [ODB-0051] SanityCheck: 'w2' has less than 2 connections
2626
wire w1, w2;
2727
and2 u1 (.A(w1), .B(), .Z(w2));
2828

29-
// For ORD-2039: Net with < 2 connections.
29+
// [ODB-0051] SanityCheck: 'single_conn_wire' has less than 2 connections
3030
wire single_conn_wire;
3131
and2 u2 (.A(single_conn_wire), .B(top_in), .Z());
3232

33-
wire dangling_wire; // another case for ORD-2039
33+
wire dangling_wire;
3434

3535
// Normal connection to make the design valid for linking.
3636
assign top_out = w2;

src/ifp/include/ifp/InitFloorplan.hh

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33

44
#pragma once
55

6+
#include <cstdint>
7+
#include <limits>
68
#include <set>
79
#include <string>
810
#include <vector>
@@ -51,7 +53,7 @@ class InitFloorplan
5153
const std::vector<odb::dbSite*>& additional_sites = {},
5254
RowParity row_parity = RowParity::NONE,
5355
const std::set<odb::dbSite*>& flipped_sites = {},
54-
int gap = -1);
56+
int gap = std::numeric_limits<std::int32_t>::min());
5557

5658
// The base_site determines the single-height rows. For hybrid rows it is
5759
// a site containing a row pattern.
@@ -61,7 +63,7 @@ class InitFloorplan
6163
const std::vector<odb::dbSite*>& additional_sites = {},
6264
RowParity row_parity = RowParity::NONE,
6365
const std::set<odb::dbSite*>& flipped_sites = {},
64-
int gap = -1);
66+
int gap = std::numeric_limits<std::int32_t>::min());
6567

6668
void insertTiecells(odb::dbMTerm* tie_term,
6769
const std::string& prefix = "TIEOFF_");
@@ -92,7 +94,7 @@ class InitFloorplan
9294
= {},
9395
RowParity row_parity = RowParity::NONE,
9496
const std::set<odb::dbSite*>& flipped_sites = {},
95-
int gap = -1);
97+
int gap = std::numeric_limits<std::int32_t>::min());
9698

9799
// The base_site determines the single-height rows. For hybrid rows it is
98100
// a site containing a row pattern.
@@ -101,15 +103,15 @@ class InitFloorplan
101103
const std::vector<odb::dbSite*>& additional_sites = {},
102104
RowParity row_parity = RowParity::NONE,
103105
const std::set<odb::dbSite*>& flipped_sites = {},
104-
int gap = -1);
106+
int gap = std::numeric_limits<std::int32_t>::min());
105107

106108
// Create rows for a polygon core area using true polygon-aware generation
107109
void makePolygonRows(const odb::Polygon& core_polygon,
108110
odb::dbSite* base_site,
109111
const std::vector<odb::dbSite*>& additional_sites = {},
110112
RowParity row_parity = RowParity::NONE,
111113
const std::set<odb::dbSite*>& flipped_sites = {},
112-
int gap = -1);
114+
int gap = std::numeric_limits<std::int32_t>::min());
113115

114116
void makeTracks();
115117
void makeTracks(odb::dbTechLayer* layer,
@@ -178,6 +180,8 @@ class InitFloorplan
178180
// this is a set of sets of all constructed site ids.
179181
std::set<std::set<int>> constructed_patterns_;
180182
std::vector<std::vector<odb::dbSite*>> repeating_row_patterns_;
183+
184+
void checkGap(int gap);
181185
};
182186

183187
} // namespace ifp

0 commit comments

Comments
 (0)