From e493a5a61f6a1683c65955337c458ec793d09853 Mon Sep 17 00:00:00 2001
From: Oscar Gustafsson <oscar.gustafsson@gmail.com>
Date: Mon, 14 Apr 2025 18:01:24 +0200
Subject: [PATCH] Move Sink and DontCare to special_operations

---
 b_asic/core_operations.py    | 140 -----------------------------------
 b_asic/schedule.py           |   3 +-
 b_asic/scheduler.py          |   3 +-
 b_asic/sfg_generators.py     |   3 +-
 b_asic/special_operations.py | 140 +++++++++++++++++++++++++++++++++++
 5 files changed, 143 insertions(+), 146 deletions(-)

diff --git a/b_asic/core_operations.py b/b_asic/core_operations.py
index e5d9dc02..d4eaccfe 100644
--- a/b_asic/core_operations.py
+++ b/b_asic/core_operations.py
@@ -1652,143 +1652,3 @@ class Shift(AbstractOperation):
         if not isinstance(value, int):
             raise TypeError("value must be an int")
         self.set_param("value", value)
-
-
-class DontCare(AbstractOperation):
-    r"""
-    Dont-care operation
-
-    Used for ignoring the input to another operation and thus avoiding dangling input nodes.
-
-    Parameters
-    ----------
-    name : Name, optional
-        Operation name.
-
-    """
-
-    __slots__ = "_name"
-    _name: Name
-
-    is_linear = True
-
-    def __init__(self, name: Name = ""):
-        """Construct a DontCare operation."""
-        super().__init__(
-            input_count=0,
-            output_count=1,
-            name=name,
-            latency_offsets={"out0": 0},
-            execution_time=0,
-        )
-
-    @classmethod
-    def type_name(cls) -> TypeName:
-        return TypeName("dontcare")
-
-    def evaluate(self):
-        return 0
-
-    @property
-    def latency(self) -> int:
-        return 0
-
-    def __repr__(self) -> str:
-        return "DontCare()"
-
-    def __str__(self) -> str:
-        return "dontcare"
-
-    def get_plot_coordinates(
-        self,
-    ) -> tuple[tuple[tuple[float, float], ...], tuple[tuple[float, float], ...]]:
-        # Doc-string inherited
-        return (
-            (
-                (-0.5, 0),
-                (-0.5, 1),
-                (-0.25, 1),
-                (0, 0.5),
-                (-0.25, 0),
-                (-0.5, 0),
-            ),
-            (
-                (-0.5, 0),
-                (-0.5, 1),
-                (-0.25, 1),
-                (0, 0.5),
-                (-0.25, 0),
-                (-0.5, 0),
-            ),
-        )
-
-    def get_input_coordinates(self) -> tuple[tuple[float, float], ...]:
-        # doc-string inherited
-        return ()
-
-    def get_output_coordinates(self) -> tuple[tuple[float, float], ...]:
-        # doc-string inherited
-        return ((0, 0.5),)
-
-
-class Sink(AbstractOperation):
-    r"""
-    Sink operation.
-
-    Used for ignoring the output from another operation to avoid dangling output nodes.
-
-    Parameters
-    ==========
-
-    name : Name, optional
-        Operation name.
-    """
-
-    __slots__ = "_name"
-    _name: Name
-
-    is_linear = True
-
-    def __init__(self, name: Name = ""):
-        """Construct a Sink operation."""
-        super().__init__(
-            input_count=1,
-            output_count=0,
-            name=name,
-            latency_offsets={"in0": 0},
-            execution_time=0,
-        )
-
-    @classmethod
-    def type_name(cls) -> TypeName:
-        return TypeName("sink")
-
-    def evaluate(self):
-        raise NotImplementedError
-
-    @property
-    def latency(self) -> int:
-        return 0
-
-    def __repr__(self) -> str:
-        return "Sink()"
-
-    def __str__(self) -> str:
-        return "sink"
-
-    def get_plot_coordinates(
-        self,
-    ) -> tuple[tuple[tuple[float, float], ...], tuple[tuple[float, float], ...]]:
-        # Doc-string inherited
-        return (
-            ((0, 0), (0, 1), (0.25, 1), (0.5, 0.5), (0.25, 0), (0, 0)),
-            ((0, 0), (0, 1), (0.25, 1), (0.5, 0.5), (0.25, 0), (0, 0)),
-        )
-
-    def get_input_coordinates(self) -> tuple[tuple[float, float], ...]:
-        # doc-string inherited
-        return ((0, 0.5),)
-
-    def get_output_coordinates(self) -> tuple[tuple[float, float], ...]:
-        # doc-string inherited
-        return ()
diff --git a/b_asic/schedule.py b/b_asic/schedule.py
index 368a20f2..aac58538 100644
--- a/b_asic/schedule.py
+++ b/b_asic/schedule.py
@@ -29,7 +29,6 @@ from b_asic._preferences import (
     SIGNAL_LINEWIDTH,
     SPLINE_OFFSET,
 )
-from b_asic.core_operations import DontCare, Sink
 from b_asic.graph_component import GraphID
 from b_asic.operation import Operation
 from b_asic.port import InputPort, OutputPort
@@ -37,7 +36,7 @@ from b_asic.process import MemoryVariable, OperatorProcess
 from b_asic.resources import ProcessCollection
 from b_asic.scheduler import Scheduler
 from b_asic.signal_flow_graph import SFG
