diff --git a/b_asic/GUI/arrow.py b/b_asic/GUI/arrow.py
index c975c728c8c4a36a1aa208e4f5bfd22107bc9a26..3c931150f3af95f6f2f2d17552c91072e41c4008 100644
--- a/b_asic/GUI/arrow.py
+++ b/b_asic/GUI/arrow.py
@@ -5,7 +5,7 @@ QGraphicsLineItem, QGraphicsWidget
 from PySide2.QtCore import Qt, QSize, QLineF, QPoint, QRectF
 from PySide2.QtGui import QIcon, QFont, QPainter, QPen
 
-from b_asic import Signal 
+from b_asic import Signal
 
 class Arrow(QGraphicsLineItem):
 
@@ -25,6 +25,8 @@ class Arrow(QGraphicsLineItem):
         menu.exec_(self.cursor().pos())
 
     def remove(self):
+        self.signal.remove_destination()
+        self.signal.remove_source()
         self._window.scene.removeItem(self)
         self._window.signalList.remove(self)
 
diff --git a/b_asic/GUI/drag_button.py b/b_asic/GUI/drag_button.py
index 5b0a734a09c41cd64848dd994ecaaef2d2fa120f..b6ef243ceee127b60ffca58d6833c1d69e2f391e 100644
--- a/b_asic/GUI/drag_button.py
+++ b/b_asic/GUI/drag_button.py
@@ -20,24 +20,31 @@ class DragButton(QPushButton):
     moved = Signal()
     def __init__(self, name, operation, operation_path_name, is_show_name, window, parent = None):
         self.name = name
+        self.ports = []
         self.is_show_name = is_show_name
         self._window = window
         self.operation = operation
         self.operation_path_name = operation_path_name
         self.clicked = 0
         self.pressed = False
+        self._m_press = False
+        self._m_drag = False
         self._mouse_press_pos = None
         self._mouse_move_pos = None
-        super(DragButton, self).__init__(self._window)
+        super(DragButton, self).__init__(parent)
 
     def contextMenuEvent(self, event):
         menu = QMenu()
         properties = QAction("Properties")
         menu.addAction(properties)
         properties.triggered.connect(self.show_properties_window)
+
+        delete = QAction("Delete")
+        menu.addAction(delete)
+        delete.triggered.connect(self.remove)
         menu.exec_(self.cursor().pos())
 
-    def show_properties_window(self, event):
+    def show_properties_window(self):
         self.properties_window = PropertiesWindow(self, self._window)
         self.properties_window.show()
 
@@ -45,55 +52,86 @@ class DragButton(QPushButton):
         self.label = label
 
     def mousePressEvent(self, event):
-
         if event.button() == Qt.LeftButton:
+            self._m_press = True
             self._mouse_press_pos = event.pos()
             self._mouse_move_pos = event.pos()
 
-            for signal in self._window.signalList:
-                signal.update()
-
-            self.clicked += 1
-            if self.clicked == 1:
-                self.pressed = True
-                self.setStyleSheet("background-color: grey; border-style: solid;\
-                border-color: black; border-width: 2px; border-radius: 10px")
-                self.setStyleSheet(""" QToolTip { background-color: white;
-                color: black }""")
-                path_to_image = os.path.join('operation_icons', self.operation_path_name + '_grey.png')
-                self.setIcon(QIcon(path_to_image))
-                self.setIconSize(QSize(55, 55))
-                self._window.pressed_operations.append(self)
-
-            elif self.clicked == 2:
-                self.clicked = 0
-                self.pressed = False
-                self.setStyleSheet("background-color: white; border-style: solid;\
-                border-color: black; border-width: 2px; border-radius: 10px")
-                self.setStyleSheet(""" QToolTip { background-color: white;
-                color: black}""")
-                path_to_image = os.path.join('operation_icons', self.operation_path_name + '.png')
-                self.setIcon(QIcon(path_to_image))
-                self.setIconSize(QSize(55, 55))
-                self._window.pressed_operations.remove(self)
-
         super(DragButton, self).mousePressEvent(event)
 
     def mouseMoveEvent(self, event):
-        if event.buttons() == Qt.LeftButton:
+        if event.buttons() == Qt.LeftButton and self._m_press:
+            self._m_drag = True
             self.move(self.mapToParent(event.pos() - self._mouse_press_pos))
