Fixes for multibit

This commit is contained in:
Eddie Hung 2019-03-22 18:32:42 -07:00
parent 03d108cd1f
commit 456295eb66
1 changed files with 38 additions and 18 deletions

View File

@ -95,7 +95,7 @@ struct ShregmapTechGreenpak4 : ShregmapTech
struct ShregmapTechXilinx7 : ShregmapTech struct ShregmapTechXilinx7 : ShregmapTech
{ {
dict<SigBit, std::pair<Cell*,int>> sigbit_to_shiftx_offset; dict<SigBit, std::tuple<Cell*,int,int>> sigbit_to_shiftx_offset;
const ShregmapOptions &opts; const ShregmapOptions &opts;
ShregmapTechXilinx7(const ShregmapOptions &opts) : opts(opts) {} ShregmapTechXilinx7(const ShregmapOptions &opts) : opts(opts) {}
@ -108,18 +108,25 @@ struct ShregmapTechXilinx7 : ShregmapTech
if (cell->getParam("\\Y_WIDTH") != 1) continue; if (cell->getParam("\\Y_WIDTH") != 1) continue;
int j = 0; int j = 0;
for (auto bit : sigmap(cell->getPort("\\A"))) for (auto bit : sigmap(cell->getPort("\\A")))
sigbit_to_shiftx_offset[bit] = std::make_pair(cell, j++); sigbit_to_shiftx_offset[bit] = std::make_tuple(cell, j++, 0);
log_assert(j == cell->getParam("\\A_WIDTH").as_int()); log_assert(j == cell->getParam("\\A_WIDTH").as_int());
} }
else if (cell->type == "$pmux") { else if (cell->type == "$pmux") {
if (cell->getParam("\\WIDTH") != 1) continue; int width = cell->getParam("\\WIDTH").as_int();
auto a_bit = sigmap(cell->getPort("\\A")).as_bit(); int j = 0;
sigbit_to_shiftx_offset[a_bit] = std::make_pair(cell, 0); for (auto bit : cell->getPort("\\A"))
int j = cell->getParam("\\S_WIDTH").as_int(); sigbit_to_shiftx_offset[bit] = std::make_tuple(cell, 0, j++);
for (auto bit : sigmap(cell->getPort("\\B"))) j = cell->getParam("\\S_WIDTH").as_int();
sigbit_to_shiftx_offset[bit] = std::make_pair(cell, j--); int k = 0;
for (auto bit : sigmap(cell->getPort("\\B"))) {
printf("%d\n", bit.offset);
sigbit_to_shiftx_offset[bit] = std::make_tuple(cell, j, k++);
if (k == width) {
k = 0;
--j;
}
}
log_assert(j == 0); log_assert(j == 0);
} }
} }
} }
@ -140,6 +147,9 @@ 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;
@ -147,6 +157,7 @@ struct ShregmapTechXilinx7 : ShregmapTech
return false; return false;
Cell *shiftx = nullptr; Cell *shiftx = nullptr;
int group = 0;
for (int i = 0; i < GetSize(taps); ++i) { for (int i = 0; i < GetSize(taps); ++i) {
// Check taps are sequential // Check taps are sequential
if (i != taps[i]) if (i != taps[i])
@ -159,8 +170,8 @@ struct ShregmapTechXilinx7 : ShregmapTech
return false; return false;
} }
else { else {
shiftx = it->second.first; int offset;
int offset = it->second.second; std::tie(shiftx,offset,group) = it->second;
if (offset != i) if (offset != i)
return false; return false;
} }
@ -170,11 +181,15 @@ struct ShregmapTechXilinx7 : ShregmapTech
return false; return false;
} }
else { else {
if (shiftx != it->second.first) Cell *shiftx_ = std::get<0>(it->second);
if (shiftx_ != shiftx)
return false; return false;
int offset = it->second.second; int offset = std::get<1>(it->second);
if (offset != i) if (offset != i)
return false; return false;
int group_ = std::get<2>(it->second);
if (group_ != group)
return false;
} }
} }
} }
@ -214,10 +229,12 @@ struct ShregmapTechXilinx7 : ShregmapTech
newcell->setPort("\\D", cell->getPort("\\D")); newcell->setPort("\\D", cell->getPort("\\D"));
newcell->setPort("\\E", cell->getPort("\\E")); newcell->setPort("\\E", cell->getPort("\\E"));
Cell* shiftx = it->second.first; Cell* shiftx = std::get<0>(it->second);
RTLIL::SigSpec l_wire; RTLIL::SigSpec l_wire, q_wire;
if (shiftx->type == "$shiftx") { if (shiftx->type == "$shiftx") {
l_wire = shiftx->getPort("\\B"); l_wire = shiftx->getPort("\\B");
q_wire = shiftx->getPort("\\Y");
shiftx->setPort("\\Y", cell->module->addWire(NEW_ID));
} }
else if (shiftx->type == "$pmux") { else if (shiftx->type == "$pmux") {
// Create a new encoder, out of a $pmux, that takes // Create a new encoder, out of a $pmux, that takes
@ -229,14 +246,17 @@ struct ShregmapTechXilinx7 : ShregmapTech
b_port.append(RTLIL::Const(i, clog2taps)); b_port.append(RTLIL::Const(i, clog2taps));
l_wire = cell->module->addWire(NEW_ID, clog2taps); l_wire = cell->module->addWire(NEW_ID, clog2taps);
cell->module->addPmux(NEW_ID, RTLIL::Const(0, clog2taps), b_port, shiftx->getPort("\\S"), l_wire); cell->module->addPmux(NEW_ID, RTLIL::Const(0, clog2taps), b_port, shiftx->getPort("\\S"), 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 log_abort(); else log_abort();
newcell->setPort("\\Q", shiftx->getPort("\\Y")); newcell->setPort("\\Q", q_wire);
newcell->setPort("\\L", l_wire); newcell->setPort("\\L", l_wire);
cell->module->remove(shiftx);
return false; return false;
} }
}; };