odb: impl 3dblox verilog writer#9754
odb: impl 3dblox verilog writer#9754ahmed532 wants to merge 2 commits intoThe-OpenROAD-Project:masterfrom
Conversation
Signed-off-by: Ahmed R. Mohamed <ahmed@precisioninno.com>
There was a problem hiding this comment.
Code Review
This pull request introduces a Verilog writer for 3D-BLOX, a significant new feature. The implementation is well-structured, adding a VerilogWriter class and integrating it into the existing ThreeDBlox flow and Tcl interface. I've included a few suggestions to enhance correctness and maintainability, primarily within the new verilogWriter.cpp file, focusing on ensuring deterministic output and stricter validation.
| if (bump_inst == nullptr || path.empty()) { | ||
| continue; | ||
| } |
There was a problem hiding this comment.
The comment on line 45 indicates that only direct children (path length 1) should be handled. However, the current check !path.empty() allows for paths of any length greater than 0. This could lead to incorrect connections if hierarchical paths are encountered. To ensure correctness, the check should be more strict to only allow paths of size 1.
| if (bump_inst == nullptr || path.empty()) { | |
| continue; | |
| } | |
| if (bump_inst == nullptr || path.size() != 1) { | |
| continue; | |
| } |
|
|
||
| #include "verilogWriter.h" | ||
|
|
||
| #include <cstddef> |
| } | ||
|
|
||
| // Write module header. | ||
| fmt::print(verilog_file, "module {} ();\n", chip->getName()); | ||
|
|
||
| // Write wire declarations for each net. | ||
| for (dbChipNet* net : chip->getChipNets()) { | ||
| fmt::print(verilog_file, " wire {};\n", net->getName()); | ||
| } | ||
|
|
||
| // Write instance declarations. | ||
| for (dbChipInst* chip_inst : chip->getChipInsts()) { | ||
| fmt::print(verilog_file, | ||
| " {} {} (\n", | ||
| chip_inst->getMasterChip()->getName(), | ||
| chip_inst->getName()); | ||
| const auto it = inst_connections.find(chip_inst); | ||
| if (it != inst_connections.end()) { | ||
| const std::vector<std::pair<std::string, std::string>>& conns | ||
| = it->second; | ||
| for (size_t j = 0; j < conns.size(); j++) { | ||
| const bool is_last = (j + 1 == conns.size()); | ||
| fmt::print(verilog_file, | ||
| " .{}({}){}\n", | ||
| conns[j].first, | ||
| conns[j].second, | ||
| is_last ? "" : ","); | ||
| } | ||
| } | ||
| fmt::print(verilog_file, " );\n"); | ||
| } |
There was a problem hiding this comment.
The order of elements (wires, instances, ports) in the generated Verilog file can be non-deterministic as it depends on the iteration order of internal database structures. This can make testing fragile and the output harder for humans to parse.
To ensure deterministic output, I recommend sorting nets, instances, and connections alphabetically before writing them. This will make the output consistent across runs.
}
for (auto& pair : inst_connections) {
std::sort(pair.second.begin(), pair.second.end());
}
// Write module header.
fmt::print(verilog_file, "module {} ();\n", chip->getName());
// Write wire declarations for each net.
std::vector<dbChipNet*> nets(chip->getChipNets()->begin(),
chip->getChipNets()->end());
std::sort(nets.begin(), nets.end(), [](dbChipNet* a, dbChipNet* b) {
return std::string(a->getName()) < std::string(b->getName());
});
for (dbChipNet* net : nets) {
fmt::print(verilog_file, " wire {};\n", net->getName());
}
// Write instance declarations.
std::vector<dbChipInst*> insts(chip->getChipInsts()->begin(),
chip->getChipInsts()->end());
std::sort(insts.begin(), insts.end(), [](dbChipInst* a, dbChipInst* b) {
return std::string(a->getName()) < std::string(b->getName());
});
for (dbChipInst* chip_inst : insts) {
fmt::print(verilog_file,
" {} {} (\n",
chip_inst->getMasterChip()->getName(),
chip_inst->getName());
const auto it = inst_connections.find(chip_inst);
if (it != inst_connections.end()) {
const std::vector<std::pair<std::string, std::string>>& conns
= it->second;
for (size_t j = 0; j < conns.size(); j++) {
const bool is_last = (j + 1 == conns.size());
fmt::print(verilog_file,
" .{}({}){}\n",
conns[j].first,
conns[j].second,
is_last ? "" : ",");
}
}
fmt::print(verilog_file, " );\n");
}|
clang-tidy review says "All clean, LGTM! 👍" |
Only output direct direct children (path.size()==1) Sort nets, instances, and connections alphabetically before writing them Signed-off-by: Ahmed R. Mohamed <ahmed@precisioninno.com>
|
clang-tidy review says "All clean, LGTM! 👍" |
Closes: #9709