3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2026-05-30 21:57:47 +00:00

Accumulate connect cells.

This commit is contained in:
nella 2026-05-12 14:47:49 +02:00
parent 4e4fd1a26e
commit d9faee0153
5 changed files with 99 additions and 75 deletions

View file

@ -240,11 +240,11 @@ struct HierarchyPass : public Pass {
if ((flag_simcheck || flag_smtcheck) && top_mod == nullptr) if ((flag_simcheck || flag_smtcheck) && top_mod == nullptr)
log_error("Design has no top module.\n"); log_error("Design has no top module.\n");
expand_all_interfaces(design, top_mod, flag_check, flag_simcheck, flag_smtcheck, libdirs); Hierarchy::ConnectAccumulator connect_acc;
expand_all_interfaces(design, top_mod, flag_check, flag_simcheck, flag_smtcheck, libdirs, &connect_acc);
log_header(design, "Resolving $connect directionality..\n"); log_header(design, "Resolving $connect directionality..\n");
for (auto module : design->modules()) Hierarchy::resolve_acc_connects(design, connect_acc);
resolve_connect_directionality(module);
if (top_mod != NULL) { if (top_mod != NULL) {
log_header(design, "Analyzing design hierarchy..\n"); log_header(design, "Analyzing design hierarchy..\n");

View file

@ -172,14 +172,14 @@ void delete_marked_modules(Design* design) {
} }
} }
void expand_all_interfaces(Design* design, Module*& top_mod, bool flag_check, bool flag_simcheck, bool flag_smtcheck, const std::vector<std::string> &libdirs) { void expand_all_interfaces(Design* design, Module*& top_mod, bool flag_check, bool flag_simcheck, bool flag_smtcheck, const std::vector<std::string> &libdirs, ConnectAccumulator* connect_acc) {
bool did_something = true; bool did_something = true;
while (did_something) while (did_something)
{ {
did_something = false; did_something = false;
for (auto module : used_modules(design, top_mod)) { for (auto module : used_modules(design, top_mod)) {
if (expand_module(design, module, flag_check, flag_simcheck, flag_smtcheck, libdirs)) if (expand_module(design, module, flag_check, flag_simcheck, flag_smtcheck, libdirs, connect_acc))
did_something = true; did_something = true;
} }
@ -246,7 +246,7 @@ struct CellArrays {
} }
}; };
bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check, bool flag_simcheck, bool flag_smtcheck, const std::vector<std::string> &libdirs) bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check, bool flag_simcheck, bool flag_smtcheck, const std::vector<std::string> &libdirs, ConnectAccumulator* connect_acc)
{ {
bool did_something = false; bool did_something = false;
CellArrays cell_arrays; CellArrays cell_arrays;
@ -264,6 +264,8 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check
} }
IFModExpander if_mod_expander(*design, *module); IFModExpander if_mod_expander(*design, *module);
for (auto cell : module->cells()) { for (auto cell : module->cells()) {
if (connect_acc)
connect_acc->collect(module, cell);
if (auto unarrayed_type = cell_arrays.trim_and_register(cell)) if (auto unarrayed_type = cell_arrays.trim_and_register(cell))
cell->type = *unarrayed_type; cell->type = *unarrayed_type;

View file

@ -26,8 +26,23 @@
YOSYS_NAMESPACE_BEGIN YOSYS_NAMESPACE_BEGIN
namespace Hierarchy { namespace Hierarchy {
void expand_all_interfaces(Design* design, Module*& top_mod, bool flag_check, bool flag_simcheck, bool flag_smtcheck, const std::vector<std::string> &libdirs); struct ConnectAccumulator {
bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check, bool flag_simcheck, bool flag_smtcheck, const std::vector<std::string> &libdirs); dict<IdString, pool<IdString>> module_connect_cells;
// Collect a $connect cell during hierarchy traversal
void collect(Module* module, Cell* cell) {
if (cell->type == ID($connect) && !cell->has_keep_attr()) {
SigSpec sig_a = cell->getPort(ID::A);
SigSpec sig_b = cell->getPort(ID::B);
if (sig_a.size() > 0 && sig_b.size() > 0) {
module_connect_cells[module->name].insert(cell->name);
}
}
}
};
void expand_all_interfaces(Design* design, Module*& top_mod, bool flag_check, bool flag_simcheck, bool flag_smtcheck, const std::vector<std::string> &libdirs, ConnectAccumulator* connect_acc);
bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check, bool flag_simcheck, bool flag_smtcheck, const std::vector<std::string> &libdirs, ConnectAccumulator* connect_acc);
// For expanding a module's interface connections // For expanding a module's interface connections
struct IFModExpander struct IFModExpander

View file

@ -20,6 +20,7 @@
#include "kernel/yosys_common.h" #include "kernel/yosys_common.h"
#include "passes/hierarchy/util/ports.h" #include "passes/hierarchy/util/ports.h"
#include "passes/hierarchy/util/interfaces.h"
#include "kernel/sigtools.h" #include "kernel/sigtools.h"
YOSYS_NAMESPACE_BEGIN YOSYS_NAMESPACE_BEGIN
@ -190,8 +191,19 @@ namespace Hierarchy {
} }
} }
bool resolve_connect_directionality(Module* module) { void resolve_acc_connects(Design* design, const ConnectAccumulator& connect_acc) {
bool did_something = false; std::vector<IdString> sorted_module_names;
for (const auto& [mod_name, cell_names] : connect_acc.module_connect_cells)
sorted_module_names.push_back(mod_name);
std::sort(sorted_module_names.begin(), sorted_module_names.end());
for (auto mod_name : sorted_module_names) {
Module* module = design->module(mod_name);
if (!module)
continue;
const pool<IdString>& cell_names = connect_acc.module_connect_cells.at(mod_name);
pool<IdString> remaining_cell_names = cell_names;
int iteration = 0; int iteration = 0;
while (true) { while (true) {
@ -203,12 +215,9 @@ namespace Hierarchy {
build_driven_signals_index(module, sigmap, driven_signals); build_driven_signals_index(module, sigmap, driven_signals);
for (auto cell : module->cells()) for (auto cell_name : remaining_cell_names) {
{ Cell* cell = module->cell(cell_name);
if (cell->type != ID($connect)) if (!cell || cell->type != ID($connect) || cell->has_keep_attr())
continue;
if (cell->has_keep_attr())
continue; continue;
SigSpec sig_a = cell->getPort(ID::A); SigSpec sig_a = cell->getPort(ID::A);
@ -246,9 +255,6 @@ namespace Hierarchy {
driven = sig_a; driven = sig_a;
can_resolve = true; can_resolve = true;
} }
else {
continue;
}
if (can_resolve) { if (can_resolve) {
log_debug("Resolving $connect %s: %s <- %s\n", log_id(cell), log_signal(driven), log_signal(driver)); log_debug("Resolving $connect %s: %s <- %s\n", log_id(cell), log_signal(driven), log_signal(driver));
@ -260,17 +266,17 @@ namespace Hierarchy {
for (auto &conn : new_connections) for (auto &conn : new_connections)
module->connect(conn); module->connect(conn);
for (auto cell : cells_to_remove) for (auto cell : cells_to_remove) {
remaining_cell_names.erase(cell->name);
module->remove(cell); module->remove(cell);
}
if (cells_to_remove.empty()) if (cells_to_remove.empty())
break; break;
did_something = true;
log_debug("$connect res iteration %d: resolved %d cells\n", iteration, GetSize(cells_to_remove)); log_debug("$connect res iteration %d: resolved %d cells\n", iteration, GetSize(cells_to_remove));
} }
}
return did_something;
} }
}; };

View file

@ -22,13 +22,14 @@
#define HIERARCHY_PORTS_H #define HIERARCHY_PORTS_H
#include "kernel/yosys.h" #include "kernel/yosys.h"
#include "passes/hierarchy/util/interfaces.h"
YOSYS_NAMESPACE_BEGIN YOSYS_NAMESPACE_BEGIN
namespace Hierarchy { namespace Hierarchy {
std::pair<Module*, bool> derive_blackbox_dynports(Module* module, Cell* cell, Design* design, std::set<Module*>& blackbox_derivatives); std::pair<Module*, bool> derive_blackbox_dynports(Module* module, Cell* cell, Design* design, std::set<Module*>& blackbox_derivatives);
void check_and_adjust_ports(Module* module, std::set<Module*>& blackbox_derivatives, bool keep_portwidths, bool top_is_from_verific); void check_and_adjust_ports(Module* module, std::set<Module*>& blackbox_derivatives, bool keep_portwidths, bool top_is_from_verific);
bool resolve_connect_directionality(Module* module); void resolve_acc_connects(Design* design, const ConnectAccumulator& connect_acc);
}; };
YOSYS_NAMESPACE_END YOSYS_NAMESPACE_END