aboutsummaryrefslogtreecommitdiffstats
path: root/fpga_interchange/macros.cc
diff options
context:
space:
mode:
authorYRabbit <rabbit@yrabbit.cyou>2021-07-07 08:36:45 +1000
committerYRabbit <rabbit@yrabbit.cyou>2021-07-07 08:36:45 +1000
commit5f018df4e463a37f5a63aeb9bd7a55988e4f2027 (patch)
treefac6d37cd3954f44475d904094a3af231fc664f6 /fpga_interchange/macros.cc
parentfd7734f0006d6522dea1ea4ea29750c8bafc77c4 (diff)
parentc696e885736ed052bd1d5e8fd91b42ee3bc6af9f (diff)
downloadnextpnr-5f018df4e463a37f5a63aeb9bd7a55988e4f2027.tar.gz
nextpnr-5f018df4e463a37f5a63aeb9bd7a55988e4f2027.tar.bz2
nextpnr-5f018df4e463a37f5a63aeb9bd7a55988e4f2027.zip
Merge branch 'master' into io_port
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)