+            if self in self._window.pressed_operations:
+                for button in self._window.pressed_operations:
+                    if button is self:
+                        continue
+
+                    button.move(button.mapToParent(event.pos() - self._mouse_press_pos))
 
         self._window.update()
         super(DragButton, self).mouseMoveEvent(event)
 
     def mouseReleaseEvent(self, event):
-        if self._mouse_press_pos is not None:
-            moved = event.pos() - self._mouse_press_pos
-            if moved.manhattanLength() > 3:
-                event.ignore()
-                return
+        self._m_press = False
+        if self._m_drag:
+            if self._mouse_press_pos is not None:
+                moved = event.pos() - self._mouse_press_pos
+                if moved.manhattanLength() > 3:
+                    event.ignore()
+
+            self._m_drag = False
+
+        else:
+            self.select_button(event.modifiers())
 
         super(DragButton, self).mouseReleaseEvent(event)
 
+    def _toggle_button(self, pressed=False):
+        self.pressed = not pressed
+        self.setStyleSheet(f"background-color: {'white' if not self.pressed else 'grey'}; border-style: solid;\
+        border-color: black; border-width: 2px")
+        path_to_image = os.path.join('operation_icons', f"{self.operation_path_name}{'_grey.png' if self.pressed else '.png'}")
+        self.setIcon(QIcon(path_to_image))
+        self.setIconSize(QSize(55, 55))
+
+    def select_button(self, modifiers=None):
+        if modifiers != Qt.ControlModifier:
+            for button in self._window.pressed_operations:
+                button._toggle_button(button.pressed)
+
+            self._toggle_button(self.pressed)
+            self._window.pressed_operations = [self]
+
+        else:
+            self._toggle_button(self.pressed)
+            if self in self._window.pressed_operations:
+                self._window.pressed_operations.remove(self)
+            else:
+                self._window.pressed_operations.append(self)
+
+        for signal in self._window.signalList:
+            signal.update()
+
     def remove(self):
-        self.deleteLater()
\ No newline at end of file
+        self._window.scene.removeItem(self._window.operationDict[self])
+
+        _signals = []
+        for signal, ports in self._window.signalPortDict.items():
+            if any([port in self._window.portDict[self] for port in ports]):
+                signal.remove()
+                _signals.append(signal)
+
+        for signal in _signals:
+            del self._window.signalPortDict[signal]
+
+        for port in self._window.portDict[self]:
+            if port in self._window.pressed_ports:
+                self._window.pressed_ports.remove(port)
+
+        if self in self._window.pressed_operations:
+            self._window.pressed_operations.remove(self)
+
+        if self in self._window.operationDict.keys():
+            del self._window.operationDict[self]
\ No newline at end of file
diff --git a/b_asic/GUI/gui_interface.py b/b_asic/GUI/gui_interface.py
index 2d42d808f24d6c55850ae122979f1498f2191a2f..d026fd399a3c7a9281c75f0f9e62a19f7bbf4aaa 100644
--- a/b_asic/GUI/gui_interface.py
+++ b/b_asic/GUI/gui_interface.py
@@ -223,6 +223,8 @@ class Ui_main_window(object):
         self.edit_menu.setObjectName("edit_menu")
         self.view_menu = QtWidgets.QMenu(self.menu_bar)
         self.view_menu.setObjectName("view_menu")
+        self.run_menu = QtWidgets.QMenu(self.menu_bar)
+        self.run_menu.setObjectName("run_menu")
         main_window.setMenuBar(self.menu_bar)
         self.status_bar = QtWidgets.QStatusBar(main_window)
         self.status_bar.setObjectName("status_bar")
@@ -235,6 +237,8 @@ class Ui_main_window(object):
         self.actionUndo.setObjectName("actionUndo")
         self.actionRedo = QtWidgets.QAction(main_window)
         self.actionRedo.setObjectName("actionRedo")
+        self.actionSimulateSFG = QtWidgets.QAction(main_window)
+        self.actionSimulateSFG.setObjectName("actionSimulateSFG")
         self.actionToolbar = QtWidgets.QAction(main_window)
         self.actionToolbar.setCheckable(True)
         self.actionToolbar.setObjectName("actionToolbar")
