mirror of https://github.com/YosysHQ/yosys.git
Support more than one port in the abc_scc_break attr
This commit is contained in:
parent
1d0be89214
commit
26efd6f0a9
|
@ -80,6 +80,8 @@ void handle_loops(RTLIL::Design *design)
|
||||||
{
|
{
|
||||||
Pass::call(design, "scc -set_attr abc_scc_id {}");
|
Pass::call(design, "scc -set_attr abc_scc_id {}");
|
||||||
|
|
||||||
|
dict<IdString, vector<IdString>> module_break;
|
||||||
|
|
||||||
// For every unique SCC found, (arbitrarily) find the first
|
// For every unique SCC found, (arbitrarily) find the first
|
||||||
// cell in the component, and select (and mark) all its output
|
// cell in the component, and select (and mark) all its output
|
||||||
// wires
|
// wires
|
||||||
|
@ -113,44 +115,46 @@ void handle_loops(RTLIL::Design *design)
|
||||||
}
|
}
|
||||||
cell->attributes.erase(it);
|
cell->attributes.erase(it);
|
||||||
}
|
}
|
||||||
RTLIL::Module* box_module = design->module(cell->type);
|
|
||||||
if (box_module) {
|
auto jt = module_break.find(cell->type);
|
||||||
auto jt = box_module->attributes.find("\\abc_scc_break");
|
if (jt == module_break.end()) {
|
||||||
if (jt != box_module->attributes.end()) {
|
std::vector<IdString> ports;
|
||||||
auto it = cell->connections_.find(RTLIL::escape_id(jt->second.decode_string()));
|
if (!yosys_celltypes.cell_known(cell->type)) {
|
||||||
if (it == cell->connections_.end())
|
RTLIL::Module* box_module = design->module(cell->type);
|
||||||
log_error("abc_scc_break attribute value '%s' does not exist as port on module '%s'\n", jt->second.decode_string().c_str(), log_id(box_module));
|
log_assert(box_module);
|
||||||
log_assert(it != cell->connections_.end());
|
auto ports_csv = box_module->attributes.at("\\abc_scc_break", RTLIL::Const::from_string("")).decode_string();
|
||||||
RTLIL::SigSpec sig;
|
for (const auto &port_name : split_tokens(ports_csv, ",")) {
|
||||||
for (auto b : it->second) {
|
auto port_id = RTLIL::escape_id(port_name);
|
||||||
Wire *w = b.wire;
|
auto kt = cell->connections_.find(port_id);
|
||||||
if (!w) continue;
|
if (kt == cell->connections_.end())
|
||||||
if (w->port_output) {
|
log_error("abc_scc_break attribute value '%s' does not exist as port on module '%s'\n", port_name.c_str(), log_id(box_module));
|
||||||
log_assert(w->get_bool_attribute("\\abc_scc_break"));
|
ports.push_back(port_id);
|
||||||
w = module->wire(stringf("%s.abci", w->name.c_str()));
|
}
|
||||||
log_assert(w);
|
}
|
||||||
log_assert(b.offset < GetSize(w));
|
jt = module_break.insert(std::make_pair(cell->type, std::move(ports))).first;
|
||||||
log_assert(w->port_input);
|
}
|
||||||
}
|
|
||||||
else {
|
for (auto port_name : jt->second) {
|
||||||
log_assert(!w->port_output);
|
RTLIL::SigSpec sig;
|
||||||
w->port_output = true;
|
auto &rhs = cell->connections_.at(port_name);
|
||||||
w->set_bool_attribute("\\abc_scc_break");
|
for (auto b : rhs) {
|
||||||
w = module->wire(stringf("%s.abci", w->name.c_str()));
|
Wire *w = b.wire;
|
||||||
if (!w) {
|
if (!w) continue;
|
||||||
w = module->addWire(stringf("%s.abci", b.wire->name.c_str()), GetSize(b.wire));
|
w->port_output = true;
|
||||||
w->port_input = true;
|
w->set_bool_attribute("\\abc_scc_break");
|
||||||
}
|
w = module->wire(stringf("%s.abci", w->name.c_str()));
|
||||||
else {
|
if (!w) {
|
||||||
log_assert(w->port_input);
|
w = module->addWire(stringf("%s.abci", b.wire->name.c_str()), GetSize(b.wire));
|
||||||
log_assert(b.offset < GetSize(w));
|
w->port_input = true;
|
||||||
}
|
}
|
||||||
}
|
else {
|
||||||
sig.append(RTLIL::SigBit(w, b.offset));
|
log_assert(b.offset < GetSize(w));
|
||||||
}
|
log_assert(w->port_input);
|
||||||
it->second = sig;
|
}
|
||||||
}
|
sig.append(RTLIL::SigBit(w, b.offset));
|
||||||
}
|
}
|
||||||
|
rhs = sig;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module->fixup_ports();
|
module->fixup_ports();
|
||||||
|
|
Loading…
Reference in New Issue