diff --git a/src/main/java/de/neemann/digital/core/element/ElementAttributes.java b/src/main/java/de/neemann/digital/core/element/ElementAttributes.java
index 9cf5056d6..f67a57835 100644
--- a/src/main/java/de/neemann/digital/core/element/ElementAttributes.java
+++ b/src/main/java/de/neemann/digital/core/element/ElementAttributes.java
@@ -5,6 +5,7 @@
*/
package de.neemann.digital.core.element;
+import de.neemann.digital.FileLocator;
import de.neemann.digital.core.ValueFormatter;
import de.neemann.digital.hdl.hgs.HGSMap;
@@ -23,6 +24,7 @@ public class ElementAttributes implements HGSMap {
private HashMap attributes;
private transient ArrayList listeners;
private transient HashMap cache;
+ private transient File origin;
/**
* Creates a new instance
@@ -206,6 +208,19 @@ public class ElementAttributes implements HGSMap {
return attributes.isEmpty();
}
+ /**
+ * Gets a file stored in the map
+ *
+ * @param key the file key
+ * @return the file
+ */
+ public File getFile(Key key) {
+ File f = get(key);
+ if (origin != null)
+ f = new FileLocator(f).setBaseFile(origin).locate();
+ return f;
+ }
+
/**
* Gets a file stored directly in the map
*
@@ -215,8 +230,12 @@ public class ElementAttributes implements HGSMap {
public File getFile(String fileKey) {
if (attributes != null) {
Object f = attributes.get(fileKey);
- if (f != null)
- return new File(f.toString().trim());
+ if (f != null) {
+ File file = new File(f.toString().trim());
+ if (origin != null)
+ file = new FileLocator(file).setBaseFile(origin).locate();
+ return file;
+ }
}
return null;
}
@@ -347,4 +366,20 @@ public class ElementAttributes implements HGSMap {
return null;
return cache.remove(key);
}
+
+ /**
+ * Sets the origin of this data
+ *
+ * @param filename the file this data comes from
+ */
+ public void setOrigin(File filename) {
+ this.origin = filename;
+ }
+
+ /**
+ * @return the file this data comes from
+ */
+ public File getOrigin() {
+ return origin;
+ }
}
diff --git a/src/main/java/de/neemann/digital/core/element/Keys.java b/src/main/java/de/neemann/digital/core/element/Keys.java
index ba4eed550..865e8cd83 100644
--- a/src/main/java/de/neemann/digital/core/element/Keys.java
+++ b/src/main/java/de/neemann/digital/core/element/Keys.java
@@ -727,6 +727,11 @@ public final class Keys {
*/
public static final Key.LongString EXTERNAL_CODE
= new Key.LongString("Code").setRows(30).setColumns(80).setLineNumbers(true);
+ /**
+ * The code to be executed by the external process
+ */
+ public static final Key.KeyFile EXTERNAL_CODE_FILE
+ = new Key.KeyFile("CodeFile", new File(""));
/**
* Path to ghdl
diff --git a/src/main/java/de/neemann/digital/core/extern/Application.java b/src/main/java/de/neemann/digital/core/extern/Application.java
index 6829d1886..ba3af8fa3 100644
--- a/src/main/java/de/neemann/digital/core/extern/Application.java
+++ b/src/main/java/de/neemann/digital/core/extern/Application.java
@@ -6,15 +6,49 @@
package de.neemann.digital.core.extern;
import de.neemann.digital.core.element.ElementAttributes;
+import de.neemann.digital.core.element.Keys;
import de.neemann.digital.core.extern.handler.ProcessInterface;
+import java.io.File;
import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
/**
* Represents an application
*/
public interface Application {
+ /**
+ * Extract the code from the attributes.
+ * The code is either stored directly or there is a file given.
+ *
+ * @param attr the attributes
+ * @return the code
+ * @throws IOException IOException
+ */
+ static String getCode(ElementAttributes attr) throws IOException {
+ if (attr.contains(Keys.EXTERNAL_CODE))
+ return attr.get(Keys.EXTERNAL_CODE);
+
+ if (attr.contains(Keys.EXTERNAL_CODE_FILE))
+ return readCode(attr.getFile(Keys.EXTERNAL_CODE_FILE));
+
+ return "";
+ }
+
+ /**
+ * Reads the code from a file
+ *
+ * @param file the file
+ * @return the code
+ * @throws IOException IOException
+ */
+ static String readCode(File file) throws IOException {
+ byte[] data = Files.readAllBytes(file.toPath());
+ return new String(data, StandardCharsets.UTF_8);
+ }
+
/**
* The available types of applications
*/
diff --git a/src/main/java/de/neemann/digital/core/extern/ApplicationVHDLStdIO.java b/src/main/java/de/neemann/digital/core/extern/ApplicationVHDLStdIO.java
index 4d9c00571..dfd5f7d70 100644
--- a/src/main/java/de/neemann/digital/core/extern/ApplicationVHDLStdIO.java
+++ b/src/main/java/de/neemann/digital/core/extern/ApplicationVHDLStdIO.java
@@ -74,9 +74,9 @@ public abstract class ApplicationVHDLStdIO implements Application {
@Override
public boolean ensureConsistency(ElementAttributes attributes) {
- String code = attributes.get(Keys.EXTERNAL_CODE);
- VHDLTokenizer st = new VHDLTokenizer(new StringReader(code));
try {
+ String code = Application.getCode(attributes);
+ VHDLTokenizer st = new VHDLTokenizer(new StringReader(code));
while (!st.value().equalsIgnoreCase("entity"))
st.next();
diff --git a/src/main/java/de/neemann/digital/core/extern/ApplicationVerilogStdIO.java b/src/main/java/de/neemann/digital/core/extern/ApplicationVerilogStdIO.java
index 2c2c40106..1e3517e28 100644
--- a/src/main/java/de/neemann/digital/core/extern/ApplicationVerilogStdIO.java
+++ b/src/main/java/de/neemann/digital/core/extern/ApplicationVerilogStdIO.java
@@ -82,10 +82,10 @@ public abstract class ApplicationVerilogStdIO implements Application {
@Override
public boolean ensureConsistency(ElementAttributes attributes) {
- String code = attributes.get(Keys.EXTERNAL_CODE);
- VerilogTokenizer st = new VerilogTokenizer(new StringReader(code));
-
try {
+ String code = Application.getCode(attributes);
+ VerilogTokenizer st = new VerilogTokenizer(new StringReader(code));
+
PortDefinition in;
PortDefinition out;
String label;
diff --git a/src/main/java/de/neemann/digital/core/extern/External.java b/src/main/java/de/neemann/digital/core/extern/External.java
index 0a175cffc..607cfc134 100644
--- a/src/main/java/de/neemann/digital/core/extern/External.java
+++ b/src/main/java/de/neemann/digital/core/extern/External.java
@@ -49,8 +49,8 @@ public class External extends Node implements Element {
private final PortDefinition outs;
private final ElementAttributes attr;
private final ObservableValues outputs;
- private final String code;
private final String label;
+ private String code;
private ObservableValues inputs;
private ProcessInterface processInterface;
@@ -103,6 +103,9 @@ public class External extends Node implements Element {
@Override
public void init(Model model) throws NodeException {
+ if (label.isEmpty())
+ throw new NodeException(Lang.get("err_emptyLabelIsNotAllowed"));
+
try {
Application app = Application.create(type, attr);
if (app == null)
@@ -123,4 +126,13 @@ public class External extends Node implements Element {
}
}, ModelEventType.CLOSED);
}
+
+ /**
+ * Sets the code to use.
+ *
+ * @param code the code
+ */
+ public void setCode(String code) {
+ this.code = code;
+ }
}
diff --git a/src/main/java/de/neemann/digital/core/extern/ExternalFile.java b/src/main/java/de/neemann/digital/core/extern/ExternalFile.java
new file mode 100644
index 000000000..a2d454737
--- /dev/null
+++ b/src/main/java/de/neemann/digital/core/extern/ExternalFile.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2018 Helmut Neemann.
+ * Use of this source code is governed by the GPL v3 license
+ * that can be found in the LICENSE file.
+ */
+package de.neemann.digital.core.extern;
+
+import de.neemann.digital.core.Model;
+import de.neemann.digital.core.NodeException;
+import de.neemann.digital.core.element.*;
+import de.neemann.digital.lang.Lang;
+
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * The external component
+ */
+public class ExternalFile extends External {
+
+ /**
+ * The external component description
+ */
+ public static final ElementTypeDescription DESCRIPTION = new ElementTypeDescription(ExternalFile.class) {
+ @Override
+ public PinDescriptions getInputDescription(ElementAttributes elementAttributes) {
+ return new PortDefinition(elementAttributes.get(Keys.EXTERNAL_INPUTS)).getPinDescriptions(PinDescription.Direction.input);
+ }
+
+ @Override
+ public PinDescriptions getOutputDescriptions(ElementAttributes elementAttributes) {
+ return new PortDefinition(elementAttributes.get(Keys.EXTERNAL_OUTPUTS)).getPinDescriptions(PinDescription.Direction.output);
+ }
+ }
+ .addAttribute(Keys.LABEL)
+ .addAttribute(Keys.WIDTH)
+ .addAttribute(Keys.EXTERNAL_INPUTS)
+ .addAttribute(Keys.EXTERNAL_OUTPUTS)
+ .addAttribute(Keys.EXTERNAL_CODE_FILE)
+ .addAttribute(Keys.APPLICATION_TYPE)
+ .addAttribute(Keys.GHDL_OPTIONS)
+ .addAttribute(Keys.IVERILOG_OPTIONS)
+ .supportsHDL();
+
+ private final File file;
+
+ /**
+ * Creates a new instance
+ *
+ * @param attr the elements attributes
+ */
+ public ExternalFile(ElementAttributes attr) {
+ super(attr);
+ file = attr.getFile(Keys.EXTERNAL_CODE_FILE);
+ }
+
+ @Override
+ public void init(Model model) throws NodeException {
+ try {
+ setCode(Application.readCode(file));
+ } catch (IOException e) {
+ throw new NodeException(Lang.get("err_errorLoadingHDLFile_N", file));
+ }
+ super.init(model);
+ }
+}
diff --git a/src/main/java/de/neemann/digital/draw/elements/Circuit.java b/src/main/java/de/neemann/digital/draw/elements/Circuit.java
index 61bee0b52..d0f1b3da9 100644
--- a/src/main/java/de/neemann/digital/draw/elements/Circuit.java
+++ b/src/main/java/de/neemann/digital/draw/elements/Circuit.java
@@ -118,6 +118,8 @@ public class Circuit implements Copyable {
public static Circuit loadCircuit(File filename, ShapeFactory shapeFactory) throws IOException {
final Circuit circuit = loadCircuit(new FileInputStream(filename), shapeFactory);
circuit.origin = filename;
+ for (VisualElement ve : circuit.visualElements)
+ ve.setOrigin(filename);
return circuit;
}
@@ -162,6 +164,8 @@ public class Circuit implements Copyable {
*/
public void save(File filename) throws IOException {
save(new FileOutputStream(filename));
+ for (VisualElement ve : visualElements)
+ ve.setOrigin(filename);
}
/**
diff --git a/src/main/java/de/neemann/digital/draw/elements/VisualElement.java b/src/main/java/de/neemann/digital/draw/elements/VisualElement.java
index 49844fdf9..64ac43f3e 100644
--- a/src/main/java/de/neemann/digital/draw/elements/VisualElement.java
+++ b/src/main/java/de/neemann/digital/draw/elements/VisualElement.java
@@ -16,6 +16,7 @@ import de.neemann.gui.Screen;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
+import java.io.File;
import static de.neemann.digital.draw.shapes.GenericShape.SIZE;
import static de.neemann.digital.draw.shapes.GenericShape.SIZE2;
@@ -491,4 +492,12 @@ public class VisualElement implements Drawable, Movable, AttributeListener {
return null;
}
+ /**
+ * Sets the file this data comes from
+ *
+ * @param filename the origin of this data
+ */
+ public void setOrigin(File filename) {
+ elementAttributes.setOrigin(filename);
+ }
}
diff --git a/src/main/java/de/neemann/digital/draw/library/ElementLibrary.java b/src/main/java/de/neemann/digital/draw/library/ElementLibrary.java
index 9e1ef1d69..b300adb1a 100644
--- a/src/main/java/de/neemann/digital/draw/library/ElementLibrary.java
+++ b/src/main/java/de/neemann/digital/draw/library/ElementLibrary.java
@@ -12,6 +12,7 @@ import de.neemann.digital.core.element.ElementAttributes;
import de.neemann.digital.core.element.ElementTypeDescription;
import de.neemann.digital.core.element.Keys;
import de.neemann.digital.core.extern.External;
+import de.neemann.digital.core.extern.ExternalFile;
import de.neemann.digital.core.flipflops.*;
import de.neemann.digital.core.io.*;
import de.neemann.digital.core.memory.*;
@@ -236,6 +237,7 @@ public class ElementLibrary implements Iterable
.add(Stop.DESCRIPTION)
.add(AsyncSeq.DESCRIPTION)
.add(External.DESCRIPTION)
+ .add(ExternalFile.DESCRIPTION)
.add(PinControl.DESCRIPTION));
addExternalJarComponents(jarFile);
diff --git a/src/main/java/de/neemann/digital/gui/components/EditorFactory.java b/src/main/java/de/neemann/digital/gui/components/EditorFactory.java
index 702bab09f..41082e27b 100644
--- a/src/main/java/de/neemann/digital/gui/components/EditorFactory.java
+++ b/src/main/java/de/neemann/digital/gui/components/EditorFactory.java
@@ -821,9 +821,9 @@ public final class EditorFactory {
PortDefinition ins = new PortDefinition(elementAttributes.get(Keys.EXTERNAL_INPUTS));
PortDefinition outs = new PortDefinition(elementAttributes.get(Keys.EXTERNAL_OUTPUTS));
String label = elementAttributes.getLabel();
- String code = elementAttributes.get(Keys.EXTERNAL_CODE);
-
try {
+ String code = Application.getCode(elementAttributes);
+
String message = app.checkCode(label, code, ins, outs);
if (message != null && !message.isEmpty()) {
createError(consistent, Lang.get("msg_checkResult") + "\n\n" + message).show(getAttributeDialog());
diff --git a/src/main/java/de/neemann/digital/hdl/hgs/Context.java b/src/main/java/de/neemann/digital/hdl/hgs/Context.java
index a59095808..1e87c5339 100644
--- a/src/main/java/de/neemann/digital/hdl/hgs/Context.java
+++ b/src/main/java/de/neemann/digital/hdl/hgs/Context.java
@@ -7,6 +7,8 @@ package de.neemann.digital.hdl.hgs;
import de.neemann.digital.FileLocator;
import de.neemann.digital.core.Bits;
+import de.neemann.digital.core.element.ElementAttributes;
+import de.neemann.digital.core.extern.Application;
import de.neemann.digital.core.memory.DataField;
import de.neemann.digital.core.memory.importer.Importer;
import de.neemann.digital.hdl.hgs.function.Func;
@@ -55,6 +57,7 @@ public class Context implements HGSMap {
BUILT_IN.put("splitString", new FunctionSplitString());
BUILT_IN.put("identifier", new FunctionIdentifier());
BUILT_IN.put("loadHex", new FunctionLoadHex());
+ BUILT_IN.put("loadFile", new FunctionLoadFile());
BUILT_IN.put("sizeOf", new Func(1, args -> Value.toArray(args[0]).hgsArraySize()));
}
@@ -677,6 +680,25 @@ public class Context implements HGSMap {
}
}
+ private static final class FunctionLoadFile extends InnerFunction {
+ private FunctionLoadFile() {
+ super(1);
+ }
+
+ @Override
+ public Object call(Context c, ArrayList args) throws HGSEvalException {
+ File f = new File(args.get(0).value(c).toString());
+ File origin = ((ElementAttributes) c.map.get("elem")).getOrigin();
+ if (origin != null)
+ f = new FileLocator(f).setBaseFile(origin).locate();
+ try {
+ return Application.readCode(f);
+ } catch (IOException e) {
+ throw new HGSEvalException("error reading the file " + f.getPath(), e);
+ }
+ }
+ }
+
@Override
public boolean equals(Object o) {
if (this == o) return true;
diff --git a/src/main/resources/lang/lang_de.xml b/src/main/resources/lang/lang_de.xml
index eec8170b8..d7b276414 100644
--- a/src/main/resources/lang/lang_de.xml
+++ b/src/main/resources/lang/lang_de.xml
@@ -1009,6 +1009,14 @@
Wird verwendet, um das Verhalten eines Elements mit einer Hardwarebeschreibungssprache wie VHDL oder
Verilog zu beschreiben. Die eigentliche Simulation des Verhaltens muss mit einem externen Simulator erfolgen.
Zur Zeit wird nur der VHDL-Simulator ghdl und der Verilog-Simulator Icarus Verilog unterstützt.
+ Das Label der Komponente muss mit dem Namen der Entity bzw. des Moduls übereinstimmen!
+
+ Extern Datei
+ Element zur Anbindung von externen Programmen zur Berechnung der Logik.
+ Wird verwendet, um das Verhalten eines Elements mit einer Hardwarebeschreibungssprache wie VHDL oder
+ Verilog zu beschreiben. Die eigentliche Simulation des Verhaltens muss mit einem externen Simulator erfolgen.
+ Zur Zeit wird nur der VHDL-Simulator ghdl und der Verilog-Simulator Icarus Verilog unterstützt.
+ Das Label der Komponente muss mit dem Namen der Entity bzw. des Moduls übereinstimmen!
Diode
@@ -1183,6 +1191,9 @@ Sind evtl. die Namen der Variablen nicht eindeutig?
Der Verilog Simulator Icarus scheint nicht installiert zu sein. Installieren Sie Icarus (http://iverilog.icarus.com/) und versuchen Sie es erneut. Sollte es immer noch Probleme geben, überprüfen Sie den Pfad zur ausfühbaren iverilog-Datei in den Digital-Einstellungen.
+ Fehler beim Laden der HDL-Datei {0}
+ Eine leere Bezeichnung is nicht erlaubt!
+
Fehler bei der Analyse der Schaltung: {0}
Jedes ROM braucht eine eindeutige Bezeichnung um exportiert zu werden!
Jede LUT braucht eine eindeutige Bezeichnung um exportiert zu werden!
@@ -1486,6 +1497,8 @@ Sind evtl. die Namen der Variablen nicht eindeutig?
Programmcode
Der Programmcode welcher ausgeführt werden soll.
+ Programmcode
+ Datei mit dem Programmcode welcher ausgeführt werden soll.
Optionen
GHDL
Pfad der ausführbaren ghdl-Datei. Nur wichtig, wenn ghdl zur Interpretation von
diff --git a/src/main/resources/lang/lang_en.xml b/src/main/resources/lang/lang_en.xml
index 890264092..32858e76f 100644
--- a/src/main/resources/lang/lang_en.xml
+++ b/src/main/resources/lang/lang_en.xml
@@ -984,6 +984,14 @@
Is used to specify the behaviour of a component by VHDL or Verilog.
The actual simulation of the behavior must be done with an external simulator.
At present only the VHDL simulator ghdl and the verilog simulator Icarus Verilog are supported.
+ The label of the component must match the name of the entity or module!
+
+ External File
+ Component to execute an external process to calculate the logic function.
+ Is used to specify the behaviour of a component by VHDL or Verilog.
+ The actual simulation of the behavior must be done with an external simulator.
+ At present only the VHDL simulator ghdl and the verilog simulator Icarus Verilog are supported.
+ The label of the component must match the name of the entity or module!
Diode
@@ -1171,6 +1179,9 @@
try again.
If there are still problems, check the path to the IVerilog executable in the Digital settings.
+ Error loading the HDL file {0}
+ A empty label is not allowed!
+
Error analysing the circuit: {0}
Every ROM needs a unique label to be exported!
Every LUT needs a unique label to be exported!
@@ -1477,6 +1488,8 @@
Program code
The program code to be executed by the external application.
+ Program code
+ The file containing the program code to be executed by the external application.
Options
GHDL
Path to the executable ghdl file. Only necessary if you want to use ghdl to simulate
diff --git a/src/main/resources/verilog/DIG_ExternalFile.v b/src/main/resources/verilog/DIG_ExternalFile.v
new file mode 100644
index 000000000..98d3780d1
--- /dev/null
+++ b/src/main/resources/verilog/DIG_ExternalFile.v
@@ -0,0 +1,8 @@
+=loadFile(elem.CodeFile);
+
+ moduleName=elem.Label;
+
+ if (elem.applicationType!="IVERILOG")
+ panic("err_canOnlyExportExternalVerilog");
+
+?>
\ No newline at end of file
diff --git a/src/main/resources/vhdl/DIG_ExternalFile.tem b/src/main/resources/vhdl/DIG_ExternalFile.tem
new file mode 100644
index 000000000..68287214f
--- /dev/null
+++ b/src/main/resources/vhdl/DIG_ExternalFile.tem
@@ -0,0 +1,8 @@
+=loadFile(elem.CodeFile);
+
+ entityName:=elem.Label;
+
+ if (elem.applicationType!="GHDL")
+ panic("err_canOnlyExportExternalVHDL");
+
+?>
\ No newline at end of file
diff --git a/src/test/java/de/neemann/digital/hdl/verilog2/VerilogSimulatorTest.java b/src/test/java/de/neemann/digital/hdl/verilog2/VerilogSimulatorTest.java
index fd60c3617..75062c662 100644
--- a/src/test/java/de/neemann/digital/hdl/verilog2/VerilogSimulatorTest.java
+++ b/src/test/java/de/neemann/digital/hdl/verilog2/VerilogSimulatorTest.java
@@ -129,7 +129,7 @@ public class VerilogSimulatorTest extends TestCase {
// check simulation in Digital
new TestExamples().check(f);
}).scan(source);
- assertEquals(4, tested);
+ assertEquals(5, tested);
}
}
diff --git a/src/test/java/de/neemann/digital/hdl/vhdl2/VHDLSimulatorTest.java b/src/test/java/de/neemann/digital/hdl/vhdl2/VHDLSimulatorTest.java
index a4002f1da..159b6d18c 100644
--- a/src/test/java/de/neemann/digital/hdl/vhdl2/VHDLSimulatorTest.java
+++ b/src/test/java/de/neemann/digital/hdl/vhdl2/VHDLSimulatorTest.java
@@ -123,7 +123,7 @@ public class VHDLSimulatorTest extends TestCase {
// check simulation in Digital
new TestExamples().check(f);
}).noOutput().scan(source);
- assertEquals(4, tested);
+ assertEquals(5, tested);
}
diff --git a/src/test/resources/dig/external/ghdl/ghdlFile.dig b/src/test/resources/dig/external/ghdl/ghdlFile.dig
new file mode 100644
index 000000000..365129304
--- /dev/null
+++ b/src/test/resources/dig/external/ghdl/ghdlFile.dig
@@ -0,0 +1,175 @@
+
+
+ 1
+
+
+
+ In
+
+
+ Label
+ A
+
+
+ Bits
+ 4
+
+
+ InDefault
+
+
+
+
+
+
+ In
+
+
+ Label
+ B
+
+
+ Bits
+ 4
+
+
+ InDefault
+
+
+
+
+
+
+ Out
+
+
+ Label
+ S
+
+
+ Bits
+ 4
+
+
+
+
+
+ In
+
+
+ Label
+ C_i
+
+
+ InDefault
+
+
+
+
+
+
+ Out
+
+
+ Label
+ C_o
+
+
+
+
+
+ Testcase
+
+
+ Testdata
+
+ A B C_i C_o S
+
+loop(a,16)
+loop(b,16)
+ let sum=a+b;
+ (a) (b) 0 (sum>>4) (sum)
+ (a) (b) 1 ((sum+1)>>4) (sum+1)
+end loop
+end loop
+
+
+
+
+
+
+
+ ExternalFile
+
+
+ applicationType
+ GHDL
+
+
+ Label
+ add
+
+
+ externalInputs
+ a:4,b:4,c_i
+
+
+ externalOutputs
+ s:4,c_o
+
+
+ CodeFile
+ /home/hneemann/Dokumente/Java/digital/src/test/resources/dig/external/ghdl/ghdlFile.vhdl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/test/resources/dig/external/ghdl/ghdlFile.vhdl b/src/test/resources/dig/external/ghdl/ghdlFile.vhdl
new file mode 100644
index 000000000..2dd9c2ed0
--- /dev/null
+++ b/src/test/resources/dig/external/ghdl/ghdlFile.vhdl
@@ -0,0 +1,21 @@
+LIBRARY ieee;
+USE ieee.std_logic_1164.all;
+USE ieee.std_logic_unsigned.all;
+
+entity add is
+ port (
+ a: in std_logic_vector(3 downto 0);
+ b: in std_logic_vector(3 downto 0);
+ c_i: in std_logic;
+ s: out std_logic_vector(3 downto 0);
+ c_o: out std_logic );
+end add;
+
+architecture add_arch of add is
+ signal temp : std_logic_vector(4 downto 0);
+begin
+ temp <= ('0' & a) + b + c_i;
+
+ s <= temp(3 downto 0);
+ c_o <= temp(4);
+end add_arch;
diff --git a/src/test/resources/dig/external/verilog/verilogFile.dig b/src/test/resources/dig/external/verilog/verilogFile.dig
new file mode 100644
index 000000000..42a7cc57a
--- /dev/null
+++ b/src/test/resources/dig/external/verilog/verilogFile.dig
@@ -0,0 +1,173 @@
+
+
+ 1
+
+
+
+ In
+
+
+ Label
+ A
+
+
+ Bits
+ 4
+
+
+ InDefault
+
+
+
+
+
+
+ In
+
+
+ Label
+ B
+
+
+ Bits
+ 4
+
+
+ InDefault
+
+
+
+
+
+
+ Out
+
+
+ Label
+ S
+
+
+ Bits
+ 4
+
+
+
+
+
+ In
+
+
+ Label
+ C_i
+
+
+ InDefault
+
+
+
+
+
+
+ Out
+
+
+ Label
+ C_o
+
+
+
+
+
+ Testcase
+
+
+ Testdata
+
+ A B C_i C_o S
+
+loop(a,16)
+loop(b,16)
+ (a) (b) 0 ((a+b)>>4) (a+b)
+end loop
+end loop
+
+
+
+
+
+
+
+ ExternalFile
+
+
+ Label
+ add
+
+
+ applicationType
+ IVERILOG
+
+
+ externalInputs
+ a:4,b:4,c_i
+
+
+ externalOutputs
+ s:4,c_o
+
+
+ CodeFile
+ /home/hneemann/Dokumente/Java/digital/src/test/resources/dig/external/verilog/verilogFile.v
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/test/resources/dig/external/verilog/verilogFile.v b/src/test/resources/dig/external/verilog/verilogFile.v
new file mode 100644
index 000000000..8492bb47e
--- /dev/null
+++ b/src/test/resources/dig/external/verilog/verilogFile.v
@@ -0,0 +1,14 @@
+module add
+(
+ input [3:0] a,
+ input [3:0] b,
+ input c_i,
+ output [3:0] s,
+ output c_o
+);
+ wire [4:0] temp;
+
+ assign temp = a + b + c_i;
+ assign s = temp [3:0];
+ assign c_o = temp[4];
+endmodule
\ No newline at end of file