@@ -244,9 +248,11 @@ class Ui_main_window(object):
         self.edit_menu.addAction(self.actionUndo)
         self.edit_menu.addAction(self.actionRedo)
         self.view_menu.addAction(self.actionToolbar)
+        self.run_menu.addAction(self.actionSimulateSFG)
         self.menu_bar.addAction(self.file_menu.menuAction())
         self.menu_bar.addAction(self.edit_menu.menuAction())
         self.menu_bar.addAction(self.view_menu.menuAction())
+        self.menu_bar.addAction(self.run_menu.menuAction())
 
         self.retranslateUi(main_window)
         self.operation_list.setCurrentIndex(1)
@@ -269,6 +275,8 @@ class Ui_main_window(object):
         self.file_menu.setTitle(_translate("main_window", "File"))
         self.edit_menu.setTitle(_translate("main_window", "Edit"))
         self.view_menu.setTitle(_translate("main_window", "View"))
+        self.run_menu.setTitle(_translate("main_window", "Run"))
+        self.actionSimulateSFG.setText(_translate("main_window", "Simulate SFG"))
         self.save_menu.setText(_translate("main_window", "Save"))
         self.exit_menu.setText(_translate("main_window", "Exit"))
         self.exit_menu.setShortcut(_translate("main_window", "Ctrl+Q"))
diff --git a/b_asic/GUI/main_window.py b/b_asic/GUI/main_window.py
index ffa8448a7b2ed93b2b7cb79d3c609ac2fed34303..71cb5cb99a2bf410d7a818547230f24004cf090c 100644
--- a/b_asic/GUI/main_window.py
+++ b/b_asic/GUI/main_window.py
@@ -3,6 +3,7 @@ B-ASIC GUI Module.
 This python file is the main window of the GUI for B-ASIC.
 """
 
+from pprint import pprint
 from os import getcwd, path
 import sys
 
@@ -11,12 +12,12 @@ from gui_interface import Ui_main_window
 from arrow import Arrow
 from port_button import PortButton
 
-from b_asic import Operation
+from b_asic import Operation, SFG, InputPort, OutputPort
+from b_asic.simulation import Simulation
 import b_asic.core_operations as c_oper
 import b_asic.special_operations as s_oper
 from utils import decorate_class, handle_error
-from b_asic import SFG
-from b_asic import InputPort, OutputPort
+from simulate_sfg_window import SimulateSFGWindow, Plot
 
 from numpy import linspace
 
@@ -24,11 +25,10 @@ from PySide2.QtWidgets import QApplication, QWidget, QMainWindow, QLabel, QActio
 QStatusBar, QMenuBar, QLineEdit, QPushButton, QSlider, QScrollArea, QVBoxLayout,\
 QHBoxLayout, QDockWidget, QToolBar, QMenu, QLayout, QSizePolicy, QListWidget,\
 QListWidgetItem, QGraphicsView, QGraphicsScene, QShortcut, QGraphicsTextItem,\
-QGraphicsProxyWidget
+QGraphicsProxyWidget, QInputDialog
 from PySide2.QtCore import Qt, QSize
 from PySide2.QtGui import QIcon, QFont, QPainter, QPen, QBrush, QKeySequence
 
-
 MIN_WIDTH_SCENE = 600
 MIN_HEIGHT_SCENE = 520
 
@@ -44,21 +44,25 @@ class MainWindow(QMainWindow):
         self._operations_from_name = dict()
         self.zoom = 1
         self.sfg_name_i = 0
-        self.operationList = []
+        self.operationDict = dict()
+        self.operationItemSceneList = []
         self.signalList = []
         self.pressed_operations = []
-        self.portList = []
+        self.portDict = dict()
+        self.signalPortDict = dict()
         self.pressed_ports = []
         self.sfg_list = []
         self.source = None
         self._window = self
-
         self.init_ui()
         self.add_operations_from_namespace(c_oper, self.ui.core_operations_list)
         self.add_operations_from_namespace(s_oper, self.ui.special_operations_list)
 
         self.shortcut_core = QShortcut(QKeySequence("Ctrl+R"), self.ui.operation_box)
         self.shortcut_core.activated.connect(self._refresh_operations_list_from_namespace)
+        self.shortcut_select_all = QShortcut(QKeySequence("Ctrl+A"), self.graphic_view)
+        self.shortcut_select_all.activated.connect(self._select_all_operations)
+        self.scene.selectionChanged.connect(self._select_operations)
 
         self.move_button_index = 0
         self.is_show_names = True
@@ -69,6 +73,8 @@ class MainWindow(QMainWindow):
         self.check_show_names.setChecked(1)
         self.ui.view_menu.addAction(self.check_show_names)
 
+        self.ui.actionSimulateSFG.triggered.connect(self.simulate_sfg)
+
     def init_ui(self):
         self.ui.core_operations_list.itemClicked.connect(self.on_list_widget_item_clicked)
         self.ui.special_operations_list.itemClicked.connect(self.on_list_widget_item_clicked)
@@ -81,7 +87,7 @@ class MainWindow(QMainWindow):
         self.graphic_view = QGraphicsView(self.scene, self)
         self.graphic_view.setRenderHint(QPainter.Antialiasing)
         self.graphic_view.setGeometry(self.ui.operation_box.width(), 0, self.width(), self.height())
-        self.graphic_view.setDragMode(QGraphicsView.ScrollHandDrag)
+        self.graphic_view.setDragMode(QGraphicsView.RubberBandDrag)
 
     def create_toolbar_view(self):
         self.toolbar = self.addToolBar("Toolbar")
@@ -99,16 +105,16 @@ class MainWindow(QMainWindow):
             self.graphic_view.scale(self.zoom, self.zoom)
             self.zoom = old_zoom
 
-    def view_operation_names(self, event):
+    def view_operation_names(self):
         if self.check_show_names.isChecked():
             self.is_show_names = True
         else:
             self.is_show_names = False
-        for operation in self.operationList:
+        for operation in self.operationDict.keys():
             operation.label.setOpacity(self.is_show_names)
             operation.is_show_name = self.is_show_names
 
-    def exit_app(self, checked):
+    def exit_app(self):
         QApplication.quit()
 
     def create_SFG_from_toolbar(self):
@@ -120,8 +126,9 @@ class MainWindow(QMainWindow):
             elif isinstance(op.operation, s_oper.Output):
                 outputs.append(op.operation)
 
-        self.sfg_name_i += 1 
-        sfg = SFG(inputs=inputs, outputs=outputs, name="sfg" + str(self.sfg_name_i))
+        name = QInputDialog.getText(self, "Create SFG", "Name: ", QLineEdit.Normal)
+
+        sfg = SFG(inputs=inputs, outputs=outputs, name=name[0])
         for op in self.pressed_operations:
             op.setToolTip(sfg.name)
         self.sfg_list.append(sfg)
@@ -132,24 +139,22 @@ class MainWindow(QMainWindow):
         """
         return [length / 2] if ports == 1 else linspace(0, length, ports)
 
