Skip to content

Commit

Permalink
Added unit test for reapirhold. Signed-off-by: Andy Fox <[email protected]>
Browse files Browse the repository at this point in the history
Signed-off-by: andyfox-rushc <[email protected]>
  • Loading branch information
andyfox-rushc committed Sep 13, 2024
1 parent c5c8316 commit d7fce14
Show file tree
Hide file tree
Showing 7 changed files with 167 additions and 34 deletions.
5 changes: 2 additions & 3 deletions src/odb/include/odb/db.h
Original file line number Diff line number Diff line change
Expand Up @@ -3566,10 +3566,9 @@ class dbITerm : public dbObject
void disconnect();

///
/// Disconnect this iterm from the mod net, if any, it is connect to.
/// Selectively disconnect db_net/mod_net
//

void disconnectFromModNet();
void disconnect(bool db_net, bool mod_net);
///
/// Get the average of the centers for the iterm shapes
/// Returns false if iterm has no shapes
Expand Down
95 changes: 76 additions & 19 deletions src/odb/src/db/dbITerm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -459,7 +459,6 @@ void dbITerm::connect(dbNet* net_)

net->_iterms = iterm->getOID();


for (auto callback : block->_callbacks) {
callback->inDbITermPostConnect(this);
}
Expand Down Expand Up @@ -513,8 +512,14 @@ void dbITerm::connect(dbModNet* mod_net)
_mod_net->_iterms = iterm->getOID();
}