-from b_asic.special_operations import Delay, Input, Output
+from b_asic.special_operations import Delay, DontCare, Input, Output, Sink
 from b_asic.types import TypeName
 
 # Need RGB from 0 to 1
diff --git a/b_asic/scheduler.py b/b_asic/scheduler.py
index 05fe4763..025db297 100644
--- a/b_asic/scheduler.py
+++ b/b_asic/scheduler.py
@@ -4,9 +4,8 @@ from collections import defaultdict
 from typing import TYPE_CHECKING, cast
 
 import b_asic.logger
-from b_asic.core_operations import DontCare, Sink
 from b_asic.port import OutputPort
-from b_asic.special_operations import Delay, Input, Output
+from b_asic.special_operations import Delay, DontCare, Input, Output, Sink
 from b_asic.types import TypeName
 
 if TYPE_CHECKING:
diff --git a/b_asic/sfg_generators.py b/b_asic/sfg_generators.py
index b7e21aaa..755e82d1 100644
--- a/b_asic/sfg_generators.py
+++ b/b_asic/sfg_generators.py
@@ -14,14 +14,13 @@ from b_asic.core_operations import (
     Addition,
     Butterfly,
     ConstantMultiplication,
-    DontCare,
     Name,
     Reciprocal,
     SymmetricTwoportAdaptor,
 )
 from b_asic.signal import Signal
 from b_asic.signal_flow_graph import SFG
-from b_asic.special_operations import Delay, Input, Output
+from b_asic.special_operations import Delay, DontCare, Input, Output
 
 if TYPE_CHECKING:
     from b_asic.port import OutputPort
diff --git a/b_asic/special_operations.py b/b_asic/special_operations.py
index ca115908..6a1a3d03 100644
--- a/b_asic/special_operations.py
+++ b/b_asic/special_operations.py
@@ -249,3 +249,143 @@ class Delay(AbstractOperation):
     def initial_value(self, value: Num) -> None:
         """Set the initial value of this delay."""
         self.set_param("initial_value", value)
+
+
+class DontCare(AbstractOperation):
+    r"""
+    Dont-care operation
+
+    Used for ignoring the input to another operation and thus avoiding dangling input nodes.
+
+    Parameters
+    ----------
+    name : Name, optional
+        Operation name.
+
+    """
+
+    __slots__ = "_name"
+    _name: Name
+
+    is_linear = True
+
+    def __init__(self, name: Name = ""):
+        """Construct a DontCare operation."""
+        super().__init__(
+            input_count=0,
+            output_count=1,
+            name=name,
+            latency_offsets={"out0": 0},
+            execution_time=0,
+        )
+
+    @classmethod
+    def type_name(cls) -> TypeName:
+        return TypeName("dontcare")
+
+    def evaluate(self):
+        return 0
+
+    @property
+    def latency(self) -> int:
+        return 0
+
+    def __repr__(self) -> str:
+        return "DontCare()"
+
+    def __str__(self) -> str:
+        return "dontcare"
+
+    def get_plot_coordinates(
+        self,
+    ) -> tuple[tuple[tuple[float, float], ...], tuple[tuple[float, float], ...]]:
+        # Doc-string inherited
+        return (
+            (
+                (-0.5, 0),
+                (-0.5, 1),
+                (-0.25, 1),
+                (0, 0.5),
+                (-0.25, 0),
+                (-0.5, 0),
+            ),
+            (
+                (-0.5, 0),
+                (-0.5, 1),
+                (-0.25, 1),
+                (0, 0.5),
+                (-0.25, 0),
+                (-0.5, 0),
+            ),
+        )
+
+    def get_input_coordinates(self) -> tuple[tuple[float, float], ...]:
+        # doc-string inherited
+        return ()
+
+    def get_output_coordinates(self) -> tuple[tuple[float, float], ...]:
+        # doc-string inherited
+        return ((0, 0.5),)
+
+
+class Sink(AbstractOperation):
+    r"""
+    Sink operation.
+
+    Used for ignoring the output from another operation to avoid dangling output nodes.
+
+    Parameters
+    ==========
+
+    name : Name, optional
+        Operation name.
+    """
+
+    __slots__ = "_name"
+    _name: Name
+
+    is_linear = True
+
+    def __init__(self, name: Name = ""):
+        """Construct a Sink operation."""
+        super().__init__(
+            input_count=1,
+            output_count=0,
+            name=name,
+            latency_offsets={"in0": 0},
+            execution_time=0,
+        )
+
+    @classmethod
+    def type_name(cls) -> TypeName:
+        return TypeName("sink")
+
+    def evaluate(self):
+        raise NotImplementedError
+
+    @property
+    def latency(self) -> int:
+        return 0
+
+    def __repr__(self) -> str:
+        return "Sink()"
+
+    def __str__(self) -> str:
+        return "sink"
+
+    def get_plot_coordinates(
+        self,
+    ) -> tuple[tuple[tuple[float, float], ...], tuple[tuple[float, float], ...]]:
+        # Doc-string inherited
+        return (
+            ((0, 0), (0, 1), (0.25, 1), (0.5, 0.5), (0.25, 0), (0, 0)),
+            ((0, 0), (0, 1), (0.25, 1), (0.5, 0.5), (0.25, 0), (0, 0)),
+        )
+
+    def get_input_coordinates(self) -> tuple[tuple[float, float], ...]:
+        # doc-string inherited
+        return ((0, 0.5),)
+
+    def get_output_coordinates(self) -> tuple[tuple[float, float], ...]:
+        # doc-string inherited
+        return ()
-- 
GitLab