-    def _create_port(self, operation, port, output_port=True):
-        text = ">" if output_port else "<"
-        button = PortButton(text, operation, port, self)
-        button.setStyleSheet("background-color: white")
-        button.connectionRequested.connect(self.connectButton)
-        return button
-
     def add_ports(self, operation):
         _output_ports_dist = self._determine_port_distance(55 - 17, operation.operation.output_count)
         _input_ports_dist = self._determine_port_distance(55 - 17, operation.operation.input_count)
+        self.portDict[operation] = list()
 
         for i, dist in enumerate(_input_ports_dist):
-            port = self._create_port(operation, operation.operation.input(i))
+            port = PortButton(">", operation, operation.operation.input(i), self)
+            self.portDict[operation].append(port)
+            operation.ports.append(port)
             port.move(0, dist)
             port.show()
 
         for i, dist in enumerate(_output_ports_dist):
-            port = self._create_port(operation, operation.operation.output(i))
+            port = PortButton(">", operation, operation.operation.output(i), self)
+            self.portDict[operation].append(port)
+            operation.ports.append(port)
             port.move(55 - 12, dist)
             port.show()
 
@@ -188,6 +193,7 @@ class MainWindow(QMainWindow):
             attr_button.setParent(None)
             attr_button_scene = self.scene.addWidget(attr_button)
             attr_button_scene.moveBy(self.move_button_index * 100, 0)
