odb: fix createNewFlatNet flat/modnet name collision with BTerm#9675
Conversation
|
clang-tidy review says "All clean, LGTM! 👍" |
There was a problem hiding this comment.
Code Review
This pull request addresses a net naming collision issue that occurs during buffer insertion, particularly after remove_buffers has run. The fix ensures that when a new net is created before a BTerm, it is always named after the BTerm, and any existing flat nets or modnets with conflicting names are renamed to avoid collisions. The changes are well-supported by a new test case that reproduces the bug scenario. My review includes a suggestion to refactor a portion of the logic for improved readability and maintainability, which aligns with general best practices.
Note: Security Review did not run due to the size of the PR.
src/odb/src/db/dbInsertBuffer.cpp
Outdated
| // Rename the original flat net if it has the same name as the port. | ||
| std::string avoidance_name; | ||
| if (bterm_name == block_->getBaseName(net_->getConstName())) { | ||
| avoidance_name = make_avoidance_name(); | ||
| net_->rename(avoidance_name.c_str()); | ||
| } | ||
|
|
||
| // Rename the modnet if it has the same name as the port. | ||
| dbModNet* load_mnet = bterm->getModNet(); | ||
| if (load_mnet | ||
| && std::string_view{load_mnet->getConstName()} == bterm_name) { | ||
| if (avoidance_name.empty()) { | ||
| avoidance_name = make_avoidance_name(); | ||
| } | ||
| load_mnet->rename(avoidance_name.c_str()); | ||
| } |
There was a problem hiding this comment.
The logic for renaming the flat net and modnet to avoid collisions is correct, but it can be refactored for better readability and to make the intent clearer. You can determine if collisions exist for both the flat net and modnet first, and then perform the renames within a single conditional block. This avoids nested checks and separates collision detection from the renaming action.
// Rename the original flat net and/or modnet if they have the same name as the port.
const bool flat_net_collides = (bterm_name == block_->getBaseName(net_->getConstName()));
dbModNet* load_mnet = bterm->getModNet();
const bool mod_net_collides = (load_mnet
&& std::string_view{load_mnet->getConstName()} == bterm_name);
if (flat_net_collides || mod_net_collides) {
const std::string avoidance_name = make_avoidance_name();
if (flat_net_collides) {
net_->rename(avoidance_name.c_str());
}
if (mod_net_collides) {
load_mnet->rename(avoidance_name.c_str());
}
}When remove_buffers merges two port-named nets, a BTerm can end up on a net with a different port's name. Additionally, the modnet retains the original port name (stale). createNewFlatNet now always names the new net after the BTerm and renames any colliding flat net or modnet first. This fixes spurious assign statements and multi-driver errors in VerilogWriter output that caused Kepler LEC failures in hierarchical designs (e.g., bp_fe_top). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Jaehyun Kim <jhkim@precisioninno.com>
f9b888f to
54a7105
Compare
Refactor the flat net and modnet renaming logic to separate collision detection from the renaming action. This improves readability by determining collisions upfront and handling renames within a single conditional block. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Jaehyun Kim <jhkim@precisioninno.com>
|
clang-tidy review says "All clean, LGTM! 👍" |
54a7105 to
03a2d14
Compare
|
clang-tidy review says "All clean, LGTM! 👍" |
Summary
createNewFlatNet()now always names the new net after the BTerm (port name), and renames any colliding flat net or modnet to a unique avoidance name first.assignstatements and multi-driver errors in VerilogWriter output caused byremove_buffersleaving a BTerm on a mismatched net name with a stale modnet.bp_fe_topwhere Kepler LEC rejected multi-driver outputs.Root Cause
When
remove_buffersmerges two port-named nets (both having BTerms), the survivor selection defaults to the input net. This causes:remove_buffersmerges flat nets but NOT modnets — the modnet retains the old port name.createNewFlatNet()previously only handled case 1 (and only when names matched). VerilogWriter uses modnet names (viadbNetwork::net()) for submodule instance pin connections, so the stale modnet caused multi-driver even after flat net naming was corrected.Fix
In
createNewFlatNet():makeNewNetName().Test plan
🤖 Generated with Claude Code