From fadeadb8c87670b1cfe8f92ac9c5ac3beadcb312 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Sat, 16 Mar 2019 08:51:13 -0700 Subject: [PATCH] Only accept <128 for variable length, only if $shiftx exclusive --- passes/techmap/shregmap.cc | 25 +++++++++++++++++-------- techlibs/xilinx/cells_map.v | 6 +----- 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/passes/techmap/shregmap.cc b/passes/techmap/shregmap.cc index 4b8f8a828..f893461a0 100644 --- a/passes/techmap/shregmap.cc +++ b/passes/techmap/shregmap.cc @@ -161,6 +161,16 @@ struct ShregmapTechXilinx7 : ShregmapTech } } + // Cannot implement variable-length shift registers + // greater than 128 since Q31 cannot be output onto + // fabric + if (shiftx && GetSize(taps) > 128) + return false; + + // Only map if $shiftx exclusively covers the shift register + if (GetSize(taps) != shiftx->getParam("\\A_WIDTH").as_int()) + return false; + return true; } @@ -173,34 +183,33 @@ struct ShregmapTechXilinx7 : ShregmapTech return true; Cell* shiftx = it->second; - - auto module = cell->module; + auto shiftx_a = shiftx->getPort("\\A").bits(); auto cell_q = cell->getPort("\\Q").as_bit(); - auto shiftx_a = shiftx->getPort("\\A").bits(); int offset = 0; +#ifndef NDEBUG for (auto bit : shiftx_a) { if (bit == cell_q) break; ++offset; } offset -= taps.size() - 1; - log_assert(offset >= 0); + log_assert(offset == 0); +#endif for (size_t i = offset; i < offset + taps.size(); ++i) shiftx_a[i] = cell_q; + // FIXME: Hack to ensure that $shiftx gets optimised away // Without this, Yosys will refuse to optimise away a $shiftx // where \\A 's width is not perfectly \\B_WIDTH ** 2 + // See YosysHQ/yosys#878 auto shiftx_bwidth = shiftx->getParam("\\B_WIDTH").as_int(); shiftx_a.resize(1 << shiftx_bwidth, shiftx_a.back()); shiftx->setPort("\\A", shiftx_a); shiftx->setParam("\\A_WIDTH", shiftx_a.size()); - auto length = module->addWire(NEW_ID, ceil(log2(taps.size()))); - module->addSub(NEW_ID, shiftx->getPort("\\B"), RTLIL::Const(offset, ceil(log2(offset))), length); - cell->setPort("\\L", length); - + cell->setPort("\\L", shiftx->getPort("\\B")); return true; } diff --git a/techlibs/xilinx/cells_map.v b/techlibs/xilinx/cells_map.v index a35b0742b..1d538e262 100644 --- a/techlibs/xilinx/cells_map.v +++ b/techlibs/xilinx/cells_map.v @@ -121,11 +121,7 @@ module \$__SHREG_ (input C, input D, input [31:0] L, input E, output Q); else begin // No way to create variable length shift registers >128 bits as Q31 // cannot be output to the fabric... - wire [DEPTH-1:-1] c; - genvar i; - for (i = 0; i < DEPTH; i=i+1) - \$__SHREG_ #(.DEPTH(1), .INIT(INIT_R[i]), .CLKPOL(CLKPOL), .ENPOL(ENPOL)) fpga_srl (.C(C), .D(c[i-1]), .L(0), .E(E), .Q(c[i])); - assign { c[-1], Q } = { D, c[L] }; + wire _TECHMAP_FAIL_ = 1; end end endgenerate -- 2.30.2