mirror of
https://github.com/hneemann/Digital.git
synced 2025-09-18 17:34:43 -04:00
Added a method to make an external component consistent.
Implement a very simple VHDL parser to ensure consistency
This commit is contained in:
parent
b3d7ac164c
commit
985fac138b
@ -5,6 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
package de.neemann.digital.core.extern;
|
package de.neemann.digital.core.extern;
|
||||||
|
|
||||||
|
import de.neemann.digital.core.element.ElementAttributes;
|
||||||
import de.neemann.digital.core.extern.handler.ProcessInterface;
|
import de.neemann.digital.core.extern.handler.ProcessInterface;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -59,6 +60,18 @@ public interface Application {
|
|||||||
*/
|
*/
|
||||||
ProcessInterface start(String label, String code, PortDefinition inputs, PortDefinition outputs) throws IOException;
|
ProcessInterface start(String label, String code, PortDefinition inputs, PortDefinition outputs) throws IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to make the component consistent.
|
||||||
|
* Could extract the label and the input and output configuration from the code or vice versa.
|
||||||
|
* If this is not supported, nothing is done.
|
||||||
|
*
|
||||||
|
* @param attributes the attributed of this component
|
||||||
|
* @return true if attributes are modified
|
||||||
|
*/
|
||||||
|
default boolean ensureConsistency(ElementAttributes attributes) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return true if the code check function is supported
|
* @return true if the code check function is supported
|
||||||
*/
|
*/
|
||||||
|
@ -5,8 +5,14 @@
|
|||||||
*/
|
*/
|
||||||
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.Keys;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
|
import java.util.StringTokenizer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class of applications which are able to interprete VHDL-Code.
|
* Base class of applications which are able to interprete VHDL-Code.
|
||||||
@ -151,4 +157,93 @@ public abstract class ApplicationVHDLStdIO implements Application {
|
|||||||
return "std_logic_vector (" + (bits - 1) + " downto 0)";
|
return "std_logic_vector (" + (bits - 1) + " downto 0)";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean ensureConsistency(ElementAttributes attributes) {
|
||||||
|
String code = attributes.get(Keys.EXTERNAL_CODE);
|
||||||
|
StringTokenizer st = new StringTokenizer(code, "(), :;\t\n\r");
|
||||||
|
try {
|
||||||
|
while (st.hasMoreTokens()) {
|
||||||
|
if (st.nextToken().toLowerCase().equals("entity"))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
String label = st.nextToken();
|
||||||
|
|
||||||
|
while (st.hasMoreTokens()) {
|
||||||
|
String tok = st.nextToken().toLowerCase();
|
||||||
|
if (tok.equals("end"))
|
||||||
|
return false;
|
||||||
|
else if (tok.equals("port")) {
|
||||||
|
PortDefinition in = new PortDefinition("");
|
||||||
|
PortDefinition out = new PortDefinition("");
|
||||||
|
scanPorts(st, in, out);
|
||||||
|
if (in.size() > 0 && out.size() > 0) {
|
||||||
|
attributes.set(Keys.LABEL, label);
|
||||||
|
attributes.set(Keys.EXTERNAL_INPUTS, in.toString());
|
||||||
|
attributes.set(Keys.EXTERNAL_OUTPUTS, out.toString());
|
||||||
|
return true;
|
||||||
|
} else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
} catch (NoSuchElementException | ParseException e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void scanPorts(StringTokenizer st, PortDefinition in, PortDefinition out) throws ParseException {
|
||||||
|
ArrayList<String> vars = new ArrayList<>();
|
||||||
|
while (st.hasMoreTokens()) {
|
||||||
|
String tok = st.nextToken();
|
||||||
|
switch (tok.toLowerCase()) {
|
||||||
|
case "in":
|
||||||
|
scanPort(st, vars, in);
|
||||||
|
vars.clear();
|
||||||
|
break;
|
||||||
|
case "out":
|
||||||
|
scanPort(st, vars, out);
|
||||||
|
vars.clear();
|
||||||
|
break;
|
||||||
|
case "end":
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
vars.add(tok);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void scanPort(StringTokenizer st, ArrayList<String> vars, PortDefinition port) throws ParseException {
|
||||||
|
switch (st.nextToken().toLowerCase()) {
|
||||||
|
case "std_logic":
|
||||||
|
for (String var : vars)
|
||||||
|
port.addPort(var, 1);
|
||||||
|
break;
|
||||||
|
case "std_logic_vector":
|
||||||
|
int upper = getNumber(st);
|
||||||
|
if (!st.nextToken().toLowerCase().equals("downto"))
|
||||||
|
throw new ParseException();
|
||||||
|
int lower = getNumber(st);
|
||||||
|
|
||||||
|
if (lower != 0)
|
||||||
|
throw new ParseException();
|
||||||
|
|
||||||
|
for (String var : vars)
|
||||||
|
port.addPort(var, upper + 1);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new ParseException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getNumber(StringTokenizer st) throws ParseException {
|
||||||
|
try {
|
||||||
|
return Integer.parseInt(st.nextToken());
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
throw new ParseException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final class ParseException extends Exception {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,18 @@ public class Port {
|
|||||||
private final int bits;
|
private final int bits;
|
||||||
private final String name;
|
private final String name;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new port
|
||||||
|
*
|
||||||
|
* @param name the name
|
||||||
|
* @param bits the number of bits
|
||||||
|
*/
|
||||||
|
public Port(String name, int bits) {
|
||||||
|
this.name = name;
|
||||||
|
this.bits = bits;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new port
|
* Creates a new port
|
||||||
*
|
*
|
||||||
@ -49,4 +61,12 @@ public class Port {
|
|||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
if (bits == 1)
|
||||||
|
return name;
|
||||||
|
else
|
||||||
|
return name + ":" + bits;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -82,4 +82,33 @@ public class PortDefinition implements Iterable<Port> {
|
|||||||
public Iterator<Port> iterator() {
|
public Iterator<Port> iterator() {
|
||||||
return ports.iterator();
|
return ports.iterator();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a port to this description
|
||||||
|
*
|
||||||
|
* @param name the name
|
||||||
|
* @param bits the number of bits
|
||||||
|
*/
|
||||||
|
public void addPort(String name, int bits) {
|
||||||
|
ports.add(new Port(name, bits));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the number of ports
|
||||||
|
*/
|
||||||
|
public int size() {
|
||||||
|
return ports.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
for (Port p : ports) {
|
||||||
|
if (sb.length() > 0)
|
||||||
|
sb.append(",");
|
||||||
|
sb.append(p.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -204,6 +204,16 @@ public class AttributeDialog extends JDialog {
|
|||||||
e.setTo(modifiedAttributes);
|
e.setTo(modifiedAttributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* update gui fields with attributes
|
||||||
|
*
|
||||||
|
* @throws Editor.EditorParseException Editor.EditorParseException
|
||||||
|
*/
|
||||||
|
public void updateEditedValues() throws Editor.EditorParseException {
|
||||||
|
for (EditorHolder e : editors)
|
||||||
|
e.getFrom(modifiedAttributes);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shows the dialog
|
* Shows the dialog
|
||||||
*
|
*
|
||||||
@ -283,6 +293,11 @@ public class AttributeDialog extends JDialog {
|
|||||||
attr.set(key, value);
|
attr.set(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void getFrom(ElementAttributes attr) throws Editor.EditorParseException {
|
||||||
|
T value = attr.get(key);
|
||||||
|
e.setValue(value);
|
||||||
|
}
|
||||||
|
|
||||||
void setDependantEditor(Editor editor, boolean inverted) {
|
void setDependantEditor(Editor editor, boolean inverted) {
|
||||||
if (key.getValueClass() != Boolean.class)
|
if (key.getValueClass() != Boolean.class)
|
||||||
throw new RuntimeException("key " + key.getName() + " is not a bool key");
|
throw new RuntimeException("key " + key.getName() + " is not a bool key");
|
||||||
|
@ -21,6 +21,13 @@ public interface Editor<T> {
|
|||||||
*/
|
*/
|
||||||
T getValue() throws EditorParseException;
|
T getValue() throws EditorParseException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the value to the gui
|
||||||
|
*
|
||||||
|
* @param value the value to set
|
||||||
|
*/
|
||||||
|
void setValue(T value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds the components of the editor to the panel
|
* Adds the components of the editor to the panel
|
||||||
*
|
*
|
||||||
|
@ -199,6 +199,11 @@ public final class EditorFactory {
|
|||||||
return text.getText().trim();
|
return text.getText().trim();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setValue(String value) {
|
||||||
|
text.setText(value);
|
||||||
|
}
|
||||||
|
|
||||||
public JTextComponent getTextComponent() {
|
public JTextComponent getTextComponent() {
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
@ -252,6 +257,11 @@ public final class EditorFactory {
|
|||||||
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setValue(Integer value) {
|
||||||
|
comboBox.setSelectedItem(value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final static class LongEditor extends LabelEditor<Long> {
|
private final static class LongEditor extends LabelEditor<Long> {
|
||||||
@ -284,6 +294,11 @@ public final class EditorFactory {
|
|||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setValue(Long value) {
|
||||||
|
comboBox.setSelectedItem(value.toString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final static class InValueEditor extends LabelEditor<InValue> {
|
private final static class InValueEditor extends LabelEditor<InValue> {
|
||||||
@ -310,6 +325,11 @@ public final class EditorFactory {
|
|||||||
throw new EditorParseException(e);
|
throw new EditorParseException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setValue(InValue value) {
|
||||||
|
comboBox.setSelectedItem(value.toString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final static class BooleanEditor implements Editor<Boolean> {
|
final static class BooleanEditor implements Editor<Boolean> {
|
||||||
@ -339,6 +359,11 @@ public final class EditorFactory {
|
|||||||
JCheckBox getCheckBox() {
|
JCheckBox getCheckBox() {
|
||||||
return bool;
|
return bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setValue(Boolean value) {
|
||||||
|
bool.setEnabled(value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final static class ColorEditor extends LabelEditor<Color> {
|
private final static class ColorEditor extends LabelEditor<Color> {
|
||||||
@ -378,6 +403,12 @@ public final class EditorFactory {
|
|||||||
public Color getValue() {
|
public Color getValue() {
|
||||||
return color;
|
return color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setValue(Color value) {
|
||||||
|
this.color = value;
|
||||||
|
button.setBackground(color);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final static class FileEditor extends LabelEditor<File> {
|
private final static class FileEditor extends LabelEditor<File> {
|
||||||
@ -417,6 +448,11 @@ public final class EditorFactory {
|
|||||||
public File getValue() {
|
public File getValue() {
|
||||||
return new File(textField.getText());
|
return new File(textField.getText());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setValue(File value) {
|
||||||
|
textField.setText(value.getPath());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final static class DataFieldEditor extends LabelEditor<DataField> {
|
private final static class DataFieldEditor extends LabelEditor<DataField> {
|
||||||
@ -481,6 +517,11 @@ public final class EditorFactory {
|
|||||||
public DataField getValue() {
|
public DataField getValue() {
|
||||||
return data.getMinimized();
|
return data.getMinimized();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setValue(DataField value) {
|
||||||
|
this.data = value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final static class RotationEditor extends LabelEditor<Rotation> {
|
private final static class RotationEditor extends LabelEditor<Rotation> {
|
||||||
@ -504,6 +545,11 @@ public final class EditorFactory {
|
|||||||
public Rotation getValue() {
|
public Rotation getValue() {
|
||||||
return new Rotation(comb.getSelectedIndex());
|
return new Rotation(comb.getSelectedIndex());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setValue(Rotation value) {
|
||||||
|
comb.setSelectedIndex(value.getRotation());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class EnumEditor<E extends Enum> extends LabelEditor<E> {
|
private static class EnumEditor<E extends Enum> extends LabelEditor<E> {
|
||||||
@ -530,6 +576,11 @@ public final class EditorFactory {
|
|||||||
public E getValue() {
|
public E getValue() {
|
||||||
return values[comboBox.getSelectedIndex()];
|
return values[comboBox.getSelectedIndex()];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setValue(E value) {
|
||||||
|
comboBox.setSelectedIndex(value.ordinal());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final class IntFormatsEditor extends EnumEditor<IntFormat> {
|
private static final class IntFormatsEditor extends EnumEditor<IntFormat> {
|
||||||
@ -573,7 +624,8 @@ public final class EditorFactory {
|
|||||||
if (app != null) {
|
if (app != null) {
|
||||||
try {
|
try {
|
||||||
getAttributeDialog().storeEditedValues();
|
getAttributeDialog().storeEditedValues();
|
||||||
Application.create(elementAttributes.get(key));
|
if (app.ensureConsistency(elementAttributes))
|
||||||
|
getAttributeDialog().updateEditedValues();
|
||||||
|
|
||||||
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));
|
||||||
@ -641,6 +693,11 @@ public final class EditorFactory {
|
|||||||
public Language getValue() {
|
public Language getValue() {
|
||||||
return (Language) comb.getSelectedItem();
|
return (Language) comb.getSelectedItem();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setValue(Language value) {
|
||||||
|
comb.setSelectedItem(value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class FormatEditor extends LabelEditor<FormatToExpression> {
|
private static class FormatEditor extends LabelEditor<FormatToExpression> {
|
||||||
@ -661,6 +718,11 @@ public final class EditorFactory {
|
|||||||
public FormatToExpression getValue() {
|
public FormatToExpression getValue() {
|
||||||
return (FormatToExpression) comb.getSelectedItem();
|
return (FormatToExpression) comb.getSelectedItem();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setValue(FormatToExpression value) {
|
||||||
|
comb.setSelectedItem(value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class InverterConfigEditor extends LabelEditor<InverterConfig> {
|
private static class InverterConfigEditor extends LabelEditor<InverterConfig> {
|
||||||
@ -712,6 +774,12 @@ public final class EditorFactory {
|
|||||||
this.elementAttributes = elementAttributes;
|
this.elementAttributes = elementAttributes;
|
||||||
return button;
|
return button;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setValue(InverterConfig value) {
|
||||||
|
inverterConfig = value;
|
||||||
|
button.setText(getButtonText());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final static class InputSelectDialog extends JDialog {
|
private final static class InputSelectDialog extends JDialog {
|
||||||
@ -814,5 +882,10 @@ public final class EditorFactory {
|
|||||||
public ROMManger getValue() {
|
public ROMManger getValue() {
|
||||||
return romManager;
|
return romManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setValue(ROMManger value) {
|
||||||
|
romManager=value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -71,4 +71,8 @@ public class TestCaseDescriptionEditor extends EditorFactory.LabelEditor<TestCas
|
|||||||
|
|
||||||
return panel;
|
return panel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setValue(TestCaseDescription value) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -697,7 +697,11 @@
|
|||||||
Der schnelle Simulationslauf kann nur genutzt werden, wenn der Echtzeittakt deaktiviert ist!</string>
|
Der schnelle Simulationslauf kann nur genutzt werden, wenn der Echtzeittakt deaktiviert ist!</string>
|
||||||
|
|
||||||
<string name="elem_External">Extern</string>
|
<string name="elem_External">Extern</string>
|
||||||
<string name="elem_External_tt">Element zur Anbindung von externen Programmen zur Berechnung der Logik.</string>
|
<string name="elem_External_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 unterstützt.
|
||||||
|
</string>
|
||||||
|
|
||||||
<string name="elem_Diode">Diode</string>
|
<string name="elem_Diode">Diode</string>
|
||||||
<string name="elem_Diode_tt">Echt bidirektionale Diode.
|
<string name="elem_Diode_tt">Echt bidirektionale Diode.
|
||||||
@ -1060,15 +1064,17 @@ Sind evtl. die Namen der Variablen nicht eindeutig?</string>
|
|||||||
<string name="key_applicationType_Generic">Generisch</string>
|
<string name="key_applicationType_Generic">Generisch</string>
|
||||||
<string name="key_applicationType_GHDL">GHDL</string>
|
<string name="key_applicationType_GHDL">GHDL</string>
|
||||||
<string name="key_externalInputs">Eingänge</string>
|
<string name="key_externalInputs">Eingänge</string>
|
||||||
<string name="key_externalInputs_tt">Die Eingänge des externen Prozesses.</string>
|
<string name="key_externalInputs_tt">Die Eingänge des externen Prozesses. Es handelt sich um eine kommaseparierte
|
||||||
|
Liste mit Signalnamen. Bei jedem Signalnamen kann, mit einem Doppelpunkt getrennt, eine Bitanzahl angegeben werden.
|
||||||
|
Die Eingänge eines 8-Bit Addierers könnten also mit "a:8,b:8,c_in" beschrieben werden.</string>
|
||||||
<string name="key_externalOutputs">Ausgänge</string>
|
<string name="key_externalOutputs">Ausgänge</string>
|
||||||
<string name="key_externalOutputs_tt">Die Ausgänge des externen Prozesses.</string>
|
<string name="key_externalOutputs_tt">Die Ausgänge des externen Prozesses. Es handelt sich um eine kommaseparierte
|
||||||
|
Liste mit Signalnamen. Bei jedem Signalnamen kann, mit einem Doppelpunkt getrennt, eine Bitanzahl angegeben werden.
|
||||||
|
Die Ausgänge eines 8-Bit Addierers könnten also mit "s:8,c_out" beschrieben werden.</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_externalExecutable">Ausfühbare Datei</string>
|
|
||||||
<string name="key_externalExecutable_tt">Die Datei, die ausgeführt werden soll!</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
|
||||||
VHDL-Code verwendet werden soll.</string>
|
VHDL-Code verwendet werden soll.</string>
|
||||||
|
|
||||||
<string name="mod_insertWire">Leitung eingefügt.</string>
|
<string name="mod_insertWire">Leitung eingefügt.</string>
|
||||||
|
@ -693,7 +693,11 @@
|
|||||||
Fast forward clocking can only be used if the real-time clock is disabled.</string>
|
Fast forward clocking can only be used if the real-time clock is disabled.</string>
|
||||||
|
|
||||||
<string name="elem_External">External</string>
|
<string name="elem_External">External</string>
|
||||||
<string name="elem_External_tt">Component to execute an external process to calculate the logic function.</string>
|
<string name="elem_External_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 is supported.
|
||||||
|
</string>
|
||||||
|
|
||||||
<string name="elem_Diode">Diode</string>
|
<string name="elem_Diode">Diode</string>
|
||||||
<string name="elem_Diode_tt">Simplified bidirectional diode. It is used to implement a wired AND or a wired OR..
|
<string name="elem_Diode_tt">Simplified bidirectional diode. It is used to implement a wired AND or a wired OR..
|
||||||
@ -1052,13 +1056,15 @@
|
|||||||
<string name="key_applicationType_Generic">Generic</string>
|
<string name="key_applicationType_Generic">Generic</string>
|
||||||
<string name="key_applicationType_GHDL">GHDL</string>
|
<string name="key_applicationType_GHDL">GHDL</string>
|
||||||
<string name="key_externalInputs">Inputs</string>
|
<string name="key_externalInputs">Inputs</string>
|
||||||
<string name="key_externalInputs_tt">The inputs of the external process.</string>
|
<string name="key_externalInputs_tt">The inputs of the external process.
|
||||||
|
It is a comma-separated list of signal names. For each signal name, with a colon separated, a number of bits
|
||||||
|
can be specified. The inputs of an 8-bit adder could thus be described as "a:8,b:8,c_in".</string>
|
||||||
<string name="key_externalOutputs">Outputs</string>
|
<string name="key_externalOutputs">Outputs</string>
|
||||||
<string name="key_externalOutputs_tt">The outputs of the external process.</string>
|
<string name="key_externalOutputs_tt">The outputs of the external process.
|
||||||
|
It is a comma-separated list of signal names. For each signal name, with a colon separated, a number of bits
|
||||||
|
can be specified. The outputs of an 8-bit adder could thus be described as "s:8,c_out".</string>
|
||||||
<string name="key_Code">Programcode</string>
|
<string name="key_Code">Programcode</string>
|
||||||
<string name="key_Code_tt">The programm code to use with the external process.</string>
|
<string name="key_Code_tt">The programm code to be executed by the external application.</string>
|
||||||
<string name="key_externalExecutable">Executeable</string>
|
|
||||||
<string name="key_externalExecutable_tt">The programm which is to execute.</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
|
||||||
components defined with vhdl.</string>
|
components defined with vhdl.</string>
|
||||||
|
124
src/test/java/de/neemann/digital/core/extern/ApplicationVHDLStdIOTest.java
vendored
Normal file
124
src/test/java/de/neemann/digital/core/extern/ApplicationVHDLStdIOTest.java
vendored
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
/*
|
||||||
|
* 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.element.ElementAttributes;
|
||||||
|
import de.neemann.digital.core.element.Keys;
|
||||||
|
import de.neemann.digital.core.extern.handler.ProcessInterface;
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class ApplicationVHDLStdIOTest extends TestCase {
|
||||||
|
|
||||||
|
private class TestApp extends ApplicationVHDLStdIO {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ProcessInterface start(String label, String code, PortDefinition inputs, PortDefinition outputs) throws IOException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean checkSupported() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String checkCode(String label, String code, PortDefinition inputs, PortDefinition outputs) throws IOException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void testExtraction() {
|
||||||
|
ElementAttributes attr = extractParameters("LIBRARY ieee;\n" +
|
||||||
|
"USE ieee.std_logic_1164.all;\n" +
|
||||||
|
"USE ieee.std_logic_unsigned.all;\n" +
|
||||||
|
"\n" +
|
||||||
|
"entity add is\n" +
|
||||||
|
" port (\n" +
|
||||||
|
" a: in std_logic_vector(3 downto 0);\n" +
|
||||||
|
" b: in std_logic_vector(3 downto 0);\n" +
|
||||||
|
" c_i: in std_logic;\n" +
|
||||||
|
" s: out std_logic_vector(3 downto 0);\n" +
|
||||||
|
" c_o: out std_logic );\n" +
|
||||||
|
"end add;\n" +
|
||||||
|
"\n" +
|
||||||
|
"architecture add_arch of add is\n" +
|
||||||
|
"begin\n" +
|
||||||
|
"end add_arch;", true);
|
||||||
|
|
||||||
|
assertEquals("add", attr.getCleanLabel());
|
||||||
|
assertEquals("a:4,b:4,c_i", attr.get(Keys.EXTERNAL_INPUTS));
|
||||||
|
assertEquals("s:4,c_o", attr.get(Keys.EXTERNAL_OUTPUTS));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testExtractionUpper() {
|
||||||
|
ElementAttributes attr = extractParameters("LIBRARY Ieee;\n" +
|
||||||
|
"USE Ieee.std_logic_1164.all;\n" +
|
||||||
|
"USE Ieee.std_logic_unsigned.all;\n" +
|
||||||
|
"\n" +
|
||||||
|
"Entity Add Is\n" +
|
||||||
|
" Port (\n" +
|
||||||
|
" A: In Std_logic_vector(3 Downto 0);\n" +
|
||||||
|
" B: In Std_logic_vector(3 Downto 0);\n" +
|
||||||
|
" C_i: In Std_logic;\n" +
|
||||||
|
" S: Out Std_logic_vector(3 Downto 0);\n" +
|
||||||
|
" C_o: Out Std_logic );\n" +
|
||||||
|
"End Add;\n" +
|
||||||
|
"\n" +
|
||||||
|
"architecture Add_arch Of Add Is\n" +
|
||||||
|
"begin\n" +
|
||||||
|
"end Add_arch;", true);
|
||||||
|
|
||||||
|
assertEquals("Add", attr.getCleanLabel());
|
||||||
|
assertEquals("A:4,B:4,C_i", attr.get(Keys.EXTERNAL_INPUTS));
|
||||||
|
assertEquals("S:4,C_o", attr.get(Keys.EXTERNAL_OUTPUTS));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testExtractionCompact() {
|
||||||
|
ElementAttributes attr = extractParameters("library IEEE;\n" +
|
||||||
|
"use IEEE.std_logic_1164.all;\n" +
|
||||||
|
"use IEEE.numeric_std.all;\n" +
|
||||||
|
"\n" +
|
||||||
|
"\n" +
|
||||||
|
"entity nBitZaehler is\n" +
|
||||||
|
"\tport (LoadIn : in std_logic_vector (7 downto 0); load,reset,clk : in std_logic; CountOut : out std_logic_vector (7 downto 0));\n" +
|
||||||
|
"end nBitZaehler;\n" +
|
||||||
|
"\n" +
|
||||||
|
"architecture nBitZaehlerRTL of nBitZaehler is\n" +
|
||||||
|
"\tsignal ALUOut : unsigned(7 downto 0); -- internal\n" +
|
||||||
|
"\tsignal ALUIn : unsigned(7 downto 0); -- internal\n" +
|
||||||
|
"begin\n" +
|
||||||
|
"\tend process;\n" +
|
||||||
|
"end nBitZaehlerRTL;", true);
|
||||||
|
|
||||||
|
assertEquals("nBitZaehler", attr.getCleanLabel());
|
||||||
|
assertEquals("LoadIn:8,load,reset,clk", attr.get(Keys.EXTERNAL_INPUTS));
|
||||||
|
assertEquals("CountOut:8", attr.get(Keys.EXTERNAL_OUTPUTS));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testExtractionFail() {
|
||||||
|
extractParameters("library IEEE;\n" +
|
||||||
|
"use IEEE.std_logic_1164.all;\n" +
|
||||||
|
"use IEEE.numeric_std.all;\n" +
|
||||||
|
"\n" +
|
||||||
|
"\n" +
|
||||||
|
"entity nBitZaehler is\n" +
|
||||||
|
"\tgeneric(size : natural := 32);\n" +
|
||||||
|
"\tport (LoadIn : in std_logic_vector ((size-1) downto 0); load,reset,clk : in std_logic; CountOut : out std_logic_vector (size-1 downto 0));\n" +
|
||||||
|
"end nBitZaehler;\n", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public ElementAttributes extractParameters(String code, boolean workExpected) {
|
||||||
|
TestApp ta = new TestApp();
|
||||||
|
ElementAttributes attr = new ElementAttributes();
|
||||||
|
attr.set(Keys.EXTERNAL_CODE, code);
|
||||||
|
assertEquals(workExpected, ta.ensureConsistency(attr));
|
||||||
|
return attr;
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user