Skip to content

Commit 1f00c70

Browse files
authored
Merge pull request #8168 from The-OpenROAD-Project-staging/secure-dbsta-fix-hasMembers-api
dbSta: Fixed dbNetwork::hasMember() and DbInstanceNetIterator.
2 parents 9b0deaa + faf08d6 commit 1f00c70

34 files changed

+1985
-15
lines changed

src/cts/test/hier_insertion_delay.vok

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,43 @@
11
module multi_sink (clk);
22
input clk;
33

4+
wire clknet_leaf_15_clk_regs;
5+
wire clknet_leaf_13_clk_regs;
6+
wire clknet_leaf_12_clk_regs;
7+
wire clknet_leaf_11_clk_regs;
8+
wire clk_regs;
9+
wire clknet_0_clk;
10+
wire clknet_1_0__leaf_clk;
11+
wire clknet_leaf_0_clk_regs;
12+
wire clknet_leaf_1_clk_regs;
13+
wire clknet_leaf_2_clk_regs;
14+
wire clknet_leaf_3_clk_regs;
15+
wire clknet_leaf_4_clk_regs;
16+
wire clknet_leaf_5_clk_regs;
17+
wire clknet_leaf_6_clk_regs;
18+
wire clknet_leaf_7_clk_regs;
19+
wire clknet_leaf_8_clk_regs;
20+
wire clknet_leaf_9_clk_regs;
21+
wire clknet_leaf_10_clk_regs;
22+
wire clknet_leaf_14_clk_regs;
23+
wire clknet_leaf_16_clk_regs;
24+
wire clknet_leaf_17_clk_regs;
25+
wire clknet_leaf_18_clk_regs;
26+
wire clknet_leaf_19_clk_regs;
27+
wire clknet_leaf_20_clk_regs;
28+
wire clknet_leaf_21_clk_regs;
29+
wire clknet_leaf_22_clk_regs;
30+
wire clknet_leaf_23_clk_regs;
31+
wire clknet_leaf_24_clk_regs;
32+
wire clknet_leaf_25_clk_regs;
33+
wire clknet_leaf_26_clk_regs;
34+
wire clknet_leaf_27_clk_regs;
35+
wire clknet_0_clk_regs;
36+
wire clknet_1_0__leaf_clk_regs;
37+
wire clknet_1_1__leaf_clk_regs;
38+
wire delaynet_0_core;
39+
wire delaynet_1_core;
40+
wire delaynet_2_core;
441

542
CLKBUF_X3 delaybuf_2_core (.A(delaynet_2_core),
643
.Z(clknet_0_clk));

src/cts/test/simple_test_hier_out.vok

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
module test_16_sinks (clk);
22
input clk;
33

4+
wire clknet_1_1__leaf_clk;
5+
wire clknet_1_0__leaf_clk;
6+
wire clknet_0_clk;
47

58
INV_X1 clkload0 (.A(clknet_1_1__leaf_clk));
69
CLKBUF_X3 clkbuf_1_1__f_clk (.A(clknet_0_clk),

src/dbSta/src/dbNetwork.cc

Lines changed: 85 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -316,23 +316,81 @@ class DbInstanceNetIterator : public InstanceNetIterator
316316
dbSet<dbNet>::iterator end_;
317317
dbSet<dbModNet>::iterator mod_net_iter_;
318318
dbSet<dbModNet>::iterator mod_net_end_;
319+
std::vector<dbNet*> flat_nets_vec_;
320+
size_t flat_net_idx_ = 0;
319321
};
320322

