autoname: selection determines what gets renamed, not the name it gets renamed to

This commit is contained in:
Emil J. Tywoniak 2026-07-17 22:48:46 +02:00
parent fb0bb160ad
commit 8565451ef9
2 changed files with 60 additions and 27 deletions

View File

@ -79,6 +79,7 @@ struct node {
unsigned int fanout = 0; unsigned int fanout = 0;
bool is_public = false; bool is_public = false;
bool renameable = false; bool renameable = false;
bool selected = false;
size_t name_length = 0; size_t name_length = 0;
// Node index from which we want to construct the rename // Node index from which we want to construct the rename
@ -89,6 +90,8 @@ struct node {
string suffix; string suffix;
// Is this name final? // Is this name final?
bool decided = false; bool decided = false;
const IdString& name() const { return cell ? cell->name : wire->name; }
}; };
// Decides the order of exploring neighbors // Decides the order of exploring neighbors
@ -106,7 +109,7 @@ struct ModuleAutonamer
// Cells in module order, then wires in the order that they're seen from cells. // Cells in module order, then wires in the order that they're seen from cells.
// The index doubles as the tie-break between equally good // The index doubles as the tie-break between equally good
// proposals for different nodes. // proposals for different nodes
vector<node> nodes; vector<node> nodes;
vector<int> decided; vector<int> decided;
std::priority_queue<queue_item, std::vector<queue_item>, std::greater<>> queue; std::priority_queue<queue_item, std::vector<queue_item>, std::greater<>> queue;
@ -116,9 +119,9 @@ struct ModuleAutonamer
void build_adjacency() void build_adjacency()
{ {
auto selected = module->selected_cells(); vector<Cell*> cells(module->cells().begin(), module->cells().end());
// Arbitrary. Kinda just for passing tests without modifying them. // Arbitrary. Kinda just for passing tests without modifying them
for (auto cell : selected | std::views::reverse) for (auto cell : cells | std::views::reverse)
nodes.emplace_back().cell = cell; nodes.emplace_back().cell = cell;
int ncells = GetSize(nodes); int ncells = GetSize(nodes);
@ -153,23 +156,25 @@ struct ModuleAutonamer
} }
} }
// Resolve selection before renaming
for (auto &nd : nodes) { for (auto &nd : nodes) {
IdString name = nd.cell ? nd.cell->name : nd.wire->name; IdString name = nd.name();
nd.selected = nd.cell ? module->selected(nd.cell) : module->selected(nd.wire);
nd.is_public = (name[0] != '$'); nd.is_public = (name[0] != '$');
nd.renameable = !nd.is_public && (nd.cell || nd.wire->port_id == 0); nd.renameable = !nd.is_public && (nd.cell || nd.wire->port_id == 0);
if (nd.is_public) if (nd.is_public)
nd.name_length = name.str().size(); nd.name_length = name.str().size();
} }
// Only possible once every fanout is known. // Only possible once every fanout is known
for (auto &nd : nodes) for (auto &nd : nodes)
for (auto &edge : nd.edges) for (auto &edge : nd.edges)
edge.score = edge.cell_is_output ? 0 : nodes[edge.wire].fanout; edge.score = edge.cell_is_output ? 0 : nodes[edge.wire].fanout;
} }
void offer(int from, int n, const Edge &edge, int edge_pos) void offer(int from, int to, const Edge &edge, int edge_pos)
{ {
node &nd = nodes[n]; node &nd = nodes[to];
if (!nd.renameable || nd.decided) if (!nd.renameable || nd.decided)
return; return;
string suffix = nd.cell string suffix = nd.cell
@ -182,7 +187,7 @@ struct ModuleAutonamer
nd.from_node = from; nd.from_node = from;
nd.name_length = c.length; nd.name_length = c.length;
nd.suffix = std::move(suffix); nd.suffix = std::move(suffix);
queue.push(queue_item{c.score, c.length, n}); queue.push(queue_item{c.score, c.length, to});
} }
// Expand a public (or newly decided) node. The name it lends // Expand a public (or newly decided) node. The name it lends
@ -214,15 +219,23 @@ struct ModuleAutonamer
} }
} }
// The source neighbour is decided before this node, so commit() reaches it void append_name(int n, string &out)
// first and its name is already final -- uniquify() suffix and all. {
const node &nd = nodes[n];
if (nd.is_public || nd.selected)
return nd.name().append_to(&out);
append_name(nd.from_node, out);
out += nd.suffix;
}
void commit(int n) void commit(int n)
{ {
node &nd = nodes[n]; node &nd = nodes[n];
const node &src = nodes[nd.from_node]; if (!nd.selected)
return;
string full; string full;
full.reserve(nd.name_length); full.reserve(nd.name_length);
(src.cell ? src.cell->name : src.wire->name).append_to(&full); append_name(nd.from_node, full);
full += nd.suffix; full += nd.suffix;
IdString name = module->uniquify(IdString(full)); IdString name = module->uniquify(IdString(full));
if (nd.cell) { if (nd.cell) {

View File

@ -78,12 +78,21 @@ module \top
end end
end end
EOT EOT
design -save fanout_test
logger -expect log "Rename cell .name in top to bcd_.and_B" 1 logger -expect log "Rename cell .name in top to bcd_.and_B" 1
logger -expect log "Rename cell .name2 in top to c_has_a_long_name_.or_B" 1 logger -expect log "Rename cell .name2 in top to c_has_a_long_name_.or_B" 1
logger -expect log "Renamed 2 objects" 1 logger -expect log "Renamed 2 objects" 1
debug autoname debug autoname
logger -check-expected logger -check-expected
# a selection only limits what gets renamed, never the name that gets picked:
# \a's fanout still counts $name2, even though it isn't selected
design -load fanout_test
logger -expect log "Rename cell .name in top to bcd_.and_B" 1
logger -expect log "Renamed 1 objects" 1
debug autoname c:$name
logger -check-expected
# names are unique # names are unique
design -reset design -reset
read_rtlil <<EOT read_rtlil <<EOT
@ -177,30 +186,41 @@ end
EOT EOT
design -save order_test design -save order_test
# don't rename prematurely (some objects should be named after $name2)
# wires are named for being cell outputs # wires are named for being cell outputs
logger -expect log "Rename wire .d in top to or_Y" 1 logger -expect log "Rename wire .d in top to or_Y" 1
logger -expect log "Rename cell .name2 in top to or_Y_.or_B" 1 logger -expect log "Rename cell .name2 in top to or_Y_.or_B" 1
logger -expect log "Rename wire .e in top to or_Y_.or_B_Y" 1 logger -expect log "Rename wire .e in top to or_Y_.or_B_Y" 1
logger -expect log "Rename wire .c in top to or_Y_.or_B_A" 1
logger -expect log "Renamed 4 objects" 1
debug autoname t:$or
logger -check-expected
# $name gets shortest name (otherwise bcd_$__unknown_B) # $name gets shortest name (otherwise bcd_$__unknown_B)
logger -expect log "Rename cell .name in top to a_.__unknown_A" 1 logger -expect log "Rename cell .name in top to a_.__unknown_A" 1
# $name3 named for lowest fanout wire (otherwise a_$__unknown_A_Y_$and_A)
logger -expect log "Rename cell .name3 in top to or_Y_.or_B_Y_.and_B" 1 logger -expect log "Rename cell .name3 in top to or_Y_.or_B_Y_.and_B" 1
logger -expect log "Renamed 2 objects" 1
debug autoname
logger -check-expected
# don't rename prematurely (some objects should be named after $name2)
design -load order_test
# $c gets shortest name, since the cell driving it doesn't have known port # $c gets shortest name, since the cell driving it doesn't have known port
# directions (otherwise a_$__unknown_A_Y) # directions (otherwise a_$__unknown_A_Y)
logger -expect log "Rename wire .c in top to or_Y_.or_B_A" 1 logger -expect log "Rename wire .c in top to or_Y_.or_B_A" 1
# $name3 named for lowest fanout wire (otherwise a_$__unknown_A_Y_$and_A)
logger -expect log "Rename cell .name3 in top to or_Y_.or_B_Y_.and_B" 1
logger -expect log "Renamed 6 objects" 1 logger -expect log "Renamed 6 objects" 1
debug autoname debug autoname
logger -check-expected logger -check-expected
# Only selected objects are renamed, but each one gets exactly the name the
# unrestricted run above gave it, whatever the selection.
design -load order_test
logger -expect log "Rename cell .name2 in top to or_Y_.or_B" 1
logger -expect log "Renamed 1 objects" 1
debug autoname t:$or
logger -check-expected
design -load order_test
logger -expect log "Rename wire .d in top to or_Y" 1
logger -expect log "Rename wire .e in top to or_Y_.or_B_Y" 1
logger -expect log "Rename wire .c in top to or_Y_.or_B_A" 1
logger -expect log "Renamed 3 objects" 1
debug autoname w:*
logger -check-expected
# $name3 is named after a chain of objects that all keep their $-names
design -load order_test
logger -expect log "Rename cell .name3 in top to or_Y_.or_B_Y_.and_B" 1
logger -expect log "Renamed 1 objects" 1
debug autoname c:$name3
logger -check-expected