mirror of
https://github.com/YosysHQ/yosys
synced 2025-06-06 06:03:23 +00:00
bulk splitnets
This commit is contained in:
parent
7df2a8eb8e
commit
4035a24e4c
1 changed files with 46 additions and 37 deletions
|
@ -509,41 +509,51 @@ void calculateFanout(RTLIL::Module *module, SigMap &sigmap, dict<RTLIL::SigSpec,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void splitNet(Design *design, std::set<std::string> &netsToSplitS, RTLIL::SigSpec &sigToSplit, bool formalFriendly, bool debug, bool inputPort = false)
|
void splitNets(Design *design, std::set<std::string> &netsToSplitS, std::vector<RTLIL::SigSpec> &sigsToSplit, bool formalFriendly, bool debug,
|
||||||
|
bool inputPort = false)
|
||||||
{
|
{
|
||||||
|
std::string wires;
|
||||||
|
std::string inputs;
|
||||||
|
std::string outputs;
|
||||||
|
for (RTLIL::SigSpec sigToSplit : sigsToSplit) {
|
||||||
Wire *parentWire = getParentWire(sigToSplit);
|
Wire *parentWire = getParentWire(sigToSplit);
|
||||||
if (!parentWire)
|
if (!parentWire)
|
||||||
return;
|
continue;
|
||||||
std::string parent = parentWire->name.c_str();
|
std::string parent = parentWire->name.c_str();
|
||||||
if (parent == "") {
|
if (parent == "") {
|
||||||
return;
|
continue;
|
||||||
}
|
}
|
||||||
if (parentWire->width == 1)
|
if (parentWire->width == 1)
|
||||||
return;
|
continue;
|
||||||
parent = substringuntil(parent, '[');
|
parent = substringuntil(parent, '[');
|
||||||
|
if (netsToSplitS.find(parent) == netsToSplitS.end()) {
|
||||||
|
netsToSplitS.insert(parent);
|
||||||
if (debug) {
|
if (debug) {
|
||||||
std::cout << "splitnets: " << parent << std::endl;
|
std::cout << "splitnets: " << parent << std::endl;
|
||||||
}
|
}
|
||||||
if (netsToSplitS.find(parent) == netsToSplitS.end()) {
|
|
||||||
netsToSplitS.insert(parent);
|
|
||||||
// Splitnets has to be invoke with individual nets. Sending a bunch of nets as selection,
|
|
||||||
// selects more than required (bug in selection/splitnets).
|
|
||||||
if ((!parentWire->port_input) && (!parentWire->port_output))
|
if ((!parentWire->port_input) && (!parentWire->port_output))
|
||||||
Pass::call(design, "splitnets w:" + parent); // Wire
|
wires += " w:" + parent;
|
||||||
if (!formalFriendly) {
|
if (!formalFriendly) {
|
||||||
// Formal verification does not like ports to be split.
|
// Formal verification does not like ports to be split.
|
||||||
// This option will prevent some buffering to happen on high fanout input/output ports,
|
// This option will prevent some buffering to happen on high fanout input/output ports,
|
||||||
// but it will make formal happy.
|
// but it will make formal happy.
|
||||||
if (inputPort) {
|
if (inputPort) {
|
||||||
if (parentWire->port_input)
|
if (parentWire->port_input)
|
||||||
Pass::call(design, "splitnets -ports_only i:" + parent); // Input port
|
inputs += " i:" + parent;
|
||||||
} else {
|
} else {
|
||||||
if (parentWire->port_output)
|
if (parentWire->port_output)
|
||||||
Pass::call(design, "splitnets -ports_only o:" + parent); // Output port
|
outputs += " o:" + parent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!wires.empty()) {
|
||||||
|
Pass::call(design, "splitnets" + wires); // Wire
|
||||||
|
}
|
||||||
|
if (!inputs.empty() || !outputs.empty()) {
|
||||||
|
Pass::call(design, "splitnets -ports_only" + inputs + outputs); // Input port
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct AnnotateCellFanout : public ScriptPass {
|
struct AnnotateCellFanout : public ScriptPass {
|
||||||
AnnotateCellFanout() : ScriptPass("annotate_cell_fanout", "Annotate the cell fanout on the cell") {}
|
AnnotateCellFanout() : ScriptPass("annotate_cell_fanout", "Annotate the cell fanout on the cell") {}
|
||||||
|
@ -616,6 +626,7 @@ struct AnnotateCellFanout : public ScriptPass {
|
||||||
|
|
||||||
std::set<std::string> netsToSplitS;
|
std::set<std::string> netsToSplitS;
|
||||||
// Split cells output nets with high fanout
|
// Split cells output nets with high fanout
|
||||||
|
std::vector<RTLIL::SigSpec> cellOutputsToSplit;
|
||||||
for (auto itrCell : cellFanout) {
|
for (auto itrCell : cellFanout) {
|
||||||
Cell *cell = itrCell.first;
|
Cell *cell = itrCell.first;
|
||||||
int fanout = itrCell.second;
|
int fanout = itrCell.second;
|
||||||
|
@ -625,28 +636,26 @@ struct AnnotateCellFanout : public ScriptPass {
|
||||||
RTLIL::SigSpec actual = conn.second;
|
RTLIL::SigSpec actual = conn.second;
|
||||||
if (cell->output(portName)) {
|
if (cell->output(portName)) {
|
||||||
RTLIL::SigSpec cellOutSig = sigmap(actual);
|
RTLIL::SigSpec cellOutSig = sigmap(actual);
|
||||||
splitNet(design, netsToSplitS, cellOutSig, formalFriendly, debug);
|
cellOutputsToSplit.push_back(cellOutSig);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
splitNets(design, netsToSplitS, cellOutputsToSplit, formalFriendly, debug);
|
||||||
|
|
||||||
if (inputs) {
|
if (inputs) {
|
||||||
// Split module input nets with high fanout
|
// Split module input nets with high fanout
|
||||||
std::set<Wire *> wiresToSplit;
|
std::vector<RTLIL::SigSpec> wiresToSplit;
|
||||||
for (Wire *wire : module->wires()) {
|
for (Wire *wire : module->wires()) {
|
||||||
if (wire->port_input) {
|
if (wire->port_input) {
|
||||||
SigSpec inp = sigmap(wire);
|
SigSpec inp = sigmap(wire);
|
||||||
int fanout = sigFanout[inp];
|
int fanout = sigFanout[inp];
|
||||||
if (limit > 0 && (fanout > limit)) {
|
if (limit > 0 && (fanout > limit)) {
|
||||||
wiresToSplit.insert(wire);
|
wiresToSplit.push_back(inp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (Wire *wire : wiresToSplit) {
|
splitNets(design, netsToSplitS, wiresToSplit, formalFriendly, debug, true);
|
||||||
SigSpec inp = sigmap(wire);
|
|
||||||
splitNet(design, netsToSplitS, inp, formalFriendly, debug, true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue