From b96714d61c1ca28835eaf7b8bc0a9332a75c9ba5 Mon Sep 17 00:00:00 2001 From: hneemann Date: Thu, 31 Dec 2020 14:04:34 +0100 Subject: [PATCH] allows the generic code to load a hex file --- .../digital/draw/library/ResolveGenerics.java | 6 + .../de/neemann/digital/hdl/hgs/Context.java | 38 ++++++ .../hdl/verilog2/VerilogSimulatorTest.java | 4 +- .../digital/hdl/vhdl2/VHDLSimulatorTest.java | 4 +- .../digital/integration/TestExamples.java | 4 +- .../dig/test/vhdl/romPreload/lut.dig | 89 ++++++++++++++ .../dig/test/vhdl/romPreload/lut1.hex | 9 ++ .../dig/test/vhdl/romPreload/lut2.hex | 9 ++ .../dig/test/vhdl/romPreload/lutTest.dig | 110 ++++++++++++++++++ 9 files changed, 267 insertions(+), 6 deletions(-) create mode 100644 src/test/resources/dig/test/vhdl/romPreload/lut.dig create mode 100644 src/test/resources/dig/test/vhdl/romPreload/lut1.hex create mode 100644 src/test/resources/dig/test/vhdl/romPreload/lut2.hex create mode 100644 src/test/resources/dig/test/vhdl/romPreload/lutTest.dig diff --git a/src/main/java/de/neemann/digital/draw/library/ResolveGenerics.java b/src/main/java/de/neemann/digital/draw/library/ResolveGenerics.java index cc67c55e3..0f7042407 100644 --- a/src/main/java/de/neemann/digital/draw/library/ResolveGenerics.java +++ b/src/main/java/de/neemann/digital/draw/library/ResolveGenerics.java @@ -58,6 +58,7 @@ public class ResolveGenerics { boolean isCustom = library.getElementType(ve.getElementName(), ve.getElementAttributes()).isCustom(); Statement genS = getStatement(gen); Context mod = new Context(); + mod.declareVar(Context.BASE_FILE_KEY, circuit.getOrigin().getPath()); if (isCustom) { mod.declareVar("args", args) .declareFunc("setCircuit", new SetCircuitFunc(ve)); @@ -96,6 +97,11 @@ public class ResolveGenerics { } } else { context = new Context(); + try { + context.declareVar(Context.BASE_FILE_KEY, circuit.getOrigin().getPath()); + } catch (HGSEvalException e) { + throw new NodeException("error setting the base filename", e); + } List g = circuit.getElements(v -> v.equalsDescription(GenericInitCode.DESCRIPTION) && v.getElementAttributes().get(Keys.ENABLED)); if (g.size() == 0) throw new NodeException(Lang.get("err_noGenericInitCode")); 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 a563c0371..7964789a5 100644 --- a/src/main/java/de/neemann/digital/hdl/hgs/Context.java +++ b/src/main/java/de/neemann/digital/hdl/hgs/Context.java @@ -5,7 +5,10 @@ */ package de.neemann.digital.hdl.hgs; +import de.neemann.digital.FileLocator; import de.neemann.digital.core.Bits; +import de.neemann.digital.core.memory.DataField; +import de.neemann.digital.core.memory.importer.Importer; import de.neemann.digital.hdl.hgs.function.Func; import de.neemann.digital.hdl.hgs.function.Function; import de.neemann.digital.hdl.hgs.function.InnerFunction; @@ -13,6 +16,8 @@ import de.neemann.digital.lang.Lang; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.File; +import java.io.IOException; import java.util.*; /** @@ -23,6 +28,11 @@ public class Context implements HGSMap { // declare some functions which are always present private static final HashMap BUILT_IN = new HashMap<>(); + /** + * Key used to store the base file name in the context + */ + public static final String BASE_FILE_KEY = "baseFile"; + static { BUILT_IN.put("bitsNeededFor", new FunctionBitsNeeded()); BUILT_IN.put("ceil", new FunctionCeil()); @@ -43,6 +53,7 @@ public class Context implements HGSMap { BUILT_IN.put("output", new FunctionOutput()); BUILT_IN.put("splitString", new FunctionSplitString()); BUILT_IN.put("identifier", new FunctionIdentifier()); + BUILT_IN.put("loadHex", new FunctionLoadHex()); BUILT_IN.put("sizeOf", new Func(1, args -> Value.toArray(args[0]).hgsArraySize())); BUILT_IN.put("newMap", new Func(0, args -> new HashMap())); BUILT_IN.put("newList", new Func(0, args -> new ArrayList())); @@ -605,6 +616,33 @@ public class Context implements HGSMap { } } + private static final class FunctionLoadHex extends InnerFunction { + private FunctionLoadHex() { + super(2); + } + + @Override + public Object call(Context c, ArrayList args) throws HGSEvalException { + String name = args.get(0).value(c).toString(); + int dataBits = Value.toInt(args.get(1).value(c)); + FileLocator fileLocator = new FileLocator(name); + if (c.contains(BASE_FILE_KEY)) + fileLocator.setBaseFile(new File(c.getVar(BASE_FILE_KEY).toString())); + File hexFile = fileLocator.locate(); + + if (hexFile == null) + throw new HGSEvalException("file " + name + " not found!"); + + try { + DataField dataField = Importer.read(hexFile, dataBits); + dataField.trim(); + return dataField; + } catch (IOException e) { + throw new HGSEvalException("error reading the file " + hexFile.getPath(), e); + } + } + } + @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/src/test/java/de/neemann/digital/hdl/verilog2/VerilogSimulatorTest.java b/src/test/java/de/neemann/digital/hdl/verilog2/VerilogSimulatorTest.java index 34345a17d..85d77554a 100644 --- a/src/test/java/de/neemann/digital/hdl/verilog2/VerilogSimulatorTest.java +++ b/src/test/java/de/neemann/digital/hdl/verilog2/VerilogSimulatorTest.java @@ -51,8 +51,8 @@ public class VerilogSimulatorTest extends TestCase { File examples = new File(Resources.getRoot(), "/dig/test/vhdl"); try { int tested = new FileScanner(this::checkVerilogExport).noOutput().scan(examples); - assertEquals(58, tested); - assertEquals(52, testBenches); + assertEquals(60, tested); + assertEquals(53, testBenches); } catch (FileScanner.SkipAllException e) { // if iverilog is not installed its also ok } diff --git a/src/test/java/de/neemann/digital/hdl/vhdl2/VHDLSimulatorTest.java b/src/test/java/de/neemann/digital/hdl/vhdl2/VHDLSimulatorTest.java index 67d84b901..91a9573b4 100644 --- a/src/test/java/de/neemann/digital/hdl/vhdl2/VHDLSimulatorTest.java +++ b/src/test/java/de/neemann/digital/hdl/vhdl2/VHDLSimulatorTest.java @@ -43,8 +43,8 @@ public class VHDLSimulatorTest extends TestCase { File examples = new File(Resources.getRoot(), "/dig/test/vhdl"); try { int tested = new FileScanner(this::checkVHDLExport).noOutput().scan(examples); - assertEquals(58, tested); - assertEquals(52, testBenches); + assertEquals(60, tested); + assertEquals(53, testBenches); } catch (FileScanner.SkipAllException e) { // if ghdl is not installed its also ok } diff --git a/src/test/java/de/neemann/digital/integration/TestExamples.java b/src/test/java/de/neemann/digital/integration/TestExamples.java index fe8baf04f..5059baac3 100644 --- a/src/test/java/de/neemann/digital/integration/TestExamples.java +++ b/src/test/java/de/neemann/digital/integration/TestExamples.java @@ -50,8 +50,8 @@ public class TestExamples extends TestCase { */ public void testTestExamples() throws Exception { File examples = new File(Resources.getRoot(), "/dig/test"); - assertEquals(196, new FileScanner(this::check).scan(examples)); - assertEquals(186, testCasesInFiles); + assertEquals(198, new FileScanner(this::check).scan(examples)); + assertEquals(187, testCasesInFiles); } /** diff --git a/src/test/resources/dig/test/vhdl/romPreload/lut.dig b/src/test/resources/dig/test/vhdl/romPreload/lut.dig new file mode 100644 index 000000000..5da6b5bcf --- /dev/null +++ b/src/test/resources/dig/test/vhdl/romPreload/lut.dig @@ -0,0 +1,89 @@ + + + 1 + + + isGeneric + true + + + + + ROM + + + AddrBits + 3 + + + Data + 0,1,1,0,1,0,0,1 + + + generic + this.Data=loadHex(args.hexName,1); +this.Label=args.hexName; + + + + + + VDD + + + + + Out + + + Label + Y + + + + + + In + + + Label + A + + + Bits + 3 + + + + + + GenericInitCode + + + generic + hexName:="lut1.hex"; + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/test/resources/dig/test/vhdl/romPreload/lut1.hex b/src/test/resources/dig/test/vhdl/romPreload/lut1.hex new file mode 100644 index 000000000..53627e3c8 --- /dev/null +++ b/src/test/resources/dig/test/vhdl/romPreload/lut1.hex @@ -0,0 +1,9 @@ +v2.0 raw +0 +1 +1 +0 +1 +1 +1 +1 diff --git a/src/test/resources/dig/test/vhdl/romPreload/lut2.hex b/src/test/resources/dig/test/vhdl/romPreload/lut2.hex new file mode 100644 index 000000000..73891f90d --- /dev/null +++ b/src/test/resources/dig/test/vhdl/romPreload/lut2.hex @@ -0,0 +1,9 @@ +v2.0 raw +0 +1 +1 +0 +0 +0 +0 +0 diff --git a/src/test/resources/dig/test/vhdl/romPreload/lutTest.dig b/src/test/resources/dig/test/vhdl/romPreload/lutTest.dig new file mode 100644 index 000000000..40817e271 --- /dev/null +++ b/src/test/resources/dig/test/vhdl/romPreload/lutTest.dig @@ -0,0 +1,110 @@ + + + 1 + + + + lut.dig + + + generic + hexName := "lut1.hex"; + + + + + + lut.dig + + + generic + hexName := "lut2.hex"; + + + + + + Out + + + Label + Y + + + + + + Out + + + Label + X + + + + + + In + + + Label + A + + + Bits + 3 + + + + + + Testcase + + + Testdata + + A Y X + + 0b000 0 0 + 0b001 1 1 + 0b010 1 1 + 0b011 0 0 + 0b100 1 0 + 0b101 1 0 + 0b110 1 0 + 0b111 1 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file