From 1d526b7f061fb7e7961fa4d0b318b27cfda469d4 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 5 Apr 2019 17:35:49 -0700 Subject: [PATCH] Call shregmap twice -- once for variable, another for fixed --- passes/techmap/shregmap.cc | 46 ++++++++++++--------------------- techlibs/xilinx/cells_map.v | 3 +++ techlibs/xilinx/synth_xilinx.cc | 19 ++++++++------ 3 files changed, 31 insertions(+), 37 deletions(-) diff --git a/passes/techmap/shregmap.cc b/passes/techmap/shregmap.cc index 408e3f8c7..a805ac5a6 100644 --- a/passes/techmap/shregmap.cc +++ b/passes/techmap/shregmap.cc @@ -138,11 +138,8 @@ struct ShregmapTechXilinx7 : ShregmapTech virtual bool analyze(vector &taps, const vector &qbits) override { - log("analyze() with %zu taps", taps.size()); - for (auto t : taps) log(" %d", t); - log("\n"); if (GetSize(taps) == 1) - return taps[0] >= opts.minlen-1; + return taps[0] >= opts.minlen-1 && sigbit_to_shiftx_offset.count(qbits[0]); if (taps.back() < opts.minlen-1) return false; @@ -150,38 +147,31 @@ struct ShregmapTechXilinx7 : ShregmapTech Cell *shiftx = nullptr; int group = 0; for (int i = 0; i < GetSize(taps); ++i) { + auto it = sigbit_to_shiftx_offset.find(qbits[i]); + if (it == sigbit_to_shiftx_offset.end()) + return false; + // Check taps are sequential if (i != taps[i]) return false; // Check taps are not connected to a shift register, // or sequential to the same shift register - auto it = sigbit_to_shiftx_offset.find(qbits[i]); if (i == 0) { - if (it == sigbit_to_shiftx_offset.end()) { + int offset; + std::tie(shiftx,offset,group) = it->second; + if (offset != i) return false; - } - else { - int offset; - std::tie(shiftx,offset,group) = it->second; - if (offset != i) - return false; - } } else { - if (it == sigbit_to_shiftx_offset.end()) { + Cell *shiftx_ = std::get<0>(it->second); + if (shiftx_ != shiftx) + return false; + int offset = std::get<1>(it->second); + if (offset != i) + return false; + int group_ = std::get<2>(it->second); + if (group_ != group) return false; - } - else { - Cell *shiftx_ = std::get<0>(it->second); - if (shiftx_ != shiftx) - return false; - int offset = std::get<1>(it->second); - if (offset != i) - return false; - int group_ = std::get<2>(it->second); - if (group_ != group) - return false; - } } } log_assert(shiftx); @@ -206,9 +196,7 @@ struct ShregmapTechXilinx7 : ShregmapTech auto bit = tap.second; auto it = sigbit_to_shiftx_offset.find(bit); - // If fixed-length, no fixup necessary - if (it == sigbit_to_shiftx_offset.end()) - return true; + log_assert(it != sigbit_to_shiftx_offset.end()); auto newcell = cell->module->addCell(NEW_ID, "$__XILINX_SHREG_"); newcell->setParam("\\DEPTH", cell->getParam("\\DEPTH")); diff --git a/techlibs/xilinx/cells_map.v b/techlibs/xilinx/cells_map.v index c80e51bd0..704ab21b1 100644 --- a/techlibs/xilinx/cells_map.v +++ b/techlibs/xilinx/cells_map.v @@ -141,3 +141,6 @@ module \$__XILINX_SHREG_ (input C, input D, input [31:0] L, input E, output Q, o end endgenerate endmodule + +`ifndef SRL_ONLY +`endif diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index 2676f5915..57bde998f 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -113,22 +113,23 @@ struct SynthXilinxPass : public Pass log(" dffsr2dff\n"); log(" dff2dffe\n"); log(" opt -full\n"); - log(" simplemap t:$dff t:$dffe (without -nosrl and without -retime only)\n"); - log(" shregmap -tech xilinx -minlen 3 (without -nosrl and without -retime only)\n"); + log(" simplemap t:$dff t:$dffe (without '-nosrl' only)\n"); + log(" shregmap -tech xilinx -minlen 3 (without '-nosrl' only)\n"); log(" techmap -map +/techmap.v -map +/xilinx/arith_map.v\n"); log(" opt -fast\n"); log("\n"); log(" map_cells:\n"); - log(" techmap -map +/xilinx/cells_map.v\n"); - log(" dffinit -ff FDRE Q INIT -ff FDCE Q INIT -ff FDPE Q INIT -ff FDSE Q INIT \\\n"); - log(" -ff FDRE_1 Q INIT -ff FDCE_1 Q INIT -ff FDPE_1 Q INIT -ff FDSE_1 Q INIT\n"); + log(" techmap -map +/techmap.v -map +/xilinx/cells_map.v\n"); log(" clean\n"); log("\n"); log(" map_luts:\n"); log(" techmap -map +/techmap.v -map +/xilinx/ff_map.v t:$_DFF_?N?\n"); log(" abc -luts 2:2,3,6:5,10,20 [-dff]\n"); log(" clean\n"); - log(" techmap -map +/xilinx/lut_map.v -map +/xilinx/ff_map.v"); + log(" shregmap -minlen 3 -init -params -enpol any_or_none (without '-nosrl' only)\n"); + log(" techmap -map +/xilinx/lut_map.v -map +/xilinx/ff_map.v -map +/xilinx/cells_map.v"); + log(" dffinit -ff FDRE Q INIT -ff FDCE Q INIT -ff FDPE Q INIT -ff FDSE Q INIT \\\n"); + log(" -ff FDRE_1 Q INIT -ff FDCE_1 Q INIT -ff FDPE_1 Q INIT -ff FDSE_1 Q INIT\n"); log("\n"); log(" check:\n"); log(" hierarchy -check\n"); @@ -266,7 +267,7 @@ struct SynthXilinxPass : public Pass Pass::call(design, "dff2dffe"); Pass::call(design, "opt -full"); - if (!nosrl && !retime) { + if (!nosrl) { Pass::call(design, "simplemap t:$dff t:$dffe"); Pass::call(design, "shregmap -tech xilinx -minlen 3"); } @@ -292,7 +293,9 @@ struct SynthXilinxPass : public Pass Pass::call(design, "techmap -map +/techmap.v -map +/xilinx/ff_map.v t:$_DFF_?N?"); Pass::call(design, "abc -luts 2:2,3,6:5,10,20" + string(retime ? " -dff" : "")); Pass::call(design, "clean"); - Pass::call(design, "techmap -map +/xilinx/lut_map.v -map +/xilinx/ff_map.v"); + if (!nosrl) + Pass::call(design, "shregmap -minlen 3 -init -params -enpol any_or_none"); + Pass::call(design, "techmap -map +/xilinx/lut_map.v -map +/xilinx/ff_map.v -map +/xilinx/cells_map.v"); Pass::call(design, "dffinit -ff FDRE Q INIT -ff FDCE Q INIT -ff FDPE Q INIT -ff FDSE Q INIT " "-ff FDRE_1 Q INIT -ff FDCE_1 Q INIT -ff FDPE_1 Q INIT -ff FDSE_1 Q INIT"); } -- 2.30.2