aboutsummaryrefslogtreecommitdiffstats
path: root/passes/techmap
diff options
context:
space:
mode:
authorEddie Hung <eddieh@ece.ubc.ca>2019-03-16 12:49:46 -0700
committerEddie Hung <eddieh@ece.ubc.ca>2019-03-16 12:49:46 -0700
commitd6d9ef0fee3a187b884cbfd0b9a97da935666189 (patch)
treede18d6299f2861e1793c558c556e82fb1d96cabd /passes/techmap
parentfadeadb8c87670b1cfe8f92ac9c5ac3beadcb312 (diff)
downloadyosys-d6d9ef0fee3a187b884cbfd0b9a97da935666189.tar.gz
yosys-d6d9ef0fee3a187b884cbfd0b9a97da935666189.tar.bz2
yosys-d6d9ef0fee3a187b884cbfd0b9a97da935666189.zip
Cleanup
Diffstat (limited to 'passes/techmap')
-rw-r--r--passes/techmap/shregmap.cc60
1 files changed, 25 insertions, 35 deletions
diff --git a/passes/techmap/shregmap.cc b/passes/techmap/shregmap.cc
index f893461a0..179a331fd 100644
--- a/passes/techmap/shregmap.cc
+++ b/passes/techmap/shregmap.cc
@@ -95,7 +95,7 @@ struct ShregmapTechGreenpak4 : ShregmapTech
struct ShregmapTechXilinx7 : ShregmapTech
{
- dict<SigBit, Cell*> sigbit_to_shiftx;
+ dict<SigBit, std::pair<Cell*,int>> sigbit_to_shiftx_offset;
const ShregmapOptions &opts;
ShregmapTechXilinx7(const ShregmapOptions &opts) : opts(opts) {}
@@ -106,19 +106,21 @@ struct ShregmapTechXilinx7 : ShregmapTech
auto cell = i.second;
if (cell->type != "$shiftx") continue;
if (cell->getParam("\\Y_WIDTH") != 1) continue;
+ int j = 0;
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
{
- auto it = sigbit_to_shiftx.find(bit);
- if (it == sigbit_to_shiftx.end())
+ auto it = sigbit_to_shiftx_offset.find(bit);
+ if (it == sigbit_to_shiftx_offset.end())
return;
if (cell->type == "$shiftx" && port == "\\A")
return;
- it->second = nullptr;
+ it->second = std::make_pair(nullptr, 0);
}
virtual bool analyze(vector<int> &taps, const vector<SigBit> &qbits) override
@@ -130,32 +132,34 @@ struct ShregmapTechXilinx7 : ShregmapTech
return false;
Cell *shiftx = nullptr;
- int offset = 0;
for (int i = 0; i < GetSize(taps); ++i) {
// 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.find(qbits[i]);
+ auto it = sigbit_to_shiftx_offset.find(qbits[i]);
if (i == 0) {
- if (it != sigbit_to_shiftx.end()) {
- shiftx = it->second;
+ if (it != sigbit_to_shiftx_offset.end()) {
+ shiftx = it->second.first;
// NULL indicates there are non-shiftx users
if (shiftx == nullptr)
return false;
- offset = qbits[i].offset;
+ int offset = it->second.second;
+ if (offset != i)
+ return false;
}
}
else {
- if (it == sigbit_to_shiftx.end()) {
+ if (it == sigbit_to_shiftx_offset.end()) {
if (shiftx != nullptr)
return false;
}
else {
- if (shiftx != it->second)
+ if (shiftx != it->second.first)
return false;
- if (qbits[i].offset != offset + i)
+ int offset = it->second.second;
+ if (offset != i)
return false;
}
}
@@ -178,36 +182,22 @@ struct ShregmapTechXilinx7 : ShregmapTech
{
const auto &tap = *taps.begin();
auto bit = tap.second;
- auto it = sigbit_to_shiftx.find(bit);
- if (it == sigbit_to_shiftx.end())
+ auto it = sigbit_to_shiftx_offset.find(bit);
+ // If fixed-length, no fixup necessary
+ if (it == sigbit_to_shiftx_offset.end())
return true;
- Cell* shiftx = it->second;
- auto shiftx_a = shiftx->getPort("\\A").bits();
-
- 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;
+ auto cell_q = cell->getPort("\\Q");
+ log_assert(cell_q.is_bit());
+ Cell* shiftx = it->second.first;
// 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());
+ shiftx->setPort("\\A", cell_q.repeat(1 << shiftx_bwidth));
+ shiftx->setParam("\\A_WIDTH", 1 << shiftx_bwidth);
cell->setPort("\\L", shiftx->getPort("\\B"));