aboutsummaryrefslogtreecommitdiffstats
path: root/passes
diff options
context:
space:
mode:
Diffstat (limited to 'passes')
-rw-r--r--passes/memory/memory_collect.cc4
-rw-r--r--passes/opt/opt_share.cc15
-rw-r--r--passes/pmgen/ice40_wrapcarry.cc75
-rw-r--r--passes/pmgen/xilinx_dsp.pmg6
-rw-r--r--passes/techmap/abc9.cc69
-rw-r--r--passes/techmap/iopadmap.cc243
6 files changed, 222 insertions, 190 deletions
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);
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);
}
}
diff --git a/passes/pmgen/ice40_wrapcarry.cc b/passes/pmgen/ice40_wrapcarry.cc
index 69ef3cd82..6e154147f 100644
--- a/passes/pmgen/ice40_wrapcarry.cc
+++ b/passes/pmgen/ice40_wrapcarry.cc
@@ -50,6 +50,14 @@ void create_ice40_wrapcarry(ice40_wrapcarry_pm &pm)
cell->setPort("\\O", st.lut->getPort("\\O"));
cell->setParam("\\LUT", st.lut->getParam("\\LUT_INIT"));
+ 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);
}
@@ -62,28 +70,79 @@ 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 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<std::string> 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(CI)));
+ 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($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)));
+
+ 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 == 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);
+ }
+ }
+ }
}
} Ice40WrapCarryPass;
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 <SigBit> 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 <bool> 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
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);
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<pair<IdString, IdString>> 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<IdString, pool<int>> skip_wires;
pool<SigBit> skip_wire_bits;
- SigMap sigmap(module);
+ dict<Wire *, dict<int, pair<Cell *, IdString>>> 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<SigBit, pair<IdString, pool<IdString>>> tbuf_bits;
- pool<pair<IdString, IdString>> norewrites;
- SigMap rewrites;
+ dict<SigBit, Cell *> 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<int> 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;