Skip to content

Commit

Permalink
Merge pull request #6163 from The-OpenROAD-Project-staging/secure-swa…
Browse files Browse the repository at this point in the history
…p-module

Operator module swap phase 1
  • Loading branch information
maliberty authored Nov 19, 2024
2 parents b61519b + 2b9cb35 commit 142a440
Show file tree
Hide file tree
Showing 21 changed files with 908 additions and 46 deletions.
1 change: 0 additions & 1 deletion src/cts/test/regression_tests.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ record_tests {
simple_test
simple_test_clustered
simple_test_clustered_max_cap
simple_test_hier
lvt_lib
#cts_readme_msgs_check
#cts_man_tcl_check
Expand Down
28 changes: 14 additions & 14 deletions src/cts/test/simple_test_hier_out.vok
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,18 @@ module test_16_sinks (clk);
.Z(clknet_0_clk));
flop_pair U1 (.clknet_1_1__leaf_clk_i(clknet_1_1__leaf_clk),
.clknet_1_0__leaf_clk_i(clknet_1_0__leaf_clk));
flop_pair-1 U2 (.clknet_1_1__leaf_clk_i(clknet_1_1__leaf_clk),
flop_pair_U2 U2 (.clknet_1_1__leaf_clk_i(clknet_1_1__leaf_clk),
.clknet_1_0__leaf_clk_i(clknet_1_0__leaf_clk));
flop_pair-2 U3 (.clknet_1_1__leaf_clk_i(clknet_1_1__leaf_clk),
flop_pair_U3 U3 (.clknet_1_1__leaf_clk_i(clknet_1_1__leaf_clk),
.clknet_1_0__leaf_clk_i(clknet_1_0__leaf_clk));
flop_pair-3 U4 (.clknet_1_1__leaf_clk_i(clknet_1_1__leaf_clk),
flop_pair_U4 U4 (.clknet_1_1__leaf_clk_i(clknet_1_1__leaf_clk),
.clknet_1_0__leaf_clk_i(clknet_1_0__leaf_clk));
flop_pair-4 U5 (.clknet_1_0__leaf_clk_i(clknet_1_0__leaf_clk));
flop_pair-5 U6 (.clknet_1_1__leaf_clk_i(clknet_1_1__leaf_clk),
flop_pair_U5 U5 (.clknet_1_0__leaf_clk_i(clknet_1_0__leaf_clk));
flop_pair_U6 U6 (.clknet_1_1__leaf_clk_i(clknet_1_1__leaf_clk),
.clknet_1_0__leaf_clk_i(clknet_1_0__leaf_clk));
flop_pair-6 U7 (.clknet_1_1__leaf_clk_i(clknet_1_1__leaf_clk),
flop_pair_U7 U7 (.clknet_1_1__leaf_clk_i(clknet_1_1__leaf_clk),
.clknet_1_0__leaf_clk_i(clknet_1_0__leaf_clk));
flop_pair-7 U8 (.clknet_1_1__leaf_clk_i(clknet_1_1__leaf_clk),
flop_pair_U8 U8 (.clknet_1_1__leaf_clk_i(clknet_1_1__leaf_clk),
.clknet_1_0__leaf_clk_i(clknet_1_0__leaf_clk));
endmodule
module flop_pair (clknet_1_1__leaf_clk_i,
Expand All @@ -34,7 +34,7 @@ module flop_pair (clknet_1_1__leaf_clk_i,
DFF_X1 ff1 (.CK(clknet_1_1__leaf_clk_i));
DFF_X1 ff2 (.CK(clknet_1_0__leaf_clk_i));
endmodule
module flop_pair-1 (clknet_1_1__leaf_clk_i,
module flop_pair_U2 (clknet_1_1__leaf_clk_i,
clknet_1_0__leaf_clk_i);
input clknet_1_1__leaf_clk_i;
input clknet_1_0__leaf_clk_i;
Expand All @@ -43,7 +43,7 @@ module flop_pair-1 (clknet_1_1__leaf_clk_i,
DFF_X1 ff1 (.CK(clknet_1_1__leaf_clk_i));
DFF_X1 ff2 (.CK(clknet_1_0__leaf_clk_i));
endmodule
module flop_pair-2 (clknet_1_1__leaf_clk_i,
module flop_pair_U3 (clknet_1_1__leaf_clk_i,
clknet_1_0__leaf_clk_i);
input clknet_1_1__leaf_clk_i;
input clknet_1_0__leaf_clk_i;
Expand All @@ -52,7 +52,7 @@ module flop_pair-2 (clknet_1_1__leaf_clk_i,
DFF_X1 ff1 (.CK(clknet_1_1__leaf_clk_i));
DFF_X1 ff2 (.CK(clknet_1_0__leaf_clk_i));
endmodule
module flop_pair-3 (clknet_1_1__leaf_clk_i,
module flop_pair_U4 (clknet_1_1__leaf_clk_i,
clknet_1_0__leaf_clk_i);
input clknet_1_1__leaf_clk_i;
input clknet_1_0__leaf_clk_i;
Expand All @@ -61,14 +61,14 @@ module flop_pair-3 (clknet_1_1__leaf_clk_i,
DFF_X1 ff1 (.CK(clknet_1_0__leaf_clk_i));
DFF_X1 ff2 (.CK(clknet_1_1__leaf_clk_i));
endmodule
module flop_pair-4 (clknet_1_0__leaf_clk_i);
module flop_pair_U5 (clknet_1_0__leaf_clk_i);
input clknet_1_0__leaf_clk_i;


DFF_X1 ff1 (.CK(clknet_1_0__leaf_clk_i));
DFF_X1 ff2 (.CK(clknet_1_0__leaf_clk_i));
endmodule
module flop_pair-5 (clknet_1_1__leaf_clk_i,
module flop_pair_U6 (clknet_1_1__leaf_clk_i,
clknet_1_0__leaf_clk_i);
input clknet_1_1__leaf_clk_i;
input clknet_1_0__leaf_clk_i;
Expand All @@ -77,7 +77,7 @@ module flop_pair-5 (clknet_1_1__leaf_clk_i,
DFF_X1 ff1 (.CK(clknet_1_1__leaf_clk_i));
DFF_X1 ff2 (.CK(clknet_1_0__leaf_clk_i));
endmodule
module flop_pair-6 (clknet_1_1__leaf_clk_i,
module flop_pair_U7 (clknet_1_1__leaf_clk_i,
clknet_1_0__leaf_clk_i);
input clknet_1_1__leaf_clk_i;
input clknet_1_0__leaf_clk_i;
Expand All @@ -86,7 +86,7 @@ module flop_pair-6 (clknet_1_1__leaf_clk_i,
DFF_X1 ff1 (.CK(clknet_1_0__leaf_clk_i));
DFF_X1 ff2 (.CK(clknet_1_1__leaf_clk_i));
endmodule
module flop_pair-7 (clknet_1_1__leaf_clk_i,
module flop_pair_U8 (clknet_1_1__leaf_clk_i,
clknet_1_0__leaf_clk_i);
input clknet_1_1__leaf_clk_i;
input clknet_1_0__leaf_clk_i;
Expand Down
3 changes: 3 additions & 0 deletions src/dbSta/include/db_sta/dbNetwork.hh
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,9 @@ class dbNetwork : public ConcreteNetwork
std::vector<dbModule*>& parent_hierarchy);
dbModule* findHighestCommonModule(std::vector<dbModule*>& itree1,
std::vector<dbModule*>& itree2);
dbModule* findModule(const char* name);
Instance* findHierInstance(const char* name);
void replaceDesign(Instance* instance, dbModule* module);

////////////////////////////////////////////////////////////////
//
Expand Down
60 changes: 60 additions & 0 deletions src/dbSta/src/dbNetwork.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3105,4 +3105,64 @@ void dbNetwork::hierarchicalConnect(dbITerm* source_pin,
}
}

// Find a hierarchical module with a given name
// TODO: support finding uninstantiated modules
dbModule* dbNetwork::findModule(const char* name)
{
dbModule* module = nullptr;
Instance* top_inst = topInstance();
std::unique_ptr<InstanceChildIterator> child_iter{childIterator(top_inst)};
while (child_iter->hasNext()) {
Instance* child = child_iter->next();
if (network_->isHierarchical(child)) {
dbInst* db_inst;
dbModInst* mod_inst;
staToDb(child, db_inst, mod_inst);
if (mod_inst) {
dbModule* master = mod_inst->getMaster();
if (master) {
if (strcmp(master->getName(), name) == 0) {
module = master;
break;
}
}
}
}
}
return module;
}

// Find a hierarchical instance with a given name
Instance* dbNetwork::findHierInstance(const char* name)
{
Instance* inst = nullptr;
Instance* top_inst = topInstance();
std::unique_ptr<InstanceChildIterator> child_iter{childIterator(top_inst)};
while (child_iter->hasNext()) {
Instance* child = child_iter->next();
if (network_->isHierarchical(child)
&& strcmp(network_->name(child), name) == 0) {
inst = child;
break;
}
}
return inst;
}

void dbNetwork::replaceDesign(Instance* instance, dbModule* module)
{
dbInst* db_inst;
dbModInst* mod_inst;
staToDb(instance, db_inst, mod_inst);
if (mod_inst) {
mod_inst->swapMaster(module);
} else {
logger_->error(ORD,
1104,
"Instance {} cannot be replaced because it is not a "
"hierarchical module",
network_->name(instance));
}
}

} // namespace sta
20 changes: 2 additions & 18 deletions src/dbSta/src/dbReadVerilog.cc
Original file line number Diff line number Diff line change
Expand Up @@ -179,15 +179,13 @@ class Verilog2db

bool hasTerminals(Net* net) const;
dbMaster* getMaster(Cell* cell);
dbModule* makeUniqueDbModule(const char* name);
std::optional<LineInfo> parseLineInfo(const std::string& attribute);

Network* network_;
dbDatabase* db_;
dbBlock* block_ = nullptr;
Logger* logger_;
std::map<Cell*, dbMaster*> master_map_;
std::map<std::string, int> uniquify_id_; // key: module name
// Map file names to a unique id to avoid having to store the full file name
// for each instance
std::map<std::string, int> src_file_id_;
Expand Down Expand Up @@ -293,21 +291,6 @@ void Verilog2db::recordBusPortsOrder()
}
}

dbModule* Verilog2db::makeUniqueDbModule(const char* name)
{
dbModule* module;
do {
std::string full_name(name);
int& id = uniquify_id_[name];
if (id > 0) {
full_name += '-' + std::to_string(id);
}
++id;
module = dbModule::create(block_, full_name.c_str());
} while (module == nullptr);
return module;
}

std::optional<Verilog2db::LineInfo> Verilog2db::parseLineInfo(
const std::string& attribute)
{
Expand Down Expand Up @@ -339,7 +322,8 @@ void Verilog2db::makeDbModule(
module = block_->getTopModule();
} else {
// This uniquifies the cell
module = makeUniqueDbModule(network_->name(cell));
module = dbModule::makeUniqueDbModule(
network_->name(cell), network_->name(inst), block_);

// Strip out the full hiearchical name. We are now
// storing the module instances in the scope of their
Expand Down
24 changes: 24 additions & 0 deletions src/dbSta/src/dbSta.i
Original file line number Diff line number Diff line change
Expand Up @@ -190,4 +190,28 @@ write_verilog_cmd(const char *filename,
delete remove_cells;
}

Instance*
find_hier_inst_cmd(const char *name)
{
ord::OpenRoad *openroad = ord::getOpenRoad();
sta::dbNetwork *db_network = openroad->getDbNetwork();
return db_network->findHierInstance(name);
}

odb::dbModule*
find_module_cmd(const char *name)
{
ord::OpenRoad *openroad = ord::getOpenRoad();
sta::dbNetwork *db_network = openroad->getDbNetwork();
return db_network->findModule(name);
}

void
replace_design_cmd(Instance* inst, odb::dbModule* module)
{
ord::OpenRoad *openroad = ord::getOpenRoad();
sta::dbNetwork *db_network = openroad->getDbNetwork();
db_network->replaceDesign(inst, module);
}

%} // inline
23 changes: 23 additions & 0 deletions src/dbSta/src/dbSta.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -112,5 +112,28 @@ proc sta_warn { id msg } {
utl::warn STA $id $msg
}

define_cmd_args "replace_design" {instance module}

proc replace_design { instance module } {
set design [get_design_error $module]
if { $design != "NULL" } {
set inst [find_hier_inst_cmd $instance]
replace_design_cmd $inst $design
return 1
}
return 0
}

proc get_design_error { arg } {
if { [llength $arg] > 1 } {
sta_error 200 "module must be a single module."
}
set design [find_module_cmd $arg]
if { $design == "NULL" } {
sta_error 201 "module $arg cannot be found."
}
return $design
}

# namespace
}
4 changes: 2 additions & 2 deletions src/dbSta/test/hierclock_out.vok
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ module hierclock (a_count_valid_o,
a_count_o[1],
a_count_o[0]}),
.count_valid_o(a_count_valid_o));
counter-1 U3 (.clk_i(clk2_int),
counter_U3 U3 (.clk_i(clk2_int),
.rst_n_i(rst_n_i),
.load_i(b_ld_i),
.load_value_i({b_i[3],
Expand Down Expand Up @@ -200,7 +200,7 @@ module counter (clk_i,
.Q(counter_q[3]),
.QN(\U2/_38_ ));
endmodule
module counter-1 (clk_i,
module counter_U3 (clk_i,
rst_n_i,
load_i,
load_value_i,
Expand Down
2 changes: 1 addition & 1 deletion src/dbSta/test/read_verilog10.ok
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ b1 block1
b1/r1 snl_ffqx1
b1/u1 snl_bufx1
b1/u2 snl_bufx1
b2 block1-1
b2 block1_b2
b2/r1 snl_ffqx1
b2/u1 snl_bufx1
b2/u2 snl_bufx1
2 changes: 1 addition & 1 deletion src/dbSta/test/report_cell_usage_modinsts.ok
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Cell type report: Count Area
Cell instance report:
snl_bufx1 2 2000.00
snl_ffqx1 1 1000.00
Cell type report for b2 (block1-1)
Cell type report for b2 (block1_b2)
Cell type report: Count Area
Buffer 2 2000.00
Sequential cell 1 1000.00
Expand Down
12 changes: 6 additions & 6 deletions src/dbSta/test/report_cell_usage_modinsts_metrics.jsonok
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@
"design__instance__area__class:sequential_cell__in_module:block1": 1000,
"design__instance__count__in_module:block1": 3,
"design__instance__area__in_module:block1": 3000,
"design__instance__count__class:buffer__in_module:block1-1": 2,
"design__instance__area__class:buffer__in_module:block1-1": 2000,
"design__instance__count__class:sequential_cell__in_module:block1-1": 1,
"design__instance__area__class:sequential_cell__in_module:block1-1": 1000,
"design__instance__count__in_module:block1-1": 3,
"design__instance__area__in_module:block1-1": 3000
"design__instance__count__class:buffer__in_module:block1.b2": 2,
"design__instance__area__class:buffer__in_module:block1.b2": 2000,
"design__instance__count__class:sequential_cell__in_module:block1.b2": 1,
"design__instance__area__class:sequential_cell__in_module:block1.b2": 1000,
"design__instance__count__in_module:block1.b2": 3,
"design__instance__area__in_module:block1.b2": 3000
}
6 changes: 4 additions & 2 deletions src/dbSta/test/report_cell_usage_modinsts_metrics.ok
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Cell type report: Count Area
Cell instance report:
snl_bufx1 2 2000.00
snl_ffqx1 1 1000.00
Cell type report for b2 (block1-1)
Cell type report for b2 (block1_b2)
Cell type report: Count Area
Buffer 2 2000.00
Sequential cell 1 1000.00
Expand All @@ -25,4 +25,6 @@ Cell type report: Count Area
Cell instance report:
snl_bufx1 2 2000.00
snl_ffqx1 1 1000.00
No differences found.
Differences found at line 14.
"design__instance__count__class:buffer__in_module:block1.b2": 2,
"design__instance__count__class:buffer__in_module:block1_b2": 2,
18 changes: 18 additions & 0 deletions src/odb/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,24 @@ design_is_routed [-verbose]
| `verbose` | Flag that allow the command to show all the nets that are not routed. |


### Replace Design

This command swaps a hierarchical module with another module.
Two modules must have identical number of ports and port names must match.
Functional equivalence is not required.
New module is not allowed to have multiple levels of hierarchy for now.
Newly instantiated module is uniquified.

```tcl
replace_design instance_name module_name
```

#### Options

| Switch Name | Description |
| ----- | ----- |
| `instance_name` | Name of a hierarchical instance for which the module swap needs to happen. For example, 'l1/l2/U3' |
| `module_name` | Name of a new module that needs to be swapped in. |


## Example scripts
Expand Down
Loading

0 comments on commit 142a440

Please sign in to comment.