void dbITerm::disconnectFromModNet(){
void dbITerm::disconnect(bool db_net, bool mod_net)
{
_dbITerm* iterm = (_dbITerm*) this;

if (iterm->_net == 0) {
return;
}

_dbInst* inst = iterm->getInst();
if (inst->_flags._dont_touch) {
inst->getLogger()->error(
Expand All @@ -524,31 +529,83 @@ void dbITerm::disconnectFromModNet(){
inst->_name);
}
_dbBlock* block = (_dbBlock*) iterm->getOwner();
if (iterm->_mnet == 0) {
return;
_dbNet* net = block->_net_tbl->getPtr(iterm->_net);

if (net->_flags._dont_touch) {
inst->getLogger()->error(utl::ODB,
400,
"Attempt to disconnect iterm of dont_touch net {}",
net->_name);
}
_dbModNet* mod_net = block->_modnet_tbl->getPtr(iterm->_mnet);

for (auto callback : block->_callbacks) {
callback->inDbITermPreDisconnect(this);
}
if (block->_journal) {
debugPrint(iterm->getImpl()->getLogger(),
utl::ODB,
"DB_ECO",
1,
"ECO: disconnect Iterm {}",
getId());
block->_journal->beginAction(dbJournal::DISCONNECT_OBJECT);
block->_journal->pushParam(dbITermObj);
block->_journal->pushParam(getId());
block->_journal->pushParam(net->getOID());
block->_journal->endAction();
}

uint id = iterm->getOID();
if (mod_net->_iterms == id) {
mod_net->_iterms = iterm->_next_modnet_iterm;
if (mod_net->_iterms != 0) {
_dbITerm* t = block->_iterm_tbl->getPtr(mod_net->_iterms);
t->_prev_modnet_iterm = 0;
if (db_net) {
if (net->_iterms == id) {
net->_iterms = iterm->_next_net_iterm;
if (net->_iterms != 0) {
_dbITerm* t = block->_iterm_tbl->getPtr(net->_iterms);
t->_prev_net_iterm = 0;
}
} else {
if (iterm->_next_net_iterm != 0) {
_dbITerm* next = block->_iterm_tbl->getPtr(iterm->_next_net_iterm);
next->_prev_net_iterm = iterm->_prev_net_iterm;
}
if (iterm->_prev_net_iterm != 0) {
_dbITerm* prev = block->_iterm_tbl->getPtr(iterm->_prev_net_iterm);
prev->_next_net_iterm = iterm->_next_net_iterm;
}
}
} else {
if (iterm->_next_modnet_iterm != 0) {
_dbITerm* next = block->_iterm_tbl->getPtr(iterm->_next_modnet_iterm);
next->_prev_modnet_iterm = iterm->_prev_modnet_iterm;
iterm->_net = 0;
for (auto callback : block->_callbacks) {
callback->inDbITermPostDisconnect(this, (dbNet*) net);
}
if (iterm->_prev_modnet_iterm != 0) {
_dbITerm* prev = block->_iterm_tbl->getPtr(iterm->_prev_modnet_iterm);
prev->_next_modnet_iterm = iterm->_next_modnet_iterm;
}

if (mod_net) {
// the modnet part
if (iterm->_mnet == 0) {
return;
}
_dbModNet* mod_net = block->_modnet_tbl->getPtr(iterm->_mnet);

if (mod_net->_iterms == id) {
mod_net->_iterms = iterm->_next_modnet_iterm;
if (mod_net->_iterms != 0) {
_dbITerm* t = block->_iterm_tbl->getPtr(mod_net->_iterms);
t->_prev_modnet_iterm = 0;
}
} else {
if (iterm->_next_modnet_iterm != 0) {
_dbITerm* next = block->_iterm_tbl->getPtr(iterm->_next_modnet_iterm);
next->_prev_modnet_iterm = iterm->_prev_modnet_iterm;
}
if (iterm->_prev_modnet_iterm != 0) {
_dbITerm* prev = block->_iterm_tbl->getPtr(iterm->_prev_modnet_iterm);
prev->_next_modnet_iterm = iterm->_next_modnet_iterm;
}
}
iterm->_mnet = 0;
}
iterm->_mnet = 0;
}


void dbITerm::disconnect()
{
_dbITerm* iterm = (_dbITerm*) this;
Expand Down
34 changes: 22 additions & 12 deletions src/rsz/src/RepairHold.cc
Original file line number Diff line number Diff line change
Expand Up @@ -581,7 +581,8 @@ void RepairHold::makeHoldDelay(Vertex* drvr,
odb::dbBTerm* bterm = nullptr;
db_network_->staToDb(drvr_pin, iterm, bterm, moditerm, modbterm);
if (iterm) {
iterm->disconnectFromModNet();
// only disconnect to the modnet.
iterm->disconnect(false, true);
}
if (moditerm) {
moditerm->disconnect();
Expand Down Expand Up @@ -640,25 +641,34 @@ void RepairHold::makeHoldDelay(Vertex* drvr,
Net* load_net = network_->isTopLevelPort(load_pin)
? network_->net(network_->term(load_pin))
: network_->net(load_pin);

odb::dbModNet* original_load_mod_net;
odb::dbNet* original_load_flat_net;
db_network_->net(load_pin, original_load_flat_net, original_load_mod_net);

if (load_net != out_net) {
Instance* load = db_network_->instance(load_pin);
Port* load_port = db_network_->port(load_pin);
// record the original connections
odb::dbModNet* original_mod_net;
odb::dbNet* original_flat_net;
db_network_->net(load_pin, original_flat_net, original_mod_net);
(void) original_flat_net;
// Remove all the connections on load_pin
sta_->disconnectPin(const_cast<Pin*>(load_pin));
// Connect it to the correct output driver net
sta_->connectPin(load, load_port, out_net);
// hook to modnet to preserve original hierarchical connection, if any
if (mod_drvr_net) {
odb::dbITerm* iterm;
odb::dbBTerm* bterm;
odb::dbModITerm* moditerm;
odb::dbModBTerm* modbterm;
db_network_->staToDb(load_pin, iterm, bterm, moditerm, modbterm);
if (iterm) {
iterm->connect(mod_drvr_net);
}
// restore the original load modnet.
odb::dbITerm* iterm;
odb::dbBTerm* bterm;
odb::dbModITerm* moditerm;
odb::dbModBTerm* modbterm;
db_network_->staToDb(load_pin, iterm, bterm, moditerm, modbterm);
if (iterm && original_mod_net) {
iterm->connect(original_mod_net);
}
}
}

Pin* buffer_out_pin = network_->findPin(buffer, output);
Vertex* buffer_out_vertex = graph_->pinDrvrVertex(buffer_out_pin);
resizer_->updateParasitics();
Expand Down
1 change: 1 addition & 0 deletions src/rsz/test/regression_tests.tcl
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
record_tests {
resize1_hier
repair_hold1_hier
buffer_ports1
buffer_ports3
buffer_ports4
Expand Down
6 changes: 6 additions & 0 deletions src/rsz/test/repair_hold1_hier.ok
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[INFO ODB-0227] LEF file: Nangate45/Nangate45.lef, created 22 layers, 27 vias, 135 library cells
(clk ^) r -0.03:1.91 f -0.03:1.91
[INFO RSZ-0046] Found 1 endpoints with hold violations.
[INFO RSZ-0032] Inserted 2 hold buffers.
(clk ^) r 0.02:1.89 f 0.02:1.88
No differences found.
3 changes: 3 additions & 0 deletions src/rsz/test/repair_hold1_hier.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,6 @@ report_slack r3/D
rsz::repair_hold_pin [get_pins r3/D] 0.0 0.0 0 1.0 100

report_slack r3/D
set verilog_file [make_result_file repair_hold1_hier_out.v]
write_verilog $verilog_file
diff_files $verilog_file repair_hold1_hier_out.vok
57 changes: 57 additions & 0 deletions src/rsz/test/repair_hold1_hier_out.vok
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
module top (clk,
in1,
in2,
out);
input clk;
input in1;
input in2;
output out;


CLKBUF_X1 hold2 (.A(u2z),
.Z(u2z));
BUF_X1 i1 (.A(clk),
.Z(i1z));
BUF_X1 i2 (.A(i1z),
.Z(i2z));
BUF_X1 i3 (.A(i2z),
.Z(i3z));
BUF_X1 i4 (.A(i3z),
.Z(i4z));
BUF_X1 i5 (.A(i4z),
.Z(i5z));
BUF_X1 i6 (.A(i5z),
.Z(i6z));
BUF_X1 i7 (.A(i6z),
.Z(i7z));
BUF_X1 i8 (.A(i7z),
.Z(i8z));
DFF_X1 r2 (.D(in2),
.CK(i4z),
.Q(r2q));
DFF_X1 r3 (.D(u2z),
.CK(i8z),
.Q(out));
BUF_X1 u1 (.A(r2q),
.Z(u1z));
AND2_X1 u2 (.A1(r1q),
.A2(u1z),
.ZN(u2z));
hier1 h1 (.in1(in1),
.i1z(i1z),
.op(r1q));
endmodule
module hier1 (in1,
i1z,
op);
input in1;
input i1z;
output op;


CLKBUF_X1 hold1 (.A(r1q),
.Z(op));
DFF_X1 \h1/r1 (.D(in1),
.CK(i1z),
.Q(r1q));
endmodule

0 comments on commit d7fce14

Please sign in to comment.