mirror of
https://github.com/YosysHQ/yosys
synced 2026-07-23 23:52:32 +00:00
twine: fix replayability, reduce TwineSearch usage
This commit is contained in:
parent
e9eb3889b7
commit
7c73fd62e4
41 changed files with 273 additions and 272 deletions
|
|
@ -269,13 +269,14 @@ end_of_header:
|
|||
else
|
||||
log_abort();
|
||||
|
||||
RTLIL::Wire* n0 = module->wire(TwineSearch(&design->twines).find(stringf("$aiger%d$0", aiger_autoidx)));
|
||||
RTLIL::Wire* n0 = aiger_wires.count(0) ? aiger_wires.at(0) : nullptr;
|
||||
if (n0)
|
||||
module->connect(n0, State::S0);
|
||||
|
||||
// Parse footer (symbol table, comments, etc.)
|
||||
unsigned l1;
|
||||
std::string s;
|
||||
TwineSearch search(&design->twines);
|
||||
for (int c = f.peek(); c != EOF; c = f.peek(), ++line_count) {
|
||||
if (c == 'i' || c == 'l' || c == 'o' || c == 'b') {
|
||||
f.ignore(1);
|
||||
|
|
@ -294,7 +295,7 @@ end_of_header:
|
|||
log_assert(l1 < latches.size());
|
||||
wire = latches[l1];
|
||||
} else if (c == 'o') {
|
||||
wire = module->wire(TwineSearch(&design->twines).find(escaped_s.str()));
|
||||
wire = module->wire(search.find(escaped_s.str()));
|
||||
log_assert(l1 < outputs.size());
|
||||
if (wire) {
|
||||
// Could have been renamed by a latch
|
||||
|
|
@ -307,7 +308,7 @@ end_of_header:
|
|||
wire = bad_properties[l1];
|
||||
} else log_abort();
|
||||
|
||||
module->rename(wire, design->twines.add(std::string{escaped_s.str()}));
|
||||
module->rename(wire, intern_name(escaped_s.str(), search));
|
||||
}
|
||||
else if (c == 'j' || c == 'f') {
|
||||
// TODO
|
||||
|
|
@ -346,25 +347,28 @@ RTLIL::Wire* AigerReader::createWireIfNotExists(RTLIL::Module *module, unsigned
|
|||
{
|
||||
const unsigned variable = literal >> 1;
|
||||
const bool invert = literal & 1;
|
||||
if (auto it = aiger_wires.find(literal); it != aiger_wires.end())
|
||||
return it->second;
|
||||
RTLIL::IdString wire_name(stringf("$aiger%d$%d%s", aiger_autoidx, variable, invert ? "b" : ""));
|
||||
RTLIL::Wire *wire = module->wire(TwineSearch(&design->twines).find(wire_name.str()));
|
||||
if (wire) return wire;
|
||||
log_debug2("Creating %s\n", wire_name.c_str());
|
||||
wire = module->addWire(design->twines.add(std::string{wire_name.str()}));
|
||||
RTLIL::Wire *wire = module->addWire(design->twines.add(std::string{wire_name.str()}));
|
||||
wire->port_input = wire->port_output = false;
|
||||
aiger_wires[literal] = wire;
|
||||
if (!invert) return wire;
|
||||
RTLIL::IdString wire_inv_name(stringf("$aiger%d$%d", aiger_autoidx, variable));
|
||||
RTLIL::Wire *wire_inv = module->wire(TwineSearch(&design->twines).find(wire_inv_name.str()));
|
||||
if (wire_inv) {
|
||||
if (module->cell(TwineSearch(&design->twines).find(wire_inv_name.str()))) return wire;
|
||||
const unsigned base_literal = variable << 1;
|
||||
RTLIL::Wire *wire_inv;
|
||||
if (auto it = aiger_wires.find(base_literal); it != aiger_wires.end()) {
|
||||
wire_inv = it->second;
|
||||
}
|
||||
else {
|
||||
RTLIL::IdString wire_inv_name(stringf("$aiger%d$%d", aiger_autoidx, variable));
|
||||
log_debug2("Creating %s\n", wire_inv_name.c_str());
|
||||
wire_inv = module->addWire(design->twines.add(std::string{wire_inv_name.str()}));
|
||||
wire_inv->port_input = wire_inv->port_output = false;
|
||||
aiger_wires[base_literal] = wire_inv;
|
||||
}
|
||||
|
||||
log_debug2("Creating %s = ~%s\n", wire_name.c_str(), wire_inv_name.c_str());
|
||||
log_debug2("Creating %s = ~$aiger%d$%d\n", wire_name.c_str(), aiger_autoidx, variable);
|
||||
module->addNotGate(Twine{stringf("$not$aiger%d$%d", aiger_autoidx, variable)}, wire_inv, wire);
|
||||
|
||||
return wire;
|
||||
|
|
@ -402,7 +406,7 @@ void AigerReader::parse_xaiger()
|
|||
else
|
||||
log_abort();
|
||||
|
||||
RTLIL::Wire* n0 = module->wire(TwineSearch(&design->twines).find(stringf("$aiger%d$0", aiger_autoidx)));
|
||||
RTLIL::Wire* n0 = aiger_wires.count(0) ? aiger_wires.at(0) : nullptr;
|
||||
if (n0)
|
||||
module->connect(n0, State::S0);
|
||||
|
||||
|
|
@ -422,11 +426,12 @@ void AigerReader::parse_xaiger()
|
|||
uint32_t lutSize = parse_xaiger_literal(f);
|
||||
log_debug("m: dataSize=%u lutNum=%u lutSize=%u\n", dataSize, lutNum, lutSize);
|
||||
ConstEvalAig ce(module);
|
||||
TwineSearch search(&design->twines);
|
||||
for (unsigned i = 0; i < lutNum; ++i) {
|
||||
uint32_t rootNodeID = parse_xaiger_literal(f);
|
||||
uint32_t cutLeavesM = parse_xaiger_literal(f);
|
||||
log_debug2("rootNodeID=%d cutLeavesM=%d\n", rootNodeID, cutLeavesM);
|
||||
RTLIL::Wire *output_sig = module->wire(TwineSearch(&design->twines).find(stringf("$aiger%d$%d", aiger_autoidx, rootNodeID)));
|
||||
RTLIL::Wire *output_sig = module->wire(search.find(stringf("$aiger%d$%d", aiger_autoidx, rootNodeID)));
|
||||
log_assert(output_sig);
|
||||
uint32_t nodeID;
|
||||
RTLIL::SigSpec input_sig;
|
||||
|
|
@ -437,7 +442,7 @@ void AigerReader::parse_xaiger()
|
|||
log_debug("\tLUT '$lut$aiger%d$%d' input %d is constant!\n", aiger_autoidx, rootNodeID, cutLeavesM);
|
||||
continue;
|
||||
}
|
||||
RTLIL::Wire *wire = module->wire(TwineSearch(&design->twines).find(stringf("$aiger%d$%d", aiger_autoidx, nodeID)));
|
||||
RTLIL::Wire *wire = module->wire(search.find(stringf("$aiger%d$%d", aiger_autoidx, nodeID)));
|
||||
log_assert(wire);
|
||||
input_sig.append(wire);
|
||||
}
|
||||
|
|
@ -456,7 +461,7 @@ void AigerReader::parse_xaiger()
|
|||
log_assert(o.wire == nullptr);
|
||||
lut_mask.set(gray, o.data);
|
||||
}
|
||||
RTLIL::Cell *output_cell = module->cell(TwineSearch(&design->twines).find(stringf("$and$aiger%d$%d", aiger_autoidx, rootNodeID)));
|
||||
RTLIL::Cell *output_cell = module->cell(search.find(stringf("$and$aiger%d$%d", aiger_autoidx, rootNodeID)));
|
||||
log_assert(output_cell);
|
||||
module->remove(output_cell);
|
||||
module->addLut(Twine{stringf("$lut$aiger%d$%d", aiger_autoidx, rootNodeID)}, input_sig, output_sig, std::move(lut_mask));
|
||||
|
|
@ -772,6 +777,21 @@ void AigerReader::parse_aiger_binary()
|
|||
}
|
||||
}
|
||||
|
||||
// add(std::string) always interns a fresh leaf, but an equal-content name may
|
||||
// already exist in the pool as a NEW_TWINE suffix (auto-generated names share a
|
||||
// prefix leaf). Reuse that ref so every wire/cell with the same name string is
|
||||
// keyed by a single canonical ref; otherwise leaf-vs-suffix refs diverge and
|
||||
// module->wire()/cell() lookups miss.
|
||||
TwineRef AigerReader::intern_name(const std::string &escaped, TwineSearch &search)
|
||||
{
|
||||
TwineRef existing = search.find(escaped);
|
||||
if (existing != Twine::Null)
|
||||
return existing;
|
||||
TwineRef ref = design->twines.add(std::string{escaped});
|
||||
search.insert(ref);
|
||||
return ref;
|
||||
}
|
||||
|
||||
void AigerReader::post_process()
|
||||
{
|
||||
unsigned ci_count = 0, co_count = 0;
|
||||
|
|
@ -816,6 +836,7 @@ void AigerReader::post_process()
|
|||
std::ifstream mf(map_filename);
|
||||
std::string type, symbol;
|
||||
int variable, index;
|
||||
TwineSearch search(&design->twines);
|
||||
while (mf >> type >> variable >> index >> symbol) {
|
||||
RTLIL::IdString escaped_s = RTLIL::escape_id(symbol);
|
||||
if (type == "input") {
|
||||
|
|
@ -830,9 +851,9 @@ void AigerReader::post_process()
|
|||
// Cope with the fact that a CI might be identical
|
||||
// to a PI (necessary due to ABC); in those cases
|
||||
// simply connect the latter to the former
|
||||
existing = module->wire(TwineSearch(&design->twines).find(escaped_s.str()));
|
||||
existing = module->wire(search.find(escaped_s.str()));
|
||||
if (!existing)
|
||||
module->rename(wire, design->twines.add(std::string{escaped_s.str()}));
|
||||
module->rename(wire, intern_name(escaped_s.str(), search));
|
||||
else {
|
||||
wire->port_input = false;
|
||||
module->connect(wire, existing);
|
||||
|
|
@ -841,9 +862,9 @@ void AigerReader::post_process()
|
|||
}
|
||||
else {
|
||||
RTLIL::IdString indexed_name = stringf("%s[%d]", escaped_s, index);
|
||||
existing = module->wire(TwineSearch(&design->twines).find(indexed_name.str()));
|
||||
existing = module->wire(search.find(indexed_name.str()));
|
||||
if (!existing)
|
||||
module->rename(wire, design->twines.add(std::string{indexed_name.str()}));
|
||||
module->rename(wire, intern_name(indexed_name.str(), search));
|
||||
else {
|
||||
module->connect(wire, existing);
|
||||
wire->port_input = false;
|
||||
|
|
@ -875,9 +896,9 @@ void AigerReader::post_process()
|
|||
// Cope with the fact that a CO might be identical
|
||||
// to a PO (necessary due to ABC); in those cases
|
||||
// simply connect the latter to the former
|
||||
existing = module->wire(TwineSearch(&design->twines).find(escaped_s.str()));
|
||||
existing = module->wire(search.find(escaped_s.str()));
|
||||
if (!existing)
|
||||
module->rename(wire, design->twines.add(std::string{escaped_s.str()}));
|
||||
module->rename(wire, intern_name(escaped_s.str(), search));
|
||||
else {
|
||||
wire->port_output = false;
|
||||
existing->port_output = true;
|
||||
|
|
@ -888,9 +909,9 @@ void AigerReader::post_process()
|
|||
}
|
||||
else {
|
||||
RTLIL::IdString indexed_name = stringf("%s[%d]", escaped_s, index);
|
||||
existing = module->wire(TwineSearch(&design->twines).find(indexed_name.str()));
|
||||
existing = module->wire(search.find(indexed_name.str()));
|
||||
if (!existing)
|
||||
module->rename(wire, design->twines.add(std::string{indexed_name.str()}));
|
||||
module->rename(wire, intern_name(indexed_name.str(), search));
|
||||
else {
|
||||
wire->port_output = false;
|
||||
existing->port_output = true;
|
||||
|
|
@ -912,17 +933,18 @@ void AigerReader::post_process()
|
|||
}
|
||||
}
|
||||
else if (type == "box") {
|
||||
RTLIL::Cell* cell = module->cell(TwineSearch(&design->twines).find(stringf("$box%d", variable)));
|
||||
RTLIL::Cell* cell = module->cell(search.find(stringf("$box%d", variable)));
|
||||
if (!cell)
|
||||
log_debug("Box %d (%s) no longer exists.\n", variable, log_id(escaped_s));
|
||||
else
|
||||
module->rename(cell, design->twines.add(std::string{escaped_s.str()}));
|
||||
module->rename(cell, intern_name(escaped_s.str(), search));
|
||||
}
|
||||
else
|
||||
log_error("Symbol type '%s' not recognised.\n", type);
|
||||
}
|
||||
}
|
||||
|
||||
TwineSearch wp_search(&design->twines);
|
||||
for (auto &wp : wideports_cache) {
|
||||
auto name = wp.first;
|
||||
int min = wp.second.first;
|
||||
|
|
@ -930,30 +952,33 @@ void AigerReader::post_process()
|
|||
if (min == 0 && max == 0)
|
||||
continue;
|
||||
|
||||
RTLIL::Wire *wire = module->wire(TwineSearch(&design->twines).find(name.str()));
|
||||
if (wire)
|
||||
module->rename(wire, design->twines.add(std::string{RTLIL::escape_id(stringf("%s[%d]", name.str(), 0))}));
|
||||
RTLIL::Wire *wire = module->wire(wp_search.find(name.str()));
|
||||
if (wire) {
|
||||
TwineRef renamed = design->twines.add(std::string{RTLIL::escape_id(stringf("%s[%d]", name.str(), 0))});
|
||||
wp_search.insert(renamed);
|
||||
module->rename(wire, renamed);
|
||||
}
|
||||
|
||||
// Do not make ports with a mix of input/output into
|
||||
// wide ports
|
||||
bool port_input = false, port_output = false;
|
||||
for (int i = min; i <= max; i++) {
|
||||
RTLIL::IdString other_name = name.str() + stringf("[%d]", i);
|
||||
RTLIL::Wire *other_wire = module->wire(TwineSearch(&design->twines).find(other_name.str()));
|
||||
RTLIL::Wire *other_wire = module->wire(wp_search.find(other_name.str()));
|
||||
if (other_wire) {
|
||||
port_input = port_input || other_wire->port_input;
|
||||
port_output = port_output || other_wire->port_output;
|
||||
}
|
||||
}
|
||||
|
||||
wire = module->addWire(design->twines.add(std::string{name.str()}), max-min+1);
|
||||
wire = module->addWire(intern_name(name.str(), wp_search), max-min+1);
|
||||
wire->start_offset = min;
|
||||
wire->port_input = port_input;
|
||||
wire->port_output = port_output;
|
||||
|
||||
for (int i = min; i <= max; i++) {
|
||||
RTLIL::IdString other_name = stringf("%s[%d]", name, i);
|
||||
RTLIL::Wire *other_wire = module->wire(TwineSearch(&design->twines).find(other_name.str()));
|
||||
RTLIL::Wire *other_wire = module->wire(wp_search.find(other_name.str()));
|
||||
if (other_wire) {
|
||||
other_wire->port_input = false;
|
||||
other_wire->port_output = false;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue