mirror of
https://github.com/YosysHQ/yosys
synced 2026-07-15 03:35:40 +00:00
WIP
This commit is contained in:
parent
dab9a386cc
commit
c3457e2e5c
35 changed files with 204 additions and 63 deletions
|
|
@ -113,6 +113,8 @@ struct CellTypes
|
|||
setup_type(ID($future_ff), {ID::A}, {ID::Y});
|
||||
setup_type(ID($scopeinfo), {}, {});
|
||||
setup_type(ID($input_port), {}, {ID::Y});
|
||||
setup_type(ID($output_port), {ID::A}, {});
|
||||
setup_type(ID($public), {ID::A}, {});
|
||||
setup_type(ID($connect), {ID::A, ID::B}, {});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -253,12 +253,14 @@ X($not)
|
|||
X($or)
|
||||
X($original_tag)
|
||||
X($output)
|
||||
X($output_port)
|
||||
X($overwrite_tag)
|
||||
X($pending)
|
||||
X($pmux)
|
||||
X($pos)
|
||||
X($pow)
|
||||
X($print)
|
||||
X($public)
|
||||
X($recrem)
|
||||
X($reduce_and)
|
||||
X($reduce_bool)
|
||||
|
|
|
|||
|
|
@ -90,6 +90,8 @@ struct CellTableBuilder {
|
|||
setup_type(ID($future_ff), {ID::A}, {ID::Y}, features);
|
||||
setup_type(ID($scopeinfo), {}, {}, features);
|
||||
setup_type(ID($input_port), {}, {ID::Y}, features);
|
||||
setup_type(ID($output_port), {ID::A}, {}, features);
|
||||
setup_type(ID($public), {ID::A}, {}, features);
|
||||
setup_type(ID($connect), {ID::A, ID::B}, {}, features);
|
||||
}
|
||||
constexpr void setup_internals_eval()
|
||||
|
|
|
|||
|
|
@ -2539,6 +2539,12 @@ namespace {
|
|||
check_expected();
|
||||
return;
|
||||
}
|
||||
if (cell->type.in(ID($output_port), ID($public))) {
|
||||
param(ID::WIDTH);
|
||||
port(ID::A, param(ID::WIDTH));
|
||||
check_expected();
|
||||
return;
|
||||
}
|
||||
if (cell->type.in(ID($connect))) {
|
||||
param(ID::WIDTH);
|
||||
port(ID::A, param(ID::WIDTH));
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@ struct RTLIL::SigNormIndex
|
|||
module->fixup_ports();
|
||||
setup_module_inputs();
|
||||
setup_driven_wires();
|
||||
setup_module_outputs_and_publics();
|
||||
setup_fanout();
|
||||
}
|
||||
|
||||
|
|
@ -110,6 +111,72 @@ struct RTLIL::SigNormIndex
|
|||
}
|
||||
}
|
||||
|
||||
// Creates $output_port cells consuming each pure-output module port wire
|
||||
// and $public cells consuming each public-named wire that isn't already
|
||||
// covered by an $input_port or $output_port. These act as fanout sentinels
|
||||
// so local GC (e.g. in Patch) won't remove driver cells whose only purpose
|
||||
// is to feed a port or a user-visible wire.
|
||||
void setup_module_outputs_and_publics() {
|
||||
std::vector<Cell *> cells_to_remove;
|
||||
dict<Wire *, Cell *> output_port_cells;
|
||||
dict<Wire *, Cell *> public_cells;
|
||||
|
||||
for (auto cell : module->cells()) {
|
||||
if (cell->type != ID($output_port) && cell->type != ID($public))
|
||||
continue;
|
||||
|
||||
auto const &sig_a = cell->getPort(ID::A);
|
||||
Wire *wire = nullptr;
|
||||
if (!sig_a.is_wire()) {
|
||||
cells_to_remove.push_back(cell);
|
||||
continue;
|
||||
}
|
||||
wire = sig_a.as_wire();
|
||||
|
||||
if (cell->type == ID($output_port)) {
|
||||
if (wire->port_output && !wire->port_input && !output_port_cells.count(wire))
|
||||
output_port_cells.emplace(wire, cell);
|
||||
else
|
||||
cells_to_remove.push_back(cell);
|
||||
} else { // $public
|
||||
bool is_pure_input = wire->port_input && !wire->port_output;
|
||||
bool is_pure_output = wire->port_output && !wire->port_input;
|
||||
if (wire->name.isPublic() && !is_pure_input && !is_pure_output && !public_cells.count(wire))
|
||||
public_cells.emplace(wire, cell);
|
||||
else
|
||||
cells_to_remove.push_back(cell);
|
||||
}
|
||||
}
|
||||
for (auto cell : cells_to_remove)
|
||||
module->remove(cell);
|
||||
|
||||
for (auto portname : module->ports) {
|
||||
Wire *wire = module->wire(portname);
|
||||
if (wire->port_output && !wire->port_input && !output_port_cells.count(wire)) {
|
||||
Cell *cell = module->addCell(NEW_ID, ID($output_port));
|
||||
cell->setParam(ID::WIDTH, GetSize(wire));
|
||||
cell->setPort(ID::A, wire);
|
||||
output_port_cells.emplace(wire, cell);
|
||||
}
|
||||
}
|
||||
|
||||
for (auto &it : module->wires_) {
|
||||
Wire *wire = it.second;
|
||||
if (!wire->name.isPublic())
|
||||
continue;
|
||||
bool is_pure_input = wire->port_input && !wire->port_output;
|
||||
bool is_pure_output = wire->port_output && !wire->port_input;
|
||||
if (is_pure_input || is_pure_output)
|
||||
continue;
|
||||
if (public_cells.count(wire))
|
||||
continue;
|
||||
Cell *cell = module->addCell(NEW_ID, ID($public));
|
||||
cell->setParam(ID::WIDTH, GetSize(wire));
|
||||
cell->setPort(ID::A, wire);
|
||||
public_cells.emplace(wire, cell);
|
||||
}
|
||||
}
|
||||
|
||||
void setup_driven_wires() {
|
||||
for (auto cell : module->cells()) {
|
||||
xlog("setup_driven_wires cell %s %s\n", cell->type, cell->name);
|
||||
|
|
@ -352,7 +419,7 @@ void RTLIL::Design::sigNormalize(bool enable)
|
|||
// TODO inefficient?
|
||||
std::vector<Cell*> cells_snapshot = module->cells();
|
||||
for (auto cell : cells_snapshot) {
|
||||
if (cell->type == ID($input_port))
|
||||
if (cell->type.in(ID($input_port), ID($output_port), ID($public)))
|
||||
module->remove(cell);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1399,7 +1399,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
|
|||
return true;
|
||||
}
|
||||
|
||||
if (cell->type == ID($scopeinfo) || cell->type == ID($input_port))
|
||||
if (cell->type.in(ID($scopeinfo), ID($input_port), ID($output_port), ID($public)))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -178,6 +178,13 @@ void Patch::patch(Cell* old_cell, IdString old_port, SigSpec new_sig) {
|
|||
for (auto& wire: wires_)
|
||||
commit_wire(std::move(wire));
|
||||
|
||||
// Flush pending sigmap updates (from the mod->connect above) into the
|
||||
// fanout index so gc() sees the updated fanout for cells whose outputs
|
||||
// were the patched wires. Without this, downstream consumers like the
|
||||
// $output_port / $public sentinels still appear in the OLD wire's fanout
|
||||
// instead of the new representative.
|
||||
mod->sigNormalize();
|
||||
|
||||
gc(old_cell);
|
||||
cells_.clear();
|
||||
wires_.clear();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue