Merge pull request #6223 from YosysHQ/nella/abc-new-keep-wires

Keep keep wires in abc.
This commit is contained in:
nella
2026-09-21 16:08:26 +00:00
committed by GitHub
4 changed files with 58 additions and 11 deletions
+24 -9
View File
@@ -1607,6 +1607,20 @@ struct XAigerWriter : AigerWriter {
}
}
static bool is_keep_po(Wire *w)
{
return !w->port_input && !w->port_output && w->get_bool_attribute(ID::keep);
}
void add_proper_po(Wire *w, int i, const char *symbol)
{
if (map_file.is_open())
map_file << symbol << " " << proper_pos_counter << " " << w->start_offset + i
<< " " << w->name.c_str() << "\n";
proper_pos_counter++;
pos.push_back(std::make_pair(SigBit(w, i), HierCursor{}));
}
void write(std::ostream *f) {
reset_counters();
@@ -1620,20 +1634,21 @@ struct XAigerWriter : AigerWriter {
int proper_po_num = 0;
for (auto w : top->wires())
if (w->port_output)
if (w->port_output || is_keep_po(w))
proper_po_num += w->width;
prep_boxes(proper_po_num);
for (auto w : top->wires())
if (w->port_output)
for (int i = 0; i < w->width; i++) {
if (map_file.is_open()) {
map_file << "output " << proper_pos_counter << " " << w->start_offset + i
<< " " << w->name.c_str() << "\n";
}
proper_pos_counter++;
pos.push_back(std::make_pair(SigBit(w, i), HierCursor{}));
}
for (int i = 0; i < w->width; i++)
add_proper_po(w, i, "output");
for (auto w : top->wires())
if (is_keep_po(w)) {
keep_wires.insert(w);
for (int i = 0; i < w->width; i++)
add_proper_po(w, i, "keepwire");
}
this->f = f;
// start with the header
+31
View File
@@ -40,6 +40,11 @@ struct PseudoPo {
int offset;
};
struct KeptWire {
RTLIL::IdString wire;
int offset;
};
void reintegrate(RTLIL::Module *module, bool dff_mode, std::string map_filename)
{
auto design = module->design;
@@ -57,6 +62,7 @@ void reintegrate(RTLIL::Module *module, bool dff_mode, std::string map_filename)
dict<RTLIL::IdString, std::pair<int,int>> wideports_cache;
dict<RTLIL::IdString, PseudoPo> pseudopos;
dict<RTLIL::IdString, KeptWire> keptwires;
if (!map_filename.empty()) {
std::ifstream mf(map_filename);
@@ -172,6 +178,17 @@ void reintegrate(RTLIL::Module *module, bool dff_mode, std::string map_filename)
pseudopos.insert({wire_name, PseudoPo{escaped_s, escaped_p, index}});
log_debug(" -> %s.%s[%d]\n", escaped_s, escaped_p, index);
}
else if (type == "keepwire") {
log_assert(variable + co_count < output_count);
RTLIL::IdString wire_name = stringf("$aiger$o%d", variable + co_count);
RTLIL::Wire* wire = mapped_mod->wire(wire_name);
log_assert(wire);
log_assert(wire->port_output);
log_debug("Mapping kept wire %s", wire);
keptwires.insert({wire_name, KeptWire{escaped_s, index}});
log_debug(" -> %s[%d]\n", escaped_s, index);
}
else if (type == "box") {
RTLIL::Cell* cell = mapped_mod->cell(stringf("$box%d", variable));
if (!cell)
@@ -548,6 +565,20 @@ void reintegrate(RTLIL::Module *module, bool dff_mode, std::string map_filename)
mapped_wire->port_output = false;
}
// Drive the kept wires from the nets that replaced them
for (auto &[wire_name, kept] : keptwires) {
RTLIL::Wire *mapped_wire = mapped_mod->wire(wire_name);
log_assert(mapped_wire);
RTLIL::Wire *remap_wire = module->wire(remap_name(wire_name));
log_assert(remap_wire);
RTLIL::Wire *wire = module->wire(kept.wire);
log_assert(wire);
module->connect(SigBit(wire, kept.offset - wire->start_offset), remap_wire);
mapped_wire->port_output = false;
}
mapped_mod->fixup_ports();
// Stitch in mapped_mod's inputs/outputs into module
-1
View File
@@ -9,7 +9,6 @@ import gen_tests_makefile
skip = [
"hier_check.ys",
"keep_wire.ys",
]
def create_tests():
+3 -1
View File
@@ -3,7 +3,8 @@ read_verilog <<EOT
module top(input [3:0] a, b, output y);
(* keep *) wire t = &a;
(* keep *) wire u = |b;
assign y = t ^ u ^ (a[0] & b[0]);
(* keep *) wire [2:1] v = a[2:1] & b[2:1];
assign y = t ^ u ^ ^v ^ (a[0] & b[0]);
endmodule
EOT
@@ -15,6 +16,7 @@ techmap
abc_new -liberty openroad/cm_test_cells.lib
select -assert-count 1 w:t a:keep %i
select -assert-count 1 w:u a:keep %i
select -assert-count 1 w:v a:keep %i
select -assert-none t:$_*_
check -assert
read_verilog openroad/cells_sim.v