Skip to content

odb: impl 3dblox verilog writer#9754

Closed
ahmed532 wants to merge 2 commits intoThe-OpenROAD-Project:masterfrom
ahmed532:feat/3dblox-write-top-verilog
Closed

odb: impl 3dblox verilog writer#9754
ahmed532 wants to merge 2 commits intoThe-OpenROAD-Project:masterfrom
ahmed532:feat/3dblox-write-top-verilog

Conversation

@ahmed532
Copy link
Copy Markdown

@ahmed532 ahmed532 commented Mar 13, 2026

Closes: #9709

Signed-off-by: Ahmed R. Mohamed <ahmed@precisioninno.com>
@ahmed532 ahmed532 self-assigned this Mar 13, 2026
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread src/odb/src/3dblox/verilogWriter.cpp Outdated
Comment on lines +42 to +44
if (bump_inst == nullptr || path.empty()) {
continue;
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

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.

Suggested change
if (bump_inst == nullptr || path.empty()) {
continue;
}
if (bump_inst == nullptr || path.size() != 1) {
continue;
}


#include "verilogWriter.h"

#include <cstddef>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

To use std::sort for ensuring deterministic output as suggested in another comment, you'll need to include the <algorithm> header.

Suggested change
#include <cstddef>
#include <algorithm>
#include <cstddef>

Comment on lines +58 to +88
}

// 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");
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

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");
  }

@github-actions
Copy link
Copy Markdown
Contributor

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>
@ahmed532 ahmed532 requested a review from osamahammad21 March 16, 2026 16:14
@github-actions
Copy link
Copy Markdown
Contributor

clang-tidy review says "All clean, LGTM! 👍"

@ahmed532 ahmed532 closed this Mar 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ODB: Write 3dblox top verilog

1 participant