mirror of
https://github.com/YosysHQ/yosys
synced 2025-04-13 04:28:18 +00:00
Cleanup
This commit is contained in:
parent
fadeadb8c8
commit
d6d9ef0fee
|
@ -95,7 +95,7 @@ struct ShregmapTechGreenpak4 : ShregmapTech
|
||||||
|
|
||||||
struct ShregmapTechXilinx7 : ShregmapTech
|
struct ShregmapTechXilinx7 : ShregmapTech
|
||||||
{
|
{
|
||||||
dict<SigBit, Cell*> sigbit_to_shiftx;
|
dict<SigBit, std::pair<Cell*,int>> sigbit_to_shiftx_offset;
|
||||||
const ShregmapOptions &opts;
|
const ShregmapOptions &opts;
|
||||||
|
|
||||||
ShregmapTechXilinx7(const ShregmapOptions &opts) : opts(opts) {}
|
ShregmapTechXilinx7(const ShregmapOptions &opts) : opts(opts) {}
|
||||||
|
@ -106,19 +106,21 @@ struct ShregmapTechXilinx7 : ShregmapTech
|
||||||
auto cell = i.second;
|
auto cell = i.second;
|
||||||
if (cell->type != "$shiftx") continue;
|
if (cell->type != "$shiftx") continue;
|
||||||
if (cell->getParam("\\Y_WIDTH") != 1) continue;
|
if (cell->getParam("\\Y_WIDTH") != 1) continue;
|
||||||
|
int j = 0;
|
||||||
for (auto bit : sigmap(cell->getPort("\\A")))
|
for (auto bit : sigmap(cell->getPort("\\A")))
|
||||||
sigbit_to_shiftx[bit] = cell;
|
sigbit_to_shiftx_offset[bit] = std::make_pair(cell, j++);
|
||||||
|
log_assert(j == cell->getParam("\\A_WIDTH").as_int());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void non_chain_user(const SigBit &bit, const Cell *cell, IdString port) override
|
virtual void non_chain_user(const SigBit &bit, const Cell *cell, IdString port) override
|
||||||
{
|
{
|
||||||
auto it = sigbit_to_shiftx.find(bit);
|
auto it = sigbit_to_shiftx_offset.find(bit);
|
||||||
if (it == sigbit_to_shiftx.end())
|
if (it == sigbit_to_shiftx_offset.end())
|
||||||
return;
|
return;
|
||||||
if (cell->type == "$shiftx" && port == "\\A")
|
if (cell->type == "$shiftx" && port == "\\A")
|
||||||
return;
|
return;
|
||||||
it->second = nullptr;
|
it->second = std::make_pair(nullptr, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool analyze(vector<int> &taps, const vector<SigBit> &qbits) override
|
virtual bool analyze(vector<int> &taps, const vector<SigBit> &qbits) override
|
||||||
|
@ -130,32 +132,34 @@ struct ShregmapTechXilinx7 : ShregmapTech
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
Cell *shiftx = nullptr;
|
Cell *shiftx = nullptr;
|
||||||
int offset = 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])
|
||||||
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.find(qbits[i]);
|
auto it = sigbit_to_shiftx_offset.find(qbits[i]);
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
if (it != sigbit_to_shiftx.end()) {
|
if (it != sigbit_to_shiftx_offset.end()) {
|
||||||
shiftx = it->second;
|
shiftx = it->second.first;
|
||||||
// NULL indicates there are non-shiftx users
|
// NULL indicates there are non-shiftx users
|
||||||
if (shiftx == nullptr)
|
if (shiftx == nullptr)
|
||||||
return false;
|
return false;
|
||||||
offset = qbits[i].offset;
|
int offset = it->second.second;
|
||||||
|
if (offset != i)
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (it == sigbit_to_shiftx.end()) {
|
if (it == sigbit_to_shiftx_offset.end()) {
|
||||||
if (shiftx != nullptr)
|
if (shiftx != nullptr)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (shiftx != it->second)
|
if (shiftx != it->second.first)
|
||||||
return false;
|
return false;
|
||||||
if (qbits[i].offset != offset + i)
|
int offset = it->second.second;
|
||||||
|
if (offset != i)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -178,36 +182,22 @@ struct ShregmapTechXilinx7 : ShregmapTech
|
||||||
{
|
{
|
||||||
const auto &tap = *taps.begin();
|
const auto &tap = *taps.begin();
|
||||||
auto bit = tap.second;
|
auto bit = tap.second;
|
||||||
auto it = sigbit_to_shiftx.find(bit);
|
auto it = sigbit_to_shiftx_offset.find(bit);
|
||||||
if (it == sigbit_to_shiftx.end())
|
// If fixed-length, no fixup necessary
|
||||||
|
if (it == sigbit_to_shiftx_offset.end())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
Cell* shiftx = it->second;
|
auto cell_q = cell->getPort("\\Q");
|
||||||
auto shiftx_a = shiftx->getPort("\\A").bits();
|
log_assert(cell_q.is_bit());
|
||||||
|
|
||||||
auto cell_q = cell->getPort("\\Q").as_bit();
|
|
||||||
|
|
||||||
int offset = 0;
|
|
||||||
#ifndef NDEBUG
|
|
||||||
for (auto bit : shiftx_a) {
|
|
||||||
if (bit == cell_q)
|
|
||||||
break;
|
|
||||||
++offset;
|
|
||||||
}
|
|
||||||
offset -= taps.size() - 1;
|
|
||||||
log_assert(offset == 0);
|
|
||||||
#endif
|
|
||||||
for (size_t i = offset; i < offset + taps.size(); ++i)
|
|
||||||
shiftx_a[i] = cell_q;
|
|
||||||
|
|
||||||
|
Cell* shiftx = it->second.first;
|
||||||
// FIXME: Hack to ensure that $shiftx gets optimised away
|
// FIXME: Hack to ensure that $shiftx gets optimised away
|
||||||
// Without this, Yosys will refuse to optimise away a $shiftx
|
// Without this, Yosys will refuse to optimise away a $shiftx
|
||||||
// where \\A 's width is not perfectly \\B_WIDTH ** 2
|
// where \\A 's width is not perfectly \\B_WIDTH ** 2
|
||||||
// See YosysHQ/yosys#878
|
// See YosysHQ/yosys#878
|
||||||
auto shiftx_bwidth = shiftx->getParam("\\B_WIDTH").as_int();
|
auto shiftx_bwidth = shiftx->getParam("\\B_WIDTH").as_int();
|
||||||
shiftx_a.resize(1 << shiftx_bwidth, shiftx_a.back());
|
shiftx->setPort("\\A", cell_q.repeat(1 << shiftx_bwidth));
|
||||||
shiftx->setPort("\\A", shiftx_a);
|
shiftx->setParam("\\A_WIDTH", 1 << shiftx_bwidth);
|
||||||
shiftx->setParam("\\A_WIDTH", shiftx_a.size());
|
|
||||||
|
|
||||||
cell->setPort("\\L", shiftx->getPort("\\B"));
|
cell->setPort("\\L", shiftx->getPort("\\B"));
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue