allows the generic code to load a hex file

This commit is contained in:
hneemann 2020-12-31 14:04:34 +01:00
parent a56b04c091
commit b96714d61c
9 changed files with 267 additions and 6 deletions

View File

@ -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<VisualElement> g = circuit.getElements(v -> v.equalsDescription(GenericInitCode.DESCRIPTION) && v.getElementAttributes().get(Keys.ENABLED));
if (g.size() == 0)
throw new NodeException(Lang.get("err_noGenericInitCode"));

View File

@ -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<String, InnerFunction> 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<Expression> 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;

View File

@ -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
}

View File

@ -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
}

View File

@ -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);
}
/**

View File

@ -0,0 +1,89 @@
<?xml version="1.0" encoding="utf-8"?>
<circuit>
<version>1</version>
<attributes>
<entry>
<string>isGeneric</string>
<boolean>true</boolean>
</entry>
</attributes>
<visualElements>
<visualElement>
<elementName>ROM</elementName>
<elementAttributes>
<entry>
<string>AddrBits</string>
<int>3</int>
</entry>
<entry>
<string>Data</string>
<data>0,1,1,0,1,0,0,1</data>
</entry>
<entry>
<string>generic</string>
<string>this.Data=loadHex(args.hexName,1);
this.Label=args.hexName;</string>
</entry>
</elementAttributes>
<pos x="440" y="220"/>
</visualElement>
<visualElement>
<elementName>VDD</elementName>
<elementAttributes/>
<pos x="420" y="240"/>
</visualElement>
<visualElement>
<elementName>Out</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>Y</string>
</entry>
</elementAttributes>
<pos x="540" y="240"/>
</visualElement>
<visualElement>
<elementName>In</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>A</string>
</entry>
<entry>
<string>Bits</string>
<int>3</int>
</entry>
</elementAttributes>
<pos x="380" y="220"/>
</visualElement>
<visualElement>
<elementName>GenericInitCode</elementName>
<elementAttributes>
<entry>
<string>generic</string>
<string>hexName:=&quot;lut1.hex&quot;;</string>
</entry>
</elementAttributes>
<pos x="400" y="300"/>
</visualElement>
</visualElements>
<wires>
<wire>
<p1 x="500" y="240"/>
<p2 x="540" y="240"/>
</wire>
<wire>
<p1 x="420" y="260"/>
<p2 x="440" y="260"/>
</wire>
<wire>
<p1 x="380" y="220"/>
<p2 x="440" y="220"/>
</wire>
<wire>
<p1 x="420" y="240"/>
<p2 x="420" y="260"/>
</wire>
</wires>
<measurementOrdering/>
</circuit>

View File

@ -0,0 +1,9 @@
v2.0 raw
0
1
1
0
1
1
1
1

View File

@ -0,0 +1,9 @@
v2.0 raw
0
1
1
0
0
0
0
0

View File

@ -0,0 +1,110 @@
<?xml version="1.0" encoding="utf-8"?>
<circuit>
<version>1</version>
<attributes/>
<visualElements>
<visualElement>
<elementName>lut.dig</elementName>
<elementAttributes>
<entry>
<string>generic</string>
<string>hexName := &quot;lut1.hex&quot;;</string>
</entry>
</elementAttributes>
<pos x="420" y="240"/>
</visualElement>
<visualElement>
<elementName>lut.dig</elementName>
<elementAttributes>
<entry>
<string>generic</string>
<string>hexName := &quot;lut2.hex&quot;;</string>
</entry>
</elementAttributes>
<pos x="420" y="300"/>
</visualElement>
<visualElement>
<elementName>Out</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>Y</string>
</entry>
</elementAttributes>
<pos x="500" y="240"/>
</visualElement>
<visualElement>
<elementName>Out</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>X</string>
</entry>
</elementAttributes>
<pos x="500" y="300"/>
</visualElement>
<visualElement>
<elementName>In</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>A</string>
</entry>
<entry>
<string>Bits</string>
<int>3</int>
</entry>
</elementAttributes>
<pos x="380" y="240"/>
</visualElement>
<visualElement>
<elementName>Testcase</elementName>
<elementAttributes>
<entry>
<string>Testdata</string>
<testData>
<dataString>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
</dataString>
</testData>
</entry>
</elementAttributes>
<pos x="400" y="340"/>
</visualElement>
</visualElements>
<wires>
<wire>
<p1 x="480" y="240"/>
<p2 x="500" y="240"/>
</wire>
<wire>
<p1 x="380" y="240"/>
<p2 x="400" y="240"/>
</wire>
<wire>
<p1 x="400" y="240"/>
<p2 x="420" y="240"/>
</wire>
<wire>
<p1 x="480" y="300"/>
<p2 x="500" y="300"/>
</wire>
<wire>
<p1 x="400" y="300"/>
<p2 x="420" y="300"/>
</wire>
<wire>
<p1 x="400" y="240"/>
<p2 x="400" y="300"/>
</wire>
</wires>
<measurementOrdering/>
</circuit>