From 7ff5d6d30ae9f48376f0c6a98d8a5fa0831faf77 Mon Sep 17 00:00:00 2001 From: David Shah Date: Mon, 18 Nov 2019 13:58:03 +0000 Subject: memory_collect: Copy attr from RTLIL::Memory to cell Signed-off-by: David Shah --- passes/memory/memory_collect.cc | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'passes') diff --git a/passes/memory/memory_collect.cc b/passes/memory/memory_collect.cc index 6acbce62f..9dcb3f024 100644 --- a/passes/memory/memory_collect.cc +++ b/passes/memory/memory_collect.cc @@ -218,6 +218,10 @@ Cell *handle_memory(Module *module, RTLIL::Memory *memory) mem->setPort("\\RD_DATA", sig_rd_data); mem->setPort("\\RD_EN", sig_rd_en); + // Copy attributes from RTLIL memory to $mem + for (auto attr : memory->attributes) + mem->attributes[attr.first] = attr.second; + for (auto c : memcells) module->remove(c); -- cgit v1.2.3 From 2105ae176a73a9839670bf8120b462d06151dae5 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 26 Nov 2019 21:26:53 -0800 Subject: Check for either sign or zero extension for postAdd packing --- passes/pmgen/xilinx_dsp.pmg | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'passes') diff --git a/passes/pmgen/xilinx_dsp.pmg b/passes/pmgen/xilinx_dsp.pmg index 0ba529011..5d3b9c2eb 100644 --- a/passes/pmgen/xilinx_dsp.pmg +++ b/passes/pmgen/xilinx_dsp.pmg @@ -347,9 +347,9 @@ match postAdd index port(postAdd, AB)[0] === sigP[0] filter GetSize(port(postAdd, AB)) >= GetSize(sigP) filter port(postAdd, AB).extract(0, GetSize(sigP)) == sigP - // Check that remainder of AB is a sign-extension - define AB_SIGNED (param(postAdd, AB == \A ? \A_SIGNED : \B_SIGNED).as_bool()) - filter port(postAdd, AB).extract_end(GetSize(sigP)) == SigSpec(AB_SIGNED ? sigP[GetSize(sigP)-1] : State::S0, GetSize(port(postAdd, AB))-GetSize(sigP)) + // Check that remainder of AB is a sign- or zero-extension + filter port(postAdd, AB).extract_end(GetSize(sigP)) == SigSpec(sigP[GetSize(sigP)-1], GetSize(port(postAdd, AB))-GetSize(sigP)) || port(postAdd, AB).extract_end(GetSize(sigP)) == SigSpec(State::S0, GetSize(port(postAdd, AB))-GetSize(sigP)) + set postAddAB AB optional endmatch -- cgit v1.2.3 From fdcbda195b8806cc3f8fb98e80da55e756c285c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20Ko=C5=9Bcielnicki?= Date: Wed, 27 Nov 2019 00:46:21 +0100 Subject: opt_share: Fix handling of fine cells. Fixes #1525. --- passes/opt/opt_share.cc | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'passes') diff --git a/passes/opt/opt_share.cc b/passes/opt/opt_share.cc index 2c456705c..f59f978a6 100644 --- a/passes/opt/opt_share.cc +++ b/passes/opt/opt_share.cc @@ -83,7 +83,9 @@ struct ExtSigSpec { bool operator==(const ExtSigSpec &other) const { return is_signed == other.is_signed && sign == other.sign && sig == other.sig && semantics == other.semantics; } }; -#define BITWISE_OPS ID($_AND_), ID($_NAND_), ID($_OR_), ID($_NOR_), ID($_XOR_), ID($_XNOR_), ID($_ANDNOT_), ID($_ORNOT_), ID($and), ID($or), ID($xor), ID($xnor) +#define FINE_BITWISE_OPS ID($_AND_), ID($_NAND_), ID($_OR_), ID($_NOR_), ID($_XOR_), ID($_XNOR_), ID($_ANDNOT_), ID($_ORNOT_) + +#define BITWISE_OPS FINE_BITWISE_OPS, ID($and), ID($or), ID($xor), ID($xnor) #define REDUCTION_OPS ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_xnor), ID($reduce_bool), ID($reduce_nand) @@ -250,14 +252,19 @@ void merge_operators(RTLIL::Module *module, RTLIL::Cell *mux, const std::vector< shared_op->setPort(ID(CO), alu_co.extract(0, conn_width)); } - shared_op->setParam(ID(Y_WIDTH), conn_width); + bool is_fine = shared_op->type.in(FINE_BITWISE_OPS); + + if (!is_fine) + shared_op->setParam(ID(Y_WIDTH), conn_width); if (decode_port(shared_op, ID::A, &assign_map) == operand) { shared_op->setPort(ID::B, mux_to_oper); - shared_op->setParam(ID(B_WIDTH), max_width); + if (!is_fine) + shared_op->setParam(ID(B_WIDTH), max_width); } else { shared_op->setPort(ID::A, mux_to_oper); - shared_op->setParam(ID(A_WIDTH), max_width); + if (!is_fine) + shared_op->setParam(ID(A_WIDTH), max_width); } } -- cgit v1.2.3 From e9ce4e658b2dddfc808e1d0383a5b93a906e2bbb Mon Sep 17 00:00:00 2001 From: David Shah Date: Sun, 1 Dec 2019 20:44:56 +0000 Subject: abc9: Fix breaking of SCCs Signed-off-by: David Shah --- passes/techmap/abc9.cc | 69 +++++++++++++++++++++++++++++--------------------- 1 file changed, 40 insertions(+), 29 deletions(-) (limited to 'passes') diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 27106cc5d..8276c3c16 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -94,20 +94,30 @@ void handle_loops(RTLIL::Design *design) 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); } } } @@ -420,24 +430,6 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri design->selection_stack.pop_back(); - // 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()) { @@ -781,6 +773,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); -- cgit v1.2.3 From 5897b918b3735e9bd621966fdcf0c52bb11cebc2 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 3 Dec 2019 14:48:11 -0800 Subject: ice40_wrapcarry to preserve SB_CARRY's attributes --- passes/pmgen/ice40_wrapcarry.cc | 2 ++ 1 file changed, 2 insertions(+) (limited to 'passes') diff --git a/passes/pmgen/ice40_wrapcarry.cc b/passes/pmgen/ice40_wrapcarry.cc index 69ef3cd82..66054ea42 100644 --- a/passes/pmgen/ice40_wrapcarry.cc +++ b/passes/pmgen/ice40_wrapcarry.cc @@ -50,6 +50,8 @@ void create_ice40_wrapcarry(ice40_wrapcarry_pm &pm) cell->setPort("\\O", st.lut->getPort("\\O")); cell->setParam("\\LUT", st.lut->getParam("\\LUT_INIT")); + cell->attributes = std::move(st.carry->attributes); + pm.autoremove(st.carry); pm.autoremove(st.lut); } -- cgit v1.2.3 From 2abe38e73e51204976129c776447c2d40578c32f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20Ko=C5=9Bcielnicki?= Date: Wed, 4 Dec 2019 08:44:08 +0100 Subject: iopadmap: Refactor and fix tristate buffer mapping. (#1527) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The previous code for rerouting wires when inserting tristate buffers was overcomplicated and didn't handle all cases correctly (in particular, only cell connections were rewired — internal connections were not). --- passes/techmap/iopadmap.cc | 243 ++++++++++++++++++--------------------------- 1 file changed, 97 insertions(+), 146 deletions(-) (limited to 'passes') diff --git a/passes/techmap/iopadmap.cc b/passes/techmap/iopadmap.cc index c868b9a87..90cfef71e 100644 --- a/passes/techmap/iopadmap.cc +++ b/passes/techmap/iopadmap.cc @@ -87,11 +87,11 @@ struct IopadmapPass : public Pass { { log_header(design, "Executing IOPADMAP pass (mapping inputs/outputs to IO-PAD cells).\n"); - std::string inpad_celltype, inpad_portname, inpad_portname2; - std::string outpad_celltype, outpad_portname, outpad_portname2; - std::string inoutpad_celltype, inoutpad_portname, inoutpad_portname2; - std::string toutpad_celltype, toutpad_portname, toutpad_portname2, toutpad_portname3; - std::string tinoutpad_celltype, tinoutpad_portname, tinoutpad_portname2, tinoutpad_portname3, tinoutpad_portname4; + std::string inpad_celltype, inpad_portname_o, inpad_portname_pad; + std::string outpad_celltype, outpad_portname_i, outpad_portname_pad; + std::string inoutpad_celltype, inoutpad_portname_io, inoutpad_portname_pad; + std::string toutpad_celltype, toutpad_portname_oe, toutpad_portname_i, toutpad_portname_pad; + std::string tinoutpad_celltype, tinoutpad_portname_oe, tinoutpad_portname_o, tinoutpad_portname_i, tinoutpad_portname_pad; std::string widthparam, nameparam; pool> ignore; bool flag_bits = false; @@ -102,35 +102,35 @@ struct IopadmapPass : public Pass { std::string arg = args[argidx]; if (arg == "-inpad" && argidx+2 < args.size()) { inpad_celltype = args[++argidx]; - inpad_portname = args[++argidx]; - split_portname_pair(inpad_portname, inpad_portname2); + inpad_portname_o = args[++argidx]; + split_portname_pair(inpad_portname_o, inpad_portname_pad); continue; } if (arg == "-outpad" && argidx+2 < args.size()) { outpad_celltype = args[++argidx]; - outpad_portname = args[++argidx]; - split_portname_pair(outpad_portname, outpad_portname2); + outpad_portname_i = args[++argidx]; + split_portname_pair(outpad_portname_i, outpad_portname_pad); continue; } if (arg == "-inoutpad" && argidx+2 < args.size()) { inoutpad_celltype = args[++argidx]; - inoutpad_portname = args[++argidx]; - split_portname_pair(inoutpad_portname, inoutpad_portname2); + inoutpad_portname_io = args[++argidx]; + split_portname_pair(inoutpad_portname_io, inoutpad_portname_pad); continue; } if (arg == "-toutpad" && argidx+2 < args.size()) { toutpad_celltype = args[++argidx]; - toutpad_portname = args[++argidx]; - split_portname_pair(toutpad_portname, toutpad_portname2); - split_portname_pair(toutpad_portname2, toutpad_portname3); + toutpad_portname_oe = args[++argidx]; + split_portname_pair(toutpad_portname_oe, toutpad_portname_i); + split_portname_pair(toutpad_portname_i, toutpad_portname_pad); continue; } if (arg == "-tinoutpad" && argidx+2 < args.size()) { tinoutpad_celltype = args[++argidx]; - tinoutpad_portname = args[++argidx]; - split_portname_pair(tinoutpad_portname, tinoutpad_portname2); - split_portname_pair(tinoutpad_portname2, tinoutpad_portname3); - split_portname_pair(tinoutpad_portname3, tinoutpad_portname4); + tinoutpad_portname_oe = args[++argidx]; + split_portname_pair(tinoutpad_portname_oe, tinoutpad_portname_o); + split_portname_pair(tinoutpad_portname_o, tinoutpad_portname_i); + split_portname_pair(tinoutpad_portname_i, tinoutpad_portname_pad); continue; } if (arg == "-ignore" && argidx+2 < args.size()) { @@ -161,16 +161,16 @@ struct IopadmapPass : public Pass { } extra_args(args, argidx, design); - if (!inpad_portname2.empty()) - ignore.insert(make_pair(RTLIL::escape_id(inpad_celltype), RTLIL::escape_id(inpad_portname2))); - if (!outpad_portname2.empty()) - ignore.insert(make_pair(RTLIL::escape_id(outpad_celltype), RTLIL::escape_id(outpad_portname2))); - if (!inoutpad_portname2.empty()) - ignore.insert(make_pair(RTLIL::escape_id(inoutpad_celltype), RTLIL::escape_id(inoutpad_portname2))); - if (!toutpad_portname3.empty()) - ignore.insert(make_pair(RTLIL::escape_id(toutpad_celltype), RTLIL::escape_id(toutpad_portname3))); - if (!tinoutpad_portname4.empty()) - ignore.insert(make_pair(RTLIL::escape_id(tinoutpad_celltype), RTLIL::escape_id(tinoutpad_portname4))); + if (!inpad_portname_pad.empty()) + ignore.insert(make_pair(RTLIL::escape_id(inpad_celltype), RTLIL::escape_id(inpad_portname_pad))); + if (!outpad_portname_pad.empty()) + ignore.insert(make_pair(RTLIL::escape_id(outpad_celltype), RTLIL::escape_id(outpad_portname_pad))); + if (!inoutpad_portname_pad.empty()) + ignore.insert(make_pair(RTLIL::escape_id(inoutpad_celltype), RTLIL::escape_id(inoutpad_portname_pad))); + if (!toutpad_portname_pad.empty()) + ignore.insert(make_pair(RTLIL::escape_id(toutpad_celltype), RTLIL::escape_id(toutpad_portname_pad))); + if (!tinoutpad_portname_pad.empty()) + ignore.insert(make_pair(RTLIL::escape_id(tinoutpad_celltype), RTLIL::escape_id(tinoutpad_portname_pad))); for (auto module : design->modules()) if (module->get_blackbox_attribute()) @@ -180,34 +180,25 @@ struct IopadmapPass : public Pass { for (auto module : design->selected_modules()) { - dict> skip_wires; pool skip_wire_bits; - SigMap sigmap(module); + dict>> rewrite_bits; for (auto cell : module->cells()) for (auto port : cell->connections()) if (ignore.count(make_pair(cell->type, port.first))) - for (auto bit : sigmap(port.second)) + for (auto bit : port.second) skip_wire_bits.insert(bit); if (!toutpad_celltype.empty() || !tinoutpad_celltype.empty()) { - dict>> tbuf_bits; - pool> norewrites; - SigMap rewrites; + dict tbuf_bits; for (auto cell : module->cells()) if (cell->type == ID($_TBUF_)) { - SigBit bit = sigmap(cell->getPort(ID::Y).as_bit()); - tbuf_bits[bit].first = cell->name; + SigBit bit = cell->getPort(ID::Y).as_bit(); + tbuf_bits[bit] = cell; } - for (auto cell : module->cells()) - for (auto port : cell->connections()) - for (auto bit : sigmap(port.second)) - if (tbuf_bits.count(bit)) - tbuf_bits.at(bit).second.insert(cell->name); - for (auto wire : module->selected_wires()) { if (!wire->port_output) @@ -216,16 +207,11 @@ struct IopadmapPass : public Pass { for (int i = 0; i < GetSize(wire); i++) { SigBit wire_bit(wire, i); - SigBit mapped_wire_bit = sigmap(wire_bit); - if (tbuf_bits.count(mapped_wire_bit) == 0) + if (tbuf_bits.count(wire_bit) == 0) continue; - if (skip_wire_bits.count(mapped_wire_bit)) - continue; - - auto &tbuf_cache = tbuf_bits.at(mapped_wire_bit); - Cell *tbuf_cell = module->cell(tbuf_cache.first); + Cell *tbuf_cell = tbuf_bits.at(wire_bit); if (tbuf_cell == nullptr) continue; @@ -238,37 +224,16 @@ struct IopadmapPass : public Pass { log("Mapping port %s.%s[%d] using %s.\n", log_id(module), log_id(wire), i, tinoutpad_celltype.c_str()); Cell *cell = module->addCell(NEW_ID, RTLIL::escape_id(tinoutpad_celltype)); - Wire *owire = module->addWire(NEW_ID); - cell->setPort(RTLIL::escape_id(tinoutpad_portname), en_sig); - cell->setPort(RTLIL::escape_id(tinoutpad_portname2), owire); - cell->setPort(RTLIL::escape_id(tinoutpad_portname3), data_sig); - cell->setPort(RTLIL::escape_id(tinoutpad_portname4), wire_bit); + cell->setPort(RTLIL::escape_id(tinoutpad_portname_oe), en_sig); + cell->setPort(RTLIL::escape_id(tinoutpad_portname_o), wire_bit); + cell->setPort(RTLIL::escape_id(tinoutpad_portname_i), data_sig); cell->attributes[ID::keep] = RTLIL::Const(1); - for (auto cn : tbuf_cache.second) { - auto c = module->cell(cn); - if (c == nullptr) - continue; - for (auto port : c->connections()) { - SigSpec sig = port.second; - bool newsig = false; - for (auto &bit : sig) - if (sigmap(bit) == mapped_wire_bit) { - bit = owire; - newsig = true; - } - if (newsig) - c->setPort(port.first, sig); - } - } - - module->remove(tbuf_cell); - skip_wires[wire->name].insert(i); - - norewrites.insert(make_pair(cell->name, RTLIL::escape_id(tinoutpad_portname4))); - rewrites.add(sigmap(wire_bit), owire); + skip_wire_bits.insert(wire_bit); + if (!tinoutpad_portname_pad.empty()) + rewrite_bits[wire][i] = make_pair(cell, RTLIL::escape_id(tinoutpad_portname_pad)); continue; } @@ -278,50 +243,19 @@ struct IopadmapPass : public Pass { Cell *cell = module->addCell(NEW_ID, RTLIL::escape_id(toutpad_celltype)); - cell->setPort(RTLIL::escape_id(toutpad_portname), en_sig); - cell->setPort(RTLIL::escape_id(toutpad_portname2), data_sig); - cell->setPort(RTLIL::escape_id(toutpad_portname3), wire_bit); + cell->setPort(RTLIL::escape_id(toutpad_portname_oe), en_sig); + cell->setPort(RTLIL::escape_id(toutpad_portname_i), data_sig); cell->attributes[ID::keep] = RTLIL::Const(1); - for (auto cn : tbuf_cache.second) { - auto c = module->cell(cn); - if (c == nullptr) - continue; - for (auto port : c->connections()) { - SigSpec sig = port.second; - bool newsig = false; - for (auto &bit : sig) - if (sigmap(bit) == mapped_wire_bit) { - bit = data_sig; - newsig = true; - } - if (newsig) - c->setPort(port.first, sig); - } - } - module->remove(tbuf_cell); - skip_wires[wire->name].insert(i); + module->connect(wire_bit, data_sig); + skip_wire_bits.insert(wire_bit); + if (!toutpad_portname_pad.empty()) + rewrite_bits[wire][i] = make_pair(cell, RTLIL::escape_id(toutpad_portname_pad)); continue; } } } - - if (GetSize(norewrites)) - { - for (auto cell : module->cells()) - for (auto port : cell->connections()) - { - if (norewrites.count(make_pair(cell->name, port.first))) - continue; - - SigSpec orig_sig = sigmap(port.second); - SigSpec new_sig = rewrites(orig_sig); - - if (orig_sig != new_sig) - cell->setPort(port.first, new_sig); - } - } } for (auto wire : module->selected_wires()) @@ -329,17 +263,11 @@ struct IopadmapPass : public Pass { if (!wire->port_id) continue; - std::string celltype, portname, portname2; + std::string celltype, portname_int, portname_pad; pool skip_bit_indices; - if (skip_wires.count(wire->name)) { - if (!flag_bits) - continue; - skip_bit_indices = skip_wires.at(wire->name); - } - for (int i = 0; i < GetSize(wire); i++) - if (skip_wire_bits.count(sigmap(SigBit(wire, i)))) + if (skip_wire_bits.count(SigBit(wire, i))) skip_bit_indices.insert(i); if (GetSize(wire) == GetSize(skip_bit_indices)) @@ -351,8 +279,8 @@ struct IopadmapPass : public Pass { continue; } celltype = inpad_celltype; - portname = inpad_portname; - portname2 = inpad_portname2; + portname_int = inpad_portname_o; + portname_pad = inpad_portname_pad; } else if (!wire->port_input && wire->port_output) { if (outpad_celltype.empty()) { @@ -360,8 +288,8 @@ struct IopadmapPass : public Pass { continue; } celltype = outpad_celltype; - portname = outpad_portname; - portname2 = outpad_portname2; + portname_int = outpad_portname_i; + portname_pad = outpad_portname_pad; } else if (wire->port_input && wire->port_output) { if (inoutpad_celltype.empty()) { @@ -369,8 +297,8 @@ struct IopadmapPass : public Pass { continue; } celltype = inoutpad_celltype; - portname = inoutpad_portname; - portname2 = inoutpad_portname2; + portname_int = inoutpad_portname_io; + portname_pad = inoutpad_portname_pad; } else log_abort(); @@ -381,29 +309,20 @@ struct IopadmapPass : public Pass { log("Mapping port %s.%s using %s.\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(wire->name), celltype.c_str()); - RTLIL::Wire *new_wire = NULL; - if (!portname2.empty()) { - new_wire = module->addWire(NEW_ID, wire); - module->swap_names(new_wire, wire); - wire->attributes.clear(); - } - if (flag_bits) { for (int i = 0; i < wire->width; i++) { - if (skip_bit_indices.count(i)) { - if (wire->port_output) - module->connect(SigSpec(new_wire, i), SigSpec(wire, i)); - else - module->connect(SigSpec(wire, i), SigSpec(new_wire, i)); + if (skip_bit_indices.count(i)) continue; - } + + SigBit wire_bit(wire, i); RTLIL::Cell *cell = module->addCell(NEW_ID, RTLIL::escape_id(celltype)); - cell->setPort(RTLIL::escape_id(portname), RTLIL::SigSpec(wire, i)); - if (!portname2.empty()) - cell->setPort(RTLIL::escape_id(portname2), RTLIL::SigSpec(new_wire, i)); + cell->setPort(RTLIL::escape_id(portname_int), wire_bit); + + if (!portname_pad.empty()) + rewrite_bits[wire][i] = make_pair(cell, RTLIL::escape_id(portname_pad)); if (!widthparam.empty()) cell->parameters[RTLIL::escape_id(widthparam)] = RTLIL::Const(1); if (!nameparam.empty()) @@ -414,9 +333,15 @@ struct IopadmapPass : public Pass { else { RTLIL::Cell *cell = module->addCell(NEW_ID, RTLIL::escape_id(celltype)); - cell->setPort(RTLIL::escape_id(portname), RTLIL::SigSpec(wire)); - if (!portname2.empty()) - cell->setPort(RTLIL::escape_id(portname2), RTLIL::SigSpec(new_wire)); + cell->setPort(RTLIL::escape_id(portname_int), RTLIL::SigSpec(wire)); + + if (!portname_pad.empty()) { + RTLIL::Wire *new_wire = NULL; + new_wire = module->addWire(NEW_ID, wire); + module->swap_names(new_wire, wire); + wire->attributes.clear(); + cell->setPort(RTLIL::escape_id(portname_pad), RTLIL::SigSpec(new_wire)); + } if (!widthparam.empty()) cell->parameters[RTLIL::escape_id(widthparam)] = RTLIL::Const(wire->width); if (!nameparam.empty()) @@ -424,6 +349,32 @@ struct IopadmapPass : public Pass { cell->attributes[ID::keep] = RTLIL::Const(1); } + if (!rewrite_bits.count(wire)) { + wire->port_id = 0; + wire->port_input = false; + wire->port_output = false; + } + } + + for (auto &it : rewrite_bits) { + RTLIL::Wire *wire = it.first; + RTLIL::Wire *new_wire = module->addWire(NEW_ID, wire); + module->swap_names(new_wire, wire); + wire->attributes.clear(); + for (int i = 0; i < wire->width; i++) + { + SigBit wire_bit(wire, i); + if (!it.second.count(i)) { + if (wire->port_output) + module->connect(SigSpec(new_wire, i), SigSpec(wire, i)); + else + module->connect(SigSpec(wire, i), SigSpec(new_wire, i)); + } else { + auto &new_conn = it.second.at(i); + new_conn.first->setPort(new_conn.second, RTLIL::SigSpec(new_wire, i)); + } + } + wire->port_id = 0; wire->port_input = false; wire->port_output = false; -- cgit v1.2.3 From a7e0cca48003dbb212326c37c0b8a5580c2e6d2c Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 5 Dec 2019 07:01:18 -0800 Subject: Merge SB_CARRY+SB_LUT4's attributes when creating $__ICE40_CARRY_WRAPPER --- passes/pmgen/ice40_wrapcarry.cc | 1 + 1 file changed, 1 insertion(+) (limited to 'passes') diff --git a/passes/pmgen/ice40_wrapcarry.cc b/passes/pmgen/ice40_wrapcarry.cc index 66054ea42..b84790d8f 100644 --- a/passes/pmgen/ice40_wrapcarry.cc +++ b/passes/pmgen/ice40_wrapcarry.cc @@ -51,6 +51,7 @@ void create_ice40_wrapcarry(ice40_wrapcarry_pm &pm) cell->setParam("\\LUT", st.lut->getParam("\\LUT_INIT")); cell->attributes = std::move(st.carry->attributes); + cell->attributes.insert(st.lut->attributes.begin(), st.lut->attributes.end()); pm.autoremove(st.carry); pm.autoremove(st.lut); -- cgit v1.2.3 From 946d5854c0b2e63a3757a0fbdf41276255967bc8 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 6 Dec 2019 17:27:47 -0800 Subject: Drop keep=0 attributes on SB_CARRY --- passes/pmgen/ice40_wrapcarry.cc | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'passes') diff --git a/passes/pmgen/ice40_wrapcarry.cc b/passes/pmgen/ice40_wrapcarry.cc index b84790d8f..8b3cf38bb 100644 --- a/passes/pmgen/ice40_wrapcarry.cc +++ b/passes/pmgen/ice40_wrapcarry.cc @@ -51,6 +51,9 @@ void create_ice40_wrapcarry(ice40_wrapcarry_pm &pm) cell->setParam("\\LUT", st.lut->getParam("\\LUT_INIT")); cell->attributes = std::move(st.carry->attributes); + auto it = cell->attributes.find(ID::keep); + if (it != cell->attributes.end() && !it->second.as_bool()) + cell->attributes.erase(it); cell->attributes.insert(st.lut->attributes.begin(), st.lut->attributes.end()); pm.autoremove(st.carry); @@ -69,6 +72,11 @@ struct Ice40WrapCarryPass : public Pass { log("into an internal $__ICE40_CARRY_WRAPPER cell for preservation across technology\n"); log("mapping."); log("\n"); + log("Attributes on both cells will be merged, with SB_CARRY attributes having priority\n"); + log("over SB_LUT4 attributes, except when (* keep *) attributes present on the SB_CARRY4\n"); + log("that logically evaluate to false will be dropped (thus allowing the keep attribute,\n"); + log("if any, on the SB_LUT4 to be adopted).\n"); + log("\n"); } void execute(std::vector args, RTLIL::Design *design) YS_OVERRIDE { -- cgit v1.2.3 From e05372778a26e5cbc5166f208eddc6a1b42ed198 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 9 Dec 2019 11:48:28 -0800 Subject: ice40_wrapcarry to really preserve attributes via -unwrap option --- passes/pmgen/ice40_wrapcarry.cc | 72 +++++++++++++++++++++++++++++++---------- 1 file changed, 55 insertions(+), 17 deletions(-) (limited to 'passes') diff --git a/passes/pmgen/ice40_wrapcarry.cc b/passes/pmgen/ice40_wrapcarry.cc index 8b3cf38bb..522c8c363 100644 --- a/passes/pmgen/ice40_wrapcarry.cc +++ b/passes/pmgen/ice40_wrapcarry.cc @@ -50,11 +50,13 @@ void create_ice40_wrapcarry(ice40_wrapcarry_pm &pm) cell->setPort("\\O", st.lut->getPort("\\O")); cell->setParam("\\LUT", st.lut->getParam("\\LUT_INIT")); - cell->attributes = std::move(st.carry->attributes); - auto it = cell->attributes.find(ID::keep); - if (it != cell->attributes.end() && !it->second.as_bool()) - cell->attributes.erase(it); - cell->attributes.insert(st.lut->attributes.begin(), st.lut->attributes.end()); + for (const auto &a : st.carry->attributes) + cell->attributes[stringf("\\SB_CARRY.%s", a.first.c_str())] = a.second; + for (const auto &a : st.lut->attributes) + cell->attributes[stringf("\\SB_LUT4.%s", a.first.c_str())] = a.second; + cell->attributes[ID(SB_LUT4.name)] = Const(st.lut->name.str()); + if (st.carry->get_bool_attribute(ID::keep) || st.lut->get_bool_attribute(ID::keep)) + cell->attributes[ID::keep] = true; pm.autoremove(st.carry); pm.autoremove(st.lut); @@ -68,33 +70,69 @@ struct Ice40WrapCarryPass : public Pass { log("\n"); log(" ice40_wrapcarry [selection]\n"); log("\n"); - log("Wrap manually instantiated SB_CARRY cells, along with their associated SB_LUTs,\n"); + log("Wrap manually instantiated SB_CARRY cells, along with their associated SB_LUT4s,\n"); log("into an internal $__ICE40_CARRY_WRAPPER cell for preservation across technology\n"); - log("mapping."); + log("mapping.\n"); log("\n"); - log("Attributes on both cells will be merged, with SB_CARRY attributes having priority\n"); - log("over SB_LUT4 attributes, except when (* keep *) attributes present on the SB_CARRY4\n"); - log("that logically evaluate to false will be dropped (thus allowing the keep attribute,\n"); - log("if any, on the SB_LUT4 to be adopted).\n"); + log("Attributes on both cells will have their names prefixed with 'SB_CARRY.' or\n"); + log("'SB_LUT4.' and attached to the wrapping cell.\n"); + log("A (* keep *) attribute on either cell will be logically OR-ed together.\n"); + log("\n"); + log(" -unwrap\n"); + log(" unwrap $__ICE40_CARRY_WRAPPER cells back into SB_CARRYs and SB_LUT4s,\n"); + log(" including restoring their attributes.\n"); log("\n"); } void execute(std::vector args, RTLIL::Design *design) YS_OVERRIDE { + bool unwrap = false; + log_header(design, "Executing ICE40_WRAPCARRY pass (wrap carries).\n"); size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) { - // if (args[argidx] == "-singleton") { - // singleton_mode = true; - // continue; - // } + if (args[argidx] == "-unwrap") { + unwrap = true; + continue; + } break; } extra_args(args, argidx, design); - for (auto module : design->selected_modules()) - ice40_wrapcarry_pm(module, module->selected_cells()).run_ice40_wrapcarry(create_ice40_wrapcarry); + for (auto module : design->selected_modules()) { + if (!unwrap) + ice40_wrapcarry_pm(module, module->selected_cells()).run_ice40_wrapcarry(create_ice40_wrapcarry); + else { + for (auto cell : module->selected_cells()) { + if (cell->type != ID($__ICE40_CARRY_WRAPPER)) + continue; + + auto carry = module->addCell(NEW_ID, ID(SB_CARRY)); + carry->setPort(ID(I0), cell->getPort(ID(A))); + carry->setPort(ID(I1), cell->getPort(ID(B))); + carry->setPort(ID(CI), cell->getPort(ID(CO))); + module->swap_names(carry, cell); + auto lut = module->addCell(cell->attributes.at(ID(SB_LUT4.name)).decode_string(), ID(SB_LUT4)); + lut->setParam(ID(WIDTH), 4); + lut->setParam(ID(LUT), cell->getParam(ID(LUT))); + lut->setPort(ID(A), { cell->getPort(ID(I0)), cell->getPort(ID(A)), cell->getPort(ID(B)), cell->getPort(ID(I3)) }); + lut->setPort(ID(Y), cell->getPort(ID(O))); + + for (const auto &a : cell->attributes) + if (a.first.begins_with("\\SB_CARRY.\\")) + carry->attributes[a.first.c_str() + strlen("\\SB_CARRY.")] = a.second; + else if (a.first.begins_with("\\SB_LUT4.\\")) + lut->attributes[a.first.c_str() + strlen("\\SB_LUT4.")] = a.second; + else if (a.first.in(ID(SB_LUT4.name), ID::keep)) + continue; + else + log_abort(); + + module->remove(cell); + } + } + } } } Ice40WrapCarryPass; -- cgit v1.2.3 From 500ed9b501386b38faf6388b43c42abdbc0ee3ec Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 9 Dec 2019 12:45:22 -0800 Subject: Sensitive to direct inst of $__ICE40_CARRY_WRAPPER; recreate SB_LUT4 --- passes/pmgen/ice40_wrapcarry.cc | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'passes') diff --git a/passes/pmgen/ice40_wrapcarry.cc b/passes/pmgen/ice40_wrapcarry.cc index 522c8c363..8c953308a 100644 --- a/passes/pmgen/ice40_wrapcarry.cc +++ b/passes/pmgen/ice40_wrapcarry.cc @@ -111,20 +111,24 @@ struct Ice40WrapCarryPass : public Pass { auto carry = module->addCell(NEW_ID, ID(SB_CARRY)); carry->setPort(ID(I0), cell->getPort(ID(A))); carry->setPort(ID(I1), cell->getPort(ID(B))); - carry->setPort(ID(CI), cell->getPort(ID(CO))); + carry->setPort(ID(CI), cell->getPort(ID(CI))); + carry->setPort(ID(CO), cell->getPort(ID(CO))); module->swap_names(carry, cell); - auto lut = module->addCell(cell->attributes.at(ID(SB_LUT4.name)).decode_string(), ID(SB_LUT4)); - lut->setParam(ID(WIDTH), 4); - lut->setParam(ID(LUT), cell->getParam(ID(LUT))); - lut->setPort(ID(A), { cell->getPort(ID(I0)), cell->getPort(ID(A)), cell->getPort(ID(B)), cell->getPort(ID(I3)) }); - lut->setPort(ID(Y), cell->getPort(ID(O))); + auto lut_name = cell->attributes.at(ID(SB_LUT4.name), Const(NEW_ID.str())).decode_string(); + auto lut = module->addCell(lut_name, ID(SB_LUT4)); + lut->setParam(ID(LUT_INIT), cell->getParam(ID(LUT))); + lut->setPort(ID(I0), cell->getPort(ID(I0))); + lut->setPort(ID(I1), cell->getPort(ID(A))); + lut->setPort(ID(I2), cell->getPort(ID(B))); + lut->setPort(ID(I3), cell->getPort(ID(I3))); + lut->setPort(ID(O), cell->getPort(ID(O))); for (const auto &a : cell->attributes) if (a.first.begins_with("\\SB_CARRY.\\")) carry->attributes[a.first.c_str() + strlen("\\SB_CARRY.")] = a.second; else if (a.first.begins_with("\\SB_LUT4.\\")) lut->attributes[a.first.c_str() + strlen("\\SB_LUT4.")] = a.second; - else if (a.first.in(ID(SB_LUT4.name), ID::keep)) + else if (a.first.in(ID(SB_LUT4.name), ID::keep, ID(module_not_derived), ID(src))) continue; else log_abort(); -- cgit v1.2.3 From bbdf2452b3bf5bd5d835fc1d6936568cb0a32a1a Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 9 Dec 2019 13:27:09 -0800 Subject: -unwrap to create $lut not SB_LUT4 for opt_lut --- passes/pmgen/ice40_wrapcarry.cc | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'passes') diff --git a/passes/pmgen/ice40_wrapcarry.cc b/passes/pmgen/ice40_wrapcarry.cc index 8c953308a..4bddece30 100644 --- a/passes/pmgen/ice40_wrapcarry.cc +++ b/passes/pmgen/ice40_wrapcarry.cc @@ -115,13 +115,11 @@ struct Ice40WrapCarryPass : public Pass { carry->setPort(ID(CO), cell->getPort(ID(CO))); module->swap_names(carry, cell); auto lut_name = cell->attributes.at(ID(SB_LUT4.name), Const(NEW_ID.str())).decode_string(); - auto lut = module->addCell(lut_name, ID(SB_LUT4)); - lut->setParam(ID(LUT_INIT), cell->getParam(ID(LUT))); - lut->setPort(ID(I0), cell->getPort(ID(I0))); - lut->setPort(ID(I1), cell->getPort(ID(A))); - lut->setPort(ID(I2), cell->getPort(ID(B))); - lut->setPort(ID(I3), cell->getPort(ID(I3))); - lut->setPort(ID(O), cell->getPort(ID(O))); + auto lut = module->addCell(lut_name, ID($lut)); + lut->setParam(ID(WIDTH), 4); + lut->setParam(ID(LUT), cell->getParam(ID(LUT))); + lut->setPort(ID(A), {cell->getPort(ID(I0)), cell->getPort(ID(A)), cell->getPort(ID(B)), cell->getPort(ID(I3)) }); + lut->setPort(ID(Y), cell->getPort(ID(O))); for (const auto &a : cell->attributes) if (a.first.begins_with("\\SB_CARRY.\\")) -- cgit v1.2.3 From 36a88be609b942f9bc1a5e44ecdbe432a3fa56e8 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 9 Dec 2019 14:28:54 -0800 Subject: ice40_wrapcarry -unwrap to preserve 'src' attribute --- passes/pmgen/ice40_wrapcarry.cc | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'passes') diff --git a/passes/pmgen/ice40_wrapcarry.cc b/passes/pmgen/ice40_wrapcarry.cc index 4bddece30..6e154147f 100644 --- a/passes/pmgen/ice40_wrapcarry.cc +++ b/passes/pmgen/ice40_wrapcarry.cc @@ -121,16 +121,24 @@ struct Ice40WrapCarryPass : public Pass { lut->setPort(ID(A), {cell->getPort(ID(I0)), cell->getPort(ID(A)), cell->getPort(ID(B)), cell->getPort(ID(I3)) }); lut->setPort(ID(Y), cell->getPort(ID(O))); + Const src; for (const auto &a : cell->attributes) if (a.first.begins_with("\\SB_CARRY.\\")) carry->attributes[a.first.c_str() + strlen("\\SB_CARRY.")] = a.second; else if (a.first.begins_with("\\SB_LUT4.\\")) lut->attributes[a.first.c_str() + strlen("\\SB_LUT4.")] = a.second; - else if (a.first.in(ID(SB_LUT4.name), ID::keep, ID(module_not_derived), ID(src))) + else if (a.first == ID(src)) + src = a.second; + else if (a.first.in(ID(SB_LUT4.name), ID::keep, ID(module_not_derived))) continue; else log_abort(); + if (!src.empty()) { + carry->attributes.insert(std::make_pair(ID(src), src)); + lut->attributes.insert(std::make_pair(ID(src), src)); + } + module->remove(cell); } } -- cgit v1.2.3