mirror of
https://github.com/hneemann/Digital.git
synced 2025-09-25 22:18:48 -04:00
adds a external file based component, see #713
This commit is contained in:
parent
074ea08fe2
commit
96ca9783ab
@ -5,6 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
package de.neemann.digital.core.element;
|
package de.neemann.digital.core.element;
|
||||||
|
|
||||||
|
import de.neemann.digital.FileLocator;
|
||||||
import de.neemann.digital.core.ValueFormatter;
|
import de.neemann.digital.core.ValueFormatter;
|
||||||
import de.neemann.digital.hdl.hgs.HGSMap;
|
import de.neemann.digital.hdl.hgs.HGSMap;
|
||||||
|
|
||||||
@ -23,6 +24,7 @@ public class ElementAttributes implements HGSMap {
|
|||||||
private HashMap<String, Object> attributes;
|
private HashMap<String, Object> attributes;
|
||||||
private transient ArrayList<AttributeListener> listeners;
|
private transient ArrayList<AttributeListener> listeners;
|
||||||
private transient HashMap<String, Object> cache;
|
private transient HashMap<String, Object> cache;
|
||||||
|
private transient File origin;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new instance
|
* Creates a new instance
|
||||||
@ -206,6 +208,19 @@ public class ElementAttributes implements HGSMap {
|
|||||||
return attributes.isEmpty();
|
return attributes.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a file stored in the map
|
||||||
|
*
|
||||||
|
* @param key the file key
|
||||||
|
* @return the file
|
||||||
|
*/
|
||||||
|
public File getFile(Key<File> 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
|
* Gets a file stored directly in the map
|
||||||
*
|
*
|
||||||
@ -215,8 +230,12 @@ public class ElementAttributes implements HGSMap {
|
|||||||
public File getFile(String fileKey) {
|
public File getFile(String fileKey) {
|
||||||
if (attributes != null) {
|
if (attributes != null) {
|
||||||
Object f = attributes.get(fileKey);
|
Object f = attributes.get(fileKey);
|
||||||
if (f != null)
|
if (f != null) {
|
||||||
return new File(f.toString().trim());
|
File file = new File(f.toString().trim());
|
||||||
|
if (origin != null)
|
||||||
|
file = new FileLocator(file).setBaseFile(origin).locate();
|
||||||
|
return file;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -347,4 +366,20 @@ public class ElementAttributes implements HGSMap {
|
|||||||
return null;
|
return null;
|
||||||
return cache.remove(key);
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -727,6 +727,11 @@ public final class Keys {
|
|||||||
*/
|
*/
|
||||||
public static final Key.LongString EXTERNAL_CODE
|
public static final Key.LongString EXTERNAL_CODE
|
||||||
= new Key.LongString("Code").setRows(30).setColumns(80).setLineNumbers(true);
|
= 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
|
* Path to ghdl
|
||||||
|
@ -6,15 +6,49 @@
|
|||||||
package de.neemann.digital.core.extern;
|
package de.neemann.digital.core.extern;
|
||||||
|
|
||||||
import de.neemann.digital.core.element.ElementAttributes;
|
import de.neemann.digital.core.element.ElementAttributes;
|
||||||
|
import de.neemann.digital.core.element.Keys;
|
||||||
import de.neemann.digital.core.extern.handler.ProcessInterface;
|
import de.neemann.digital.core.extern.handler.ProcessInterface;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents an application
|
* Represents an application
|
||||||
*/
|
*/
|
||||||
public interface 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
|
* The available types of applications
|
||||||
*/
|
*/
|
||||||
|
@ -74,9 +74,9 @@ public abstract class ApplicationVHDLStdIO implements Application {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean ensureConsistency(ElementAttributes attributes) {
|
public boolean ensureConsistency(ElementAttributes attributes) {
|
||||||
String code = attributes.get(Keys.EXTERNAL_CODE);
|
|
||||||
VHDLTokenizer st = new VHDLTokenizer(new StringReader(code));
|
|
||||||
try {
|
try {
|
||||||
|
String code = Application.getCode(attributes);
|
||||||
|
VHDLTokenizer st = new VHDLTokenizer(new StringReader(code));
|
||||||
while (!st.value().equalsIgnoreCase("entity"))
|
while (!st.value().equalsIgnoreCase("entity"))
|
||||||
st.next();
|
st.next();
|
||||||
|
|
||||||
|
@ -82,10 +82,10 @@ public abstract class ApplicationVerilogStdIO implements Application {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean ensureConsistency(ElementAttributes attributes) {
|
public boolean ensureConsistency(ElementAttributes attributes) {
|
||||||
String code = attributes.get(Keys.EXTERNAL_CODE);
|
|
||||||
VerilogTokenizer st = new VerilogTokenizer(new StringReader(code));
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
String code = Application.getCode(attributes);
|
||||||
|
VerilogTokenizer st = new VerilogTokenizer(new StringReader(code));
|
||||||
|
|
||||||
PortDefinition in;
|
PortDefinition in;
|
||||||
PortDefinition out;
|
PortDefinition out;
|
||||||
String label;
|
String label;
|
||||||
|
@ -49,8 +49,8 @@ public class External extends Node implements Element {
|
|||||||
private final PortDefinition outs;
|
private final PortDefinition outs;
|
||||||
private final ElementAttributes attr;
|
private final ElementAttributes attr;
|
||||||
private final ObservableValues outputs;
|
private final ObservableValues outputs;
|
||||||
private final String code;
|
|
||||||
private final String label;
|
private final String label;
|
||||||
|
private String code;
|
||||||
private ObservableValues inputs;
|
private ObservableValues inputs;
|
||||||
private ProcessInterface processInterface;
|
private ProcessInterface processInterface;
|
||||||
|
|
||||||
@ -103,6 +103,9 @@ public class External extends Node implements Element {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init(Model model) throws NodeException {
|
public void init(Model model) throws NodeException {
|
||||||
|
if (label.isEmpty())
|
||||||
|
throw new NodeException(Lang.get("err_emptyLabelIsNotAllowed"));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Application app = Application.create(type, attr);
|
Application app = Application.create(type, attr);
|
||||||
if (app == null)
|
if (app == null)
|
||||||
@ -123,4 +126,13 @@ public class External extends Node implements Element {
|
|||||||
}
|
}
|
||||||
}, ModelEventType.CLOSED);
|
}, ModelEventType.CLOSED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the code to use.
|
||||||
|
*
|
||||||
|
* @param code the code
|
||||||
|
*/
|
||||||
|
public void setCode(String code) {
|
||||||
|
this.code = code;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
66
src/main/java/de/neemann/digital/core/extern/ExternalFile.java
vendored
Normal file
66
src/main/java/de/neemann/digital/core/extern/ExternalFile.java
vendored
Normal file
@ -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);
|
||||||
|
}
|
||||||
|
}
|
@ -118,6 +118,8 @@ public class Circuit implements Copyable<Circuit> {
|
|||||||
public static Circuit loadCircuit(File filename, ShapeFactory shapeFactory) throws IOException {
|
public static Circuit loadCircuit(File filename, ShapeFactory shapeFactory) throws IOException {
|
||||||
final Circuit circuit = loadCircuit(new FileInputStream(filename), shapeFactory);
|
final Circuit circuit = loadCircuit(new FileInputStream(filename), shapeFactory);
|
||||||
circuit.origin = filename;
|
circuit.origin = filename;
|
||||||
|
for (VisualElement ve : circuit.visualElements)
|
||||||
|
ve.setOrigin(filename);
|
||||||
return circuit;
|
return circuit;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,6 +164,8 @@ public class Circuit implements Copyable<Circuit> {
|
|||||||
*/
|
*/
|
||||||
public void save(File filename) throws IOException {
|
public void save(File filename) throws IOException {
|
||||||
save(new FileOutputStream(filename));
|
save(new FileOutputStream(filename));
|
||||||
|
for (VisualElement ve : visualElements)
|
||||||
|
ve.setOrigin(filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -16,6 +16,7 @@ import de.neemann.gui.Screen;
|
|||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.awt.image.BufferedImage;
|
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.SIZE;
|
||||||
import static de.neemann.digital.draw.shapes.GenericShape.SIZE2;
|
import static de.neemann.digital.draw.shapes.GenericShape.SIZE2;
|
||||||
@ -491,4 +492,12 @@ public class VisualElement implements Drawable, Movable, AttributeListener {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the file this data comes from
|
||||||
|
*
|
||||||
|
* @param filename the origin of this data
|
||||||
|
*/
|
||||||
|
public void setOrigin(File filename) {
|
||||||
|
elementAttributes.setOrigin(filename);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ import de.neemann.digital.core.element.ElementAttributes;
|
|||||||
import de.neemann.digital.core.element.ElementTypeDescription;
|
import de.neemann.digital.core.element.ElementTypeDescription;
|
||||||
import de.neemann.digital.core.element.Keys;
|
import de.neemann.digital.core.element.Keys;
|
||||||
import de.neemann.digital.core.extern.External;
|
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.flipflops.*;
|
||||||
import de.neemann.digital.core.io.*;
|
import de.neemann.digital.core.io.*;
|
||||||
import de.neemann.digital.core.memory.*;
|
import de.neemann.digital.core.memory.*;
|
||||||
@ -236,6 +237,7 @@ public class ElementLibrary implements Iterable<ElementLibrary.ElementContainer>
|
|||||||
.add(Stop.DESCRIPTION)
|
.add(Stop.DESCRIPTION)
|
||||||
.add(AsyncSeq.DESCRIPTION)
|
.add(AsyncSeq.DESCRIPTION)
|
||||||
.add(External.DESCRIPTION)
|
.add(External.DESCRIPTION)
|
||||||
|
.add(ExternalFile.DESCRIPTION)
|
||||||
.add(PinControl.DESCRIPTION));
|
.add(PinControl.DESCRIPTION));
|
||||||
|
|
||||||
addExternalJarComponents(jarFile);
|
addExternalJarComponents(jarFile);
|
||||||
|
@ -821,9 +821,9 @@ public final class EditorFactory {
|
|||||||
PortDefinition ins = new PortDefinition(elementAttributes.get(Keys.EXTERNAL_INPUTS));
|
PortDefinition ins = new PortDefinition(elementAttributes.get(Keys.EXTERNAL_INPUTS));
|
||||||
PortDefinition outs = new PortDefinition(elementAttributes.get(Keys.EXTERNAL_OUTPUTS));
|
PortDefinition outs = new PortDefinition(elementAttributes.get(Keys.EXTERNAL_OUTPUTS));
|
||||||
String label = elementAttributes.getLabel();
|
String label = elementAttributes.getLabel();
|
||||||
String code = elementAttributes.get(Keys.EXTERNAL_CODE);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
String code = Application.getCode(elementAttributes);
|
||||||
|
|
||||||
String message = app.checkCode(label, code, ins, outs);
|
String message = app.checkCode(label, code, ins, outs);
|
||||||
if (message != null && !message.isEmpty()) {
|
if (message != null && !message.isEmpty()) {
|
||||||
createError(consistent, Lang.get("msg_checkResult") + "\n\n" + message).show(getAttributeDialog());
|
createError(consistent, Lang.get("msg_checkResult") + "\n\n" + message).show(getAttributeDialog());
|
||||||
|
@ -7,6 +7,8 @@ package de.neemann.digital.hdl.hgs;
|
|||||||
|
|
||||||
import de.neemann.digital.FileLocator;
|
import de.neemann.digital.FileLocator;
|
||||||
import de.neemann.digital.core.Bits;
|
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.DataField;
|
||||||
import de.neemann.digital.core.memory.importer.Importer;
|
import de.neemann.digital.core.memory.importer.Importer;
|
||||||
import de.neemann.digital.hdl.hgs.function.Func;
|
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("splitString", new FunctionSplitString());
|
||||||
BUILT_IN.put("identifier", new FunctionIdentifier());
|
BUILT_IN.put("identifier", new FunctionIdentifier());
|
||||||
BUILT_IN.put("loadHex", new FunctionLoadHex());
|
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()));
|
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<Expression> 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
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
if (this == o) return true;
|
if (this == o) return true;
|
||||||
|
@ -1009,6 +1009,14 @@
|
|||||||
Wird verwendet, um das Verhalten eines Elements mit einer Hardwarebeschreibungssprache wie VHDL oder
|
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.
|
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.
|
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!
|
||||||
|
</string>
|
||||||
|
<string name="elem_ExternalFile">Extern Datei</string>
|
||||||
|
<string name="elem_ExternalFile_tt">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!
|
||||||
</string>
|
</string>
|
||||||
|
|
||||||
<string name="elem_Diode">Diode</string>
|
<string name="elem_Diode">Diode</string>
|
||||||
@ -1183,6 +1191,9 @@ Sind evtl. die Namen der Variablen nicht eindeutig?</string>
|
|||||||
<string name="err_iverilogNotInstalled">
|
<string name="err_iverilogNotInstalled">
|
||||||
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.
|
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.
|
||||||
</string>
|
</string>
|
||||||
|
<string name="err_errorLoadingHDLFile_N">Fehler beim Laden der HDL-Datei {0}</string>
|
||||||
|
<string name="err_emptyLabelIsNotAllowed">Eine leere Bezeichnung is nicht erlaubt!</string>
|
||||||
|
|
||||||
<string name="err_errorAnalysingCircuit_N">Fehler bei der Analyse der Schaltung: {0}</string>
|
<string name="err_errorAnalysingCircuit_N">Fehler bei der Analyse der Schaltung: {0}</string>
|
||||||
<string name="err_romNeedsALabelToBeExported">Jedes ROM braucht eine eindeutige Bezeichnung um exportiert zu werden!</string>
|
<string name="err_romNeedsALabelToBeExported">Jedes ROM braucht eine eindeutige Bezeichnung um exportiert zu werden!</string>
|
||||||
<string name="err_lutNeedsALabelToBeExported">Jede LUT braucht eine eindeutige Bezeichnung um exportiert zu werden!</string>
|
<string name="err_lutNeedsALabelToBeExported">Jede LUT braucht eine eindeutige Bezeichnung um exportiert zu werden!</string>
|
||||||
@ -1486,6 +1497,8 @@ Sind evtl. die Namen der Variablen nicht eindeutig?</string>
|
|||||||
</string>
|
</string>
|
||||||
<string name="key_Code">Programmcode</string>
|
<string name="key_Code">Programmcode</string>
|
||||||
<string name="key_Code_tt">Der Programmcode welcher ausgeführt werden soll.</string>
|
<string name="key_Code_tt">Der Programmcode welcher ausgeführt werden soll.</string>
|
||||||
|
<string name="key_CodeFile">Programmcode</string>
|
||||||
|
<string name="key_CodeFile_tt">Datei mit dem Programmcode welcher ausgeführt werden soll.</string>
|
||||||
<string name="attr_panel_Options">Optionen</string>
|
<string name="attr_panel_Options">Optionen</string>
|
||||||
<string name="key_ghdlPath">GHDL</string>
|
<string name="key_ghdlPath">GHDL</string>
|
||||||
<string name="key_ghdlPath_tt">Pfad der ausführbaren ghdl-Datei. Nur wichtig, wenn ghdl zur Interpretation von
|
<string name="key_ghdlPath_tt">Pfad der ausführbaren ghdl-Datei. Nur wichtig, wenn ghdl zur Interpretation von
|
||||||
|
@ -984,6 +984,14 @@
|
|||||||
Is used to specify the behaviour of a component by VHDL or Verilog.
|
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.
|
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.
|
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!
|
||||||
|
</string>
|
||||||
|
<string name="elem_ExternalFile">External File</string>
|
||||||
|
<string name="elem_ExternalFile_tt">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!
|
||||||
</string>
|
</string>
|
||||||
|
|
||||||
<string name="elem_Diode">Diode</string>
|
<string name="elem_Diode">Diode</string>
|
||||||
@ -1171,6 +1179,9 @@
|
|||||||
try again.
|
try again.
|
||||||
If there are still problems, check the path to the IVerilog executable in the Digital settings.
|
If there are still problems, check the path to the IVerilog executable in the Digital settings.
|
||||||
</string>
|
</string>
|
||||||
|
<string name="err_errorLoadingHDLFile_N">Error loading the HDL file {0}</string>
|
||||||
|
<string name="err_emptyLabelIsNotAllowed">A empty label is not allowed!</string>
|
||||||
|
|
||||||
<string name="err_errorAnalysingCircuit_N">Error analysing the circuit: {0}</string>
|
<string name="err_errorAnalysingCircuit_N">Error analysing the circuit: {0}</string>
|
||||||
<string name="err_romNeedsALabelToBeExported">Every ROM needs a unique label to be exported!</string>
|
<string name="err_romNeedsALabelToBeExported">Every ROM needs a unique label to be exported!</string>
|
||||||
<string name="err_lutNeedsALabelToBeExported">Every LUT needs a unique label to be exported!</string>
|
<string name="err_lutNeedsALabelToBeExported">Every LUT needs a unique label to be exported!</string>
|
||||||
@ -1477,6 +1488,8 @@
|
|||||||
</string>
|
</string>
|
||||||
<string name="key_Code">Program code</string>
|
<string name="key_Code">Program code</string>
|
||||||
<string name="key_Code_tt">The program code to be executed by the external application.</string>
|
<string name="key_Code_tt">The program code to be executed by the external application.</string>
|
||||||
|
<string name="key_CodeFile">Program code</string>
|
||||||
|
<string name="key_CodeFile_tt">The file containing the program code to be executed by the external application.</string>
|
||||||
<string name="attr_panel_Options">Options</string>
|
<string name="attr_panel_Options">Options</string>
|
||||||
<string name="key_ghdlPath">GHDL</string>
|
<string name="key_ghdlPath">GHDL</string>
|
||||||
<string name="key_ghdlPath_tt">Path to the executable ghdl file. Only necessary if you want to use ghdl to simulate
|
<string name="key_ghdlPath_tt">Path to the executable ghdl file. Only necessary if you want to use ghdl to simulate
|
||||||
|
8
src/main/resources/verilog/DIG_ExternalFile.v
Normal file
8
src/main/resources/verilog/DIG_ExternalFile.v
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?=loadFile(elem.CodeFile);
|
||||||
|
|
||||||
|
moduleName=elem.Label;
|
||||||
|
|
||||||
|
if (elem.applicationType!="IVERILOG")
|
||||||
|
panic("err_canOnlyExportExternalVerilog");
|
||||||
|
|
||||||
|
?>
|
8
src/main/resources/vhdl/DIG_ExternalFile.tem
Normal file
8
src/main/resources/vhdl/DIG_ExternalFile.tem
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?=loadFile(elem.CodeFile);
|
||||||
|
|
||||||
|
entityName:=elem.Label;
|
||||||
|
|
||||||
|
if (elem.applicationType!="GHDL")
|
||||||
|
panic("err_canOnlyExportExternalVHDL");
|
||||||
|
|
||||||
|
?>
|
@ -129,7 +129,7 @@ public class VerilogSimulatorTest extends TestCase {
|
|||||||
// check simulation in Digital
|
// check simulation in Digital
|
||||||
new TestExamples().check(f);
|
new TestExamples().check(f);
|
||||||
}).scan(source);
|
}).scan(source);
|
||||||
assertEquals(4, tested);
|
assertEquals(5, tested);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,7 +123,7 @@ public class VHDLSimulatorTest extends TestCase {
|
|||||||
// check simulation in Digital
|
// check simulation in Digital
|
||||||
new TestExamples().check(f);
|
new TestExamples().check(f);
|
||||||
}).noOutput().scan(source);
|
}).noOutput().scan(source);
|
||||||
assertEquals(4, tested);
|
assertEquals(5, tested);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
175
src/test/resources/dig/external/ghdl/ghdlFile.dig
vendored
Normal file
175
src/test/resources/dig/external/ghdl/ghdlFile.dig
vendored
Normal file
@ -0,0 +1,175 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<circuit>
|
||||||
|
<version>1</version>
|
||||||
|
<attributes/>
|
||||||
|
<visualElements>
|
||||||
|
<visualElement>
|
||||||
|
<elementName>In</elementName>
|
||||||
|
<elementAttributes>
|
||||||
|
<entry>
|
||||||
|
<string>Label</string>
|
||||||
|
<string>A</string>
|
||||||
|
</entry>
|
||||||
|
<entry>
|
||||||
|
<string>Bits</string>
|
||||||
|
<int>4</int>
|
||||||
|
</entry>
|
||||||
|
<entry>
|
||||||
|
<string>InDefault</string>
|
||||||
|
<value v="3" z="false"/>
|
||||||
|
</entry>
|
||||||
|
</elementAttributes>
|
||||||
|
<pos x="240" y="100"/>
|
||||||
|
</visualElement>
|
||||||
|
<visualElement>
|
||||||
|
<elementName>In</elementName>
|
||||||
|
<elementAttributes>
|
||||||
|
<entry>
|
||||||
|
<string>Label</string>
|
||||||
|
<string>B</string>
|
||||||
|
</entry>
|
||||||
|
<entry>
|
||||||
|
<string>Bits</string>
|
||||||
|
<int>4</int>
|
||||||
|
</entry>
|
||||||
|
<entry>
|
||||||
|
<string>InDefault</string>
|
||||||
|
<value v="4" z="false"/>
|
||||||
|
</entry>
|
||||||
|
</elementAttributes>
|
||||||
|
<pos x="240" y="160"/>
|
||||||
|
</visualElement>
|
||||||
|
<visualElement>
|
||||||
|
<elementName>Out</elementName>
|
||||||
|
<elementAttributes>
|
||||||
|
<entry>
|
||||||
|
<string>Label</string>
|
||||||
|
<string>S</string>
|
||||||
|
</entry>
|
||||||
|
<entry>
|
||||||
|
<string>Bits</string>
|
||||||
|
<int>4</int>
|
||||||
|
</entry>
|
||||||
|
</elementAttributes>
|
||||||
|
<pos x="380" y="140"/>
|
||||||
|
</visualElement>
|
||||||
|
<visualElement>
|
||||||
|
<elementName>In</elementName>
|
||||||
|
<elementAttributes>
|
||||||
|
<entry>
|
||||||
|
<string>Label</string>
|
||||||
|
<string>C_i</string>
|
||||||
|
</entry>
|
||||||
|
<entry>
|
||||||
|
<string>InDefault</string>
|
||||||
|
<value v="4" z="false"/>
|
||||||
|
</entry>
|
||||||
|
</elementAttributes>
|
||||||
|
<pos x="240" y="200"/>
|
||||||
|
</visualElement>
|
||||||
|
<visualElement>
|
||||||
|
<elementName>Out</elementName>
|
||||||
|
<elementAttributes>
|
||||||
|
<entry>
|
||||||
|
<string>Label</string>
|
||||||
|
<string>C_o</string>
|
||||||
|
</entry>
|
||||||
|
</elementAttributes>
|
||||||
|
<pos x="380" y="180"/>
|
||||||
|
</visualElement>
|
||||||
|
<visualElement>
|
||||||
|
<elementName>Testcase</elementName>
|
||||||
|
<elementAttributes>
|
||||||
|
<entry>
|
||||||
|
<string>Testdata</string>
|
||||||
|
<testData>
|
||||||
|
<dataString>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
|
||||||
|
</dataString>
|
||||||
|
</testData>
|
||||||
|
</entry>
|
||||||
|
</elementAttributes>
|
||||||
|
<pos x="300" y="40"/>
|
||||||
|
</visualElement>
|
||||||
|
<visualElement>
|
||||||
|
<elementName>ExternalFile</elementName>
|
||||||
|
<elementAttributes>
|
||||||
|
<entry>
|
||||||
|
<string>applicationType</string>
|
||||||
|
<appType>GHDL</appType>
|
||||||
|
</entry>
|
||||||
|
<entry>
|
||||||
|
<string>Label</string>
|
||||||
|
<string>add</string>
|
||||||
|
</entry>
|
||||||
|
<entry>
|
||||||
|
<string>externalInputs</string>
|
||||||
|
<string>a:4,b:4,c_i</string>
|
||||||
|
</entry>
|
||||||
|
<entry>
|
||||||
|
<string>externalOutputs</string>
|
||||||
|
<string>s:4,c_o</string>
|
||||||
|
</entry>
|
||||||
|
<entry>
|
||||||
|
<string>CodeFile</string>
|
||||||
|
<file>/home/hneemann/Dokumente/Java/digital/src/test/resources/dig/external/ghdl/ghdlFile.vhdl</file>
|
||||||
|
</entry>
|
||||||
|
</elementAttributes>
|
||||||
|
<pos x="280" y="140"/>
|
||||||
|
</visualElement>
|
||||||
|
</visualElements>
|
||||||
|
<wires>
|
||||||
|
<wire>
|
||||||
|
<p1 x="240" y="160"/>
|
||||||
|
<p2 x="280" y="160"/>
|
||||||
|
</wire>
|
||||||
|
<wire>
|
||||||
|
<p1 x="340" y="160"/>
|
||||||
|
<p2 x="360" y="160"/>
|
||||||
|
</wire>
|
||||||
|
<wire>
|
||||||
|
<p1 x="260" y="180"/>
|
||||||
|
<p2 x="280" y="180"/>
|
||||||
|
</wire>
|
||||||
|
<wire>
|
||||||
|
<p1 x="360" y="180"/>
|
||||||
|
<p2 x="380" y="180"/>
|
||||||
|
</wire>
|
||||||
|
<wire>
|
||||||
|
<p1 x="240" y="100"/>
|
||||||
|
<p2 x="260" y="100"/>
|
||||||
|
</wire>
|
||||||
|
<wire>
|
||||||
|
<p1 x="240" y="200"/>
|
||||||
|
<p2 x="260" y="200"/>
|
||||||
|
</wire>
|
||||||
|
<wire>
|
||||||
|
<p1 x="340" y="140"/>
|
||||||
|
<p2 x="380" y="140"/>
|
||||||
|
</wire>
|
||||||
|
<wire>
|
||||||
|
<p1 x="260" y="140"/>
|
||||||
|
<p2 x="280" y="140"/>
|
||||||
|
</wire>
|
||||||
|
<wire>
|
||||||
|
<p1 x="260" y="100"/>
|
||||||
|
<p2 x="260" y="140"/>
|
||||||
|
</wire>
|
||||||
|
<wire>
|
||||||
|
<p1 x="260" y="180"/>
|
||||||
|
<p2 x="260" y="200"/>
|
||||||
|
</wire>
|
||||||
|
<wire>
|
||||||
|
<p1 x="360" y="160"/>
|
||||||
|
<p2 x="360" y="180"/>
|
||||||
|
</wire>
|
||||||
|
</wires>
|
||||||
|
<measurementOrdering/>
|
||||||
|
</circuit>
|
21
src/test/resources/dig/external/ghdl/ghdlFile.vhdl
vendored
Normal file
21
src/test/resources/dig/external/ghdl/ghdlFile.vhdl
vendored
Normal file
@ -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;
|
173
src/test/resources/dig/external/verilog/verilogFile.dig
vendored
Normal file
173
src/test/resources/dig/external/verilog/verilogFile.dig
vendored
Normal file
@ -0,0 +1,173 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<circuit>
|
||||||
|
<version>1</version>
|
||||||
|
<attributes/>
|
||||||
|
<visualElements>
|
||||||
|
<visualElement>
|
||||||
|
<elementName>In</elementName>
|
||||||
|
<elementAttributes>
|
||||||
|
<entry>
|
||||||
|
<string>Label</string>
|
||||||
|
<string>A</string>
|
||||||
|
</entry>
|
||||||
|
<entry>
|
||||||
|
<string>Bits</string>
|
||||||
|
<int>4</int>
|
||||||
|
</entry>
|
||||||
|
<entry>
|
||||||
|
<string>InDefault</string>
|
||||||
|
<value v="3" z="false"/>
|
||||||
|
</entry>
|
||||||
|
</elementAttributes>
|
||||||
|
<pos x="240" y="100"/>
|
||||||
|
</visualElement>
|
||||||
|
<visualElement>
|
||||||
|
<elementName>In</elementName>
|
||||||
|
<elementAttributes>
|
||||||
|
<entry>
|
||||||
|
<string>Label</string>
|
||||||
|
<string>B</string>
|
||||||
|
</entry>
|
||||||
|
<entry>
|
||||||
|
<string>Bits</string>
|
||||||
|
<int>4</int>
|
||||||
|
</entry>
|
||||||
|
<entry>
|
||||||
|
<string>InDefault</string>
|
||||||
|
<value v="4" z="false"/>
|
||||||
|
</entry>
|
||||||
|
</elementAttributes>
|
||||||
|
<pos x="240" y="160"/>
|
||||||
|
</visualElement>
|
||||||
|
<visualElement>
|
||||||
|
<elementName>Out</elementName>
|
||||||
|
<elementAttributes>
|
||||||
|
<entry>
|
||||||
|
<string>Label</string>
|
||||||
|
<string>S</string>
|
||||||
|
</entry>
|
||||||
|
<entry>
|
||||||
|
<string>Bits</string>
|
||||||
|
<int>4</int>
|
||||||
|
</entry>
|
||||||
|
</elementAttributes>
|
||||||
|
<pos x="380" y="140"/>
|
||||||
|
</visualElement>
|
||||||
|
<visualElement>
|
||||||
|
<elementName>In</elementName>
|
||||||
|
<elementAttributes>
|
||||||
|
<entry>
|
||||||
|
<string>Label</string>
|
||||||
|
<string>C_i</string>
|
||||||
|
</entry>
|
||||||
|
<entry>
|
||||||
|
<string>InDefault</string>
|
||||||
|
<value v="4" z="false"/>
|
||||||
|
</entry>
|
||||||
|
</elementAttributes>
|
||||||
|
<pos x="240" y="200"/>
|
||||||
|
</visualElement>
|
||||||
|
<visualElement>
|
||||||
|
<elementName>Out</elementName>
|
||||||
|
<elementAttributes>
|
||||||
|
<entry>
|
||||||
|
<string>Label</string>
|
||||||
|
<string>C_o</string>
|
||||||
|
</entry>
|
||||||
|
</elementAttributes>
|
||||||
|
<pos x="380" y="180"/>
|
||||||
|
</visualElement>
|
||||||
|
<visualElement>
|
||||||
|
<elementName>Testcase</elementName>
|
||||||
|
<elementAttributes>
|
||||||
|
<entry>
|
||||||
|
<string>Testdata</string>
|
||||||
|
<testData>
|
||||||
|
<dataString>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
|
||||||
|
</dataString>
|
||||||
|
</testData>
|
||||||
|
</entry>
|
||||||
|
</elementAttributes>
|
||||||
|
<pos x="300" y="40"/>
|
||||||
|
</visualElement>
|
||||||
|
<visualElement>
|
||||||
|
<elementName>ExternalFile</elementName>
|
||||||
|
<elementAttributes>
|
||||||
|
<entry>
|
||||||
|
<string>Label</string>
|
||||||
|
<string>add</string>
|
||||||
|
</entry>
|
||||||
|
<entry>
|
||||||
|
<string>applicationType</string>
|
||||||
|
<appType>IVERILOG</appType>
|
||||||
|
</entry>
|
||||||
|
<entry>
|
||||||
|
<string>externalInputs</string>
|
||||||
|
<string>a:4,b:4,c_i</string>
|
||||||
|
</entry>
|
||||||
|
<entry>
|
||||||
|
<string>externalOutputs</string>
|
||||||
|
<string>s:4,c_o</string>
|
||||||
|
</entry>
|
||||||
|
<entry>
|
||||||
|
<string>CodeFile</string>
|
||||||
|
<file>/home/hneemann/Dokumente/Java/digital/src/test/resources/dig/external/verilog/verilogFile.v</file>
|
||||||
|
</entry>
|
||||||
|
</elementAttributes>
|
||||||
|
<pos x="280" y="140"/>
|
||||||
|
</visualElement>
|
||||||
|
</visualElements>
|
||||||
|
<wires>
|
||||||
|
<wire>
|
||||||
|
<p1 x="240" y="160"/>
|
||||||
|
<p2 x="280" y="160"/>
|
||||||
|
</wire>
|
||||||
|
<wire>
|
||||||
|
<p1 x="340" y="160"/>
|
||||||
|
<p2 x="360" y="160"/>
|
||||||
|
</wire>
|
||||||
|
<wire>
|
||||||
|
<p1 x="260" y="180"/>
|
||||||
|
<p2 x="280" y="180"/>
|
||||||
|
</wire>
|
||||||
|
<wire>
|
||||||
|
<p1 x="360" y="180"/>
|
||||||
|
<p2 x="380" y="180"/>
|
||||||
|
</wire>
|
||||||
|
<wire>
|
||||||
|
<p1 x="240" y="100"/>
|
||||||
|
<p2 x="260" y="100"/>
|
||||||
|
</wire>
|
||||||
|
<wire>
|
||||||
|
<p1 x="240" y="200"/>
|
||||||
|
<p2 x="260" y="200"/>
|
||||||
|
</wire>
|
||||||
|
<wire>
|
||||||
|
<p1 x="340" y="140"/>
|
||||||
|
<p2 x="380" y="140"/>
|
||||||
|
</wire>
|
||||||
|
<wire>
|
||||||
|
<p1 x="260" y="140"/>
|
||||||
|
<p2 x="280" y="140"/>
|
||||||
|
</wire>
|
||||||
|
<wire>
|
||||||
|
<p1 x="260" y="100"/>
|
||||||
|
<p2 x="260" y="140"/>
|
||||||
|
</wire>
|
||||||
|
<wire>
|
||||||
|
<p1 x="260" y="180"/>
|
||||||
|
<p2 x="260" y="200"/>
|
||||||
|
</wire>
|
||||||
|
<wire>
|
||||||
|
<p1 x="360" y="160"/>
|
||||||
|
<p2 x="360" y="180"/>
|
||||||
|
</wire>
|
||||||
|
</wires>
|
||||||
|
<measurementOrdering/>
|
||||||
|
</circuit>
|
14
src/test/resources/dig/external/verilog/verilogFile.v
vendored
Normal file
14
src/test/resources/dig/external/verilog/verilogFile.v
vendored
Normal file
@ -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
|
Loading…
x
Reference in New Issue
Block a user