diff --git a/b_asic/signal_flow_graph.py b/b_asic/signal_flow_graph.py index 79b539cc4f037227a2ec3debe860618538c1ccb8..d51f13b4209fd1d5fc87e369b2f23dc8bf69301b 100644 --- a/b_asic/signal_flow_graph.py +++ b/b_asic/signal_flow_graph.py @@ -9,6 +9,7 @@ from collections import defaultdict, deque from io import StringIO from queue import PriorityQueue import itertools +from graphviz import Digraph from b_asic.port import SignalSourceProvider, OutputPort from b_asic.operation import Operation, AbstractOperation, MutableOutputMap, MutableRegisterMap @@ -608,6 +609,30 @@ class SFG(AbstractOperation): return precedence_list + def show_precedence_graph(self) -> None: + p_list = self.get_precedence_list() + pg = Digraph() + pg.attr(rankdir = 'LR') + + # Creates nodes for each output port in the precedence list + for i in range(len(p_list)): + ports = p_list[i] + with pg.subgraph(name='cluster_' + str(i)) as sub: + sub.attr(label='N' + str(i + 1)) + for port in ports: + sub.node(port.operation.graph_id + '.' + str(port.index)) + # Creates edges for each output port and creates nodes for each operation and edges for them as well + for i in range(len(p_list)): + ports = p_list[i] + for port in ports: + for signal in port.signals: + pg.edge(port.operation.graph_id + '.' + str(port.index), signal.destination.operation.graph_id) + pg.node(signal.destination.operation.graph_id, shape = 'square') + pg.edge(port.operation.graph_id, port.operation.graph_id + '.' + str(port.index)) + pg.node(port.operation.graph_id, shape = 'square') + + pg.view() + def print_precedence_graph(self) -> None: """Prints a representation of the SFG's precedence list to the standard out. If the precedence list already has been calculated then it uses the cached version, diff --git a/setup.py b/setup.py index 43d55d40a95212196facb973ebc97a1bdc5e7f42..62ac6af204e5ca3b0a845a82e687d1f9d87166d1 100644 --- a/setup.py +++ b/setup.py @@ -71,7 +71,8 @@ setuptools.setup( install_requires = [ "pybind11>=2.3.0", "numpy", - "install_qt_binding" + "install_qt_binding", + "graphviz" ], packages = ["b_asic"], ext_modules = [CMakeExtension("b_asic")], diff --git a/test/test_sfg.py b/test/test_sfg.py index 6f0a7ec40ef0042f7a0a5867467d662a604d5b43..a27b404e8d2ac0eaf6b4146ed497e2f06b5973cf 100644 --- a/test/test_sfg.py +++ b/test/test_sfg.py @@ -691,12 +691,12 @@ class TestConnectExternalSignalsToComponentsMultipleComp: out1.input(0).connect(sub1, "S7") test_sfg = SFG(inputs=[inp1, inp2, inp3, inp4], outputs=[out1]) + assert test_sfg.evaluate(1, 2, 3, 4) == 16 sfg1.connect_external_signals_to_components() assert test_sfg.evaluate(1, 2, 3, 4) == 16 assert not test_sfg.connect_external_signals_to_components() - class TestTopologicalOrderOperations: def test_feedback_sfg(self, simple_filter): topological_order = simple_filter.get_operations_topological_order()