From 96b6410dcb7a82e7be8d4a2025835936f2ca84a7 Mon Sep 17 00:00:00 2001
From: Eddie Hung <eddie@fpgeh.com>
Date: Thu, 9 Sep 2021 10:06:31 -0700
Subject: abc9: make re-entrant (#2993)

* Add testcase

* Cleanup some state at end of abc9

* Re-assign abc9_box_id from scratch

* Suppress delete unless prep_bypass did something
---
 passes/techmap/abc9.cc     |  7 ++++++-
 passes/techmap/abc9_ops.cc | 11 +++--------
 tests/techmap/bug2972.ys   | 20 ++++++++++++++++++++
 3 files changed, 29 insertions(+), 9 deletions(-)
 create mode 100644 tests/techmap/bug2972.ys

diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc
index 207a280fc..1f00fc3e7 100644
--- a/passes/techmap/abc9.cc
+++ b/passes/techmap/abc9.cc
@@ -289,8 +289,10 @@ struct Abc9Pass : public ScriptPass
 			run("scc -specify -set_attr abc9_scc_id {}");
 			if (help_mode)
 				run("abc9_ops -prep_bypass [-prep_dff]", "(option if -dff)");
-			else
+			else {
+				active_design->scratchpad_unset("abc9_ops.prep_bypass.did_something");
 				run(stringf("abc9_ops -prep_bypass %s", dff_mode ? "-prep_dff" : ""));
+			}
 			if (dff_mode) {
 				run("design -copy-to $abc9_map @$abc9_flops", "(only if -dff)");
 				run("select -unset $abc9_flops", "             (only if -dff)");
@@ -450,6 +452,9 @@ struct Abc9Pass : public ScriptPass
 			run("design -delete $abc9_unmap");
 			if (saved_designs.count("$abc9_holes") || help_mode)
 				run("design -delete $abc9_holes");
+			if (help_mode || active_design->scratchpad_get_bool("abc9_ops.prep_bypass.did_something"))
+				run("delete =*_$abc9_byp");
+			run("setattr -mod -unset abc9_box_id");
 		}
 	}
 } Abc9Pass;
diff --git a/passes/techmap/abc9_ops.cc b/passes/techmap/abc9_ops.cc
index a2f1dd955..7a6959971 100644
--- a/passes/techmap/abc9_ops.cc
+++ b/passes/techmap/abc9_ops.cc
@@ -432,6 +432,8 @@ void prep_bypass(RTLIL::Design *design)
 				}
 			}
 			unmap_module->fixup_ports();
+
+			design->scratchpad_set_bool("abc9_ops.prep_bypass.did_something", true);
 		}
 }
 
@@ -942,15 +944,8 @@ void prep_box(RTLIL::Design *design)
 {
 	TimingInfo timing;
 
-	std::stringstream ss;
 	int abc9_box_id = 1;
-	for (auto module : design->modules()) {
-		auto it = module->attributes.find(ID::abc9_box_id);
-		if (it == module->attributes.end())
-			continue;
-		abc9_box_id = std::max(abc9_box_id, it->second.as_int());
-	}
-
+	std::stringstream ss;
 	dict<IdString,std::vector<IdString>> box_ports;
 	for (auto module : design->modules()) {
 		auto it = module->attributes.find(ID::abc9_box);
diff --git a/tests/techmap/bug2972.ys b/tests/techmap/bug2972.ys
new file mode 100644
index 000000000..8ae895f56
--- /dev/null
+++ b/tests/techmap/bug2972.ys
@@ -0,0 +1,20 @@
+read_verilog -specify <<EOT
+(* abc9_box, blackbox*)
+module box(input clk, d, output reg q, output do);
+parameter P = 0;
+always @(posedge clk)
+    q <= d;
+assign do = d;
+specify
+    (posedge clk => (q : d)) = 1;
+    (d => do) = 1;
+endspecify
+endmodule
+
+module top(input clk, d, output q);
+box i1(clk, d, q);
+endmodule
+EOT
+hierarchy
+abc9 -lut 4
+abc9 -lut 4
-- 
cgit v1.2.3