diff --git a/b_asic/GUI/signal_generator_input.py b/b_asic/GUI/signal_generator_input.py
index 8fba385aa1aa7d5cfa1708cd7def15622e581d97..6c20dfa0c909ff0c6aef3d31bc3eecd02c189b50 100644
--- a/b_asic/GUI/signal_generator_input.py
+++ b/b_asic/GUI/signal_generator_input.py
@@ -1,8 +1,16 @@
 # -*- coding: utf-8 -*-
-from qtpy.QtWidgets import QGridLayout, QLabel, QLineEdit, QSpinBox
+from qtpy.QtWidgets import (
+    QFileDialog,
+    QGridLayout,
+    QLabel,
+    QLineEdit,
+    QPushButton,
+    QSpinBox,
+)
 
 from b_asic.signal_generator import (
     Constant,
+    FromFile,
     Gaussian,
     Impulse,
     SignalGenerator,
@@ -94,6 +102,31 @@ class ZeroPadInput(SignalGeneratorInput):
         return ZeroPad(input_values)
 
 
+class FromFileInput(SignalGeneratorInput):
+    """
+    Class for graphically configuring and generating a
+    :class:`~b_asic.signal_generators.FromFile` signal generator.
+    """
+
+    def __init__(self, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+        self.file_label = QLabel("Browse")
+        self.addWidget(self.file_label, 0, 0)
+        self.file_browser = QPushButton("No file selected")
+        self.file_browser.clicked.connect(
+            lambda i: self.get_input_file(i, self.file_browser)
+        )
+        self.addWidget(self.file_browser, 0, 1)
+
+    def get_generator(self) -> SignalGenerator:
+        return FromFile(self.file_browser.text())
+
+    def get_input_file(self, i, file_browser):
+        module, accepted = QFileDialog().getOpenFileName()
+        file_browser.setText(module)
+        return
+
+
 class SinusoidInput(SignalGeneratorInput):
     """
     Class for graphically configuring and generating a
@@ -272,4 +305,5 @@ _GENERATOR_MAPPING = {
     "Step": StepInput,
     "Uniform": UniformInput,
     "ZeroPad": ZeroPadInput,
+    "FromFile": FromFileInput,
 }
diff --git a/b_asic/GUI/simulate_sfg_window.py b/b_asic/GUI/simulate_sfg_window.py
index 13fbf3c8281b2fc1888497c87831abde8b2a0a75..b0513006d5c5a37790ccc0a912ea79aac99d5558 100644
--- a/b_asic/GUI/simulate_sfg_window.py
+++ b/b_asic/GUI/simulate_sfg_window.py
@@ -16,6 +16,7 @@ from qtpy.QtWidgets import (
     QGridLayout,
     QHBoxLayout,
     QLabel,
+    QLayout,
     QLineEdit,
     QPushButton,
     QShortcut,
@@ -25,6 +26,7 @@ from qtpy.QtWidgets import (
 )
 
 from b_asic.GUI.signal_generator_input import _GENERATOR_MAPPING
+from b_asic.signal_generator import FromFile
 
 
 class SimulateSFGWindow(QDialog):
@@ -40,6 +42,7 @@ class SimulateSFGWindow(QDialog):
         self.setWindowTitle("Simulate SFG")
 
         self.dialog_layout = QVBoxLayout()
+        self.dialog_layout.setSizeConstraint(QLayout.SetFixedSize)
         self.simulate_btn = QPushButton("Simulate")
         self.simulate_btn.clicked.connect(self.save_properties)
         self.dialog_layout.addWidget(self.simulate_btn)
@@ -89,15 +92,13 @@ class SimulateSFGWindow(QDialog):
                 self.input_grid.addWidget(input_label, i, 0)
 
                 input_dropdown = QComboBox()
-                input_dropdown.insertItems(
-                    0, list(_GENERATOR_MAPPING.keys()) + ["File"]
-                )
+                input_dropdown.insertItems(0, list(_GENERATOR_MAPPING.keys()))
                 input_dropdown.currentTextChanged.connect(
                     lambda text, i=i: self.change_input_format(i, text)
                 )
                 self.input_grid.addWidget(input_dropdown, i, 1, alignment=Qt.AlignLeft)
 
-                self.change_input_format(i, "Impulse")
+                self.change_input_format(i, "Constant")
 
                 y += 1
 
@@ -125,14 +126,6 @@ class SimulateSFGWindow(QDialog):
 
         if text in _GENERATOR_MAPPING:
             param_grid = _GENERATOR_MAPPING[text](self._window.logger)
-        elif text == "File":
-            file_label = QLabel("Browse")
-            param_grid.addWidget(file_label, 0, 0)
-            file_browser = QPushButton("No file selected")
-            file_browser.clicked.connect(
-                lambda i=i: self.get_input_file(i, file_browser)
-            )
-            param_grid.addWidget(file_browser, 0, 1)
         else:
             raise Exception("Input selection is not implemented")
 
@@ -140,30 +133,6 @@ class SimulateSFGWindow(QDialog):
 
         return
 
-    def get_input_file(self, i, file_browser):
-        module, accepted = QFileDialog().getOpenFileName()
-        file_browser.setText(module)
-        return
-
-    def parse_input_values(self, input_values):
-        _input_values = []
-        for _list in input_values:
-            _list_values = []
-            for val in _list:
-                val = val.strip()
-                try:
-                    if not val:
-                        val = 0
-
-                    _list_values.append(complex(val))
-                except ValueError:
-                    self._window.logger.warning(f"Skipping value: {val}, not a digit.")
-                    continue
-
-            _input_values.append(_list_values)
-
-        return _input_values
-
     def save_properties(self):
         for sfg, _properties in self.input_fields.items():
             ic_value = self.input_fields[sfg]["iteration_count"].value()
@@ -178,16 +147,6 @@ class SimulateSFGWindow(QDialog):
 
                 if in_format in _GENERATOR_MAPPING:
                     tmp2 = in_param.get_generator()
-                elif in_format == "File":
-                    widget = in_param.itemAtPosition(0, 1).widget()
-                    path = widget.text()
-                    try:
-                        tmp2 = self.parse_input_values(
-                            np.loadtxt(path, dtype=str).tolist()
-                        )
-                    except FileNotFoundError:
-                        self._window.logger.error(f"Selected input file not found.")
-                        continue
                 else:
                     raise Exception("Input selection is not implemented")
 
diff --git a/b_asic/signal_generator.py b/b_asic/signal_generator.py
index 27b12518651275b0e4ad8e2357b96d75da9752d0..69f7acbc16978655d24787c3aebd6474e5e5d05c 100644
--- a/b_asic/signal_generator.py
+++ b/b_asic/signal_generator.py
@@ -13,6 +13,7 @@ if you want more information.
 
 from math import pi, sin
 from numbers import Number
+from pathlib import Path
 from typing import Optional, Sequence
 
 import numpy as np
@@ -161,6 +162,31 @@ class ZeroPad(SignalGenerator):
         return f"ZeroPad({self._data})"
 
 
+class FromFile(SignalGenerator):
+    """
+    Signal generator that reads from file and pads a sequence with zeros.
+    File should be of type .txt or .csv and contain a single column vector
+    Parameters
+    ----------
+    path : string
+        Path to input file.
+    """
+
+    def __init__(self, path) -> None:
+        self._path = path
+        data = np.loadtxt(path, dtype=complex).tolist()
+        self._data = data
+        self._len = len(data)
+
+    def __call__(self, time: int) -> complex:
+        if 0 <= time < self._len:
+            return self._data[time]
+        return 0.0
+
+    def __repr__(self) -> str:
+        return f"FromFile({self._path!r})"
+
+
 class Sinusoid(SignalGenerator):
     """
     Signal generator that generates a sinusoid.
diff --git a/test/test_gui.py b/test/test_gui.py
index e8d16e3f3b9e1fa2a480da370a2e17f274d511f1..33639f09d2dc65f7ef98e5da18afba6216a362c7 100644
--- a/test/test_gui.py
+++ b/test/test_gui.py
@@ -148,6 +148,22 @@ def test_help_dialogs(qtbot):
     widget.exit_app()
 
 
+def test_simulate(qtbot, datadir):
+    # Smoke test to open up the "Simulate SFG" and run default simulation
+    # Should really test all different tests
+    widget = GUI.MainWindow()
+    qtbot.addWidget(widget)
+    widget._load_from_file(datadir.join('twotapfir.py'))
+    assert 'twotapfir' in widget.sfg_dict
+    widget.simulate_sfg()
+    qtbot.wait(100)
+    # widget.dialog.save_properties()
+    # qtbot.wait(100)
+    widget.dialog.close()
+
+    widget.exit_app()
+
+
 def test_properties_window_smoke_test(qtbot, datadir):
     # Smoke test to open up the properties window
     # Should really check that the contents are correct and changes works etc
@@ -159,9 +175,7 @@ def test_properties_window_smoke_test(qtbot, datadir):
     dragbutton = widget.operationDragDict[op]
     dragbutton.show_properties_window()
     assert dragbutton._properties_window.operation == dragbutton
-    qtbot.mouseClick(
-        dragbutton._properties_window.ok, QtCore.Qt.MouseButton.LeftButton
-    )
+    qtbot.mouseClick(dragbutton._properties_window.ok, QtCore.Qt.MouseButton.LeftButton)
     widget.exit_app()
 
 
@@ -179,9 +193,7 @@ def test_properties_window_change_name(qtbot, datadir):
     dragbutton.show_properties_window()
     assert dragbutton._properties_window.edit_name.text() == "cmul2"
     dragbutton._properties_window.edit_name.setText("cmul73")
-    qtbot.mouseClick(
-        dragbutton._properties_window.ok, QtCore.Qt.MouseButton.LeftButton
-    )
+    qtbot.mouseClick(dragbutton._properties_window.ok, QtCore.Qt.MouseButton.LeftButton)
     dragbutton._properties_window.save_properties()
     assert dragbutton.name == "cmul73"
     assert dragbutton.operation.name == "cmul73"
diff --git a/test/test_signal_generator.py b/test/test_signal_generator.py
index b982e6cc6530d4b04d9dc43a1187a1bd5dee2e30..b086ff069f98f863be3e73df0b90818aa2a7740e 100644
--- a/test/test_signal_generator.py
+++ b/test/test_signal_generator.py
@@ -1,3 +1,4 @@
+import os
 from math import sqrt
 
 import pytest
@@ -5,6 +6,7 @@ import pytest
 from b_asic.signal_generator import (
     Constant,
     Delay,
+    FromFile,
     Gaussian,
     Impulse,
     Sinusoid,
@@ -269,3 +271,17 @@ def test_division():
 
     assert str(g) == "Sinusoid(0.5, 0.25) / (0.5 * Step())"
     assert isinstance(g, _DivGenerator)
+
+
+def test_fromfile(datadir):
+    g = FromFile(datadir.join('input.csv'))
+    assert g(-1) == 0.0
+    assert g(0) == 0
+    assert g(1) == 1
+    assert g(2) == 0
+
+    with pytest.raises(FileNotFoundError, match="tset.py not found"):
+        g = FromFile(datadir.join('tset.py'))
+
+    with pytest.raises(ValueError, match="could not convert string"):
+        g = FromFile(datadir.join('bad.csv'))
diff --git a/test/test_signal_generator/bad.csv b/test/test_signal_generator/bad.csv
new file mode 100644
index 0000000000000000000000000000000000000000..94f8f3c931ba0182527997adcce7541032023315
--- /dev/null
+++ b/test/test_signal_generator/bad.csv
@@ -0,0 +1,2 @@
+0
+a
diff --git a/test/test_signal_generator/input.csv b/test/test_signal_generator/input.csv
new file mode 100644
index 0000000000000000000000000000000000000000..b0917c8e2523298b91f0612287acd0150219ca53
--- /dev/null
+++ b/test/test_signal_generator/input.csv
@@ -0,0 +1,5 @@
+0
+1
+0
+0
+0