From 0161e7e5621c88066a0276c2417a35b8cb94e3c1 Mon Sep 17 00:00:00 2001 From: hneemann Date: Sun, 18 Mar 2018 00:39:23 +0100 Subject: [PATCH] improved integration of java methods --- .../de/neemann/digital/hdl/hgs/Context.java | 27 --- .../digital/hdl/hgs/function/JavaClass.java | 154 ++++++++++++++ .../digital/hdl/hgs/function/JavaMethod.java | 121 ----------- .../digital/hdl/vhdl/lib/VHDLTemplate.java | 199 ++---------------- .../hdl/vhdl/lib/VHDLTemplateFunctions.java | 171 +++++++++++++++ src/main/resources/vhdl/DIG_Add.tem | 6 +- src/main/resources/vhdl/DIG_BitExtender.tem | 14 +- src/main/resources/vhdl/DIG_BitSelector.tem | 8 +- src/main/resources/vhdl/DIG_Comparator.tem | 10 +- src/main/resources/vhdl/DIG_Counter.tem | 6 +- src/main/resources/vhdl/DIG_D_FF.tem | 14 +- src/main/resources/vhdl/DIG_D_FF_AS.tem | 18 +- src/main/resources/vhdl/DIG_Decoder.tem | 4 +- src/main/resources/vhdl/DIG_Demultiplexer.tem | 14 +- src/main/resources/vhdl/DIG_Driver.tem | 10 +- src/main/resources/vhdl/DIG_DriverInvSel.tem | 10 +- src/main/resources/vhdl/DIG_JK_FF.tem | 6 +- src/main/resources/vhdl/DIG_JK_FF_AS.tem | 6 +- src/main/resources/vhdl/DIG_MMCME2_BASE.tem | 16 +- src/main/resources/vhdl/DIG_Mul.tem | 6 +- src/main/resources/vhdl/DIG_Multiplexer.tem | 16 +- src/main/resources/vhdl/DIG_Not.tem | 10 +- src/main/resources/vhdl/DIG_Operate.tem | 10 +- .../resources/vhdl/DIG_PriorityEncoder.tem | 6 +- src/main/resources/vhdl/DIG_RAMDualAccess.tem | 8 +- src/main/resources/vhdl/DIG_RAMDualPort.tem | 8 +- src/main/resources/vhdl/DIG_ROM.tem | 12 +- src/main/resources/vhdl/DIG_Register.tem | 12 +- src/main/resources/vhdl/DIG_RegisterFile.tem | 8 +- src/main/resources/vhdl/DIG_Reset.tem | 6 +- src/main/resources/vhdl/DIG_Sub.tem | 6 +- .../resources/vhdl/DIG_simpleClockDivider.tem | 6 +- .../neemann/digital/hdl/hgs/ParserTest.java | 80 ++++--- 33 files changed, 519 insertions(+), 489 deletions(-) create mode 100644 src/main/java/de/neemann/digital/hdl/hgs/function/JavaClass.java delete mode 100644 src/main/java/de/neemann/digital/hdl/hgs/function/JavaMethod.java create mode 100644 src/main/java/de/neemann/digital/hdl/vhdl/lib/VHDLTemplateFunctions.java 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 b9e72f25d..90753438e 100644 --- a/src/main/java/de/neemann/digital/hdl/hgs/Context.java +++ b/src/main/java/de/neemann/digital/hdl/hgs/Context.java @@ -8,7 +8,6 @@ package de.neemann.digital.hdl.hgs; import de.neemann.digital.hdl.hgs.function.Func; import de.neemann.digital.hdl.hgs.function.Function; import de.neemann.digital.hdl.hgs.function.InnerFunction; -import de.neemann.digital.hdl.hgs.function.JavaMethod; import java.util.ArrayList; import java.util.HashMap; @@ -153,32 +152,6 @@ public class Context { return declareVar(name, func); } - /** - * Adds a static java method to the context. - * The method can then be called from the template code. - * - * @param name the name - * @param clazz the class of the method - * @return this for chained calls - * @throws HGSEvalException HGSEvalException - */ - public Context declareStaticMethod(String name, Class clazz) throws HGSEvalException { - return declareFunc(name, JavaMethod.create(clazz, name)); - } - - /** - * Adds a non static java method to the context. - * The method can then be called from the template code. - * - * @param name the name - * @param instance the instance to call the method on - * @return this for chained calls - * @throws HGSEvalException HGSEvalException - */ - public Context declareMethod(String name, Object instance) throws HGSEvalException { - return declareFunc(name, JavaMethod.create(instance, name)); - } - /** * Prints code to the context * diff --git a/src/main/java/de/neemann/digital/hdl/hgs/function/JavaClass.java b/src/main/java/de/neemann/digital/hdl/hgs/function/JavaClass.java new file mode 100644 index 000000000..5d6a56d23 --- /dev/null +++ b/src/main/java/de/neemann/digital/hdl/hgs/function/JavaClass.java @@ -0,0 +1,154 @@ +/* + * 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.hdl.hgs.function; + +import de.neemann.digital.hdl.hgs.Context; +import de.neemann.digital.hdl.hgs.Expression; +import de.neemann.digital.hdl.hgs.HGSEvalException; +import de.neemann.digital.hdl.hgs.HGSMap; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.HashMap; + +/** + * Used to call a java function from the template code. + * Uses reflection to invoke the method; + * + * @param the type of the instance + */ +public final class JavaClass { + private final HashMap> methods; + + /** + * Creates a new instance + * + * @param clazz the class + */ + public JavaClass(Class clazz) { + methods = new HashMap<>(); + for (Method m : clazz.getDeclaredMethods()) { + int mod = m.getModifiers(); + if (Modifier.isPublic(mod)) + methods.put(m.getName(), new MyMethod<>(m, Modifier.isStatic(mod))); + } + } + + /** + * Creates the method map + * + * @param instance the instance to call + * @return the method map + */ + public HGSMap createMap(T instance) { + return new MethodMap<>(this, instance); + } + + private static final class MyMethod { + private final Method method; + private final boolean isStatic; + private final boolean addContext; + private final int argCount; + private final int javaArgCount; + private final boolean isVarArgs; + + private MyMethod(Method method, boolean isStatic) { + this.method = method; + this.isStatic = isStatic; + + Class[] argTypes = method.getParameterTypes(); + javaArgCount = argTypes.length; + addContext = (argTypes.length > 0 && argTypes[0].isAssignableFrom(Context.class)); + + isVarArgs = method.isVarArgs(); + if (isVarArgs) { + argCount = -1; + } else { + if (addContext) + argCount = argTypes.length - 1; + else + argCount = argTypes.length; + } + } + + private Object call(T instance, Context c, ArrayList args) throws HGSEvalException { + if (instance == null && !isStatic) + throw new HGSEvalException("function " + method.getName() + " is not static!"); + + if (argCount >= 0 && argCount != args.size()) + throw new HGSEvalException("wrong number of arguments! expected: " + argCount + ", but found:" + args.size()); + + Object[] a = new Object[javaArgCount]; + int i = 0; + if (addContext) { + a[0] = c; + i++; + } + if (!isVarArgs) { + for (Expression exp : args) { + a[i] = exp.value(c); + i++; + } + } else { + // ellipse + int fixed = javaArgCount - i - 1; + for (int n = 0; n < fixed; n++) { + a[i] = args.get(n).value(c); + i++; + } + final int numVarArgs = args.size() - fixed; + String[] varArgs = new String[numVarArgs]; + for (int n = fixed; n < args.size(); n++) + varArgs[n - fixed] = args.get(n).value(c).toString(); + + a[i] = varArgs; + } + + try { + return method.invoke(instance, a); + } catch (RuntimeException | IllegalAccessException | InvocationTargetException e) { + throw new HGSEvalException("Error invoking the java method " + method.getName() + "!", e); + } + } + } + + private static final class MethodMap implements HGSMap { + private final JavaClass javaClass; + private final T instance; + + private MethodMap(JavaClass javaClass, T instance) { + this.javaClass = javaClass; + this.instance = instance; + } + + @Override + public Object hgsMapGet(String key) { + MyMethod m = javaClass.methods.get(key); + if (m == null) return null; + return new MethodCall<>(m, instance); + } + + } + + private static final class MethodCall extends InnerFunction { + private final MyMethod m; + private final T instance; + + private MethodCall(MyMethod m, T instance) { + super(m.argCount); + this.m = m; + this.instance = instance; + } + + @Override + public Object call(Context c, ArrayList args) throws HGSEvalException { + return m.call(instance, c, args); + } + } + +} diff --git a/src/main/java/de/neemann/digital/hdl/hgs/function/JavaMethod.java b/src/main/java/de/neemann/digital/hdl/hgs/function/JavaMethod.java deleted file mode 100644 index 7e3c92f2f..000000000 --- a/src/main/java/de/neemann/digital/hdl/hgs/function/JavaMethod.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * 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.hdl.hgs.function; - -import de.neemann.digital.hdl.hgs.Context; -import de.neemann.digital.hdl.hgs.Expression; -import de.neemann.digital.hdl.hgs.HGSEvalException; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.util.ArrayList; - -/** - * Used to call a java function from the template code. - * Uses reflection to invoke the method; - */ -public final class JavaMethod extends InnerFunction { - private final Object instance; - private final Method method; - private final Class[] argTypes; - private final boolean addContext; - - /** - * Creates a function for a static method. - * If the first argument of the method is of type {@link Context} the - * context is passed in. - * - * @param c the class - * @param name the name of the method - * @return the function - */ - public static JavaMethod create(Class c, String name) { - for (Method m : c.getMethods()) { - if (m.getName().equals(name)) - if (Modifier.isStatic(m.getModifiers())) { - Class[] argTypes = m.getParameterTypes(); - return create(null, m, argTypes); - } - } - throw new RuntimeException("method '" + name + "' not found in " + c.getName() + "!"); - } - - /** - * Creates a function for a non static method. - * If the first argument of the method is of type {@link Context} the - * context is passed in. - * - * @param inst the instance to use for the call - * @param name the name of the method - * @return the function - */ - public static JavaMethod create(Object inst, String name) { - final Class c = inst.getClass(); - for (Method m : c.getMethods()) { - if (m.getName().equals(name)) - if (!Modifier.isStatic(m.getModifiers())) { - Class[] argTypes = m.getParameterTypes(); - return create(inst, m, argTypes); - } - } - throw new RuntimeException("method '" + name + "' not found in " + c.getName() + "!"); - } - - private static JavaMethod create(Object inst, Method m, Class[] argTypes) { - if (argTypes.length > 0 && argTypes[0].isAssignableFrom(Context.class)) - return new JavaMethod(argTypes.length - 1, inst, m, argTypes, true); - else - return new JavaMethod(argTypes.length, inst, m, argTypes, false); - } - - private JavaMethod(int argCount, Object instance, Method method, Class[] argTypes, boolean addContext) { - super(argCount); - this.instance = instance; - this.method = method; - this.argTypes = argTypes; - this.addContext = addContext; - } - - @Override - public Object call(Context c, ArrayList args) throws HGSEvalException { - if (getArgCount() != args.size()) - throw new HGSEvalException("wrong number of arguments! expected: " + getArgCount() + ", but found:" + args.size()); - - Object[] a; - int i = 0; - if (addContext) { - a = new Object[args.size() + 1]; - a[0] = c; - i++; - } else - a = new Object[args.size()]; - - for (Expression exp : args) { - a[i] = exp.value(c); - i++; - } - - return f(a); - } - - - private Object f(Object... args) throws HGSEvalException { - for (int i = 0; i < args.length; i++) { - if (!argTypes[i].isAssignableFrom(args[i].getClass())) - throw new HGSEvalException("Argument " + i + " has wrong type! Expected: " - + argTypes[i].getName() - + ", found " - + args[i].getClass().getName()); - } - - try { - return method.invoke(instance, args); - } catch (IllegalAccessException | InvocationTargetException e) { - throw new HGSEvalException("Error invoking the java method " + method.getName() + "!", e); - } - } -} diff --git a/src/main/java/de/neemann/digital/hdl/vhdl/lib/VHDLTemplate.java b/src/main/java/de/neemann/digital/hdl/vhdl/lib/VHDLTemplate.java index ac71524f4..a054fad96 100644 --- a/src/main/java/de/neemann/digital/hdl/vhdl/lib/VHDLTemplate.java +++ b/src/main/java/de/neemann/digital/hdl/vhdl/lib/VHDLTemplate.java @@ -6,8 +6,7 @@ package de.neemann.digital.hdl.vhdl.lib; import de.neemann.digital.hdl.hgs.*; -import de.neemann.digital.hdl.hgs.function.Function; -import de.neemann.digital.hdl.hgs.function.InnerFunction; +import de.neemann.digital.hdl.hgs.function.JavaClass; import de.neemann.digital.hdl.model.HDLException; import de.neemann.digital.hdl.model.HDLNode; import de.neemann.digital.hdl.model.Port; @@ -20,7 +19,6 @@ import java.io.InputStreamReader; import java.io.Reader; import java.util.ArrayList; import java.util.HashMap; -import java.util.List; import static de.neemann.digital.hdl.vhdl.VHDLLibrary.writePort; @@ -28,58 +26,10 @@ import static de.neemann.digital.hdl.vhdl.VHDLLibrary.writePort; * Reads a file with the vhdl code to create the entity */ public class VHDLTemplate implements VHDLEntity { + private static final JavaClass TEMP_FUNCTIONS_CLASS + = new JavaClass<>(VHDLTemplateFunctions.class); + private static final String ENTITY_PREFIX = "DIG_"; - private static Context createBuitInContext() { - try { - return new Context() - .declareFunc("zero", new FunctionZero()) - .declareFunc("type", new FunctionType()) - .declareFunc("genericType", new FunctionGenericType()) - .declareFunc("value", new FunctionValue()) - .declareFunc("beginGenericPort", new InnerFunction(0) { - @Override - public Object call(Context c, ArrayList args) throws HGSEvalException { - c.declareVar("portStartPos", c.length()); - return null; - } - }) - .declareFunc("endGenericPort", new InnerFunction(0) { - @Override - public Object call(Context c, ArrayList args) throws HGSEvalException { - int start = Value.toInt(c.getVar("portStartPos")); - String portDecl = c.toString().substring(start); - c.declareVar("portDecl", portDecl); - return null; - } - }) - .declareFunc("registerGeneric", new InnerFunction(-1) { - @Override - public Object call(Context c, ArrayList args) throws HGSEvalException { - List generics; - if (c.contains("generics")) - generics = (List) c.getVar("generics"); - else { - generics = new ArrayList<>(); - c.declareVar("generics", generics); - } - String name = Value.toString(args.get(0).value(c)); - if (args.size() == 1) - generics.add(new Generic(name, "Integer")); - else if (args.size() == 2) - generics.add(new Generic(name, Value.toString(args.get(1).value(c)))); - else - throw new HGSEvalException("registerGeneric needs one or two arguments!"); - return null; - } - }); - } catch (HGSEvalException e) { - throw new RuntimeException("error creating template built-in's!"); - } - } - - private static final Context VHDLCONTEXT = createBuitInContext(); - - private final static String ENTITY_PREFIX = "DIG_"; private final Statement statements; private final String entityName; private HashMap entities; @@ -124,7 +74,7 @@ public class VHDLTemplate implements VHDLEntity { Entity e = getEntity(node); if (!e.isWritten()) { out.print(e.getCode()); - e.setWritten(true); + e.setWritten(); } } catch (HGSEvalException e) { throw new IOException("error evaluating the template " + createFileName(entityName), e); @@ -164,13 +114,13 @@ public class VHDLTemplate implements VHDLEntity { public void writeGenericMap(CodePrinter out, HDLNode node) throws IOException { try { final Entity e = getEntity(node); - if (e.getGenerics() != null) { + if (!e.getGenerics().isEmpty()) { out.println("generic map (").inc(); Separator semic = new Separator(",\n"); - for (Generic gen : e.getGenerics()) { + for (VHDLTemplateFunctions.Generic gen : e.getGenerics()) { semic.check(out); - final Object value = node.getAttributes().hgsMapGet(gen.name); - out.print(gen.name).print(" => ").print(gen.format(value)); + final Object value = node.getAttributes().hgsMapGet(gen.getName()); + out.print(gen.getName()).print(" => ").print(gen.format(value)); } out.println(")").dec(); } @@ -196,24 +146,17 @@ public class VHDLTemplate implements VHDLEntity { private final class Entity { private final String code; - private final String portDecl; private final String name; - private final List generics; + private final VHDLTemplateFunctions helper; private boolean isWritten = false; private Entity(HDLNode node, String name) throws HGSEvalException { - final Context c = new Context(VHDLCONTEXT) - .declareVar("elem", node.getAttributes()); + helper = new VHDLTemplateFunctions(); + final Context c = new Context() + .declareVar("elem", node.getAttributes()) + .declareVar("vhdl", TEMP_FUNCTIONS_CLASS.createMap(helper)); statements.execute(c); code = c.toString(); - if (c.contains("portDecl")) - portDecl = c.getVar("portDecl").toString(); - else - portDecl = null; - if (c.contains("generics")) - generics = (List) c.getVar("generics"); - else - generics = null; if (c.contains("entityName")) this.name = c.getVar("entityName").toString(); @@ -226,129 +169,25 @@ public class VHDLTemplate implements VHDLEntity { } private String getPortDecl() { - return portDecl; + return helper.getPortDecl(); } private boolean isWritten() { return isWritten; } - private void setWritten(boolean written) { - isWritten = written; + private void setWritten() { + isWritten = true; } private String getName() { return name; } - private List getGenerics() { - return generics; + private ArrayList getGenerics() { + return helper.getGenerics(); } } - private final static class FunctionType extends Function { - - private FunctionType() { - super(1); - } - - @Override - protected Object f(Object... args) throws HGSEvalException { - int bits = Value.toInt(args[0]); - if (bits == 0) - throw new HGSEvalException("zero bits is not allowed!"); - if (bits == 1) - return "std_logic"; - else - return "std_logic_vector (" + (bits - 1) + " downto 0)"; - } - - } - - private final static class FunctionGenericType extends Function { - - private FunctionGenericType() { - super(1); - } - - @Override - protected Object f(Object... args) throws HGSEvalException { - int n = Value.toInt(args[0]); - if (n == 1) - return "std_logic"; - else - return "std_logic_vector ((Bits-1) downto 0)"; - } - - } - - private final static class FunctionZero extends Function { - - private FunctionZero() { - super(1); - } - - @Override - protected Object f(Object... args) throws HGSEvalException { - int n = Value.toInt(args[0]); - if (n == 1) - return "'0'"; - else - return "(others => '0')"; - } - - } - - private final static class FunctionValue extends Function { - /** - * Creates a new function - */ - private FunctionValue() { - super(2); - } - - @Override - protected Object f(Object... args) throws HGSEvalException { - int val = Value.toInt(args[0]); - int bits = Value.toInt(args[1]); - return getBin(val, bits); - } - - private static String getBin(int val, int bits) { - String s = Integer.toBinaryString(val); - while (s.length() < bits) - s = "0" + s; - - if (bits > 1) - s = "\"" + s + "\""; - else - s = "'" + s + "'"; - - return s; - } - } - - private static final class Generic { - private final String name; - private final String type; - - private Generic(String name, String type) { - this.name = name; - this.type = type.toLowerCase(); - } - - public String format(Object o) throws HGSEvalException { - switch (type) { - case "integer": - return Long.toString(Value.toLong(o)); - case "real": - return Double.toString(Value.toDouble(o)); - case "std_logic": - return "'" + (Value.toBool(o) ? 1 : 0) + "'"; - default: - throw new HGSEvalException("type " + type + " not allowed as generic"); - } - } - } } diff --git a/src/main/java/de/neemann/digital/hdl/vhdl/lib/VHDLTemplateFunctions.java b/src/main/java/de/neemann/digital/hdl/vhdl/lib/VHDLTemplateFunctions.java new file mode 100644 index 000000000..64a2b4179 --- /dev/null +++ b/src/main/java/de/neemann/digital/hdl/vhdl/lib/VHDLTemplateFunctions.java @@ -0,0 +1,171 @@ +/* + * 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.hdl.vhdl.lib; + +import de.neemann.digital.hdl.hgs.Context; +import de.neemann.digital.hdl.hgs.HGSEvalException; +import de.neemann.digital.hdl.hgs.Value; + +import java.util.ArrayList; + +/** + * Helper functions for the vhdl template generator. + * The public methods are mapped to the vhdl templates. + */ +public final class VHDLTemplateFunctions { + + private int portStartPos; + private String portDecl; + private ArrayList generics; + + /** + * Creates a new instance + */ + public VHDLTemplateFunctions() { + generics = new ArrayList<>(); + } + + /** + * Create a vhdl zero with the given bit number + * + * @param bits the bit number + * @return '0' or (others => '0') + */ + public static String zero(long bits) { + if (bits == 1) + return "'0'"; + else + return "(others => '0')"; + } + + /** + * Creates a vhdl value + * + * @param val the value + * @param bits the bit number + * @return the value as vhdl code + */ + public static String value(long val, long bits) { + String s = Long.toBinaryString(val); + while (s.length() < bits) + s = "0" + s; + + if (bits > 1) + s = "\"" + s + "\""; + else + s = "'" + s + "'"; + + return s; + } + + /** + * Creats the code for a generic type + * + * @param n the number of bits + * @return the type + */ + public static String genericType(long n) { + if (n == 1) + return "std_logic"; + else + return "std_logic_vector ((Bits-1) downto 0)"; + } + + /** + * Creates a type of given width + * + * @param n the number of bits + * @return the type + */ + public static String type(long n) { + if (n == 1) + return "std_logic"; + else + return "std_logic_vector (" + (n - 1) + " downto 0)"; + } + + /** + * Begins the generic port definition. + * + * @param c the context + */ + public void beginGenericPort(Context c) { + portStartPos = c.length(); + } + + /** + * Ends the generic port definition. + * + * @param c the context + */ + public void endGenericPort(Context c) { + portDecl = c.toString().substring(portStartPos); + } + + /** + * Registers a generic value of the given type + * + * @param args the arguments + * @throws HGSEvalException HGSEvalException + */ + public void registerGeneric(String... args) throws HGSEvalException { + if (args.length == 1) + generics.add(new Generic(args[0], "integer")); + else if (args.length == 2) + generics.add(new Generic(args[0], args[1])); + else + throw new HGSEvalException("wrong number of arguments"); + } + + String getPortDecl() { + return portDecl; + } + + ArrayList getGenerics() { + return generics; + } + + /** + * A generic value + */ + public static final class Generic { + private final String name; + private final String type; + + private Generic(String name, String type) { + this.name = name; + this.type = type.toLowerCase(); + } + + /** + * @return the name of the generic value + */ + public String getName() { + return name; + } + + /** + * Formats the generic value according to the values type + * + * @param val the value + * @return the formatted vhdl value + * @throws HGSEvalException HGSEvalException + */ + public String format(Object val) throws HGSEvalException { + switch (type) { + case "integer": + return Long.toString(Value.toLong(val)); + case "real": + return Double.toString(Value.toDouble(val)); + case "std_logic": + return "'" + (Value.toBool(val) ? 1 : 0) + "'"; + default: + throw new HGSEvalException("type " + type + " not allowed as generic"); + } + } + } + +} diff --git a/src/main/resources/vhdl/DIG_Add.tem b/src/main/resources/vhdl/DIG_Add.tem index 738c2e250..e521a15e8 100644 --- a/src/main/resources/vhdl/DIG_Add.tem +++ b/src/main/resources/vhdl/DIG_Add.tem @@ -3,15 +3,15 @@ USE ieee.std_logic_1164.all; USE ieee.std_logic_unsigned.all; entity DIG_Add is - - generic ( Bits: integer ); + + generic ( Bits: integer ); port ( PORT_s: out std_logic_vector((Bits-1) downto 0); PORT_c_o: out std_logic; PORT_a: in std_logic_vector((Bits-1) downto 0); PORT_b: in std_logic_vector((Bits-1) downto 0); PORT_c_i: in std_logic ); - + end DIG_Add; architecture DIG_Add_arch of DIG_Add is diff --git a/src/main/resources/vhdl/DIG_BitExtender.tem b/src/main/resources/vhdl/DIG_BitExtender.tem index d18f26203..84999aa03 100644 --- a/src/main/resources/vhdl/DIG_BitExtender.tem +++ b/src/main/resources/vhdl/DIG_BitExtender.tem @@ -5,13 +5,13 @@ USE ieee.std_logic_1164.all; entityName:="DIG_BitExtender";?> entity DIG_BitExtender is - - generic ( inputBits : integer; - outputBits : integer); + + generic ( inputBits : integer; + outputBits : integer); port ( PORT_in: in std_logic_vector ((inputBits-1) downto 0); PORT_out: out std_logic_vector ((outputBits-1) downto 0) ); - + end DIG_BitExtender; architecture DIG_BitExtender_arch of DIG_BitExtender is @@ -24,12 +24,12 @@ end DIG_BitExtender_arch; entityName:="DIG_BitExtenderSingle"; ?> entity DIG_BitExtenderSingle is - - generic ( outputBits : integer); + + generic ( outputBits : integer); port ( PORT_in: in std_logic; PORT_out: out std_logic_vector ((outputBits-1) downto 0) ); - + end DIG_BitExtenderSingle; architecture DIG_BitExtenderSingle_arch of DIG_BitExtenderSingle is diff --git a/src/main/resources/vhdl/DIG_BitSelector.tem b/src/main/resources/vhdl/DIG_BitSelector.tem index 8944c14b0..5e35c949b 100644 --- a/src/main/resources/vhdl/DIG_BitSelector.tem +++ b/src/main/resources/vhdl/DIG_BitSelector.tem @@ -9,8 +9,8 @@ USE ieee.std_logic_1164.all; entity is port ( PORT_out: out std_logic; - PORT_in: in ; - PORT_sel: in ); + PORT_in: in ; + PORT_sel: in ); end ; architecture _arch of is @@ -18,6 +18,6 @@ begin with PORT_sel select PORT_out <= - PORT_in() when , - when others; + PORT_in() when , + when others; end _arch; diff --git a/src/main/resources/vhdl/DIG_Comparator.tem b/src/main/resources/vhdl/DIG_Comparator.tem index 845323adf..f1c82b90b 100644 --- a/src/main/resources/vhdl/DIG_Comparator.tem +++ b/src/main/resources/vhdl/DIG_Comparator.tem @@ -10,15 +10,15 @@ USE ieee.std_logic_1164.all; ?> entity is - - generic ( Bits : integer ); + + generic ( Bits : integer ); port ( PORT_gr: out std_logic; PORT_eq: out std_logic; PORT_le: out std_logic; - PORT_a: in ; - PORT_b: in ); - + PORT_a: in ; + PORT_b: in ); + end ; architecture _arch of is diff --git a/src/main/resources/vhdl/DIG_Counter.tem b/src/main/resources/vhdl/DIG_Counter.tem index abe0f0d64..958094e31 100644 --- a/src/main/resources/vhdl/DIG_Counter.tem +++ b/src/main/resources/vhdl/DIG_Counter.tem @@ -3,15 +3,15 @@ USE ieee.std_logic_1164.all; USE ieee.std_logic_unsigned.all; entity DIG_Counter is - - generic ( Bits: integer ); + + generic ( Bits: integer ); port ( PORT_out: out std_logic_vector((Bits-1) downto 0); PORT_ovf: out std_logic; PORT_C: in std_logic; PORT_en: in std_logic; PORT_clr: in std_logic ); - + end DIG_Counter; architecture DIG_Counter_arch of DIG_Counter is diff --git a/src/main/resources/vhdl/DIG_D_FF.tem b/src/main/resources/vhdl/DIG_D_FF.tem index 35643b2e8..5c3ce699b 100644 --- a/src/main/resources/vhdl/DIG_D_FF.tem +++ b/src/main/resources/vhdl/DIG_D_FF.tem @@ -8,17 +8,17 @@ USE ieee.std_logic_1164.all; ?> entity is - - 1) {?>generic ( Bits: integer ); - port ( PORT_D : in ; + + 1) {?>generic ( Bits: integer ); + port ( PORT_D : in ; PORT_C : in std_logic; - PORT_Q : out ; - PORT_notQ : out ); - + PORT_Q : out ; + PORT_notQ : out ); + end ; architecture _arch of is - signal state : := ; + signal state : := ; begin PORT_Q <= state; PORT_notQ <= NOT( state ); diff --git a/src/main/resources/vhdl/DIG_D_FF_AS.tem b/src/main/resources/vhdl/DIG_D_FF_AS.tem index af605ff63..9a7775c4f 100644 --- a/src/main/resources/vhdl/DIG_D_FF_AS.tem +++ b/src/main/resources/vhdl/DIG_D_FF_AS.tem @@ -9,28 +9,28 @@ USE ieee.std_logic_1164.all; ?> entity is - - 1) {?>generic ( Bits: integer ); + + 1) {?>generic ( Bits: integer ); port ( - PORT_Q: out ; - PORT_notQ: out ; + PORT_Q: out ; + PORT_notQ: out ; PORT_Set: in std_logic; - PORT_D: in ; + PORT_D: in ; PORT_C: in std_logic; PORT_Clr: in std_logic ); - + end ; architecture _arch of is - signal state : := ; + signal state : := ; begin process ( PORT_Set, PORT_Clr, PORT_C ) begin if (PORT_Set='1') then - state <= NOT(); + state <= NOT(); elsif (PORT_Clr='1') then - state <= ; + state <= ; elsif rising_edge(PORT_C) then state <= PORT_D; end if; diff --git a/src/main/resources/vhdl/DIG_Decoder.tem b/src/main/resources/vhdl/DIG_Decoder.tem index ad823bef9..47d997ae1 100644 --- a/src/main/resources/vhdl/DIG_Decoder.tem +++ b/src/main/resources/vhdl/DIG_Decoder.tem @@ -10,12 +10,12 @@ entity is PORT_out_: out std_logic; - PORT_sel: in ); + PORT_sel: in ); end ; architecture _arch of is begin - PORT_out_ <= '1' when PORT_sel = else '0'; + PORT_out_ <= '1' when PORT_sel = else '0'; end _arch; diff --git a/src/main/resources/vhdl/DIG_Demultiplexer.tem b/src/main/resources/vhdl/DIG_Demultiplexer.tem index 8aacb3b95..d779959e8 100644 --- a/src/main/resources/vhdl/DIG_Demultiplexer.tem +++ b/src/main/resources/vhdl/DIG_Demultiplexer.tem @@ -10,22 +10,22 @@ USE ieee.std_logic_1164.all; ?> entity is - + 1) { ?> - generic ( Bits : integer ); + generic ( Bits : integer ); port ( - PORT_out_: out ; + PORT_out_: out ; - PORT_sel: in ; - PORT_in: in ); - + PORT_sel: in ; + PORT_in: in ); + end ; architecture _arch of is begin - PORT_out_ <= PORT_in when PORT_sel = else ; + PORT_out_ <= PORT_in when PORT_sel = else ; end _arch; diff --git a/src/main/resources/vhdl/DIG_Driver.tem b/src/main/resources/vhdl/DIG_Driver.tem index 43eb0dbb0..5651bb2d2 100644 --- a/src/main/resources/vhdl/DIG_Driver.tem +++ b/src/main/resources/vhdl/DIG_Driver.tem @@ -9,13 +9,13 @@ USE ieee.std_logic_1164.all; ?> entity is - - 1) {?>generic ( Bits : integer ); + + 1) {?>generic ( Bits : integer ); port ( - PORT_out: out ; - PORT_in: in ; + PORT_out: out ; + PORT_in: in ; PORT_sel: in std_logic ); - + end ; architecture _arch of is diff --git a/src/main/resources/vhdl/DIG_DriverInvSel.tem b/src/main/resources/vhdl/DIG_DriverInvSel.tem index 060bc57cf..ddf2f03d6 100644 --- a/src/main/resources/vhdl/DIG_DriverInvSel.tem +++ b/src/main/resources/vhdl/DIG_DriverInvSel.tem @@ -9,13 +9,13 @@ USE ieee.std_logic_1164.all; ?> entity is - - 1) {?>generic ( Bits : integer ); + + 1) {?>generic ( Bits : integer ); port ( - PORT_out: out ; - PORT_in: in ; + PORT_out: out ; + PORT_in: in ; PORT_sel: in std_logic ); - + end ; architecture _arch of is diff --git a/src/main/resources/vhdl/DIG_JK_FF.tem b/src/main/resources/vhdl/DIG_JK_FF.tem index f94e9a310..b0c18f33f 100644 --- a/src/main/resources/vhdl/DIG_JK_FF.tem +++ b/src/main/resources/vhdl/DIG_JK_FF.tem @@ -2,15 +2,15 @@ LIBRARY ieee; USE ieee.std_logic_1164.all; entity DIG_JK_FF is - - generic (Default : std_logic); + + generic (Default : std_logic); port ( PORT_Q: out std_logic; PORT_notQ: out std_logic; PORT_J: in std_logic; PORT_C: in std_logic; PORT_K: in std_logic ); - + end DIG_JK_FF; architecture DIG_JK_FF_arch of DIG_JK_FF is diff --git a/src/main/resources/vhdl/DIG_JK_FF_AS.tem b/src/main/resources/vhdl/DIG_JK_FF_AS.tem index f79e63d0e..eeab77822 100644 --- a/src/main/resources/vhdl/DIG_JK_FF_AS.tem +++ b/src/main/resources/vhdl/DIG_JK_FF_AS.tem @@ -2,8 +2,8 @@ LIBRARY ieee; USE ieee.std_logic_1164.all; entity DIG_JK_FF_AS is - - generic (Default : std_logic); + + generic (Default : std_logic); port ( PORT_Q: out std_logic; PORT_notQ: out std_logic; @@ -12,7 +12,7 @@ entity DIG_JK_FF_AS is PORT_C: in std_logic; PORT_K: in std_logic; PORT_Clr: in std_logic ); - + end DIG_JK_FF_AS; architecture DIG_JK_FF_AS_arch of DIG_JK_FF_AS is diff --git a/src/main/resources/vhdl/DIG_MMCME2_BASE.tem b/src/main/resources/vhdl/DIG_MMCME2_BASE.tem index 3de06fb5f..7dc8e7330 100644 --- a/src/main/resources/vhdl/DIG_MMCME2_BASE.tem +++ b/src/main/resources/vhdl/DIG_MMCME2_BASE.tem @@ -5,21 +5,21 @@ Library UNISIM; use UNISIM.vcomponents.all; entity DIG_MMCME2_BASE is - + generic ( - D_PARAM : integer; - M_PARAM : real; + D_PARAM : integer; + M_PARAM : real; - DIV_PARAM : integer; - DIV4_PARAM : integer; + DIV_PARAM : integer; + DIV4_PARAM : integer; - DIV_PARAM : real; + DIV_PARAM : real; - PERIOD_PARAM: real); + PERIOD_PARAM: real); port ( PORT_in: in std_logic; PORT_out: out std_logic ); - + end DIG_MMCME2_BASE; architecture DIG_MMCME2_BASE_arch of DIG_MMCME2_BASE is diff --git a/src/main/resources/vhdl/DIG_Mul.tem b/src/main/resources/vhdl/DIG_Mul.tem index 912cce7d3..3d97cf3a6 100644 --- a/src/main/resources/vhdl/DIG_Mul.tem +++ b/src/main/resources/vhdl/DIG_Mul.tem @@ -3,13 +3,13 @@ USE ieee.std_logic_1164.all; USE ieee.numeric_std.all; entity DIG_Mul is - - generic ( Bits: integer ); + + generic ( Bits: integer ); port ( PORT_a: in std_logic_vector ((Bits-1) downto 0); PORT_b: in std_logic_vector ((Bits-1) downto 0); PORT_mul: out std_logic_vector ((Bits*2-1) downto 0) ); - + end DIG_Mul; architecture DIG_Mul_arch of DIG_Mul is diff --git a/src/main/resources/vhdl/DIG_Multiplexer.tem b/src/main/resources/vhdl/DIG_Multiplexer.tem index d47c44604..ec11df2c1 100644 --- a/src/main/resources/vhdl/DIG_Multiplexer.tem +++ b/src/main/resources/vhdl/DIG_Multiplexer.tem @@ -11,16 +11,16 @@ USE ieee.std_logic_1164.all; ?> entity is - + 1) { ?> - generic ( Bits : integer ); + generic ( Bits : integer ); port ( - PORT_out: out ; - PORT_sel: in ; + PORT_out: out ; + PORT_sel: in ; - PORT_in_: in ); - + PORT_in_: in ); + end ; architecture _arch of is @@ -28,6 +28,6 @@ begin with PORT_sel select PORT_out <= - PORT_in_ when , - when others; + PORT_in_ when , + when others; end _arch; diff --git a/src/main/resources/vhdl/DIG_Not.tem b/src/main/resources/vhdl/DIG_Not.tem index ff59685b2..4050332c7 100644 --- a/src/main/resources/vhdl/DIG_Not.tem +++ b/src/main/resources/vhdl/DIG_Not.tem @@ -9,12 +9,12 @@ USE ieee.std_logic_1164.all; ?> entity is - - 1) {?>generic ( Bits : integer ); + + 1) {?>generic ( Bits : integer ); port ( - PORT_out: out ; - PORT_in: in ); - + PORT_out: out ; + PORT_in: in ); + end ; architecture _arch of is diff --git a/src/main/resources/vhdl/DIG_Operate.tem b/src/main/resources/vhdl/DIG_Operate.tem index e8e11a604..d2449a977 100644 --- a/src/main/resources/vhdl/DIG_Operate.tem +++ b/src/main/resources/vhdl/DIG_Operate.tem @@ -9,17 +9,17 @@ USE ieee.std_logic_1164.all; ?> entity is - - 1) {?>generic ( Bits : integer ); + + 1) {?>generic ( Bits : integer ); port ( - PORT_out: out ; + PORT_out: out ; PORT_In_: in ; - + end ; architecture _arch of is begin diff --git a/src/main/resources/vhdl/DIG_PriorityEncoder.tem b/src/main/resources/vhdl/DIG_PriorityEncoder.tem index 5024fdb18..0c5784c9d 100644 --- a/src/main/resources/vhdl/DIG_PriorityEncoder.tem +++ b/src/main/resources/vhdl/DIG_PriorityEncoder.tem @@ -8,7 +8,7 @@ USE ieee.std_logic_1164.all; entity is port ( - PORT_num: out ; + PORT_num: out ; PORT_any: out std_logic; PORT_in: in std_logic; @@ -19,9 +19,9 @@ architecture _arch of is begin PORT_num <= 0;n--) { ?> - when PORT_in = '1' else + when PORT_in = '1' else - ; + ; PORT_any <= + generic ( - Bits : integer; - AddrBits : integer ); + Bits : integer; + AddrBits : integer ); port ( PORT_1D: out std_logic_vector ((Bits-1) downto 0); PORT_2D: out std_logic_vector ((Bits-1) downto 0); @@ -16,7 +16,7 @@ entity DIG_RAMDualAccess is PORT_1A: in std_logic_vector ((AddrBits-1) downto 0); PORT_1Din: in std_logic_vector ((Bits-1) downto 0); PORT_2A: in std_logic_vector ((AddrBits-1) downto 0) ); - + end DIG_RAMDualAccess; architecture DIG_RAMDualAccess_arch of DIG_RAMDualAccess is diff --git a/src/main/resources/vhdl/DIG_RAMDualPort.tem b/src/main/resources/vhdl/DIG_RAMDualPort.tem index b8d496e94..310615550 100644 --- a/src/main/resources/vhdl/DIG_RAMDualPort.tem +++ b/src/main/resources/vhdl/DIG_RAMDualPort.tem @@ -3,10 +3,10 @@ USE ieee.std_logic_1164.all; USE ieee.numeric_std.all; entity DIG_RAMDualPort is - + generic ( - Bits : integer; - AddrBits : integer ); + Bits : integer; + AddrBits : integer ); port ( PORT_D: out std_logic_vector ((Bits-1) downto 0); PORT_A: in std_logic_vector ((AddrBits-1) downto 0); @@ -14,7 +14,7 @@ entity DIG_RAMDualPort is PORT_str: in std_logic; PORT_C: in std_logic; PORT_ld: in std_logic ); - + end DIG_RAMDualPort; architecture DIG_RAMDualPort_arch of DIG_RAMDualPort is diff --git a/src/main/resources/vhdl/DIG_ROM.tem b/src/main/resources/vhdl/DIG_ROM.tem index 93c5c6293..894b2dd4b 100644 --- a/src/main/resources/vhdl/DIG_ROM.tem +++ b/src/main/resources/vhdl/DIG_ROM.tem @@ -10,20 +10,20 @@ use IEEE.NUMERIC_STD.ALL; entity is port ( - PORT_D: out ; - PORT_A: in ; + PORT_D: out ; + PORT_A: in ; PORT_sel: in std_logic ); end ; architecture _arch of is - type mem is array ( 0 to ) of ; + type mem is array ( 0 to ) of ; constant my_Rom : mem := ( 1) {?>(others => 'Z')'Z'; - elsif PORT_A > then - PORT_D <= ; + elsif PORT_A > then + PORT_D <= ; else PORT_D <= my_rom(to_integer(unsigned(PORT_A))); end if; diff --git a/src/main/resources/vhdl/DIG_Register.tem b/src/main/resources/vhdl/DIG_Register.tem index 2540a725e..9fb7a4fe4 100644 --- a/src/main/resources/vhdl/DIG_Register.tem +++ b/src/main/resources/vhdl/DIG_Register.tem @@ -9,18 +9,18 @@ USE ieee.std_logic_1164.all; ?> entity is - - 1) {?>generic ( Bits: integer ); + + 1) {?>generic ( Bits: integer ); port ( - PORT_Q: out ; - PORT_D: in ; + PORT_Q: out ; + PORT_D: in ; PORT_C: in std_logic; PORT_en: in std_logic ); - + end ; architecture _arch of is - signal state : := ; + signal state : := ; begin PORT_Q <= state; diff --git a/src/main/resources/vhdl/DIG_RegisterFile.tem b/src/main/resources/vhdl/DIG_RegisterFile.tem index da292b8fe..c73856d6b 100644 --- a/src/main/resources/vhdl/DIG_RegisterFile.tem +++ b/src/main/resources/vhdl/DIG_RegisterFile.tem @@ -3,10 +3,10 @@ USE ieee.std_logic_1164.all; USE ieee.numeric_std.all; entity DIG_RegisterFile is - + generic ( - Bits : integer; - AddrBits : integer ); + Bits : integer; + AddrBits : integer ); port ( PORT_Da: out std_logic_vector ((Bits-1) downto 0); PORT_Db: out std_logic_vector ((Bits-1) downto 0); @@ -16,7 +16,7 @@ entity DIG_RegisterFile is PORT_C: in std_logic; PORT_Ra: in std_logic_vector ((AddrBits-1) downto 0); PORT_Rb: in std_logic_vector ((AddrBits-1) downto 0) ); - + end DIG_RegisterFile; architecture DIG_RegisterFile_arch of DIG_RegisterFile is diff --git a/src/main/resources/vhdl/DIG_Reset.tem b/src/main/resources/vhdl/DIG_Reset.tem index 1c14ed8d0..e5374f538 100644 --- a/src/main/resources/vhdl/DIG_Reset.tem +++ b/src/main/resources/vhdl/DIG_Reset.tem @@ -2,12 +2,12 @@ LIBRARY ieee; USE ieee.std_logic_1164.all; entity DIG_Reset is - + generic ( - invertOutput : std_logic ); + invertOutput : std_logic ); port ( PORT_Reset: out std_logic ); - + end DIG_Reset; architecture DIG_Reset_arch of DIG_Reset is diff --git a/src/main/resources/vhdl/DIG_Sub.tem b/src/main/resources/vhdl/DIG_Sub.tem index 3306b59a2..7e349017a 100644 --- a/src/main/resources/vhdl/DIG_Sub.tem +++ b/src/main/resources/vhdl/DIG_Sub.tem @@ -3,15 +3,15 @@ USE ieee.std_logic_1164.all; USE ieee.std_logic_unsigned.all; entity DIG_Sub is - - generic ( Bits: integer ); + + generic ( Bits: integer ); port ( PORT_s: out std_logic_vector((Bits-1) downto 0); PORT_c_o: out std_logic; PORT_a: in std_logic_vector((Bits-1) downto 0); PORT_b: in std_logic_vector((Bits-1) downto 0); PORT_c_i: in std_logic ); - + end DIG_Sub; architecture DIG_Sub_arch of DIG_Sub is diff --git a/src/main/resources/vhdl/DIG_simpleClockDivider.tem b/src/main/resources/vhdl/DIG_simpleClockDivider.tem index a91f421c9..fcf3dee52 100644 --- a/src/main/resources/vhdl/DIG_simpleClockDivider.tem +++ b/src/main/resources/vhdl/DIG_simpleClockDivider.tem @@ -4,13 +4,13 @@ USE ieee.numeric_std.all; USE ieee.std_logic_unsigned.all; entity DIG_simpleClockDivider is - + generic ( - maxCounter : integer ); + maxCounter : integer ); port ( PORT_out: out std_logic; PORT_in: in std_logic ); - + end DIG_simpleClockDivider; architecture DIG_simpleClockDivider_arch of DIG_simpleClockDivider is diff --git a/src/test/java/de/neemann/digital/hdl/hgs/ParserTest.java b/src/test/java/de/neemann/digital/hdl/hgs/ParserTest.java index 69b90e29f..d44300613 100644 --- a/src/test/java/de/neemann/digital/hdl/hgs/ParserTest.java +++ b/src/test/java/de/neemann/digital/hdl/hgs/ParserTest.java @@ -5,7 +5,7 @@ */ package de.neemann.digital.hdl.hgs; -import de.neemann.digital.hdl.hgs.function.JavaMethod; +import de.neemann.digital.hdl.hgs.function.JavaClass; import de.neemann.digital.hdl.hgs.function.Function; import de.neemann.digital.integration.FileScanner; import de.neemann.digital.integration.Resources; @@ -405,45 +405,59 @@ public class ParserTest extends TestCase { return sb.toString(); } - private int inner = 0; + public static final class TestClass { + private long inner; - public void javaFunc2() { - inner = 5; + public void add(long n) { + inner += n; + } + + public void sub(long n) { + inner -= n; + } } - public static String javaFunc3(String text) { - return text + text; + public static final class TestClassStatic { + private static long inner; + + public static void set(long n) { + inner = n; + } + + public static void add(long n) { + inner += n; + } + + public static void sub(long n) { + inner -= n; + } + + public static String mean(String... value) { + String sum = ""; + for (int i = 0; i < value.length; i++) + sum += value[i]; + return sum; + } } - public static String javaFunc4(Context c, String text) { - return text + c.toString(); + public void testJavaClass() throws ParserException, IOException, HGSEvalException { + JavaClass jc = new JavaClass<>(TestClass.class); + TestClass t = new TestClass(); + exec("", + new Context().declareVar("z", jc.createMap(t))); + assertEquals(3L, t.inner); + + JavaClass jcs = new JavaClass<>(TestClassStatic.class); + exec("", + new Context().declareVar("z", jcs.createMap(null))); + assertEquals(3L, TestClassStatic.inner); + + + Context c = exec("", + new Context().declareVar("z", jcs.createMap(null))); + assertEquals("aababc",c.toString()); } - public static String javaFunc5(Context c) { - return c.toString(); - } - - public void testJavaMethod() throws ParserException, IOException, HGSEvalException { - Context c = exec("", - new Context().declareMethod("javaFunc", this)); - assertEquals("TestTest-aaaaa", c.toString()); - - c = exec("", - new Context().declareStaticMethod("javaFunc3", ParserTest.class)); - assertEquals("TestTest", c.toString()); - - exec("", - new Context().declareMethod("javaFunc2", this)); - assertEquals(5, inner); - - c = exec("Hello World!", - new Context().declareStaticMethod("javaFunc4", ParserTest.class)); - assertEquals("Hello World!-Test-Hello World!", c.toString()); - - c = exec("Hello World!", - new Context().declareStaticMethod("javaFunc5", ParserTest.class)); - assertEquals("Hello World!Hello World!", c.toString()); - } public void testPanic() throws IOException, ParserException, HGSEvalException { Statement s = new Parser("1) panic(\"myError\"); ?>").parse();