Skip to content
Snippets Groups Projects
port.py 3.41 KiB
Newer Older
  • Learn to ignore specific revisions
  • """@package docstring
    
    B-ASIC Port Module.
    TODO: More info.
    """
    
    from abc import ABC, abstractmethod
    
    from typing import NewType, Optional, List
    
    from b_asic.signal import Signal
    
    Kevin Scott's avatar
    Kevin Scott committed
    from b_asic.operation import Operation
    
    
    PortId = NewType("PortId", int)
    
    
    class Port(ABC):
    
    Jacob Wahlman's avatar
    Jacob Wahlman committed
        """Abstract port class.
        TODO: More info.
        """
    
        _port_id: PortId
        _operation: Operation
    
        def __init__(self, port_id: PortId, operation: Operation):
            self._port_id = port_id
            self._operation = operation
    
        @property
        def identifier(self) -> PortId:
            """Get the unique identifier."""
            return self._port_id
    
        @property
        def operation(self) -> Operation:
            """Get the connected operation."""
            return self._operation
    
        @property
        @abstractmethod
        def signals(self) -> List[Signal]:
            """Get a list of all connected signals."""
            raise NotImplementedError
    
        @abstractmethod
        def signal(self, i: int = 0) -> Signal:
            """Get the connected signal at index i."""
            raise NotImplementedError
    
        @abstractmethod
        def signal_count(self) -> int:
            """Get the number of connected signals."""
            raise NotImplementedError
    
        @abstractmethod
        def connect(self, signal: Signal) -> None:
            """Connect a signal."""
            raise NotImplementedError
    
        @abstractmethod
        def disconnect(self, i: int = 0) -> None:
            """Disconnect a signal."""
            raise NotImplementedError
    
    class InputPort(Port):
    
    Jacob Wahlman's avatar
    Jacob Wahlman committed
        """Input port.
        TODO: More info.
        """
        _source_signal: Optional[Signal]
    
    Jacob Wahlman's avatar
    Jacob Wahlman committed
        def __init__(self, port_id: PortId, operation: Operation):
            super().__init__(port_id, operation)
            self._source_signal = None
    
    Jacob Wahlman's avatar
    Jacob Wahlman committed
        @property
        def signals(self) -> List[Signal]:
            return [] if self._source_signal is None else [self._source_signal]
    
    Jacob Wahlman's avatar
    Jacob Wahlman committed
        def signal(self, i: int = 0) -> Signal:
            assert 0 <= i < self.signal_count() # TODO: Error message.
            assert self._source_signal is not None # TODO: Error message.
            return self._source_signal
    
    Jacob Wahlman's avatar
    Jacob Wahlman committed
        def signal_count(self) -> int:
            return 0 if self._source_signal is None else 1
    
    Jacob Wahlman's avatar
    Jacob Wahlman committed
        def connect(self, signal: Signal) -> None:
            self._source_signal = signal
            signal.destination = self
    
    Jacob Wahlman's avatar
    Jacob Wahlman committed
        def disconnect(self, i: int = 0) -> None:
            assert 0 <= i < self.signal_count() # TODO: Error message.
            self._source_signal.disconnect_source()
            self._source_signal = None
    
    Jacob Wahlman's avatar
    Jacob Wahlman committed
        # TODO: More stuff.
    
    class OutputPort(Port):
    
    Jacob Wahlman's avatar
    Jacob Wahlman committed
        """Output port.
        TODO: More info.
        """
    
    Jacob Wahlman's avatar
    Jacob Wahlman committed
        _destination_signals: List[Signal]
    
    Jacob Wahlman's avatar
    Jacob Wahlman committed
        def __init__(self, port_id: PortId, operation: Operation):
            super().__init__(port_id, operation)
            self._destination_signals = []
    
    Jacob Wahlman's avatar
    Jacob Wahlman committed
        @property
        def signals(self) -> List[Signal]:
            return self._destination_signals.copy()
    
    Jacob Wahlman's avatar
    Jacob Wahlman committed
        def signal(self, i: int = 0) -> Signal:
            assert 0 <= i < self.signal_count() # TODO: Error message.
            return self._destination_signals[i]
    
    Jacob Wahlman's avatar
    Jacob Wahlman committed
        def signal_count(self) -> int:
            return len(self._destination_signals)
    
    Jacob Wahlman's avatar
    Jacob Wahlman committed
        def connect(self, signal: Signal) -> None:
            assert signal not in self._destination_signals # TODO: Error message.
            self._destination_signals.append(signal)
            signal.source = self
    
    Jacob Wahlman's avatar
    Jacob Wahlman committed
        def disconnect(self, i: int = 0) -> None:
            assert 0 <= i < self.signal_count() # TODO: Error message.
            del self._destination_signals[i]
    
    Jacob Wahlman's avatar
    Jacob Wahlman committed
        # TODO: More stuff.