-
Notifications
You must be signed in to change notification settings - Fork 772
odb: Refactor 3DBlox checker into UnfoldedModel and ThreeDBloxValidator #9217
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
odb: Refactor 3DBlox checker into UnfoldedModel and ThreeDBloxValidator #9217
Conversation
This commit separates the monolithic 3DBlox checker into two distinct components
to improve modularity, maintainability, and architectural clarity:
1. UnfoldedModel: Responsible for hierarchical design "unfolding".
- Recursively traverses the design hierarchy to build a flat, global
representation of chips, regions, and bumps.
- Handles coordinate transformation accumulation and Z-mirror (MZ)
state tracking.
- Employs std::deque for internal storage to guarantee pointer stability
for hierarchical object references.
- Maintains an efficient path-based map for fast object resolution.
2. ThreeDBloxValidator: Responsible for verification logic.
- Ports existing floating chip and overlapping chip detection to the
new unfolded data structure.
- Provides a dedicated entry point for future physical alignment and
connectivity rule implementations.
3. Checker Facade:
- Updated to serve as a clean API facade that orchestrates the
UnfoldedModel construction and ThreeDBloxValidator execution.
- Maintains full backward compatibility with the current Tcl interface.
Technical Improvements:
- Decouples data construction from rule analysis (Single Responsibility Principle).
- Optimized orientation handling by caching Z-flip state during recursion.
- Improved memory safety via stable containers for cross-referenced structs.
- Modularized codebase into dedicated header/implementation files.
Verified by successfully passing all 85 existing 'odb' integration tests.
Related to: The-OpenROAD-Project#9209
Signed-off-by: Ahmed R. Mohamed <ahmed@precisioninno.com>
There was a problem hiding this 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 refactors the 3DBlox checker into two distinct components: UnfoldedModel for building a flattened representation of the design hierarchy, and ThreeDBloxValidator for performing the validation checks. This is an excellent improvement that adheres to the Single Responsibility Principle, resulting in more modular and maintainable code. The use of std::deque to ensure pointer stability for object references is a solid design choice. The existing validation logic for floating and overlapping chips has been cleanly ported to the new structure. The changes are well-executed and establish a strong foundation for future enhancements to the checker. I have one minor suggestion to further improve code clarity and robustness.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
clang-tidy made some suggestions
Signed-off-by: Ahmed R. Mohamed <ahmed@precisioninno.com>
|
clang-tidy review says "All clean, LGTM! 👍" |
src/odb/src/3dblox/unfoldedModel.cpp
Outdated
| std::string name; | ||
| for (auto* chip_inst : chip_inst_path) { | ||
| if (!name.empty()) { | ||
| name += "/"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"/" <--- Is the fixed delimiter ok?
In dbBlock, _dbBlock::hier_delimiter_ is configurable.
I am not sure if the "/" should be the same as _dbBlock::hier_delimiter_ or not.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you're right. I'm now using hier_delimiter and '/' as a default.
src/odb/src/3dblox/unfoldedModel.cpp
Outdated
|
|
||
| void UnfoldedModel::build(dbChip* chip) | ||
| { | ||
| for (auto chip_inst : chip->getChipInsts()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMO, using auto for the trivial usage case hurts code readability. Changing to dbChipInst* would be more readable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the update.
If you agree that auto for trivial type can hurt readability, it is better to change other auto statements as well. : )
| { | ||
| dbChipConn* connection; | ||
| UnfoldedRegionFull* top_region; | ||
| UnfoldedRegionFull* bottom_region; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Although there are no specific implementation for top_region & bottom_region yet, they may point entries in std::vector<UnfoldedRegionFull> regions;.
If # of regions is not constant and changes dynamically after construction, the vector can be reallocated and top_region and bottom_region require proper management because of the pointer address change.
If this scenario can happen, using vector may not be a good choice.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I reviewed all other instances of vector and changed some of them to deque for pointer stability. Thanks.
Could not use vector in more places for pointer stability. Used the block delimiter and '/' by default. Signed-off-by: Ahmed R. Mohamed <ahmed@precisioninno.com>
|
clang-tidy review says "All clean, LGTM! 👍" |
src/odb/src/3dblox/unfoldedModel.cpp
Outdated
| delimiter = d; | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's consider the following cases.
- There are multiple chips. Should we allow different hierarchical delimiters in multiple chips?
- If there should be a single hierarchical delimiter, storing it in ODB-level (not in block or chip) is better.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- It depends on the way we use the path later. For this particular function, it does not matter as long as we're consistent. And, it does not affect anything outside the checker.
- We do not need to enforce this.
In general you are right to question this, but I think it is outside the scope of this PR. I can create another issue for it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think you should infer the delimiter from the block as it will inevitably lead to misalignment and ambiguity. The delimiter should be /, as this is the implicitly defined delimiter in the 3DBlox standard.
osamahammad21
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
checker and threeDBloxValidator should be merged. The separation doesn’t buy us much and increases mental overhead for users of the API. API clarity is better achieved by keeping a single checker class with a small public interface, and moving the rest of the logic into private.
src/odb/src/3dblox/unfoldedModel.h
Outdated
| UnfoldedModel(utl::Logger* logger); | ||
| void build(dbChip* chip); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| UnfoldedModel(utl::Logger* logger); | |
| void build(dbChip* chip); | |
| UnfoldedModel(utl::Logger* logger, dbChip* chip); |
Since you already don't clear the member variables when you call build, then calling build multiple times is gonna lead to a misleading behavior.
src/odb/src/3dblox/unfoldedModel.cpp
Outdated
| delimiter = d; | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think you should infer the delimiter from the block as it will inevitably lead to misalignment and ambiguity. The delimiter should be /, as this is the implicitly defined delimiter in the 3DBlox standard.
Signed-off-by: Ahmed R. Mohamed <ahmed@precisioninno.com>
|
clang-tidy review says "All clean, LGTM! 👍" |
This commit separates the monolithic 3DBlox checker into two distinct components to improve modularity, maintainability, and architectural clarity:
UnfoldedModel: Responsible for hierarchical design "unfolding".
ThreeDBloxValidator: Responsible for verification logic.
Checker Facade:
Technical Improvements:
Verified by successfully passing all 85 existing 'odb' integration tests.
Related to: #9209