From d3930ca79eb11952d8e64588e46b0788845997c4 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 8 Apr 2019 12:01:06 -0700 Subject: [PATCH] Revert "Remove handling for $pmux, since #895" This reverts commit aa693d5723ef1438d42cd35a26673703b1eff79f. --- passes/techmap/shregmap.cc | 40 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/passes/techmap/shregmap.cc b/passes/techmap/shregmap.cc index a805ac5a6..39ca60b80 100644 --- a/passes/techmap/shregmap.cc +++ b/passes/techmap/shregmap.cc @@ -119,6 +119,22 @@ struct ShregmapTechXilinx7 : ShregmapTech for (auto bit : sigmap(cell->getPort("\\B"))) sigbit_to_shiftx_offset[bit] = std::make_tuple(cell, 1, j++); } + else if (cell->type == "$pmux") { + int width = cell->getParam("\\WIDTH").as_int(); + int j = 0; + for (auto bit : cell->getPort("\\A")) + sigbit_to_shiftx_offset[bit] = std::make_tuple(cell, 0, j++); + j = cell->getParam("\\S_WIDTH").as_int(); + int k = 0; + for (auto bit : sigmap(cell->getPort("\\B"))) { + sigbit_to_shiftx_offset[bit] = std::make_tuple(cell, j, k++); + if (k == width) { + k = 0; + --j; + } + } + log_assert(j == 0); + } } } @@ -130,6 +146,8 @@ struct ShregmapTechXilinx7 : ShregmapTech if (cell) { if (cell->type == "$shiftx" && port == "\\A") return; + if (cell->type == "$pmux" && (port == "\\A" || port == "\\B")) + return; if (cell->type == "$mux" && (port == "\\A" || port == "\\B")) return; } @@ -181,6 +199,10 @@ struct ShregmapTechXilinx7 : ShregmapTech if (GetSize(taps) != shiftx->getParam("\\A_WIDTH").as_int()) return false; } + else if (shiftx->type == "$pmux") { + if (GetSize(taps) != shiftx->getParam("\\S_WIDTH").as_int() + 1) + return false; + } else if (shiftx->type == "$mux") { if (GetSize(taps) != 2) return false; @@ -216,6 +238,24 @@ struct ShregmapTechXilinx7 : ShregmapTech q_wire = shiftx->getPort("\\Y"); shiftx->setPort("\\Y", cell->module->addWire(NEW_ID)); } + else if (shiftx->type == "$pmux") { + // Create a new encoder, out of a $pmux, that takes + // the existing pmux's 'S' input and transforms it + // back into a binary value + int clog2taps = ceil(log2(taps.size())); + RTLIL::SigSpec b_port; + for (int i = shiftx->getParam("\\S_WIDTH").as_int(); i > 0; i--) + b_port.append(RTLIL::Const(i, clog2taps)); + l_wire = cell->module->addWire(NEW_ID, clog2taps); + RTLIL::SigSpec s_wire = cell->module->addWire(NEW_ID, shiftx->getParam("\\S_WIDTH").as_int()); + cell->module->connect(s_wire.extract(0, shiftx->getParam("\\S_WIDTH").as_int()), shiftx->getPort("\\S")); + cell->module->addPmux(NEW_ID, RTLIL::Const(0, clog2taps), b_port, s_wire, l_wire); + int group = std::get<2>(it->second); + RTLIL::SigSpec y_wire = shiftx->getPort("\\Y"); + q_wire = y_wire[group]; + y_wire[group] = cell->module->addWire(NEW_ID); + shiftx->setPort("\\Y", y_wire); + } else if (shiftx->type == "$mux") { l_wire = shiftx->getPort("\\S"); q_wire = shiftx->getPort("\\Y"); -- 2.30.2