321323
DbInstanceNetIterator::DbInstanceNetIterator(const Instance* instance,
322324
const dbNetwork* network)
323325
: network_(network)
324326
{
325327
if (network_->hasHierarchy()) {
326-
dbInst* db_inst;
327-
dbModInst* mod_inst;
328-
network_->staToDb(instance, db_inst, mod_inst);
329-
if (mod_inst) {
330-
dbModule* master = mod_inst->getMaster();
331-
dbSet<dbModNet> nets = master->getModNets();
332-
mod_net_iter_ = nets.begin();
333-
mod_net_end_ = nets.end();
328+
//
329+
// In hierarchical flow, the net iterator collects both hierarchical
330+
// nets (dbModNets) and unique flat nets (dbNets) within the
331+
// instance's module scope.
332+
// Flat nets can be retrieved by traversing instance ITerms and BTerms.
333+
// Avoids the duplication b/w flat and hierarchical nets.
334+
//
335+
336+
// Get the module of the instance
337+
dbModule* module = nullptr;
338+
if (instance == network->topInstance()) {
339+
module = network->block()->getTopModule();
340+
} else {
341+
dbInst* db_inst;
342+
dbModInst* mod_inst;
343+
network_->staToDb(instance, db_inst, mod_inst);
344+
if (mod_inst) {
345+
module = mod_inst->getMaster();
346+
}
347+
}
348+
349+
if (module) {
350+
// Get dbModNets
351+
dbSet<dbModNet> mod_nets = module->getModNets();
352+
mod_net_iter_ = mod_nets.begin();
353+
mod_net_end_ = mod_nets.end();
354+
355+
// Keep track of flat nets that are already represented by a mod_net
356+
// to avoid returning both.
357+
std::set<dbNet*> handled_flat_nets;
358+
for (dbModNet* mod_net : mod_nets) {
359+
dbNet* flat_net = network_->findRelatedDbNet(mod_net);
360+
if (flat_net) {
361+
handled_flat_nets.insert(flat_net);
362+
}
363+
}
364+
365+
// Collect dbNets from children dbInsts' pins that are not already
366+
// handled.
367+
std::set<dbNet*> flat_nets_set;
368+
for (dbInst* child_inst : module->getInsts()) {
369+
for (dbITerm* iterm : child_inst->getITerms()) {
370+
dbNet* flat_net = iterm->getNet();
371+
if (flat_net
372+
&& handled_flat_nets.find(flat_net) == handled_flat_nets.end()) {
373+
flat_nets_set.insert(flat_net);
374+
}
375+
}
376+
}
377+
378+
// For top instance, also check top-level ports (BTerms)
379+
if (instance == network->topInstance()) {
380+
for (dbBTerm* bterm : network->block()->getBTerms()) {
381+
dbNet* flat_net = bterm->getNet();
382+
if (flat_net
383+
&& handled_flat_nets.find(flat_net) == handled_flat_nets.end()) {
384+
flat_nets_set.insert(flat_net);
385+
}
386+
}
387+
}
388+
flat_nets_vec_.assign(flat_nets_set.begin(), flat_nets_set.end());
334389
}
335390
} else {
391+
//
392+
// In flat flow, the net iterator collects all nets from top block
393+
//
336394
if (instance == network->topInstance()) {
337395
dbSet<dbNet> nets = network->block()->getNets();
338396
iter_ = nets.begin();
@@ -344,17 +402,27 @@ DbInstanceNetIterator::DbInstanceNetIterator(const Instance* instance,
344402
bool DbInstanceNetIterator::hasNext()
345403
{
346404
if (network_->hasHierarchy()) {
347-
return mod_net_iter_ != mod_net_end_;
405+
if (mod_net_iter_ != mod_net_end_) {
406+
return true;
407+
}
408+
return flat_net_idx_ < flat_nets_vec_.size();
348409
}
349410
return iter_ != end_;
350411
}
351412

352413
Net* DbInstanceNetIterator::next()
353414
{
354415
if (network_->hasHierarchy()) {
355-
dbModNet* net = *mod_net_iter_;
356-
mod_net_iter_++;
357-
return network_->dbToSta(net);
416+
if (mod_net_iter_ != mod_net_end_) {
417+
dbModNet* net = *mod_net_iter_;
418+
mod_net_iter_++;
419+
return network_->dbToSta(net);
420+
}
421+
if (flat_net_idx_ < flat_nets_vec_.size()) {
422+
dbNet* net = flat_nets_vec_[flat_net_idx_++];
423+
return network_->dbToSta(net);
424+
}
425+
return nullptr;
358426
}
359427
dbNet* net = *iter_;
360428
iter_++;
@@ -3226,10 +3294,12 @@ bool dbNetwork::hasMembers(const Port* port) const
32263294
dbBTerm* bterm = nullptr;
32273295
dbModBTerm* modbterm = nullptr;
32283296
staToDb(port, bterm, mterm, modbterm);
3229-
if (modbterm && modbterm->isBusPort()) {
3230-
return true;
3297+
if (modbterm) {
3298+
return modbterm->isBusPort();
32313299
}
3232-
return false;
3300+
3301+
// If port is a bus port of leaf liberty instance, modbterm is null.
3302+
// In the case, cport->hasMembers() should be checked.
32333303
}
32343304
const ConcretePort* cport = reinterpret_cast<const ConcretePort*>(port);
32353305
return cport->hasMembers();

src/dbSta/test/hier2_out.vok

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ module top (a,
55
input b;
66
output out;
77

8+
wire a_int;
89

910
INV_X1 _4_ (.ZN(a_int),
1011
.A(a));

src/dbSta/test/hierclock_out.vok

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ module hierclock (a_count_valid_o,
1919
output [3:0] b_count_o;
2020
input [3:0] b_i;
2121

22+
wire clk2_int;
23+
wire clk1_int;
2224

2325
clockgen U1 (.clk_i(clk_i),
2426
.rst_n_i(rst_n_i),
@@ -58,6 +60,19 @@ module clockgen (clk_i,
5860
output clk1_o;
5961
output clk2_o;
6062

63+
wire _03_;
64+
wire _04_;
65+
wire _05_;
66+
wire _06_;
67+
wire _11_;
68+
wire _12_;
69+
wire _13_;
70+
wire _14_;
71+
wire _15_;
72+
wire _19_;
73+
wire _20_;
74+
wire _21_;
75+
wire _22_;
6176
wire [3:0] counter_q;
6277

6378
INV_X1 _28_ (.A(rst_n_i),
@@ -124,6 +139,27 @@ module counter (clk_i,
124139
output count_valid_o;
125140

126141
wire count_valid_q;
142+
wire _12_;
143+
wire _13_;
144+
wire _14_;
145+
wire _15_;
146+
wire _16_;
147+
wire _26_;
148+
wire _27_;
149+
wire _28_;
150+
wire _29_;
151+
wire _30_;
152+
wire _31_;
153+
wire _32_;
154+
wire _33_;
155+
wire _34_;
156+
wire _35_;
157+
wire _36_;
158+
wire _38_;
159+
wire _39_;
160+
wire _40_;
161+
wire _41_;
162+
wire _42_;
127163
wire [3:0] counter_q;
128164

129165
INV_X1 _49_ (.A(_41_),
@@ -217,6 +253,27 @@ module counter_U3 (clk_i,
217253
output count_valid_o;
218254

219255
wire count_valid_q;
256+
wire _12_;
257+
wire _13_;
258+
wire _14_;
259+
wire _15_;
260+
wire _16_;
261+
wire _26_;
262+
wire _27_;
263+
wire _28_;
264+
wire _29_;
265+
wire _30_;
266+
wire _31_;
267+
wire _32_;
268+
wire _33_;
269+
wire _34_;
270+
wire _35_;
271+
wire _36_;
272+
wire _38_;
273+
wire _39_;
274+
wire _40_;
275+
wire _41_;
276+
wire _42_;
220277
wire [3:0] counter_q;
221278

222279
INV_X1 _49_ (.A(_41_),

0 commit comments

Comments
 (0)