aboutsummaryrefslogtreecommitdiffstats
path: root/passes
diff options
context:
space:
mode:
authorClifford Wolf <clifford@clifford.at>2016-04-23 23:10:13 +0200
committerClifford Wolf <clifford@clifford.at>2016-04-23 23:10:13 +0200
commit096c25d29d7e66003123dc4700ae72b0a4c10ca2 (patch)
tree17a08c2c8bf58541f112f21dbbef6889617ae193 /passes
parentc9c5192cd63dc4c08441e94c8d53428503ccc4af (diff)
downloadyosys-096c25d29d7e66003123dc4700ae72b0a4c10ca2.tar.gz
yosys-096c25d29d7e66003123dc4700ae72b0a4c10ca2.tar.bz2
yosys-096c25d29d7e66003123dc4700ae72b0a4c10ca2.zip
Improvements in greenpak4 shreg mapping
Diffstat (limited to 'passes')
-rw-r--r--passes/techmap/shregmap.cc51
1 files changed, 35 insertions, 16 deletions
diff --git a/passes/techmap/shregmap.cc b/passes/techmap/shregmap.cc
index 6332d5979..7a8495b79 100644
--- a/passes/techmap/shregmap.cc
+++ b/passes/techmap/shregmap.cc
@@ -26,8 +26,8 @@ PRIVATE_NAMESPACE_BEGIN
struct ShregmapTech
{
virtual ~ShregmapTech() { }
- virtual bool check_taps(const dict<int, SigBit> &taps) = 0;
- virtual bool fixup_shreg(Cell *cell, dict<int, SigBit> &taps) = 0;
+ virtual bool analyze(vector<int> &taps) = 0;
+ virtual bool fixup(Cell *cell, dict<int, SigBit> &taps) = 0;
};
struct ShregmapOptions
@@ -54,18 +54,22 @@ struct ShregmapOptions
struct ShregmapTechGreenpak4 : ShregmapTech
{
- bool check_taps(const dict<int, SigBit> &taps)
+ bool analyze(vector<int> &taps)
{
+ if (GetSize(taps) > 2 && taps[0] == 0 && taps[2] < 17) {
+ taps.clear();
+ return true;
+ }
+
if (GetSize(taps) > 2)
return false;
- for (auto tap : taps)
- if (tap.first > 16) return false;
+ if (taps.back() > 16) return false;
return true;
}
- bool fixup_shreg(Cell *cell, dict<int, SigBit> &taps)
+ bool fixup(Cell *cell, dict<int, SigBit> &taps)
{
auto D = cell->getPort("\\D");
auto C = cell->getPort("\\C");
@@ -232,31 +236,47 @@ struct ShregmapWorker
Cell *first_cell = chain[cursor];
IdString q_port = opts.ffcells.at(first_cell->type).second;
- dict<int, SigBit> taps;
+ dict<int, SigBit> taps_dict;
if (opts.tech)
{
+ vector<SigBit> qbits;
+ vector<int> taps;
+
for (int i = 0; i < depth; i++)
{
Cell *cell = chain[cursor+i];
auto qbit = sigmap(cell->getPort(q_port));
+ qbits.push_back(qbit);
if (sigbit_with_non_chain_users.count(qbit))
- taps[i] = qbit;
+ taps.push_back(i);
}
while (depth > 0)
{
- Cell *last_cell = chain[cursor+depth-1];
- taps[depth-1] = sigmap(last_cell->getPort(q_port));
- if (opts.tech->check_taps(taps))
+ if (taps.empty() || taps.back() < depth-1)
+ taps.push_back(depth-1);
+
+ if (opts.tech->analyze(taps))
break;
- taps.erase(--depth);
+
+ taps.pop_back();
+ depth--;
+ }
+
+ depth = 0;
+ for (auto tap : taps) {
+ taps_dict[tap] = qbits.at(tap);
+ log_assert(depth < tap+1);
+ depth = tap+1;
}
}
- if (depth < 2)
- return;
+ if (depth < 2) {
+ cursor++;
+ continue;
+ }
Cell *last_cell = chain[cursor+depth-1];
@@ -318,7 +338,7 @@ struct ShregmapWorker
first_cell->setPort(q_port, last_cell->getPort(q_port));
first_cell->setParam("\\DEPTH", depth);
- if (opts.tech != nullptr && !opts.tech->fixup_shreg(first_cell, taps))
+ if (opts.tech != nullptr && !opts.tech->fixup(first_cell, taps_dict))
remove_cells.insert(first_cell);
for (int i = 1; i < depth; i++)
@@ -479,7 +499,6 @@ struct ShregmapPass : public Pass {
string tech = args[++argidx];
if (tech == "greenpak4") {
clkpol = "pos";
- opts.maxlen = 16;
opts.zinit = true;
opts.tech = new ShregmapTechGreenpak4;
} else {