-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add connectable base in/out signals
- Loading branch information
Showing
4 changed files
with
176 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
import unittest | ||
|
||
from elasticai.creator.vhdl.signal import BaseInSignal, Identifiable | ||
|
||
|
||
class MyOutSignal(Identifiable): | ||
def id(self) -> str: | ||
return "my_out_signal" | ||
|
||
|
||
class AlwaysMatchingSignal(BaseInSignal): | ||
def __init__(self): | ||
super().__init__("always_matching_signal") | ||
|
||
def definition(self) -> str: | ||
return "empty def" | ||
|
||
def matches(self, other: Identifiable) -> bool: | ||
return True | ||
|
||
|
||
class NeverMatchingSignal(BaseInSignal): | ||
def definition(self) -> str: | ||
return "empty_definition" | ||
|
||
def __init__(self): | ||
super().__init__("in_signal") | ||
|
||
def matches(self, other: Identifiable) -> bool: | ||
return False | ||
|
||
|
||
class SignalTestCase(unittest.TestCase): | ||
def test_never_matching_signal_is_missing_inputs_after_connect(self): | ||
in_signal = NeverMatchingSignal() | ||
in_signal.connect(MyOutSignal()) | ||
self.assertTrue(in_signal.is_missing_inputs()) | ||
|
||
def test_always_matching_signal_is_not_missing_inputs_after_connect(self): | ||
in_signal = AlwaysMatchingSignal() | ||
in_signal.connect(MyOutSignal()) | ||
self.assertFalse(in_signal.is_missing_inputs()) | ||
|
||
def test_code_produces_correct_vhdl_line_after_connecting(self): | ||
in_signal = AlwaysMatchingSignal() | ||
out_signal = MyOutSignal() | ||
in_signal.connect(out_signal) | ||
self.assertEqual([f"{in_signal.id()} <= {out_signal.id()}"], in_signal.code()) | ||
|
||
|
||
if __name__ == "__main__": | ||
unittest.main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
from abc import abstractmethod | ||
from typing import Any, Protocol, TypeVar | ||
|
||
T_Connectable_contra = TypeVar( | ||
"T_Connectable_contra", bound="Connectable", contravariant=True | ||
) | ||
|
||
|
||
class Connectable(Protocol): | ||
@abstractmethod | ||
def connect(self: T_Connectable_contra, other: Any): | ||
... | ||
|
||
@abstractmethod | ||
def is_missing_inputs(self) -> bool: | ||
... |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
from abc import abstractmethod | ||
from typing import Iterable, Protocol, Reversible, TypeVar | ||
|
||
T_Node_co = TypeVar("T_Node_co", bound="Node", covariant=True) | ||
|
||
|
||
class Graph(Protocol[T_Node_co]): | ||
@property | ||
@abstractmethod | ||
def nodes(self) -> Reversible[T_Node_co]: | ||
... | ||
|
||
|
||
T_Node = TypeVar("T_Node", bound="Node") | ||
T_co = TypeVar("T_co", covariant=True) | ||
|
||
|
||
class Node(Protocol[T_co]): | ||
@property | ||
@abstractmethod | ||
def children(self: "Node[T_co]") -> Iterable["Node[T_co]"]: | ||
... | ||
|
||
@property | ||
@abstractmethod | ||
def parents(self: "Node[T_co]") -> Iterable["Node[T_co]"]: | ||
... |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
from abc import ABC, abstractmethod | ||
from typing import ( | ||
Any, | ||
ClassVar, | ||
Collection, | ||
Optional, | ||
Protocol, | ||
TypeVar, | ||
runtime_checkable, | ||
) | ||
|
||
from elasticai.creator.vhdl.connectable import Connectable | ||
|
||
|
||
class SignalProvider(Protocol): | ||
def in_signals(self) -> Collection["InSignal"]: | ||
... | ||
|
||
def out_signals(self) -> Collection["OutSignal"]: | ||
... | ||
|
||
|
||
T_Signal_contra = TypeVar("T_Signal_contra", bound="Signal", contravariant=True) | ||
|
||
|
||
class Identifiable(Protocol): | ||
@abstractmethod | ||
def id(self) -> str: | ||
... | ||
|
||
|
||
class Signal(Protocol): | ||
@abstractmethod | ||
def definition(self) -> str: | ||
... | ||
|
||
|
||
@runtime_checkable | ||
class InSignal(Signal, Connectable, Protocol): | ||
@abstractmethod | ||
def code(self) -> list[str]: | ||
... | ||
|
||
|
||
class NullIdentifiable(Identifiable): | ||
def id(self) -> str: | ||
return "" | ||
|
||
|
||
class BaseInSignal(InSignal, ABC): | ||
_NULL_SIGNAL: ClassVar[Identifiable] = NullIdentifiable() | ||
|
||
def __init__(self, id: str): | ||
self._out_signal: Identifiable = self._NULL_SIGNAL | ||
self._id = id | ||
|
||
def code(self) -> list[str]: | ||
return [f"{self.id()} <= {self._out_signal.id()}"] | ||
|
||
@abstractmethod | ||
def definition(self) -> str: | ||
return "" | ||
|
||
def id(self) -> str: | ||
return self._id | ||
|
||
def is_missing_inputs(self) -> bool: | ||
return self._out_signal == self._NULL_SIGNAL | ||
|
||
@abstractmethod | ||
def matches(self, other: Any) -> bool: | ||
... | ||
|
||
def connect(self, other: Identifiable) -> None: | ||
if self.matches(other): | ||
self._out_signal = other | ||
|
||
|
||
@runtime_checkable | ||
class OutSignal(Signal, Protocol): | ||
... |