aboutsummaryrefslogtreecommitdiffstats
path: root/fpga_interchange/macros.cc
diff options
context:
space:
mode:
authorgatecat <gatecat@ds0.me>2021-07-06 11:43:24 +0100
committerGitHub <noreply@github.com>2021-07-06 11:43:24 +0100
commitc0bb2fb76a700a1ff3b9aaa663cfd70194df2a3a (patch)
tree11d7496a94275f54e98d566958890285e18a3104 /fpga_interchange/macros.cc
parent8a9fb810369aeb5eed128ef4e7d4de456ef1ec8f (diff)
parent31abefc8e49edce55fb42c99ac99b81e948d9004 (diff)
downloadnextpnr-c0bb2fb76a700a1ff3b9aaa663cfd70194df2a3a.tar.gz
nextpnr-c0bb2fb76a700a1ff3b9aaa663cfd70194df2a3a.tar.bz2
nextpnr-c0bb2fb76a700a1ff3b9aaa663cfd70194df2a3a.zip
Merge pull request #750 from YosysHQ/gatecat/io-improve
IO improvements for OBUFTDS
Diffstat (limited to 'fpga_interchange/macros.cc')
-rw-r--r--fpga_interchange/macros.cc12
1 files changed, 12 insertions, 0 deletions
diff --git a/fpga_interchange/macros.cc b/fpga_interchange/macros.cc
index 42c8e1ba..762615c1 100644
--- a/fpga_interchange/macros.cc
+++ b/fpga_interchange/macros.cc
@@ -58,14 +58,24 @@ void Arch::expand_macros()
std::vector<CellInfo *> next_cells;
+ bool first_iter = false;
do {
// Expand cells
for (auto cell : cells) {
// TODO: consult exception map
const MacroExpansionPOD *exp = lookup_macro_rules(chip_info, cell->type);
+
+ // Block infinite expansion loop due to a macro being expanded in the same primitive.
+ // E.g.: OBUFTDS expands into the following cells, with an infinite loop being generated:
+ // - 2 OBUFTDS
+ // - 1 INV
+ if (exp && first_iter)
+ continue;
+
const MacroPOD *macro = lookup_macro(chip_info, exp ? IdString(exp->macro_name) : cell->type);
if (macro == nullptr)
continue;
+
// Get the ultimate root of this macro expansion
IdString parent = (cell->macro_parent == IdString()) ? cell->name : cell->macro_parent;
// Create child instances
@@ -158,6 +168,8 @@ void Arch::expand_macros()
// The next iteration only needs to look at cells created in this iteration
std::swap(next_cells, cells);
next_cells.clear();
+
+ first_iter = true;
} while (!cells.empty());
// Do this at the end, otherwise we might add cells that are later destroyed
for (auto &cell : ctx->cells)