Call shregmap twice -- once for variable, another for fixed

This commit is contained in:
Eddie Hung 2019-04-05 17:35:49 -07:00
parent 4afcad70e2
commit 1d526b7f06
3 changed files with 31 additions and 37 deletions

View File

@ -138,11 +138,8 @@ struct ShregmapTechXilinx7 : ShregmapTech
virtual bool analyze(vector<int> &taps, const vector<SigBit> &qbits) override virtual bool analyze(vector<int> &taps, const vector<SigBit> &qbits) override
{ {
log("analyze() with %zu taps", taps.size());
for (auto t : taps) log(" %d", t);
log("\n");
if (GetSize(taps) == 1) 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) if (taps.back() < opts.minlen-1)
return false; return false;
@ -150,27 +147,21 @@ struct ShregmapTechXilinx7 : ShregmapTech
Cell *shiftx = nullptr; Cell *shiftx = nullptr;
int group = 0; int group = 0;
for (int i = 0; i < GetSize(taps); ++i) { 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 // Check taps are sequential
if (i != taps[i]) if (i != taps[i])
return false; return false;
// Check taps are not connected to a shift register, // Check taps are not connected to a shift register,
// or sequential to the same shift register // or sequential to the same shift register
auto it = sigbit_to_shiftx_offset.find(qbits[i]);
if (i == 0) { if (i == 0) {
if (it == sigbit_to_shiftx_offset.end()) {
return false;
}
else {
int offset; int offset;
std::tie(shiftx,offset,group) = it->second; std::tie(shiftx,offset,group) = it->second;
if (offset != i) if (offset != i)
return false; return false;
} }
}
else {
if (it == sigbit_to_shiftx_offset.end()) {
return false;
}
else { else {
Cell *shiftx_ = std::get<0>(it->second); Cell *shiftx_ = std::get<0>(it->second);
if (shiftx_ != shiftx) if (shiftx_ != shiftx)
@ -183,7 +174,6 @@ struct ShregmapTechXilinx7 : ShregmapTech
return false; return false;
} }
} }
}
log_assert(shiftx); log_assert(shiftx);
// Only map if $shiftx exclusively covers the shift register // Only map if $shiftx exclusively covers the shift register
@ -206,9 +196,7 @@ struct ShregmapTechXilinx7 : ShregmapTech
auto bit = tap.second; auto bit = tap.second;
auto it = sigbit_to_shiftx_offset.find(bit); auto it = sigbit_to_shiftx_offset.find(bit);
// If fixed-length, no fixup necessary log_assert(it != sigbit_to_shiftx_offset.end());
if (it == sigbit_to_shiftx_offset.end())
return true;
auto newcell = cell->module->addCell(NEW_ID, "$__XILINX_SHREG_"); auto newcell = cell->module->addCell(NEW_ID, "$__XILINX_SHREG_");
newcell->setParam("\\DEPTH", cell->getParam("\\DEPTH")); newcell->setParam("\\DEPTH", cell->getParam("\\DEPTH"));

View File

@ -141,3 +141,6 @@ module \$__XILINX_SHREG_ (input C, input D, input [31:0] L, input E, output Q, o
end end
endgenerate endgenerate
endmodule endmodule
`ifndef SRL_ONLY
`endif

View File

@ -113,22 +113,23 @@ struct SynthXilinxPass : public Pass
log(" dffsr2dff\n"); log(" dffsr2dff\n");
log(" dff2dffe\n"); log(" dff2dffe\n");
log(" opt -full\n"); log(" opt -full\n");
log(" simplemap t:$dff t:$dffe (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 and without -retime only)\n"); log(" shregmap -tech xilinx -minlen 3 (without '-nosrl' only)\n");
log(" techmap -map +/techmap.v -map +/xilinx/arith_map.v\n"); log(" techmap -map +/techmap.v -map +/xilinx/arith_map.v\n");
log(" opt -fast\n"); log(" opt -fast\n");
log("\n"); log("\n");
log(" map_cells:\n"); log(" map_cells:\n");
log(" techmap -map +/xilinx/cells_map.v\n"); log(" techmap -map +/techmap.v -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(" clean\n"); log(" clean\n");
log("\n"); log("\n");
log(" map_luts:\n"); log(" map_luts:\n");
log(" techmap -map +/techmap.v -map +/xilinx/ff_map.v t:$_DFF_?N?\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(" abc -luts 2:2,3,6:5,10,20 [-dff]\n");
log(" clean\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("\n");
log(" check:\n"); log(" check:\n");
log(" hierarchy -check\n"); log(" hierarchy -check\n");
@ -266,7 +267,7 @@ struct SynthXilinxPass : public Pass
Pass::call(design, "dff2dffe"); Pass::call(design, "dff2dffe");
Pass::call(design, "opt -full"); Pass::call(design, "opt -full");
if (!nosrl && !retime) { if (!nosrl) {
Pass::call(design, "simplemap t:$dff t:$dffe"); Pass::call(design, "simplemap t:$dff t:$dffe");
Pass::call(design, "shregmap -tech xilinx -minlen 3"); 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, "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, "abc -luts 2:2,3,6:5,10,20" + string(retime ? " -dff" : ""));
Pass::call(design, "clean"); 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 " 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"); "-ff FDRE_1 Q INIT -ff FDCE_1 Q INIT -ff FDPE_1 Q INIT -ff FDSE_1 Q INIT");
} }