diff --git a/src/main/dig/hdl/BASYS3.config b/src/main/dig/hdl/BASYS3.config
index e0c4eed18..68405b40d 100644
--- a/src/main/dig/hdl/BASYS3.config
+++ b/src/main/dig/hdl/BASYS3.config
@@ -7,10 +7,15 @@
vivado/<?=shortname?>.xpr
+
+
+ xc7a35ticpg236-1L
+ .vhdl
+
+ if (model.frequency<4687500) { ?>
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.numeric_std.all;
@@ -22,7 +27,7 @@ entity clockGenerator is
cin: in std_logic );
end clockGenerator;
- maxCounter:=100000000 / (2 * hdl.frequency);?>
+ maxCounter:=100000000 / (2 * model.frequency);?>
architecture Behavioral of clockGenerator is
-- Don't use a logic signal as clock source in a real world application!
@@ -89,7 +94,7 @@ begin
M_IDEAL := D_MIN*VCO_MAX/F_IN;
- F_DES := hdl.frequency/1000000.0;
+ F_DES := model.frequency/1000000.0;
bestError:=F_DES;
bestErrorM:=M_MAX;
@@ -205,11 +210,11 @@ end Behavioral;
} ?>
]]>
-
+
]]>
-
+
\n");?>
-
+
-
+
-
+ if (isPresent("clockGenerator")) { ?>
+
+ } ?>
diff --git a/src/main/dig/hdl/VerilogClockExample.config b/src/main/dig/hdl/VerilogClockExample.config
index 468ed6f71..4f0e5e975 100644
--- a/src/main/dig/hdl/VerilogClockExample.config
+++ b/src/main/dig/hdl/VerilogClockExample.config
@@ -1,20 +1,25 @@
-
+
+
+
+ xc7a35ticpg236-1L
+ .v
+
module clockGenerator
@@ -45,42 +50,6 @@ endmodule
]]>
-
- \n");?>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-]]>
-
+
diff --git a/src/main/java/de/neemann/digital/toolchain/Configuration.java b/src/main/java/de/neemann/digital/toolchain/Configuration.java
index bee0bf3e5..c1f06c972 100644
--- a/src/main/java/de/neemann/digital/toolchain/Configuration.java
+++ b/src/main/java/de/neemann/digital/toolchain/Configuration.java
@@ -24,6 +24,7 @@ import de.neemann.digital.hdl.verilog2.VerilogGenerator;
import de.neemann.digital.hdl.vhdl2.VHDLGenerator;
import de.neemann.digital.lang.Lang;
import de.neemann.gui.ErrorMessage;
+import de.neemann.gui.language.Resources;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -32,6 +33,7 @@ import java.awt.event.ActionEvent;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
+import java.util.Map;
/**
* Used to create the IDE integration
@@ -76,6 +78,8 @@ public final class Configuration {
xStream.aliasAttribute(Configuration.class, "name", "name");
xStream.aliasAttribute(Configuration.class, "frequency", "frequency");
xStream.aliasAttribute(Configuration.class, "clockGenerator", "clockGenerator");
+ xStream.aliasAttribute(Configuration.class, "params", "params");
+ xStream.registerConverter(new Resources.MapEntryConverter("param"));
xStream.alias("command", Command.class);
xStream.aliasAttribute(Command.class, "name", "name");
xStream.aliasAttribute(Command.class, "requires", "requires");
@@ -97,6 +101,7 @@ public final class Configuration {
private String clockGenerator;
private ArrayList commands;
private ArrayList files;
+ private Map params;
private transient FilenameProvider filenameProvider;
private transient CircuitProvider circuitProvider;
private transient LibraryProvider libraryProvider;
@@ -173,17 +178,40 @@ public final class Configuration {
}
}
- private Context createContext(File fileToExecute, HDLModel hdlModel) throws HGSEvalException {
+ private Context createContext(File fileToExecute, HDLModel hdlModel, Command command) throws HGSEvalException {
final Context context = new Context()
.declareVar("path", fileToExecute.getPath())
.declareVar("dir", fileToExecute.getParentFile())
.declareVar("name", fileToExecute.getName())
.declareVar("shortname", createShortname(fileToExecute.getName()));
+
+ if (params != null)
+ for (Map.Entry e : params.entrySet())
+ context.declareVar(e.getKey(), toHGLValue(e.getValue()));
+
+ if (command.needsHDL())
+ context.declareVar("hdl", command.getHDL());
+
+ if (clockGenerator != null)
+ context.declareVar("clockGenerator", clockGenerator);
+
if (hdlModel != null)
- context.declareVar("hdl", new ModelAccess(hdlModel.getMain()));
+ context.declareVar("model", new ModelAccess(hdlModel.getMain()));
return context;
}
+ private Object toHGLValue(String value) {
+ try {
+ return Long.parseLong(value);
+ } catch (NumberFormatException e1) {
+ try {
+ return Double.parseDouble(value);
+ } catch (NumberFormatException e2) {
+ return value;
+ }
+ }
+ }
+
private IOInterface getIoInterface() {
if (ioInterface == null)
ioInterface = new DefaultIOInterface();
@@ -246,13 +274,13 @@ public final class Configuration {
action.setEnabled(false);
Thread t = new Thread(() -> {
try {
- checkFilesToCreate(digFile, hdlModel);
+ checkFilesToCreate(digFile, hdlModel, command);
String[] args = command.getArgs();
if (args != null) {
if (command.isFilter()) {
final int argCount = command.getArgs().length;
- Context context = createContext(digFile, hdlModel);
+ Context context = createContext(digFile, hdlModel, command);
for (int i = 0; i < argCount; i++) {
context.clearOutput();
new Parser(args[i]).parse().execute(context);
@@ -278,14 +306,17 @@ public final class Configuration {
return null;
}
- private void checkFilesToCreate(File fileToExecute, HDLModel hdlModel) throws HGSEvalException, IOException, ParserException {
- Context context = createContext(fileToExecute, hdlModel);
+ private void checkFilesToCreate(File fileToExecute, HDLModel hdlModel, Command command) throws HGSEvalException, IOException, ParserException {
+ Context context = createContext(fileToExecute, hdlModel, command);
if (files != null) {
ConfigCache configCache = new ConfigCache(origin);
for (FileToCreate f : files) {
context.clearOutput();
- Parser p = new Parser(f.getName());
+ final String name = f.getName();
+ if (name == null)
+ throw new IOException("no file name given!");
+ Parser p = new Parser(name);
p.parse().execute(context);
File filename = new File(fileToExecute.getParent(), context.toString());
diff --git a/src/main/java/de/neemann/gui/language/Bundle.java b/src/main/java/de/neemann/gui/language/Bundle.java
index 3e3d76c27..626641ac8 100644
--- a/src/main/java/de/neemann/gui/language/Bundle.java
+++ b/src/main/java/de/neemann/gui/language/Bundle.java
@@ -22,7 +22,7 @@ public class Bundle {
private static XStream getxStream() {
XStream xStream = new XStream(new StaxDriver());
xStream.alias("languages", Map.class);
- xStream.registerConverter(new Resources.MapEntryConverter());
+ xStream.registerConverter(new Resources.MapEntryConverter("string"));
return xStream;
}
diff --git a/src/main/java/de/neemann/gui/language/Resources.java b/src/main/java/de/neemann/gui/language/Resources.java
index 154ce6ebd..f188ef2bc 100644
--- a/src/main/java/de/neemann/gui/language/Resources.java
+++ b/src/main/java/de/neemann/gui/language/Resources.java
@@ -19,13 +19,14 @@ import java.nio.charset.StandardCharsets;
import java.util.*;
/**
+ * Used to store the language keys.
*/
public class Resources {
private static XStream getxStream() {
XStream xStream = new XStream(new StaxDriver());
xStream.alias("resources", Map.class);
- xStream.registerConverter(new MapEntryConverter());
+ xStream.registerConverter(new MapEntryConverter("string"));
return xStream;
}
@@ -92,23 +93,57 @@ public class Resources {
return resourceMap.keySet();
}
- static class MapEntryConverter implements Converter {
+ /**
+ * Simplified map converter
+ */
+ public static class MapEntryConverter implements Converter {
+ private String keyName;
+
+ /**
+ * Creates a new Instance
+ *
+ * @param keyName the name of the xml entity
+ */
+ public MapEntryConverter(String keyName) {
+ this.keyName = keyName;
+ }
+
+ /**
+ * Returns true if the given class can be converted by this converter.
+ *
+ * @param clazz the class to test.
+ * @return true if the given class can be converted by this converter.
+ */
public boolean canConvert(Class clazz) {
return Map.class.isAssignableFrom(clazz);
}
+ /**
+ * Marshals the given object
+ *
+ * @param value the value to matshal
+ * @param writer the writer to write the xml to
+ * @param context the context of the marshaler
+ */
public void marshal(Object value, HierarchicalStreamWriter writer, MarshallingContext context) {
Map map = (Map) value;
for (Object obj : map.entrySet()) {
Map.Entry entry = (Map.Entry) obj;
- writer.startNode("string");
+ writer.startNode(keyName);
writer.addAttribute("name", entry.getKey().toString());
writer.setValue(entry.getValue().toString());
writer.endNode();
}
}
+ /**
+ * Unmarshals a object
+ *
+ * @param reader the reader to read the xml from
+ * @param context the context of the unmarshaler
+ * @return the read object
+ */
public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
Map map = new TreeMap<>();
while (reader.hasMoreChildren()) {
diff --git a/src/test/java/de/neemann/digital/toolchain/BASYS3Test.java b/src/test/java/de/neemann/digital/toolchain/BASYS3Test.java
index fb538fe58..09e4b5953 100644
--- a/src/test/java/de/neemann/digital/toolchain/BASYS3Test.java
+++ b/src/test/java/de/neemann/digital/toolchain/BASYS3Test.java
@@ -26,7 +26,7 @@ public class BASYS3Test extends TestCase {
String content = clock.getContent();
for (int f = 4688; f < 500000; f+=77) {
Context context = new Context().disableLogging();
- context.declareVar("hdl",
+ context.declareVar("model",
new ElementAttributes()
.set(new Key<>("frequency", 10), f * 1000));
Parser p = new Parser(content);
diff --git a/src/test/java/de/neemann/digital/toolchain/ConfigurationTest.java b/src/test/java/de/neemann/digital/toolchain/ConfigurationTest.java
index 721007564..a3ff07647 100644
--- a/src/test/java/de/neemann/digital/toolchain/ConfigurationTest.java
+++ b/src/test/java/de/neemann/digital/toolchain/ConfigurationTest.java
@@ -76,7 +76,7 @@ public class ConfigurationTest extends TestCase {
" deal with <?=path?>\n" +
" \n" +
" \n" +
- " deal with <?=path?>, Bits: <?=hdl.ports[0].bits?> (<?=hdl.ports[0].name?>)\n" +
+ " deal with <?=path?>, Bits: <?=model.ports[0].bits?> (<?=model.ports[0].name?>)\n" +
" \n" +
" \n" +
" test\n" +