aboutsummaryrefslogtreecommitdiffstats
path: root/fpga_interchange/macros.cc
diff options
context:
space:
mode:
authorAlessandro Comodi <acomodi@antmicro.com>2021-07-05 13:34:34 +0200
committergatecat <gatecat@ds0.me>2021-07-06 09:57:26 +0100
commit6edc11de4de20aa5194f5cf3705a320b1891a2d6 (patch)
tree9bc2c112922b53f3009ca8cf2b72a91607d70689 /fpga_interchange/macros.cc
parent8a9fb810369aeb5eed128ef4e7d4de456ef1ec8f (diff)
downloadnextpnr-6edc11de4de20aa5194f5cf3705a320b1891a2d6.tar.gz
nextpnr-6edc11de4de20aa5194f5cf3705a320b1891a2d6.tar.bz2
nextpnr-6edc11de4de20aa5194f5cf3705a320b1891a2d6.zip
interchange: tests: add obuftds test
Signed-off-by: Alessandro Comodi <acomodi@antmicro.com>
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)