mirror of
https://github.com/YosysHQ/yosys
synced 2025-06-23 06:13:41 +00:00
formal
This commit is contained in:
parent
aa4c5e9ee5
commit
21f026cb05
1 changed files with 69 additions and 53 deletions
|
@ -64,7 +64,8 @@ void lhs2rhs_rhs2lhs(RTLIL::Module *module, SigMap &sigmap, dict<RTLIL::SigSpec,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RTLIL::Wire* getParentWire(const RTLIL::SigSpec& sigspec) {
|
RTLIL::Wire *getParentWire(const RTLIL::SigSpec &sigspec)
|
||||||
|
{
|
||||||
if (sigspec.empty()) {
|
if (sigspec.empty()) {
|
||||||
return nullptr; // Empty SigSpec, no parent wire
|
return nullptr; // Empty SigSpec, no parent wire
|
||||||
}
|
}
|
||||||
|
@ -76,8 +77,8 @@ RTLIL::Wire* getParentWire(const RTLIL::SigSpec& sigspec) {
|
||||||
return first_bit.wire;
|
return first_bit.wire;
|
||||||
}
|
}
|
||||||
|
|
||||||
void fixfanout(RTLIL::Design* design, RTLIL::Module *module, SigMap &sigmap, dict<RTLIL::SigSpec, std::set<Cell *>> &sig2CellsInFanout, RTLIL::Cell *cell, int fanout,
|
void fixfanout(RTLIL::Design *design, RTLIL::Module *module, SigMap &sigmap, dict<RTLIL::SigSpec, std::set<Cell *>> &sig2CellsInFanout,
|
||||||
int limit)
|
RTLIL::Cell *cell, int fanout, int limit)
|
||||||
{
|
{
|
||||||
if (fanout <= limit) {
|
if (fanout <= limit) {
|
||||||
std::cout << "Nothing to do for: " << cell->name.c_str() << std::endl;
|
std::cout << "Nothing to do for: " << cell->name.c_str() << std::endl;
|
||||||
|
@ -144,7 +145,8 @@ void fixfanout(RTLIL::Design* design, RTLIL::Module *module, SigMap &sigmap, dic
|
||||||
if (c->input(portName)) {
|
if (c->input(portName)) {
|
||||||
if (actual.is_chunk()) {
|
if (actual.is_chunk()) {
|
||||||
if (buffer_outputs.find(actual) != buffer_outputs.end()) {
|
if (buffer_outputs.find(actual) != buffer_outputs.end()) {
|
||||||
std::cout << " CHUNK, indexCurrentBuffer: " << bufferIndexes[actual] << " buffer_outputs " << buffer_outputs[actual].size() << std::endl;
|
std::cout << " CHUNK, indexCurrentBuffer: " << bufferIndexes[actual] << " buffer_outputs "
|
||||||
|
<< buffer_outputs[actual].size() << std::endl;
|
||||||
std::vector<std::tuple<RTLIL::SigSpec, Cell *>> &buf_info_vec = buffer_outputs[actual];
|
std::vector<std::tuple<RTLIL::SigSpec, Cell *>> &buf_info_vec = buffer_outputs[actual];
|
||||||
int bufferIndex = bufferIndexes[actual];
|
int bufferIndex = bufferIndexes[actual];
|
||||||
std::cout << " BUFFER INDEX: " << bufferIndex << std::endl;
|
std::cout << " BUFFER INDEX: " << bufferIndex << std::endl;
|
||||||
|
@ -156,7 +158,8 @@ void fixfanout(RTLIL::Design* design, RTLIL::Module *module, SigMap &sigmap, dic
|
||||||
c->setPort(portName, newSig);
|
c->setPort(portName, newSig);
|
||||||
sig2CellsInFanout[newSig].insert(c);
|
sig2CellsInFanout[newSig].insert(c);
|
||||||
bufferActualFanout[newBuf]++;
|
bufferActualFanout[newBuf]++;
|
||||||
std::cout << " b: " << newBuf->name.c_str() << " fanout: " << bufferActualFanout[newBuf] << std::endl;
|
std::cout << " b: " << newBuf->name.c_str() << " fanout: " << bufferActualFanout[newBuf]
|
||||||
|
<< std::endl;
|
||||||
if (bufferActualFanout[newBuf] >= max_output_per_buffer) {
|
if (bufferActualFanout[newBuf] >= max_output_per_buffer) {
|
||||||
std::cout << " REACHED MAX" << std::endl;
|
std::cout << " REACHED MAX" << std::endl;
|
||||||
if (buffer_outputs[actual].size() - 1 > bufferIndex) {
|
if (buffer_outputs[actual].size() - 1 > bufferIndex) {
|
||||||
|
@ -190,7 +193,8 @@ void fixfanout(RTLIL::Design* design, RTLIL::Module *module, SigMap &sigmap, dic
|
||||||
for (SigChunk chunk : actual.chunks()) {
|
for (SigChunk chunk : actual.chunks()) {
|
||||||
bool replaced = false;
|
bool replaced = false;
|
||||||
if (buffer_outputs.find(chunk) != buffer_outputs.end()) {
|
if (buffer_outputs.find(chunk) != buffer_outputs.end()) {
|
||||||
std::cout << " CHUNK, indexCurrentBuffer: " << bufferIndexes[chunk] << " buffer_outputs " << buffer_outputs[chunk].size() << std::endl;
|
std::cout << " CHUNK, indexCurrentBuffer: " << bufferIndexes[chunk]
|
||||||
|
<< " buffer_outputs " << buffer_outputs[chunk].size() << std::endl;
|
||||||
std::vector<std::tuple<RTLIL::SigSpec, Cell *>> &buf_info_vec = buffer_outputs[chunk];
|
std::vector<std::tuple<RTLIL::SigSpec, Cell *>> &buf_info_vec = buffer_outputs[chunk];
|
||||||
int bufferIndex = bufferIndexes[chunk];
|
int bufferIndex = bufferIndexes[chunk];
|
||||||
std::cout << " BUFFER INDEX: " << bufferIndex << std::endl;
|
std::cout << " BUFFER INDEX: " << bufferIndex << std::endl;
|
||||||
|
@ -203,7 +207,8 @@ void fixfanout(RTLIL::Design* design, RTLIL::Module *module, SigMap &sigmap, dic
|
||||||
sig2CellsInFanout[newSig].insert(c);
|
sig2CellsInFanout[newSig].insert(c);
|
||||||
replaced = true;
|
replaced = true;
|
||||||
bufferActualFanout[newBuf]++;
|
bufferActualFanout[newBuf]++;
|
||||||
std::cout << " b: " << newBuf->name.c_str() << " fanout: " << bufferActualFanout[newBuf] << std::endl;
|
std::cout << " b: " << newBuf->name.c_str()
|
||||||
|
<< " fanout: " << bufferActualFanout[newBuf] << std::endl;
|
||||||
if (bufferActualFanout[newBuf] >= max_output_per_buffer) {
|
if (bufferActualFanout[newBuf] >= max_output_per_buffer) {
|
||||||
std::cout << " REACHED MAX" << std::endl;
|
std::cout << " REACHED MAX" << std::endl;
|
||||||
if (buffer_outputs[chunk].size() - 1 > bufferIndex) {
|
if (buffer_outputs[chunk].size() - 1 > bufferIndex) {
|
||||||
|
@ -221,7 +226,6 @@ void fixfanout(RTLIL::Design* design, RTLIL::Module *module, SigMap &sigmap, dic
|
||||||
}
|
}
|
||||||
c->setPort(portName, newChunks);
|
c->setPort(portName, newChunks);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -245,14 +249,16 @@ void fixfanout(RTLIL::Design* design, RTLIL::Module *module, SigMap &sigmap, dic
|
||||||
if (c->input(portName)) {
|
if (c->input(portName)) {
|
||||||
if (actual.is_chunk()) {
|
if (actual.is_chunk()) {
|
||||||
if (bufferOutSig == sigmap(actual)) {
|
if (bufferOutSig == sigmap(actual)) {
|
||||||
std::cout << "Replace1: " << getParentWire(bufferOutSig)->name.c_str() << " by " << getParentWire(bufferInSig)->name.c_str() << std::endl;
|
std::cout << "Replace1: " << getParentWire(bufferOutSig)->name.c_str() << " by "
|
||||||
|
<< getParentWire(bufferInSig)->name.c_str() << std::endl;
|
||||||
c->setPort(portName, bufferInSig);
|
c->setPort(portName, bufferInSig);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
std::vector<RTLIL::SigChunk> newChunks;
|
std::vector<RTLIL::SigChunk> newChunks;
|
||||||
for (SigChunk chunk : actual.chunks()) {
|
for (SigChunk chunk : actual.chunks()) {
|
||||||
if (sigmap(SigSpec(chunk)) == sigmap(bufferOutSig)) {
|
if (sigmap(SigSpec(chunk)) == sigmap(bufferOutSig)) {
|
||||||
std::cout << "Replace2: " << getParentWire(bufferOutSig)->name.c_str() << " by " << getParentWire(bufferInSig)->name.c_str() << std::endl;
|
std::cout << "Replace2: " << getParentWire(bufferOutSig)->name.c_str()
|
||||||
|
<< " by " << getParentWire(bufferInSig)->name.c_str() << std::endl;
|
||||||
newChunks.push_back(bufferInSig.as_chunk());
|
newChunks.push_back(bufferInSig.as_chunk());
|
||||||
} else {
|
} else {
|
||||||
newChunks.push_back(chunk);
|
newChunks.push_back(chunk);
|
||||||
|
@ -328,7 +334,8 @@ void calculateFanout(RTLIL::Module *module, SigMap &sigmap, dict<RTLIL::SigSpec,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string substringUntil(const std::string& str, char delimiter) {
|
std::string substringUntil(const std::string &str, char delimiter)
|
||||||
|
{
|
||||||
size_t pos = str.find(delimiter);
|
size_t pos = str.find(delimiter);
|
||||||
if (pos != std::string::npos) {
|
if (pos != std::string::npos) {
|
||||||
return str.substr(0, pos);
|
return str.substr(0, pos);
|
||||||
|
@ -344,6 +351,7 @@ struct AnnotateCellFanout : public ScriptPass {
|
||||||
void execute(std::vector<std::string> args, RTLIL::Design *design) override
|
void execute(std::vector<std::string> args, RTLIL::Design *design) override
|
||||||
{
|
{
|
||||||
int limit = -1;
|
int limit = -1;
|
||||||
|
bool formalFriendly = false;
|
||||||
if (design == nullptr) {
|
if (design == nullptr) {
|
||||||
log_error("No design object\n");
|
log_error("No design object\n");
|
||||||
return;
|
return;
|
||||||
|
@ -357,6 +365,10 @@ struct AnnotateCellFanout : public ScriptPass {
|
||||||
limit = std::atoi(args[++argidx].c_str());
|
limit = std::atoi(args[++argidx].c_str());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (args[argidx] == "-formal") {
|
||||||
|
formalFriendly = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
extra_args(args, argidx, design);
|
extra_args(args, argidx, design);
|
||||||
|
@ -403,6 +415,10 @@ struct AnnotateCellFanout : public ScriptPass {
|
||||||
std::string splitnets = std::string("splitnets ") + netsToSplit;
|
std::string splitnets = std::string("splitnets ") + netsToSplit;
|
||||||
Pass::call(design, splitnets);
|
Pass::call(design, splitnets);
|
||||||
splitnets = std::string("splitnets -ports_only ") + portsToSplit;
|
splitnets = std::string("splitnets -ports_only ") + portsToSplit;
|
||||||
|
if (!formalFriendly)
|
||||||
|
// Formal verification does not like ports to be split.
|
||||||
|
// This will prevent some buffering to happen on output ports used also internally in high fanout,
|
||||||
|
// but it will make formal happy.
|
||||||
Pass::call(design, splitnets);
|
Pass::call(design, splitnets);
|
||||||
netsToSplit = "";
|
netsToSplit = "";
|
||||||
portsToSplit = "";
|
portsToSplit = "";
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue