Resolve wire dir WIP.
This commit is contained in:
@@ -26,6 +26,7 @@
|
||||
#include "passes/hierarchy/util/positionals.h"
|
||||
#include "passes/hierarchy/util/verilog.h"
|
||||
#include "passes/hierarchy/util/generate.h"
|
||||
#include "passes/hierarchy/util/ports.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <set>
|
||||
@@ -241,6 +242,10 @@ struct HierarchyPass : public Pass {
|
||||
|
||||
expand_all_interfaces(design, top_mod, flag_check, flag_simcheck, flag_smtcheck, libdirs);
|
||||
|
||||
log_header(design, "Resolving $connect directionality..\n");
|
||||
for (auto module : design->modules())
|
||||
resolve_connect_directionality(module);
|
||||
|
||||
if (top_mod != NULL) {
|
||||
log_header(design, "Analyzing design hierarchy..\n");
|
||||
clean(design, top_mod, purge_lib);
|
||||
|
||||
@@ -100,5 +100,60 @@ namespace Hierarchy {
|
||||
}
|
||||
}
|
||||
|
||||
bool resolve_connect_directionality(Module* module) {
|
||||
pool<Cell*> cells_to_remove;
|
||||
vector<SigSig> new_connections;
|
||||
|
||||
for (auto cell : module->cells())
|
||||
{
|
||||
if (cell->type != ID($connect))
|
||||
continue;
|
||||
|
||||
if (cell->has_keep_attr())
|
||||
continue;
|
||||
|
||||
SigSpec sig_a = cell->getPort(ID::A);
|
||||
SigSpec sig_b = cell->getPort(ID::B);
|
||||
|
||||
// TODO
|
||||
if (!sig_a.is_wire() || !sig_b.is_wire())
|
||||
continue;
|
||||
|
||||
Wire *wire_a = sig_a.as_wire();
|
||||
Wire *wire_b = sig_b.as_wire();
|
||||
|
||||
bool a_is_input = wire_a->port_input && !wire_a->port_output;
|
||||
bool a_is_output = wire_a->port_output && !wire_a->port_input;
|
||||
bool b_is_input = wire_b->port_input && !wire_b->port_output;
|
||||
bool b_is_output = wire_b->port_output && !wire_b->port_input;
|
||||
|
||||
SigSpec driver, driven;
|
||||
|
||||
if (a_is_output && b_is_input) {
|
||||
driver = sig_a;
|
||||
driven = sig_b;
|
||||
} else if (a_is_input && b_is_output) {
|
||||
driver = sig_b;
|
||||
driven = sig_a;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
||||
log_debug("Resolving $connect %s: %s <- %s\n", log_id(cell), log_signal(driven), log_signal(driver));
|
||||
|
||||
new_connections.push_back({driven, driver});
|
||||
cells_to_remove.insert(cell);
|
||||
}
|
||||
|
||||
// Apply the changes
|
||||
for (auto &conn : new_connections)
|
||||
module->connect(conn);
|
||||
|
||||
for (auto cell : cells_to_remove)
|
||||
module->remove(cell);
|
||||
|
||||
return !cells_to_remove.empty();
|
||||
}
|
||||
|
||||
};
|
||||
YOSYS_NAMESPACE_END
|
||||
|
||||
@@ -27,6 +27,7 @@ YOSYS_NAMESPACE_BEGIN
|
||||
|
||||
namespace Hierarchy {
|
||||
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);
|
||||
};
|
||||
|
||||
YOSYS_NAMESPACE_END
|
||||
|
||||
Reference in New Issue
Block a user