X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=passes%2Ftechmap%2Fabc9.cc;h=def347c210d3b676763dbe66e4eae9b5b66a0262;hb=1ea1e8e54f33e4a048c1343959e20e8f1c8ad73b;hp=c2ac4ef7fba12eba47cdc768dadeea3e6706a402;hpb=bf1167bc64eba873ceaf3e4a1988a216fb3909c3;p=yosys.git diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index c2ac4ef7f..def347c21 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -89,20 +89,30 @@ void handle_loops(RTLIL::Design *design, RTLIL::Module *module) if (cell->output(c.first)) { SigBit b = c.second.as_bit(); Wire *w = b.wire; - log_assert(!w->port_input); - w->port_input = true; - w = module->wire(stringf("%s.abci", w->name.c_str())); - if (!w) { - w = module->addWire(stringf("%s.abci", b.wire->name.c_str()), GetSize(b.wire)); - w->port_output = true; + if (w->port_input) { + // In this case, hopefully the loop break has been already created + // Get the non-prefixed wire + Wire *wo = module->wire(stringf("%s.abco", b.wire->name.c_str())); + log_assert(wo != nullptr); + log_assert(wo->port_output); + log_assert(b.offset < GetSize(wo)); + c.second = RTLIL::SigBit(wo, b.offset); } else { - log_assert(w->port_input); - log_assert(b.offset < GetSize(w)); + // Create a new output/input loop break + w->port_input = true; + w = module->wire(stringf("%s.abco", w->name.c_str())); + if (!w) { + w = module->addWire(stringf("%s.abco", b.wire->name.c_str()), GetSize(b.wire)); + w->port_output = true; + } + else { + log_assert(w->port_input); + log_assert(b.offset < GetSize(w)); + } + w->set_bool_attribute(ID(abc9_scc_break)); + c.second = RTLIL::SigBit(w, b.offset); } - w->set_bool_attribute(ID(abc9_scc_break)); - module->swap_names(b.wire, w); - c.second = RTLIL::SigBit(w, b.offset); } } } @@ -311,7 +321,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string scrip for (size_t pos = abc9_script.find("&mfs"); pos != std::string::npos; pos = abc9_script.find("&mfs", pos)) abc9_script = abc9_script.erase(pos, strlen("&mfs")); - abc9_script += stringf("; &write %s/output.aig", tempdir_name.c_str()); + abc9_script += stringf("; &write -n %s/output.aig", tempdir_name.c_str()); abc9_script = add_echos_to_abc9_cmd(abc9_script); for (size_t i = 0; i+1 < abc9_script.size(); i++) @@ -347,31 +357,13 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string scrip log_assert(!design->module(ID($__abc9__))); { AigerReader reader(design, ifs, ID($__abc9__), "" /* clk_name */, buffer.c_str() /* map_filename */, true /* wideports */); - reader.parse_xaiger(); + reader.parse_xaiger(box_lookup); } ifs.close(); - Pass::call(design, stringf("write_verilog -noexpr -norename")); + Pass::call_on_module(design, design->module(ID($__abc9__)), stringf("write_verilog -noexpr -norename -selected")); design->remove(design->module(ID($__abc9__))); #endif - // Now 'unexpose' those wires by undoing - // the expose operation -- remove them from PO/PI - // and re-connecting them back together - for (auto wire : module->wires()) { - auto it = wire->attributes.find(ID(abc9_scc_break)); - if (it != wire->attributes.end()) { - wire->attributes.erase(it); - log_assert(wire->port_output); - wire->port_output = false; - RTLIL::Wire *i_wire = module->wire(wire->name.str() + ".abci"); - log_assert(i_wire); - log_assert(i_wire->port_input); - i_wire->port_input = false; - module->connect(i_wire, wire); - } - } - module->fixup_ports(); - log_header(design, "Executing ABC9.\n"); if (!lut_costs.empty()) { @@ -421,7 +413,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string scrip ifs.close(); #if 0 - Pass::call(design, stringf("write_verilog -noexpr -norename")); + Pass::call_on_module(design, design->module(ID($__abc9__)), stringf("write_verilog -noexpr -norename -selected")); #endif log_header(design, "Re-integrating ABC9 results.\n"); @@ -429,26 +421,10 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string scrip if (mapped_mod == NULL) log_error("ABC output file does not contain a module `$__abc9__'.\n"); - pool output_bits; for (auto &it : mapped_mod->wires_) { RTLIL::Wire *w = it.second; RTLIL::Wire *remap_wire = module->addWire(remap_name(w->name), GetSize(w)); if (markgroups) remap_wire->attributes[ID(abcgroup)] = map_autoidx; - if (w->port_output) { - RTLIL::Wire *wire = module->wire(w->name); - log_assert(wire); - for (int i = 0; i < GetSize(w); i++) - output_bits.insert({wire, i}); - } - } - - for (auto &it : module->connections_) { - auto &signal = it.first; - auto bits = signal.bits(); - for (auto &b : bits) - if (output_bits.count(b)) - b = module->addWire(NEW_ID); - signal = std::move(bits); } dict abc9_box; @@ -721,6 +697,25 @@ clone_lut: } } + // Now 'unexpose' those wires by undoing + // the expose operation -- remove them from PO/PI + // and re-connecting them back together + for (auto wire : module->wires()) { + auto it = wire->attributes.find(ID(abc9_scc_break)); + if (it != wire->attributes.end()) { + wire->attributes.erase(it); + log_assert(wire->port_output); + wire->port_output = false; + std::string name = wire->name.str(); + RTLIL::Wire *i_wire = module->wire(name.substr(0, GetSize(name) - 5)); + log_assert(i_wire); + log_assert(i_wire->port_input); + i_wire->port_input = false; + module->connect(i_wire, wire); + } + } + module->fixup_ports(); + //log("ABC RESULTS: internal signals: %8d\n", int(signal_list.size()) - in_wires - out_wires); log("ABC RESULTS: input signals: %8d\n", in_wires); log("ABC RESULTS: output signals: %8d\n", out_wires); @@ -917,29 +912,28 @@ struct Abc9Pass : public Pass { //} if (arg == "-lut" && argidx+1 < args.size()) { string arg = args[++argidx]; - size_t pos = arg.find_first_of(':'); - int lut_mode = 0, lut_mode2 = 0; - if (pos != string::npos) { - lut_mode = atoi(arg.substr(0, pos).c_str()); - lut_mode2 = atoi(arg.substr(pos+1).c_str()); - } else { - pos = arg.find_first_of('.'); + if (arg.find_first_not_of("0123456789:") == std::string::npos) { + size_t pos = arg.find_first_of(':'); + int lut_mode = 0, lut_mode2 = 0; if (pos != string::npos) { - lut_file = arg; - rewrite_filename(lut_file); - if (!lut_file.empty() && !is_absolute_path(lut_file)) - lut_file = std::string(pwd) + "/" + lut_file; - } - else { + lut_mode = atoi(arg.substr(0, pos).c_str()); + lut_mode2 = atoi(arg.substr(pos+1).c_str()); + } else { lut_mode = atoi(arg.c_str()); lut_mode2 = lut_mode; } + lut_costs.clear(); + for (int i = 0; i < lut_mode; i++) + lut_costs.push_back(1); + for (int i = lut_mode; i < lut_mode2; i++) + lut_costs.push_back(2 << (i - lut_mode)); + } + else { + lut_file = arg; + rewrite_filename(lut_file); + if (!lut_file.empty() && !is_absolute_path(lut_file) && lut_file[0] != '+') + lut_file = std::string(pwd) + "/" + lut_file; } - lut_costs.clear(); - for (int i = 0; i < lut_mode; i++) - lut_costs.push_back(1); - for (int i = lut_mode; i < lut_mode2; i++) - lut_costs.push_back(2 << (i - lut_mode)); continue; } if (arg == "-luts" && argidx+1 < args.size()) { @@ -1008,7 +1002,7 @@ struct Abc9Pass : public Pass { box_file = "+/dummy.box"; rewrite_filename(box_file); - if (!box_file.empty() && !is_absolute_path(box_file)) + if (!box_file.empty() && !is_absolute_path(box_file) && box_file[0] != '+') box_file = std::string(pwd) + "/" + box_file; dict box_lookup; @@ -1072,6 +1066,8 @@ struct Abc9Pass : public Pass { } } + SigMap assign_map; + CellTypes ct(design); for (auto module : design->selected_modules()) { if (module->attributes.count(ID(abc9_box_id))) @@ -1082,27 +1078,23 @@ struct Abc9Pass : public Pass { continue; } - SigMap assign_map(module); - - CellTypes ct(design); + assign_map.set(module); std::vector all_cells = module->selected_cells(); - std::set unassigned_cells(all_cells.begin(), all_cells.end()); - - std::set expand_queue, next_expand_queue; - std::set expand_queue_up, next_expand_queue_up; - std::set expand_queue_down, next_expand_queue_down; + pool unassigned_cells(all_cells.begin(), all_cells.end()); - std::map> assigned_cells; - std::map assigned_cells_reverse; + pool expand_queue, next_expand_queue; + pool expand_queue_up, next_expand_queue_up; + pool expand_queue_down, next_expand_queue_down; - std::map> cell_to_bit, cell_to_bit_up, cell_to_bit_down; - std::map> bit_to_cell, bit_to_cell_up, bit_to_cell_down; + typedef SigSpec clkdomain_t; + std::map> assigned_cells; + std::map assigned_cells_reverse; - typedef std::pair ctrldomain_t; - std::map mergeability_class; + std::map> cell_to_bit, cell_to_bit_up, cell_to_bit_down; + std::map> bit_to_cell, bit_to_cell_up, bit_to_cell_down; - for (auto cell : all_cells) { + for (auto cell : all_cells) for (auto &conn : cell->connections()) for (auto bit : assign_map(conn.second)) if (bit.wire != nullptr) { @@ -1118,6 +1110,7 @@ struct Abc9Pass : public Pass { } } + for (auto cell : all_cells) { auto inst_module = design->module(cell->type); if (!inst_module || !inst_module->attributes.count("\\abc9_flop")) continue; @@ -1127,23 +1120,48 @@ struct Abc9Pass : public Pass { log_error("'%s$abc9_clock' is not a wire present in module '%s'.\n", cell->name.c_str(), log_id(module)); SigSpec abc9_clock = assign_map(abc9_clock_wire); - Wire *abc9_control_wire = module->wire(stringf("%s.$abc9_control", cell->name.c_str())); - if (abc9_control_wire == NULL) - log_error("'%s$abc9_control' is not a wire present in module '%s'.\n", cell->name.c_str(), log_id(module)); - SigSpec abc9_control = assign_map(abc9_control_wire); - unassigned_cells.erase(cell); - expand_queue.insert(cell); expand_queue_up.insert(cell); - expand_queue_down.insert(cell); + clkdomain_t key(abc9_clock); + assigned_cells[key].insert(cell->name); + assigned_cells_reverse[cell] = key; - assigned_cells[abc9_clock].insert(cell->name); - assigned_cells_reverse[cell] = abc9_clock; + auto YS_ATTRIBUTE(unused) r2 = cell->attributes.insert(std::make_pair(ID(abc9_mergeability), 1)); + log_assert(r2.second); - ctrldomain_t key(cell->type, abc9_control); - auto r = mergeability_class.emplace(key, mergeability_class.size() + 1); - auto YS_ATTRIBUTE(unused) r2 = cell->attributes.insert(std::make_pair(ID(abc9_mergeability), r.first->second)); + Wire *abc9_init_wire = module->wire(stringf("%s.$abc9_init", cell->name.c_str())); + if (abc9_init_wire == NULL) + log_error("'%s.$abc9_init' is not a wire present in module '%s'.\n", cell->name.c_str(), log_id(module)); + log_assert(GetSize(abc9_init_wire) == 1); + SigSpec abc9_init = assign_map(abc9_init_wire); + if (!abc9_init.is_fully_const()) + log_error("'%s.$abc9_init' is not a constant wire present in module '%s'.\n", cell->name.c_str(), log_id(module)); + r2 = cell->attributes.insert(std::make_pair(ID(abc9_init), abc9_init.as_const())); log_assert(r2.second); + + // Also assign these special ABC9 cells to the + // same clock domain + for (auto b : cell_to_bit_down[cell]) + for (auto c : bit_to_cell_down[b]) + if (c->type == "$__ABC9_FF_") { + cell = c; + unassigned_cells.erase(cell); + assigned_cells[key].insert(cell->name); + assigned_cells_reverse[cell] = key; + break; + } + for (auto b : cell_to_bit_down[cell]) + for (auto c : bit_to_cell_down[b]) + if (c->type == "$__ABC9_ASYNC") { + cell = c; + unassigned_cells.erase(cell); + assigned_cells[key].insert(cell->name); + assigned_cells_reverse[cell] = key; + break; + } + + expand_queue.insert(cell); + expand_queue_down.insert(cell); } while (!expand_queue_up.empty() || !expand_queue_down.empty()) @@ -1151,12 +1169,12 @@ struct Abc9Pass : public Pass { if (!expand_queue_up.empty()) { RTLIL::Cell *cell = *expand_queue_up.begin(); - SigSpec key = assigned_cells_reverse.at(cell); + auto key = assigned_cells_reverse.at(cell); expand_queue_up.erase(cell); for (auto bit : cell_to_bit_up[cell]) for (auto c : bit_to_cell_up[bit]) - if (unassigned_cells.count(c) && !c->type.in("$__ABC9_FF_", "$__ABC9_ASYNC_")) { + if (unassigned_cells.count(c)) { unassigned_cells.erase(c); next_expand_queue_up.insert(c); assigned_cells[key].insert(c->name); @@ -1168,7 +1186,7 @@ struct Abc9Pass : public Pass { if (!expand_queue_down.empty()) { RTLIL::Cell *cell = *expand_queue_down.begin(); - SigSpec key = assigned_cells_reverse.at(cell); + auto key = assigned_cells_reverse.at(cell); expand_queue_down.erase(cell); for (auto bit : cell_to_bit_down[cell]) @@ -1191,7 +1209,7 @@ struct Abc9Pass : public Pass { while (!expand_queue.empty()) { RTLIL::Cell *cell = *expand_queue.begin(); - SigSpec key = assigned_cells_reverse.at(cell); + auto key = assigned_cells_reverse.at(cell); expand_queue.erase(cell); for (auto bit : cell_to_bit.at(cell)) { @@ -1209,7 +1227,7 @@ struct Abc9Pass : public Pass { expand_queue.swap(next_expand_queue); } - SigSpec key; + clkdomain_t key; for (auto cell : unassigned_cells) { assigned_cells[key].insert(cell->name); assigned_cells_reverse[cell] = key;