3
0
Fork 0
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:
Emil J. Tywoniak 2026-06-22 17:53:19 +02:00
parent e9eb3889b7
commit 7c73fd62e4
41 changed files with 273 additions and 272 deletions

View file

@ -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;