From ce54e9d710ea313b16e200a9d6564b69c3aa3379 Mon Sep 17 00:00:00 2001 From: andyfox-rushc Date: Thu, 23 May 2024 11:49:03 -0700 Subject: [PATCH] Hierarchical id encoding, test for clocks constrained on same port to show unique ids. Signed-off-by: Andy Fox Signed-off-by: andyfox-rushc --- src/dbSta/src/dbNetwork.cc | 87 ++++++-- src/dbSta/test/hierclock.ok | 70 +++++++ src/dbSta/test/hierclock_out.vok | 347 +++++++++++++++++++++++++++++++ 3 files changed, 481 insertions(+), 23 deletions(-) create mode 100644 src/dbSta/test/hierclock.ok create mode 100644 src/dbSta/test/hierclock_out.vok diff --git a/src/dbSta/src/dbNetwork.cc b/src/dbSta/src/dbNetwork.cc index 35f71da430c..aa2d0dcc41e 100644 --- a/src/dbSta/src/dbNetwork.cc +++ b/src/dbSta/src/dbNetwork.cc @@ -273,8 +273,12 @@ DbInstancePinIterator::DbInstancePinIterator(const Instance* inst, if (top_) { dbBlock* block = network->block(); - bitr_ = block->getBTerms().begin(); - bitr_end_ = block->getBTerms().end(); + // it is possible that a block might not have been created if no design + // has been read in. + if (block) { + bitr_ = block->getBTerms().begin(); + bitr_end_ = block->getBTerms().end(); + } } else { dbInst* db_inst; dbModInst* mod_inst; @@ -427,9 +431,7 @@ DbNetTermIterator::DbNetTermIterator(const Net* net, const dbNetwork* network) bool DbNetTermIterator::hasNext() { - if (mod_iter_ != mod_end_ || iter_ != end_) - return true; - return false; + return (mod_iter_ != mod_end_ || iter_ != end_); } Term* DbNetTermIterator::next() @@ -508,6 +510,17 @@ ObjectId dbNetwork::id(const Instance* instance) const if (instance == top_instance_) { return 0; } + if (hierarchy_) { + dbInst* db_inst; + dbModInst* mod_inst; + staToDb(instance, db_inst, mod_inst); + if (db_inst) { + return db_inst->getId() >> 2; + } + if (mod_inst) { + return (mod_inst->getId() >> 2) + 1; + } + } return staToDb(instance)->getId(); } @@ -574,7 +587,6 @@ void dbNetwork::makeVerilogCell(Library* library, dbModInst* mod_inst) } } -// upto here. Cell* dbNetwork::cell(const Instance* instance) const { if (instance == top_instance_) { @@ -754,20 +766,36 @@ ObjectId dbNetwork::id(const Pin* pin) const dbModITerm* moditerm = nullptr; dbModBTerm* modbterm = nullptr; - staToDb(pin, iterm, bterm, moditerm, modbterm); + static std::map id_ptr_map; - if (iterm != nullptr) { - return iterm->getId() << 1; - } - if (bterm != nullptr) { - return (bterm->getId() << 1) + 1; - } + staToDb(pin, iterm, bterm, moditerm, modbterm); - if (moditerm != nullptr) { - return (moditerm->getId()); - } - if (modbterm != nullptr) { - return (modbterm->getId()); + if (hierarchy_) { + // The id is used by the STA traversers to accumulate visited. + // lower bits used to encode type + // id,00 <- iterm + // id,01 <- bterm + // id,10 <- moditerm + // id,11 <- modbterm + if (iterm != nullptr) { + return iterm->getId() << 2; + } + if (bterm != nullptr) { + return (bterm->getId() << 2) | 1; + } + if (moditerm != nullptr) { + return (moditerm->getId() << 2) | 2; + } + if (modbterm != nullptr) { + return (modbterm->getId() << 2) | 3; + } + } else { + if (iterm != nullptr) { + return iterm->getId() << 1; + } + if (bterm != nullptr) { + return (bterm->getId() << 1) + 1; + } } return 0; } @@ -775,6 +803,7 @@ ObjectId dbNetwork::id(const Pin* pin) const Instance* dbNetwork::instance(const Pin* pin) const { dbITerm* iterm; + dbBTerm* bterm; dbModITerm* moditerm = nullptr; dbModBTerm* modbterm = nullptr; @@ -814,9 +843,6 @@ Net* dbNetwork::net(const Pin* pin) const // that we have both a mod net and a dbinst net. // In the case of writing out a hierachical network we always // choose the mnet. - if (dnet && mnet) { - return dbToSta(mnet); - } if (mnet) return dbToSta(mnet); if (dnet) @@ -937,7 +963,7 @@ PortDirection* dbNetwork::direction(const Pin* pin) const // get the direction off the modbterm std::string pin_name = moditerm->getName(); dbModInst* mod_inst = moditerm->getParent(); - dbModule* module = mod_inst->getParent(); + dbModule* module = mod_inst->getMaster(); dbModBTerm* modbterm_local = module->findModBTerm(pin_name.c_str()); PortDirection* dir = dbToSta(modbterm_local->getSigType(), modbterm_local->getIoType()); @@ -969,6 +995,7 @@ void dbNetwork::setVertexId(Pin* pin, VertexId id) dbModITerm* moditerm = nullptr; dbModBTerm* modbterm = nullptr; staToDb(pin, iterm, bterm, moditerm, modbterm); + // timing arcs only set on leaf level iterm/bterm. if (iterm) { iterm->staSetVertexId(id); } else if (bterm) { @@ -1041,7 +1068,20 @@ bool dbNetwork::isPlaced(const Pin* pin) const ObjectId dbNetwork::id(const Net* net) const { - return staToDb(net)->getId(); + dbModNet* modnet = nullptr; + dbNet* dnet = nullptr; + staToDb(net, dnet, modnet); + if (hierarchy_) { + if (dnet) { + return dnet->getId() << 2; + } + if (modnet) { + return (modnet->getId() << 2) + 1; + } + } else { + return dnet->getId(); + } + return 0; } const char* dbNetwork::name(const Net* net) const @@ -1758,6 +1798,7 @@ void dbNetwork::staToDb(const Pin* pin, dbITerm*& iterm, dbBTerm*& bterm, dbModITerm*& moditerm, + // axiom never see a modbterm... dbModBTerm*& modbterm) const { iterm = nullptr; diff --git a/src/dbSta/test/hierclock.ok b/src/dbSta/test/hierclock.ok new file mode 100644 index 00000000000..96f7f10209b --- /dev/null +++ b/src/dbSta/test/hierclock.ok @@ -0,0 +1,70 @@ +[INFO ODB-0227] LEF file: Nangate45/Nangate45.lef, created 22 layers, 27 vias, 135 library cells +Startpoint: U2/_66_ (rising edge-triggered flip-flop clocked by clk1) +Endpoint: U2/_66_ (rising edge-triggered flip-flop clocked by clk1) +Path Group: clk1 +Path Type: min + +Fanout Cap Slew Delay Time Description +----------------------------------------------------------------------------- + 0.00 0.00 0.00 clock clk1 (rise edge) + 0.00 0.00 clock network delay (ideal) + 0.00 0.00 0.00 ^ U2/_66_/CK (DFF_X1) + 1 1.55 0.01 0.06 0.06 v U2/_66_/QN (DFF_X1) + _41_ (net) + 0.01 0.00 0.06 v U2/_49_/A (INV_X1) + 1 1.68 0.01 0.01 0.08 ^ U2/_49_/ZN (INV_X1) + _26_ (net) + 0.01 0.00 0.08 ^ U2/_53_/B2 (AOI21_X1) + 1 1.06 0.01 0.01 0.09 v U2/_53_/ZN (AOI21_X1) + _13_ (net) + 0.01 0.00 0.09 v U2/_66_/D (DFF_X1) + 0.09 data arrival time + + 0.00 0.00 0.00 clock clk1 (rise edge) + 0.00 0.00 clock network delay (ideal) + 0.00 0.00 clock reconvergence pessimism + 0.00 ^ U2/_66_/CK (DFF_X1) + 0.00 0.00 library hold time + 0.00 data required time +----------------------------------------------------------------------------- + 0.00 data required time + -0.09 data arrival time +----------------------------------------------------------------------------- + 0.09 slack (MET) + + +Startpoint: U3/_66_ (rising edge-triggered flip-flop clocked by clk2) +Endpoint: U3/_66_ (rising edge-triggered flip-flop clocked by clk2) +Path Group: clk2 +Path Type: min + +Fanout Cap Slew Delay Time Description +----------------------------------------------------------------------------- + 0.00 0.00 0.00 clock clk2 (rise edge) + 0.00 0.00 clock network delay (ideal) + 0.00 0.00 0.00 ^ U3/_66_/CK (DFF_X1) + 1 1.55 0.01 0.06 0.06 v U3/_66_/QN (DFF_X1) + _41_ (net) + 0.01 0.00 0.06 v U3/_49_/A (INV_X1) + 1 1.68 0.01 0.01 0.08 ^ U3/_49_/ZN (INV_X1) + _26_ (net) + 0.01 0.00 0.08 ^ U3/_53_/B2 (AOI21_X1) + 1 1.06 0.01 0.01 0.09 v U3/_53_/ZN (AOI21_X1) + _13_ (net) + 0.01 0.00 0.09 v U3/_66_/D (DFF_X1) + 0.09 data arrival time + + 0.00 0.00 0.00 clock clk2 (rise edge) + 0.00 0.00 clock network delay (ideal) + 0.00 0.00 clock reconvergence pessimism + 0.00 ^ U3/_66_/CK (DFF_X1) + 0.00 0.00 library hold time + 0.00 data required time +----------------------------------------------------------------------------- + 0.00 data required time + -0.09 data arrival time +----------------------------------------------------------------------------- + 0.09 slack (MET) + + +No differences found. diff --git a/src/dbSta/test/hierclock_out.vok b/src/dbSta/test/hierclock_out.vok new file mode 100644 index 00000000000..4b2e73d21f3 --- /dev/null +++ b/src/dbSta/test/hierclock_out.vok @@ -0,0 +1,347 @@ +module hierclock (a_count_valid_o, + a_ld_i, + b_count_valid_o, + b_ld_i, + clk_i, + rst_n_i, + a_count_o, + a_i, + b_count_o, + b_i); + output a_count_valid_o; + input a_ld_i; + output b_count_valid_o; + input b_ld_i; + input clk_i; + input rst_n_i; + output [3:0] a_count_o; + input [3:0] a_i; + output [3:0] b_count_o; + input [3:0] b_i; + + wire clk1_int; + wire clk2_int; + wire \U1/_03_ ; + wire \U1/_04_ ; + wire \U1/_05_ ; + wire \U1/_06_ ; + wire \U1/_11_ ; + wire \U1/_12_ ; + wire \U1/_13_ ; + wire \U1/_14_ ; + wire \U1/_15_ ; + wire \U1/_19_ ; + wire \U1/_20_ ; + wire \U1/_21_ ; + wire \U1/_22_ ; + wire \U2/_12_ ; + wire \U2/_13_ ; + wire \U2/_14_ ; + wire \U2/_15_ ; + wire \U2/_16_ ; + wire \U2/_26_ ; + wire \U2/_27_ ; + wire \U2/_28_ ; + wire \U2/_29_ ; + wire \U2/_30_ ; + wire \U2/_31_ ; + wire \U2/_32_ ; + wire \U2/_33_ ; + wire \U2/_34_ ; + wire \U2/_35_ ; + wire \U2/_36_ ; + wire \U2/_38_ ; + wire \U2/_39_ ; + wire \U2/_40_ ; + wire \U2/_41_ ; + wire \U2/_42_ ; + wire \U3/_12_ ; + wire \U3/_13_ ; + wire \U3/_14_ ; + wire \U3/_15_ ; + wire \U3/_16_ ; + wire \U3/_26_ ; + wire \U3/_27_ ; + wire \U3/_28_ ; + wire \U3/_29_ ; + wire \U3/_30_ ; + wire \U3/_31_ ; + wire \U3/_32_ ; + wire \U3/_33_ ; + wire \U3/_34_ ; + wire \U3/_35_ ; + wire \U3/_36_ ; + wire \U3/_38_ ; + wire \U3/_39_ ; + wire \U3/_40_ ; + wire \U3/_41_ ; + wire \U3/_42_ ; + wire [2:0] \U1/counter_q ; + + clockgen U1 (.clk2_o(clk2_int), + .clk1_o(clk1_int), + .rst_n_i(rst_n_i), + .clk_i(clk_i)); + counter U2 (.count_valid_o(a_count_valid_o), + .load_i(a_ld_i), + .rst_n_i(rst_n_i), + .clk_i(clk1_int), + .count_value_o({a_count_o[3], + a_count_o[2], + a_count_o[1], + a_count_o[0]}), + .load_value_i({a_i[3], + a_i[2], + a_i[1], + a_i[0]})); + counter-1 U3 (.count_valid_o(b_count_valid_o), + .load_i(b_ld_i), + .rst_n_i(rst_n_i), + .clk_i(clk2_int), + .count_value_o({b_count_o[3], + b_count_o[2], + b_count_o[1], + b_count_o[0]}), + .load_value_i({b_i[3], + b_i[2], + b_i[1], + b_i[0]})); +endmodule +module clockgen (clk2_o, + clk1_o, + rst_n_i, + clk_i); + output clk2_o; + output clk1_o; + input rst_n_i; + input clk_i; + + + INV_X1 \U1/_28_ (.A(rst_n_i), + .ZN(_11_)); + AND2_X1 \U1/_29_ (.A1(_22_), + .A2(rst_n_i), + .ZN(_03_)); + OAI21_X1 \U1/_30_ (.A(rst_n_i), + .B1(counter_q[1]), + .B2(counter_q[0]), + .ZN(_12_)); + AOI21_X1 \U1/_31_ (.A(_12_), + .B1(counter_q[1]), + .B2(counter_q[0]), + .ZN(_04_)); + AND3_X1 \U1/_32_ (.A1(counter_q[0]), + .A2(counter_q[1]), + .A3(counter_q[2]), + .ZN(_13_)); + AOI21_X1 \U1/_33_ (.A(counter_q[2]), + .B1(counter_q[1]), + .B2(counter_q[0]), + .ZN(_14_)); + NOR3_X1 \U1/_34_ (.A1(_11_), + .A2(_13_), + .A3(_14_), + .ZN(_05_)); + XNOR2_X1 \U1/_35_ (.A(counter_q[3]), + .B(_13_), + .ZN(_15_)); + NOR2_X1 \U1/_36_ (.A1(_11_), + .A2(_15_), + .ZN(_06_)); + DFF_X1 \U1/_37_ (.D(_03_), + .CK(clk_i), + .Q(counter_q[0]), + .QN(_22_)); + DFF_X1 \U1/_38_ (.D(_04_), + .CK(clk_i), + .Q(counter_q[1]), + .QN(_21_)); + DFF_X1 \U1/_39_ (.D(_05_), + .CK(clk_i), + .Q(counter_q[2]), + .QN(_20_)); + DFF_X1 \U1/_40_ (.D(_06_), + .CK(clk_i), + .Q(counter_q[3]), + .QN(_19_)); +endmodule +module counter (count_valid_o, + load_i, + rst_n_i, + clk_i, + count_value_o, + load_value_i); + output count_valid_o; + input load_i; + input rst_n_i; + input clk_i; + output [3:0] count_value_o; + input [3:0] load_value_i; + + + INV_X1 \U2/_49_ (.A(_41_), + .ZN(_26_)); + INV_X1 \U2/_50_ (.A(load_i), + .ZN(_27_)); + AND2_X1 \U2/_51_ (.A1(_27_), + .A2(rst_n_i), + .ZN(_12_)); + OAI21_X1 \U2/_52_ (.A(rst_n_i), + .B1(_27_), + .B2(load_value_i[0]), + .ZN(_28_)); + AOI21_X1 \U2/_53_ (.A(_28_), + .B1(_27_), + .B2(_26_), + .ZN(_13_)); + NAND2_X1 \U2/_54_ (.A1(counter_q[0]), + .A2(counter_q[1]), + .ZN(_29_)); + XNOR2_X1 \U2/_55_ (.A(counter_q[0]), + .B(counter_q[1]), + .ZN(_30_)); + OAI21_X1 \U2/_56_ (.A(rst_n_i), + .B1(load_value_i[1]), + .B2(_27_), + .ZN(_31_)); + AOI21_X1 \U2/_57_ (.A(_31_), + .B1(_30_), + .B2(_27_), + .ZN(_14_)); + NAND3_X1 \U2/_58_ (.A1(counter_q[0]), + .A2(counter_q[1]), + .A3(counter_q[2]), + .ZN(_32_)); + XOR2_X1 \U2/_59_ (.A(counter_q[2]), + .B(_29_), + .Z(_33_)); + OAI21_X1 \U2/_60_ (.A(rst_n_i), + .B1(load_value_i[2]), + .B2(_27_), + .ZN(_34_)); + AOI21_X1 \U2/_61_ (.A(_34_), + .B1(_33_), + .B2(_27_), + .ZN(_15_)); + XOR2_X1 \U2/_62_ (.A(counter_q[3]), + .B(_32_), + .Z(_35_)); + OAI21_X1 \U2/_63_ (.A(rst_n_i), + .B1(load_value_i[3]), + .B2(_27_), + .ZN(_36_)); + AOI21_X1 \U2/_64_ (.A(_36_), + .B1(_35_), + .B2(_27_), + .ZN(_16_)); + DFF_X1 \U2/_65_ (.D(_12_), + .CK(clk_i), + .Q(count_valid_q), + .QN(_42_)); + DFF_X1 \U2/_66_ (.D(_13_), + .CK(clk_i), + .Q(counter_q[0]), + .QN(_41_)); + DFF_X1 \U2/_67_ (.D(_14_), + .CK(clk_i), + .Q(counter_q[1]), + .QN(_40_)); + DFF_X1 \U2/_68_ (.D(_15_), + .CK(clk_i), + .Q(counter_q[2]), + .QN(_39_)); + DFF_X1 \U2/_69_ (.D(_16_), + .CK(clk_i), + .Q(counter_q[3]), + .QN(_38_)); +endmodule +module counter-1 (count_valid_o, + load_i, + rst_n_i, + clk_i, + count_value_o, + load_value_i); + output count_valid_o; + input load_i; + input rst_n_i; + input clk_i; + output [3:0] count_value_o; + input [3:0] load_value_i; + + + INV_X1 \U3/_49_ (.A(_41_), + .ZN(_26_)); + INV_X1 \U3/_50_ (.A(load_i), + .ZN(_27_)); + AND2_X1 \U3/_51_ (.A1(_27_), + .A2(rst_n_i), + .ZN(_12_)); + OAI21_X1 \U3/_52_ (.A(rst_n_i), + .B1(_27_), + .B2(load_value_i[0]), + .ZN(_28_)); + AOI21_X1 \U3/_53_ (.A(_28_), + .B1(_27_), + .B2(_26_), + .ZN(_13_)); + NAND2_X1 \U3/_54_ (.A1(counter_q[0]), + .A2(counter_q[1]), + .ZN(_29_)); + XNOR2_X1 \U3/_55_ (.A(counter_q[0]), + .B(counter_q[1]), + .ZN(_30_)); + OAI21_X1 \U3/_56_ (.A(rst_n_i), + .B1(load_value_i[1]), + .B2(_27_), + .ZN(_31_)); + AOI21_X1 \U3/_57_ (.A(_31_), + .B1(_30_), + .B2(_27_), + .ZN(_14_)); + NAND3_X1 \U3/_58_ (.A1(counter_q[0]), + .A2(counter_q[1]), + .A3(counter_q[2]), + .ZN(_32_)); + XOR2_X1 \U3/_59_ (.A(counter_q[2]), + .B(_29_), + .Z(_33_)); + OAI21_X1 \U3/_60_ (.A(rst_n_i), + .B1(load_value_i[2]), + .B2(_27_), + .ZN(_34_)); + AOI21_X1 \U3/_61_ (.A(_34_), + .B1(_33_), + .B2(_27_), + .ZN(_15_)); + XOR2_X1 \U3/_62_ (.A(counter_q[3]), + .B(_32_), + .Z(_35_)); + OAI21_X1 \U3/_63_ (.A(rst_n_i), + .B1(load_value_i[3]), + .B2(_27_), + .ZN(_36_)); + AOI21_X1 \U3/_64_ (.A(_36_), + .B1(_35_), + .B2(_27_), + .ZN(_16_)); + DFF_X1 \U3/_65_ (.D(_12_), + .CK(clk_i), + .Q(count_valid_q), + .QN(_42_)); + DFF_X1 \U3/_66_ (.D(_13_), + .CK(clk_i), + .Q(counter_q[0]), + .QN(_41_)); + DFF_X1 \U3/_67_ (.D(_14_), + .CK(clk_i), + .Q(counter_q[1]), + .QN(_40_)); + DFF_X1 \U3/_68_ (.D(_15_), + .CK(clk_i), + .Q(counter_q[2]), + .QN(_39_)); + DFF_X1 \U3/_69_ (.D(_16_), + .CK(clk_i), + .Q(counter_q[3]), + .QN(_38_)); +endmodule