From 579bf5d2d1221446214f5ceadc1bc8878e8d6662 Mon Sep 17 00:00:00 2001
From: Hugo Winbladh <hugwi268@student.liu.se>
Date: Thu, 29 Jun 2023 16:41:07 +0200
Subject: [PATCH] Add method to reconstruct an SFG from a schedule, and
 algorithm to simplify delays

---
 b_asic/schedule.py          |  7 +++++++
 b_asic/signal_flow_graph.py | 21 +++++++++++++++++++++
 2 files changed, 28 insertions(+)

diff --git a/b_asic/schedule.py b/b_asic/schedule.py
index 2603afcb..e5d5f96a 100644
--- a/b_asic/schedule.py
+++ b/b_asic/schedule.py
@@ -760,6 +760,13 @@ class Schedule:
             del self._laps[delay_input_id]
             delay_list = self._sfg.find_by_type_name(Delay.type_name())
 
+    def _reintroduce_delays(self) -> SFG:
+        reconstructed_sfg = self._sfg()
+        for signal_id,lap in self._laps.items():
+            for delays in range(lap):
+                reconstructed_sfg = reconstructed_sfg.insert_operation_after(signal_id, Delay())
+        return reconstructed_sfg()
+
     def _schedule_alap(self) -> None:
         """Schedule the operations using as-late-as-possible scheduling."""
         precedence_list = self._sfg.get_precedence_list()
diff --git a/b_asic/signal_flow_graph.py b/b_asic/signal_flow_graph.py
index 405681ea..19ef0a60 100644
--- a/b_asic/signal_flow_graph.py
+++ b/b_asic/signal_flow_graph.py
@@ -736,6 +736,27 @@ class SFG(AbstractOperation):
         # Recreate the newly coupled SFG so that all attributes are correct.
         return sfg_copy()
 
+    def simplify_delay_element_placement(self) -> "SFG":
+        sfg_copy = self()
+        for delay_element in sfg_copy.find_by_type_name(Delay.type_name()):
+            neighboring_delays = []
+            if len(delay_element.inputs[0].signals) > 0:
+                for signal in delay_element.inputs[0].signals[0].source.signals:
+                    if isinstance(signal.destination.operation, Delay):
+                        neighboring_delays.append(signal.destination.operation)
+
+            if delay_element in neighboring_delays:
+                neighboring_delays.remove(delay_element)
+
+            for delay in neighboring_delays:
+                for output in delay.outputs[0].signals:
+                    output.set_source(delay_element.outputs[0])
+                in_sig = delay.input(0).signals[0]
+                delay.input(0).remove_signal(in_sig)
+                in_sig.source.remove_signal(in_sig)
+
+        return sfg_copy()
+
     def _insert_operation_after_operation(
         self, output_operation: Operation, new_operation: Operation
     ):
-- 
GitLab