+            attr_button_scene.setFlag(attr_button_scene.ItemIsSelectable, True)
             self.move_button_index += 1
             operation_label = QGraphicsTextItem(attr_oper.type_name(), attr_button_scene)
             if not self.is_show_names:
@@ -195,7 +201,7 @@ class MainWindow(QMainWindow):
             operation_label.setTransformOriginPoint(operation_label.boundingRect().center())
             operation_label.moveBy(10, -20)
             attr_button.add_label(operation_label)
-            self.operationList.append(attr_button)
+            self.operationDict[attr_button] = attr_button_scene
         except Exception as e:
             print("Unexpected error occured: ", e)
 
@@ -210,13 +216,8 @@ class MainWindow(QMainWindow):
         self._create_operation(item)
 
     def keyPressEvent(self, event):
-        pressed_operations = []
-        for op in self.operationList:
-            if op.pressed:
-                pressed_operations.append(op)
         if event.key() == Qt.Key_Delete:
-            for pressed_op in pressed_operations:
-                self.operationList.remove(pressed_op)
+            for pressed_op in self.pressed_operations:
                 pressed_op.remove()
                 self.move_button_index -= 1
         super().keyPressEvent(event)
@@ -228,15 +229,62 @@ class MainWindow(QMainWindow):
             if isinstance(self.pressed_ports[i].port, OutputPort) and \
             isinstance(self.pressed_ports[i+1].port, InputPort):
                 line = Arrow(self.pressed_ports[i], self.pressed_ports[i + 1], self)
+                self.signalPortDict[line] = [self.pressed_ports[i], self.pressed_ports[i + 1]]
+
                 self.scene.addItem(line)
                 self.signalList.append(line)
 
+        for port in self.pressed_ports:
+            port.select_port()
+
         self.update()
 
     def paintEvent(self, event):
-        for signal in self.signalList:
+        for signal in self.signalPortDict.keys():
             signal.moveLine()
 
+    def _select_all_operations(self):
+        self.pressed_operations.clear()
+        for button in self.operationDict.keys():
+            button._toggle_button(pressed=False)
+            self.pressed_operations.append(button)
+
+    def _select_operations(self):
+        selected = [button.widget() for button in self.scene.selectedItems()]
+        for button in selected:
+            button._toggle_button(pressed=False)
+
+        for button in self.pressed_operations:
+            if button not in selected:
+                button._toggle_button(pressed=True)
+
+        self.pressed_operations = selected
+
+    def _simulate_sfg(self):
+        for sfg, properties in self.dialog.properties.items():
+            simulation = Simulation(sfg, input_providers=properties["input_values"], save_results=properties["all_results"])
+            l_result = simulation.run_for(properties["iteration_count"])
+
+            if properties["all_results"]:
+                print(f"{'=' * 10} {sfg.name} {'=' * 10}")
+                pprint(simulation.results)
+                print(f"{'=' * 10} /{sfg.name} {'=' * 10}")
+
+            if properties["show_plot"]:
+                self.plot = Plot(simulation, sfg)
+                self.plot.show()
+
+    def simulate_sfg(self):
+        self.dialog = SimulateSFGWindow(self)
+
+        for sfg in self.sfg_list:
+            self.dialog.add_sfg_to_dialog(sfg)
+
+        self.dialog.show()
+
+        # Wait for input to dialog. Kinda buggy because of the separate window in the same thread.
+        self.dialog.simulate.connect(self._simulate_sfg)
+
 if __name__ == "__main__":
     app = QApplication(sys.argv)
     window = MainWindow()
diff --git a/b_asic/GUI/port_button.py b/b_asic/GUI/port_button.py
index 04b355663cd057b399c6e2c182f70aebeddffc50..11c36ef5206ae4935a5bcf675a10eee22239d8dc 100644
--- a/b_asic/GUI/port_button.py
+++ b/b_asic/GUI/port_button.py
@@ -8,12 +8,17 @@ class PortButton(QPushButton):
     connectionRequested = Signal(QPushButton)
     moved = Signal()
     def __init__(self, name, operation, port, window, parent=None):
+        super(PortButton, self).__init__(name, operation, parent)
         self.pressed = False
-        self.window = window
+        self._window = window
         self.port = port
         self.operation = operation
         self.clicked = 0
