Skip to content
Snippets Groups Projects
signal_flow_graph.py 3.19 KiB
Newer Older
  • Learn to ignore specific revisions
  • """@package docstring
    
    B-ASIC Signal Flow Graph Module.
    TODO: More info.
    """
    
    
    from typing import List, Dict, Optional, DefaultDict
    from collections import defaultdict
    
    from b_asic.abstract_operation import AbstractOperation
    
    Kevin Scott's avatar
    Kevin Scott committed
    from b_asic.signal import Signal
    
    from b_asic.graph_id import GraphIDGenerator, GraphID
    
    from b_asic.graph_component import GraphComponent, Name, TypeName
    
    Jacob Wahlman's avatar
    Jacob Wahlman committed
        """Signal flow graph.
        TODO: More info.
        """
    
        _graph_components_by_id: Dict[GraphID, GraphComponent]
        _graph_components_by_name: DefaultDict[Name, List[GraphComponent]]
        _graph_id_generator: GraphIDGenerator
    
        def __init__(self, input_signals: List[Signal] = None, output_signals: List[Signal] = None, \
                    ops: List[Operation] = None, **kwds):
            super().__init__(**kwds)
            if input_signals is None:
                input_signals = []
            if output_signals is None:
                output_signals = []
            if ops is None:
                ops = []
    
            self._graph_components_by_id = dict() # Maps Graph ID to objects
            self._graph_components_by_name = defaultdict(list) # Maps Name to objects
            self._graph_id_generator = GraphIDGenerator()
    
            for operation in ops:
                self._add_graph_component(operation)
    
            for input_signal in input_signals:
                self._add_graph_component(input_signal)
    
            # TODO: Construct SFG based on what inputs that were given
            # TODO: Traverse the graph between the inputs/outputs and add to self._operations.
            # TODO: Connect ports with signals with appropriate IDs.
    
        def evaluate(self, inputs: list) -> list:
            return [] # TODO: Implement
    
        def _add_graph_component(self, graph_component: GraphComponent) -> GraphID:
    
            """Add the entered graph component to the SFG's dictionary of graph objects and
             return a generated GraphID for it.
    
    Jacob Wahlman's avatar
    Jacob Wahlman committed
    
            Keyword arguments:
            graph_component: Graph component to add to the graph.
            """
            # Add to name dict
            self._graph_components_by_name[graph_component.name].append(graph_component)
    
            # Add to ID dict
            graph_id: GraphID = self._graph_id_generator.get_next_id(graph_component.type_name)
            self._graph_components_by_id[graph_id] = graph_component
            return graph_id
    
        def find_by_id(self, graph_id: GraphID) -> Optional[GraphComponent]:
    
            """Find a graph object based on the entered Graph ID and return it. If no graph
            object with the entered ID was found then return None.
    
    Jacob Wahlman's avatar
    Jacob Wahlman committed
    
            Keyword arguments:
            graph_id: Graph ID of the wanted object.
            """
            if graph_id in self._graph_components_by_id:
                return self._graph_components_by_id[graph_id]
    
            return None
    
        def find_by_name(self, name: Name) -> List[GraphComponent]:
    
            """Find all graph objects that have the entered name and return them
            in a list. If no graph object with the entered name was found then return an
    
    Jacob Wahlman's avatar
    Jacob Wahlman committed
            empty list.
    
            Keyword arguments:
            name: Name of the wanted object.
            """
            return self._graph_components_by_name[name]
    
        @property
        def type_name(self) -> TypeName:
            return "sfg"