-        super(PortButton, self).__init__(name, operation)
+        self._m_drag = False
+        self._m_press = False
+
+        self.setStyleSheet("background-color: white")
+        self.connectionRequested.connect(self._window.connectButton)
 
     def contextMenuEvent(self, event):
         menu = QMenu()
@@ -22,18 +27,32 @@ class PortButton(QPushButton):
 
     def mousePressEvent(self, event):
         if event.button() == Qt.LeftButton:
-            self.clicked += 1
-            if self.clicked == 1:
-                self.setStyleSheet("background-color: grey")
-                self.pressed = True
-                self.window.pressed_ports.append(self)
-            elif self.clicked == 2:
-                self.setStyleSheet("background-color: white")
-                self.pressed = False
-                self.clicked = 0
-                self.window.pressed_ports.remove(self)
+            self.select_port(event.modifiers())
+
         super(PortButton, self).mousePressEvent(event)
 
     def mouseReleaseEvent(self, event):
         super(PortButton, self).mouseReleaseEvent(event)
 
+    def _toggle_port(self, pressed=False):
+        self.pressed = not pressed
+        self.setStyleSheet(f"background-color: {'white' if not self.pressed else 'grey'}")
+
+    def select_port(self, modifiers=None):
+        if modifiers != Qt.ControlModifier:
+            for port in self._window.pressed_ports:
+                port._toggle_port(port.pressed)
+
+            self._toggle_port(self.pressed)
+            self._window.pressed_ports = [self]
+
+        else:
+            self._toggle_port(self.pressed)
+            if self in self._window.pressed_ports:
+                self._window.pressed_ports.remove(self)
+            else:
+                self._window.pressed_ports.append(self)
+
+        for signal in self._window.signalList:
+            signal.update()
+
diff --git a/b_asic/GUI/simulate_sfg_window.py b/b_asic/GUI/simulate_sfg_window.py
new file mode 100644
index 0000000000000000000000000000000000000000..9976adf0ed554b7590785543473b19f5c8b49ef4
--- /dev/null
+++ b/b_asic/GUI/simulate_sfg_window.py
@@ -0,0 +1,118 @@
+from PySide2.QtWidgets import QDialog, QLineEdit, QPushButton, QVBoxLayout, QHBoxLayout,\
+QLabel, QCheckBox, QSpinBox, QGroupBox, QFrame, QFormLayout, QGridLayout, QSizePolicy
+from PySide2.QtCore import Qt, Signal
+from PySide2.QtGui import QIntValidator
+
+from matplotlib.backends import qt_compat
+from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
+from matplotlib.figure import Figure
+
+
+class SimulateSFGWindow(QDialog):
+    simulate = Signal()
+
+    def __init__(self, window):
+        super(SimulateSFGWindow, self).__init__()
+        self._window = window
+        self.properties = dict()
+        self.sfg_to_layout = dict()
+        self.setWindowFlags(Qt.WindowTitleHint | Qt.WindowCloseButtonHint)
+        self.setWindowTitle("Simulate SFG")
+
+        self.dialog_layout = QVBoxLayout()
+        self.simulate_btn = QPushButton("Simulate")
+        self.simulate_btn.clicked.connect(self.save_properties)
+        self.dialog_layout.addWidget(self.simulate_btn)
+        self.setLayout(self.dialog_layout)
+
+    def add_sfg_to_dialog(self, sfg):
+        sfg_layout = QVBoxLayout()
+        options_layout = QFormLayout()
+
+        name_label = QLabel(f"{sfg.name}")
+        sfg_layout.addWidget(name_label)
+
+        spin_box = QSpinBox()
+        spin_box.setRange(0, 2147483647)
+        options_layout.addRow("Iteration Count: ", spin_box)
+
+        check_box = QCheckBox()
+        options_layout.addRow("Plot Results: ", check_box)
+
+        check_box = QCheckBox()
+        options_layout.addRow("Get All Results: ", check_box)
+
+        input_layout = QVBoxLayout()
+        input_label = QLabel("Input Values: ")
+        input_layout.addWidget(input_label)
+        input_grid = QGridLayout()
+        x, y = 0, 0
+        for i in range(sfg.input_count):
+            if i % 2 == 0 and i > 0:
+                x += 1
+                y = 0
+
+            _input_value = QLineEdit()
+            _input_value.setValidator(QIntValidator())
+            _input_value.setFixedWidth(50)
+            input_grid.addWidget(_input_value, x, y)
+            y += 1
+
+        input_layout.addLayout(input_grid)
+        sfg_layout.addLayout(options_layout)
+        sfg_layout.addLayout(input_layout)
+
+        frame = QFrame()
+        frame.setFrameShape(QFrame.HLine)
+        frame.setFrameShadow(QFrame.Sunken)
+        self.dialog_layout.addWidget(frame)
+
+        self.sfg_to_layout[sfg] = sfg_layout
+        self.dialog_layout.addLayout(sfg_layout)
+
+    def save_properties(self):
+        for sfg, sfg_row in self.sfg_to_layout.items():
+            _option_values = sfg_row.children()[0]
+            _input_values = sfg_row.children()[1].children()[0]
+            _, spin_box, _, check_box_plot, _, check_box_all = map(lambda x: _option_values.itemAt(x).widget(), range(_option_values.count()))
+            input_values = map(lambda x: _input_values.itemAt(x).widget(), range(_input_values.count()))
+            input_values = [int(widget.text()) if widget.text() else 0 for widget in input_values]
+            self.properties[sfg] = {
+                "iteration_count": spin_box.value(),
+                "show_plot": check_box_plot.isChecked(),
+                "all_results": check_box_all.isChecked(),
+                "input_values": input_values
+            }
+
+            # If we plot we should also print the entire data, since you can't really interact with the graph.
+            if check_box_plot.isChecked():
+                self.properties[sfg]["all_results"] = True
+
+        self.accept()
+        self.simulate.emit()
+
+
+class Plot(FigureCanvas):
+    def __init__(self, simulation, sfg, parent=None, width=5, height=4, dpi=100):
+        self.simulation = simulation
+        self.sfg = sfg
+
+        fig = Figure(figsize=(width, height), dpi=dpi)
+        fig.suptitle(sfg.name, fontsize=20)
+        self.axes = fig.add_subplot(111)
+
+        FigureCanvas.__init__(self, fig)
+        self.setParent(parent)
+
+        FigureCanvas.setSizePolicy(self, QSizePolicy.Expanding, QSizePolicy.Expanding)
+        FigureCanvas.updateGeometry(self)
+        self._plot_values_sfg()
+
+    def _plot_values_sfg(self):
+        x_axis = list(range(len(self.simulation.results.keys())))
+        for _output in range(self.sfg.output_count):
+            y_axis = list()
+            for _iter in range(len(self.simulation.results.keys())):
+                y_axis.append(self.simulation.results[_iter][str(_output)])
+
+            self.axes.plot(x_axis, y_axis)
diff --git a/b_asic/core_operations.py b/b_asic/core_operations.py
index ec7306c6f4c97b5c0377794e48524d09c7ed159b..a70c86b7d966197850604ad7a269242d364eca36 100644
--- a/b_asic/core_operations.py
+++ b/b_asic/core_operations.py
@@ -249,8 +249,8 @@ class MAD(AbstractOperation):
     def __init__(self, src0: Optional[SignalSourceProvider] = None, src1: Optional[SignalSourceProvider] = None, src2: Optional[SignalSourceProvider] = None, name: Name = ""):
         super().__init__(input_count = 3, output_count = 1, name = name, input_sources = [src0, src1, src2])
 
-    @property
-    def type_name(self) -> TypeName:
+    @classmethod
+    def type_name(cls) -> TypeName:
         return "mad"
 
     def evaluate(self, a, b, c):
diff --git a/setup.py b/setup.py
index 94285a70c496dc08923a9a36258316e8397670c6..f91d34d54336708275a28b1f9f02ea1b2d80141f 100644
--- a/setup.py
+++ b/setup.py
@@ -72,10 +72,11 @@ setuptools.setup(
         "pybind11>=2.3.0",
         "numpy",
         "pyside2",
-        "graphviz"
+        "graphviz",
+        "matplotlib"
     ],
     packages = ["b_asic"],
     ext_modules = [CMakeExtension("b_asic")],
     cmdclass = {"build_ext": CMakeBuild},
     zip_safe = False
-)
\ No newline at end of file
+)