diff --git a/distribution/ReleaseNotes.txt b/distribution/ReleaseNotes.txt index 7e6430ef1..40a0012ad 100644 --- a/distribution/ReleaseNotes.txt +++ b/distribution/ReleaseNotes.txt @@ -7,6 +7,8 @@ HEAD, planned as v0.26 provided the translation. - Fixed a bug in the Demuxer Verilog template that causes problems when using multiple demuxers in the same circuit. +- Generic circuits are easier to debug: It is possible now to create + a specific, concrete circuit from a generic one. - Fixed a bug in the value editor, which occurs, if high-z is the default value of an input. - Fixed an issue which avoids to restart a running simulation by just diff --git a/src/main/dig/generic/barrelShifter/barrelShifter.dig b/src/main/dig/generic/barrelShifter/barrelShifter.dig index 97f749dd5..351b7c010 100644 --- a/src/main/dig/generic/barrelShifter/barrelShifter.dig +++ b/src/main/dig/generic/barrelShifter/barrelShifter.dig @@ -80,33 +80,36 @@ generic - if (isPresent(args)) { - - if (args.direction="right") { - export circuit:="shift-fixed-right-inc.dig"; - } else { - if (args.direction="arith") { - export circuit:="shift-fixed-arith-right-inc.dig"; - } else { - if (args.direction="left") { - export circuit:="shift-fixed-left-inc.dig"; - } else { - panic("only \"left\", \"right\" or \"arith\" is allowed as direction, not \""+args.direction+"\"!"); - } - } - } - - export shiftBits:=bitsNeededFor(args.dataBits-1); + if (args.direction="right") { + export circuit:="shift-fixed-right-inc.dig"; } else { - // used if circuit is started as the main circuit - export circuit:="shift-fixed-left-inc.dig"; - export dataBits:=16; - export shiftBits:=int(4); -} + if (args.direction="arith") { + export circuit:="shift-fixed-arith-right-inc.dig"; + } else { + if (args.direction="left") { + export circuit:="shift-fixed-left-inc.dig"; + } else { + panic("only \"left\", \"right\" or \"arith\" is allowed as direction, not \""+args.direction+"\"!"); + } + } +} + +shiftBits:=bitsNeededFor(args.dataBits-1); + + GenericInitCode + + + generic + dataBits := 5; +direction := "left"; + + + + diff --git a/src/main/dig/generic/barrelShifter/shift-fixed-arith-right-inc.dig b/src/main/dig/generic/barrelShifter/shift-fixed-arith-right-inc.dig index 504a1d409..3d39f2baf 100644 --- a/src/main/dig/generic/barrelShifter/shift-fixed-arith-right-inc.dig +++ b/src/main/dig/generic/barrelShifter/shift-fixed-arith-right-inc.dig @@ -106,6 +106,17 @@ this.outputBits=int(args.dataBits); + + GenericInitCode + + + generic + dataBits := 8; +shift := 3; + + + + diff --git a/src/main/dig/generic/barrelShifter/shift-fixed-left-inc.dig b/src/main/dig/generic/barrelShifter/shift-fixed-left-inc.dig index edff6777c..9e06e6548 100644 --- a/src/main/dig/generic/barrelShifter/shift-fixed-left-inc.dig +++ b/src/main/dig/generic/barrelShifter/shift-fixed-left-inc.dig @@ -116,6 +116,17 @@ this.'Output Splitting' = "0-"+(args.dataBits-args.shift-1); + + GenericInitCode + + + generic + dataBits := 8; +shift := 3; + + + + diff --git a/src/main/dig/generic/barrelShifter/shift-fixed-right-inc.dig b/src/main/dig/generic/barrelShifter/shift-fixed-right-inc.dig index ed307c078..0da3c4b0d 100644 --- a/src/main/dig/generic/barrelShifter/shift-fixed-right-inc.dig +++ b/src/main/dig/generic/barrelShifter/shift-fixed-right-inc.dig @@ -116,6 +116,17 @@ this.'Output Splitting' = args.shift+"-"+(args.dataBits-1);< + + GenericInitCode + + + generic + dataBits := 8; +shift := 3; + + + + diff --git a/src/main/dig/generic/barrelShifter/shift-inc.dig b/src/main/dig/generic/barrelShifter/shift-inc.dig index 393b19585..df277e2f4 100644 --- a/src/main/dig/generic/barrelShifter/shift-inc.dig +++ b/src/main/dig/generic/barrelShifter/shift-inc.dig @@ -13,14 +13,8 @@ generic - if (isPresent(args)) { - export shift := 1<<(args.shiftBits-1); - setCircuit(args.circuit); -} else { - // used if circuit is started as the main circuit - export dataBits:=16; - export shift:=8; -} + shift := 1<<(args.shiftBits-1); +setCircuit(args.circuit); @@ -92,18 +86,11 @@ generic - if (isPresent(args)) { - if (args.shiftBits=2) { - export shift := 1; - setCircuit(args.circuit); - } else { - export shiftBits := args.shiftBits-1; - } + if (args.shiftBits=2) { + export shift := 1; + setCircuit(args.circuit); } else { - // used if circuit is started as the main circuit - export dataBits:=16; - export shiftBits:=3; - export circuit:="shift-fixed-left-inc.dig"; + export shiftBits := args.shiftBits-1; } @@ -128,6 +115,42 @@ this.'Output Splitting' = (args.shiftBits-1)+"-"+(args.shift + + GenericInitCode + + + Label + 3 bits + + + generic + circuit := "shift-fixed-left-inc.dig"; +dataBits := 8; +shiftBits := 3; + + + enabled + false + + + + + + GenericInitCode + + + Label + 2 bits + + + generic + circuit := "shift-fixed-left-inc.dig"; +dataBits := 8; +shiftBits := 2; + + + + diff --git a/src/main/dig/generic/gray/GrayCounter.dig b/src/main/dig/generic/gray/GrayCounter.dig index 844185588..7d76ae064 100644 --- a/src/main/dig/generic/gray/GrayCounter.dig +++ b/src/main/dig/generic/gray/GrayCounter.dig @@ -138,15 +138,23 @@ ist als drei.}} generic inBits:=2; -if (isPresent(args)) { - if (args.bits>3) { - setCircuit("GrayNode-inc.dig"); - } +if (args.bits>3) { + setCircuit("GrayNode-inc.dig"); } + + GenericInitCode + + + generic + bits := 3; + + + + diff --git a/src/main/dig/generic/gray/GrayFinal-inc.dig b/src/main/dig/generic/gray/GrayFinal-inc.dig index 8dab7df63..f6fbd98c4 100644 --- a/src/main/dig/generic/gray/GrayFinal-inc.dig +++ b/src/main/dig/generic/gray/GrayFinal-inc.dig @@ -162,6 +162,16 @@ den Überlauf korrekt umzusetzen.}} + + GenericInitCode + + + generic + inBits := 2; + + + + diff --git a/src/main/dig/generic/gray/GrayNode-inc.dig b/src/main/dig/generic/gray/GrayNode-inc.dig index 48d7d5513..a10f1dc3d 100644 --- a/src/main/dig/generic/gray/GrayNode-inc.dig +++ b/src/main/dig/generic/gray/GrayNode-inc.dig @@ -107,13 +107,9 @@ generic - if (isPresent(args)) { - export inBits := args.inBits+1; - if (args.inBits<args.bits-2) { - setCircuit("GrayNode-inc.dig"); - } -} else { - export inBits:=3; + export inBits := args.inBits+1; +if (args.inBits<args.bits-2) { + setCircuit("GrayNode-inc.dig"); } @@ -187,6 +183,17 @@ noch nicht erreicht ist.}} + + GenericInitCode + + + generic + bits := 4; +inBits := 2; + + + + diff --git a/src/main/dig/lib/RAMs/RAM32Bit.dig b/src/main/dig/lib/RAMs/RAM32Bit.dig index bca04268a..15d46c520 100644 --- a/src/main/dig/lib/RAMs/RAM32Bit.dig +++ b/src/main/dig/lib/RAMs/RAM32Bit.dig @@ -1060,6 +1060,16 @@ this.'Output Splitting'="2-"+(args.addrBits-1)+",0-0,1- + + GenericInitCode + + + generic + addrBits := 8; + + + + diff --git a/src/main/java/de/neemann/digital/draw/library/ElementLibrary.java b/src/main/java/de/neemann/digital/draw/library/ElementLibrary.java index 2fb02e471..e3988b348 100644 --- a/src/main/java/de/neemann/digital/draw/library/ElementLibrary.java +++ b/src/main/java/de/neemann/digital/draw/library/ElementLibrary.java @@ -220,6 +220,7 @@ public class ElementLibrary implements Iterable .add(TransGate.DESCRIPTION)) .add(new LibraryNode(Lang.get("lib_misc")) .add(TestCaseElement.TESTCASEDESCRIPTION) + .add(GenericInitCode.DESCRIPTION) .add(DummyElement.RECTDESCRIPTION) .add(PowerSupply.DESCRIPTION) .add(BusSplitter.DESCRIPTION) diff --git a/src/main/java/de/neemann/digital/draw/library/ElementTypeDescriptionCustom.java b/src/main/java/de/neemann/digital/draw/library/ElementTypeDescriptionCustom.java index dc72b4939..82f4daa62 100644 --- a/src/main/java/de/neemann/digital/draw/library/ElementTypeDescriptionCustom.java +++ b/src/main/java/de/neemann/digital/draw/library/ElementTypeDescriptionCustom.java @@ -151,11 +151,18 @@ public final class ElementTypeDescriptionCustom extends ElementTypeDescription { */ public String getDeclarationDefault() throws NodeException { if (declarationDefault == null) - declarationDefault = createDeclarationDefault(); + declarationDefault = createDeclarationDefault(circuit); return declarationDefault; } - private String createDeclarationDefault() throws NodeException { + /** + * Creates the default for custom element declarations + * + * @param circuit the circuit + * @return the default code template + * @throws NodeException NodeException + */ + public static String createDeclarationDefault(Circuit circuit) throws NodeException { TreeSet nameSet = new TreeSet<>(); for (VisualElement ve : circuit.getElements()) { String gen = ve.getElementAttributes().get(Keys.GENERIC).trim(); diff --git a/src/main/java/de/neemann/digital/draw/library/GenericInitCode.java b/src/main/java/de/neemann/digital/draw/library/GenericInitCode.java new file mode 100644 index 000000000..165069fc2 --- /dev/null +++ b/src/main/java/de/neemann/digital/draw/library/GenericInitCode.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2020 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.draw.library; + +import de.neemann.digital.core.Model; +import de.neemann.digital.core.NodeException; +import de.neemann.digital.core.ObservableValues; +import de.neemann.digital.core.element.Element; +import de.neemann.digital.core.element.ElementAttributes; +import de.neemann.digital.core.element.ElementTypeDescription; +import de.neemann.digital.core.element.Keys; + +/** + * Allows to a generic init code to a circuit. + */ +public class GenericInitCode implements Element { + /** + * The GenericInitCodeElement description + */ + public static final ElementTypeDescription DESCRIPTION + = new ElementTypeDescription(GenericInitCode.class) + .addAttribute(Keys.LABEL) + .addAttribute(Keys.ENABLED) + .addAttribute(Keys.GENERIC) + .supportsHDL(); + + /** + * creates a new instance + * + * @param attributes the attributes + */ + public GenericInitCode(ElementAttributes attributes) { + } + + @Override + public void setInputs(ObservableValues inputs) throws NodeException { + } + + @Override + public ObservableValues getOutputs() { + return ObservableValues.EMPTY_LIST; + } + + @Override + public void registerNodes(Model model) { + } +} 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 ebfee72e0..06536b0c6 100644 --- a/src/main/java/de/neemann/digital/draw/library/ResolveGenerics.java +++ b/src/main/java/de/neemann/digital/draw/library/ResolveGenerics.java @@ -12,10 +12,13 @@ import de.neemann.digital.draw.elements.Circuit; import de.neemann.digital.draw.elements.VisualElement; 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.lang.Lang; import java.io.IOException; import java.util.HashMap; +import java.util.HashSet; +import java.util.List; import java.util.Objects; /** @@ -24,6 +27,7 @@ import java.util.Objects; public class ResolveGenerics { private final HashMap map; + private LibraryInterface library; /** * Creates a new instance @@ -43,6 +47,7 @@ public class ResolveGenerics { * @throws ElementNotFoundException ElementNotFoundException */ public CircuitHolder resolveCircuit(VisualElement visualElement, Circuit circuit, LibraryInterface library) throws NodeException, ElementNotFoundException { + this.library = library; final Args args = createArgs(visualElement, circuit); Circuit c = circuit.createDeepCopy(); @@ -52,18 +57,17 @@ public class ResolveGenerics { if (!gen.isEmpty()) { boolean isCustom = library.getElementType(ve.getElementName(), ve.getElementAttributes()).isCustom(); Statement genS = getStatement(gen); + Context mod = new Context(); if (isCustom) { - Context mod = new Context() - .declareVar("args", args) + mod.declareVar("args", args) .declareFunc("setCircuit", new SetCircuitFunc(ve)); genS.execute(mod); - ve.setGenericArgs(mod); } else { - Context mod = new Context() - .declareVar("args", args) + mod.declareVar("args", args) .declareVar("this", new SubstituteLibrary.AllowSetAttributes(ve.getElementAttributes())); genS.execute(mod); } + ve.setGenericArgs(mod); } } catch (HGSEvalException | ParserException | IOException e) { final NodeException ex = new NodeException(Lang.get("err_evaluatingGenericsCode_N_N", ve, gen), e); @@ -90,8 +94,20 @@ public class ResolveGenerics { throw ex; } } - } else + } else { context = new Context(); + 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")); + if (g.size() > 1) + throw new NodeException(Lang.get("err_multipleGenericInitCodes")); + String argsCode = g.get(0).getElementAttributes().get(Keys.GENERIC); + try { + getStatement(argsCode).execute(context); + } catch (IOException | ParserException | HGSEvalException e) { + throw new NodeException(Lang.get("err_inGenericInitCode"), e); + } + } return new Args(context); } @@ -145,7 +161,7 @@ public class ResolveGenerics { /** * Holds the circuit and the args that created that circuit. */ - public static final class CircuitHolder { + public final class CircuitHolder { private final Circuit circuit; private final Args args; @@ -167,12 +183,80 @@ public class ResolveGenerics { public Args getArgs() { return args; } + + /** + * Converts a circuit that is only suitable for creating a model + * to a circuit that can also be edited and saved. + * + * @return this for chained calls + */ + public CircuitHolder cleanupConcreteCircuit() { + for (VisualElement gic : circuit.getElements(v -> v.equalsDescription(GenericInitCode.DESCRIPTION))) + circuit.delete(gic); + for (VisualElement v : circuit.getElements()) { + try { + boolean isCustom = library.getElementType(v.getElementName(), v.getElementAttributes()).isCustom(); + if (isCustom) + v.getElementAttributes().set(Keys.GENERIC, createGenericCode(v.getGenericArgs())); + else + v.getElementAttributes().set(Keys.GENERIC, ""); + } catch (ElementNotFoundException e) { + // can not happen + e.printStackTrace(); + } + v.setGenericArgs(null); + } + + circuit.getAttributes().set(Keys.IS_GENERIC, false); + + return this; + } + } + + private static String createGenericCode(Context args) { + StringBuilder sb = new StringBuilder(); + HashSet contentSet = new HashSet<>(); + addVal(sb, "", args, contentSet); + return sb.toString(); + } + + private static void addVal(StringBuilder sb, String key, Object val, HashSet contentSet) { + if (contentSet.contains(key)) + return; + + if (val instanceof InnerFunction) + return; + + if (val instanceof Context) { + Context c = (Context) val; + for (String k : c.getKeySet()) { + Object v = c.hgsMapGet(k); + if (!(v instanceof Args)) + addVal(sb, k, v, contentSet); + } + for (String k : c.getKeySet()) { + Object v = c.hgsMapGet(k); + if (v instanceof Args) + addVal(sb, k, ((Args) v).args, contentSet); + } + return; + } + + contentSet.add(key); + sb.append(key).append(":="); + if (val instanceof String) + sb.append("\"").append(val).append("\""); + else if (val instanceof Integer) + sb.append("int(").append(val).append(")"); + else + sb.append(val); + sb.append(";\n"); } private static final class SetCircuitFunc extends Function { private final VisualElement ve; - private SetCircuitFunc(VisualElement ve) { + private SetCircuitFunc(VisualElement ve) { super(1); this.ve = ve; } diff --git a/src/main/java/de/neemann/digital/draw/model/ModelCreator.java b/src/main/java/de/neemann/digital/draw/model/ModelCreator.java index 8970ec978..0a08d6101 100644 --- a/src/main/java/de/neemann/digital/draw/model/ModelCreator.java +++ b/src/main/java/de/neemann/digital/draw/model/ModelCreator.java @@ -19,6 +19,7 @@ import de.neemann.digital.draw.graphics.Vector; import de.neemann.digital.draw.library.CustomElement; import de.neemann.digital.draw.library.ElementNotFoundException; import de.neemann.digital.draw.library.LibraryInterface; +import de.neemann.digital.draw.library.ResolveGenerics; import de.neemann.digital.draw.shapes.Drawable; import de.neemann.digital.lang.Lang; @@ -48,7 +49,24 @@ public class ModelCreator implements Iterable { * @throws ElementNotFoundException ElementNotFoundException */ public ModelCreator(Circuit circuit, LibraryInterface library) throws PinException, NodeException, ElementNotFoundException { - this(circuit, library, false); + this(fixGenerics(circuit, library), library, false); + } + + /** + * Creates a concrete circuit from a generic on. + * Uses the included generic init code. + * + * @param circuit the generic circuit + * @param library the element library + * @return the concrete circuit + * @throws NodeException NodeException + * @throws ElementNotFoundException ElementNotFoundException + */ + public static Circuit fixGenerics(Circuit circuit, LibraryInterface library) throws NodeException, ElementNotFoundException { + if (circuit.getAttributes().get(Keys.IS_GENERIC)) + return new ResolveGenerics().resolveCircuit(null, circuit, library).getCircuit(); + else + return circuit; } /** diff --git a/src/main/java/de/neemann/digital/draw/shapes/GenericInitCodeShape.java b/src/main/java/de/neemann/digital/draw/shapes/GenericInitCodeShape.java new file mode 100644 index 000000000..194ec64e9 --- /dev/null +++ b/src/main/java/de/neemann/digital/draw/shapes/GenericInitCodeShape.java @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2016 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.draw.shapes; + +import de.neemann.digital.core.element.ElementAttributes; +import de.neemann.digital.core.element.Keys; +import de.neemann.digital.core.element.PinDescriptions; +import de.neemann.digital.draw.elements.IOState; +import de.neemann.digital.draw.elements.Pins; +import de.neemann.digital.draw.graphics.*; + +import static de.neemann.digital.draw.graphics.Style.DISABLED; +import static de.neemann.digital.draw.graphics.Style.NORMAL; +import static de.neemann.digital.draw.shapes.GenericShape.SIZE; +import static de.neemann.digital.draw.shapes.GenericShape.SIZE2; + +/** + * The shape to visualize a test case + */ +public class GenericInitCodeShape implements Shape { + + private final String label; + private final boolean enabled; + + /** + * Creates a new instance + * + * @param attributes the attributes + * @param inputs inputs + * @param outputs outputs + */ + public GenericInitCodeShape(ElementAttributes attributes, PinDescriptions inputs, PinDescriptions outputs) { + label = attributes.getLabel(); + enabled = attributes.get(Keys.ENABLED); + } + + @Override + public Pins getPins() { + return new Pins(); + } + + @Override + public InteractorInterface applyStateMonitor(IOState ioState) { + return null; + } + + @Override + public void drawTo(Graphic graphic, Style highLight) { + if (!graphic.isFlagSet(Graphic.Flag.hideTest)) { + Polygon pol = new Polygon(true) + .add(SIZE2, SIZE2) + .add(SIZE2 + SIZE * 6, SIZE2) + .add(SIZE2 + SIZE * 6, SIZE * 2 + SIZE2) + .add(SIZE2, SIZE * 2 + SIZE2); + Style textStyle = NORMAL; + if (enabled) { + graphic.drawPolygon(pol, NORMAL); + graphic.drawPolygon(pol, Style.THIN); + } else { + graphic.drawPolygon(pol, DISABLED); + textStyle = DISABLED; + } + + graphic.drawText(new Vector(SIZE2 + SIZE * 3, SIZE + SIZE2), "generic", Orientation.CENTERCENTER, textStyle); + graphic.drawText(new Vector(SIZE2 + SIZE * 3, 0), label, Orientation.CENTERBOTTOM, textStyle); + } + } +} diff --git a/src/main/java/de/neemann/digital/draw/shapes/ShapeFactory.java b/src/main/java/de/neemann/digital/draw/shapes/ShapeFactory.java index 9d7559b47..eb7dbddea 100644 --- a/src/main/java/de/neemann/digital/draw/shapes/ShapeFactory.java +++ b/src/main/java/de/neemann/digital/draw/shapes/ShapeFactory.java @@ -22,6 +22,7 @@ import de.neemann.digital.draw.elements.Tunnel; import de.neemann.digital.draw.graphics.Style; import de.neemann.digital.draw.library.ElementLibrary; import de.neemann.digital.draw.library.ElementTypeDescriptionCustom; +import de.neemann.digital.draw.library.GenericInitCode; import de.neemann.digital.draw.library.JarComponentManager; import de.neemann.digital.draw.shapes.custom.CustomShape; import de.neemann.digital.draw.shapes.custom.CustomShapeDescription; @@ -158,6 +159,7 @@ public final class ShapeFactory { map.put(DummyElement.TEXTDESCRIPTION.getName(), TextShape::new); map.put(DummyElement.RECTDESCRIPTION.getName(), RectShape::new); map.put(TestCaseElement.TESTCASEDESCRIPTION.getName(), TestCaseShape::new); + map.put(GenericInitCode.DESCRIPTION.getName(), GenericInitCodeShape::new); map.put(AsyncSeq.DESCRIPTION.getName(), AsyncClockShape::new); map.put(Diode.DESCRIPTION.getName(), DiodeShape::new); diff --git a/src/main/java/de/neemann/digital/gui/Main.java b/src/main/java/de/neemann/digital/gui/Main.java index c5ba40874..efc77d073 100644 --- a/src/main/java/de/neemann/digital/gui/Main.java +++ b/src/main/java/de/neemann/digital/gui/Main.java @@ -1385,6 +1385,8 @@ public final class Main extends JFrame implements ClosingWindowListener.ConfirmS } circuitComponent.setModeAndReset(true, model); + if (circuitComponent.getCircuit().getAttributes().get(Keys.IS_GENERIC)) + circuitComponent.setCopy(modelCreator.getCircuit()); modelCreator.connectToGui(); diff --git a/src/main/java/de/neemann/digital/gui/components/CircuitComponent.java b/src/main/java/de/neemann/digital/gui/components/CircuitComponent.java index 84558ee74..8696c704e 100644 --- a/src/main/java/de/neemann/digital/gui/components/CircuitComponent.java +++ b/src/main/java/de/neemann/digital/gui/components/CircuitComponent.java @@ -1121,6 +1121,16 @@ public class CircuitComponent extends JComponent implements ChangedListener, Lib } } + if (elementType == GenericInitCode.DESCRIPTION) { + if (element.getElementAttributes().get(Keys.GENERIC).isEmpty()) { + try { + element.getElementAttributes().set(Keys.GENERIC, ElementTypeDescriptionCustom.createDeclarationDefault(getCircuit())); + } catch (NodeException ex) { + new ErrorMessage(Lang.get("msg_errParsingGenerics")).addCause(ex).show(CircuitComponent.this); + } + } + } + Point p = new Point(e.getX(), e.getY()); SwingUtilities.convertPointToScreen(p, CircuitComponent.this); AttributeDialog attributeDialog = new AttributeDialog(parent, p, list, element.getElementAttributes()) @@ -1141,6 +1151,36 @@ public class CircuitComponent extends JComponent implements ChangedListener, Lib } }.setToolTip(Lang.get("attr_openCircuit_tt"))); } + if (elementType == GenericInitCode.DESCRIPTION && getCircuit().getAttributes().get(Keys.IS_GENERIC)) { + attributeDialog.addButton(Lang.get("attr_createConcreteCircuitLabel"), new ToolTipAction(Lang.get("attr_createConcreteCircuit")) { + @Override + public void actionPerformed(ActionEvent e) { + try { + attributeDialog.fireOk(); + ElementAttributes modified = attributeDialog.getModifiedAttributes(); + if (modified != null && !isLocked() && !modified.equals(element.getElementAttributes())) { + Modification mod = new ModifyAttributes(element, modified); + modify(checkNetRename(element, modified, mod)); + } + + Circuit concreteCircuit = new ResolveGenerics() + .resolveCircuit(element, getCircuit(), library) + .cleanupConcreteCircuit() + .getCircuit(); + + new Main.MainBuilder() + .setParent(parent) + .setCircuit(concreteCircuit) + .setLibrary(library) + .denyMostFileActions() + .keepPrefMainFile() + .openLater(); + } catch (NodeException | ElementNotFoundException | Editor.EditorParseException ex) { + new ErrorMessage(Lang.get("attr_createConcreteCircuitErr")).addCause(ex).show(parent); + } + } + }.setToolTip(Lang.get("attr_createConcreteCircuit_tt"))); + } attributeDialog.addButton(new ToolTipAction(Lang.get("attr_help")) { @Override public void actionPerformed(ActionEvent actionEvent) { @@ -1401,6 +1441,16 @@ public class CircuitComponent extends JComponent implements ChangedListener, Lib return isManualScale; } + /** + * Sets a copy to use temporarily to draw the circuit. + * Used to visualize a created concrete circuit created from a generic one. + * + * @param circuit the circuit to use. + */ + public void setCopy(Circuit circuit) { + shallowCopy = circuit; + } + private final class PlusMinusAction extends ToolTipAction { private final int delta; @@ -2400,7 +2450,12 @@ public class CircuitComponent extends JComponent implements ChangedListener, Lib } private VisualElement getInteractiveElementAt(MouseEvent e) { - List elementList = getCircuit().getElementListAt(getPosVector(e), false); + Circuit circuit; + if (shallowCopy != null) + circuit = shallowCopy; + else + circuit = getCircuit(); + List elementList = circuit.getElementListAt(getPosVector(e), false); for (VisualElement ve : elementList) { if (ve.isInteractive()) return ve; 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 e44cf1b57..a563c0371 100644 --- a/src/main/java/de/neemann/digital/hdl/hgs/Context.java +++ b/src/main/java/de/neemann/digital/hdl/hgs/Context.java @@ -281,6 +281,13 @@ public class Context implements HGSMap { return map.get(key); } + /** + * @return the set of all contained values + */ + public HashSet getKeySet() { + return new HashSet<>(map.keySet()); + } + private static final class FunctionPrint extends InnerFunction { private FunctionPrint() { super(-1); diff --git a/src/main/java/de/neemann/digital/hdl/hgs/Parser.java b/src/main/java/de/neemann/digital/hdl/hgs/Parser.java index ee2047e64..2c24b4f84 100644 --- a/src/main/java/de/neemann/digital/hdl/hgs/Parser.java +++ b/src/main/java/de/neemann/digital/hdl/hgs/Parser.java @@ -13,6 +13,8 @@ import de.neemann.digital.hdl.hgs.refs.*; import java.io.*; import java.nio.charset.StandardCharsets; import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; import static de.neemann.digital.hdl.hgs.Tokenizer.Token.*; @@ -544,6 +546,8 @@ public class Parser { Expression exp = parseExpression(); expect(CLOSE); return exp; + case OPENBRACE: + return parseStructLiteral(); case FUNC: FirstClassFunction func = parseFunction(); return c -> new FirstClassFunctionCall(func, c); @@ -552,6 +556,31 @@ public class Parser { } } + private Expression parseStructLiteral() throws IOException, ParserException { + StructLiteral sl = new StructLiteral(); + while (true) { + Tokenizer.Token t = tok.next(); + switch (t) { + case CLOSEDBRACE: + return sl; + case IDENT: + String key = tok.getIdent(); + expect(COLON); + Expression exp = parseExpression(); + sl.add(key, exp); + if (nextIs(COMMA)) + tok.consume(); + else { + if (tok.peek() != CLOSEDBRACE) + throw newUnexpectedToken(t); + } + break; + default: + throw newUnexpectedToken(t); + } + } + } + private FirstClassFunction parseFunction() throws IOException, ParserException { expect(OPEN); ArrayList args = new ArrayList<>(); @@ -608,4 +637,24 @@ public class Parser { } } + private static final class StructLiteral implements Expression { + private final HashMap map; + + private StructLiteral() { + map = new HashMap<>(); + } + + private void add(String key, Expression exp) { + map.put(key, exp); + } + + @Override + public Object value(Context c) throws HGSEvalException { + HashMap vmap = new HashMap<>(); + for (Map.Entry e : map.entrySet()) + vmap.put(e.getKey(), e.getValue().value(c)); + return vmap; + } + + } } diff --git a/src/main/java/de/neemann/digital/hdl/model2/HDLCircuit.java b/src/main/java/de/neemann/digital/hdl/model2/HDLCircuit.java index 2a9ce07c0..1d3cc7cc5 100644 --- a/src/main/java/de/neemann/digital/hdl/model2/HDLCircuit.java +++ b/src/main/java/de/neemann/digital/hdl/model2/HDLCircuit.java @@ -18,6 +18,7 @@ import de.neemann.digital.core.wiring.Break; import de.neemann.digital.core.wiring.Clock; import de.neemann.digital.core.wiring.Splitter; import de.neemann.digital.draw.elements.*; +import de.neemann.digital.draw.library.GenericInitCode; import de.neemann.digital.draw.model.InverterConfig; import de.neemann.digital.draw.model.Net; import de.neemann.digital.draw.model.NetList; @@ -240,7 +241,8 @@ public class HDLCircuit implements Iterable, HDLModel.BitProvider, Prin && !v.equalsDescription(DummyElement.TEXTDESCRIPTION) && !v.equalsDescription(DummyElement.DATADESCRIPTION) && !v.equalsDescription(DummyElement.RECTDESCRIPTION) - && !v.equalsDescription(TestCaseElement.TESTCASEDESCRIPTION); + && !v.equalsDescription(TestCaseElement.TESTCASEDESCRIPTION) + && !v.equalsDescription(GenericInitCode.DESCRIPTION); } HDLNet getNetOfPin(Pin pin) { diff --git a/src/main/java/de/neemann/digital/hdl/model2/HDLModel.java b/src/main/java/de/neemann/digital/hdl/model2/HDLModel.java index 50741d2f7..f87d1d701 100644 --- a/src/main/java/de/neemann/digital/hdl/model2/HDLModel.java +++ b/src/main/java/de/neemann/digital/hdl/model2/HDLModel.java @@ -26,6 +26,8 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; +import static de.neemann.digital.draw.model.ModelCreator.fixGenerics; + /** * The context of creating nodes and circuits. * Ensures that every circuit is only processed one time. @@ -207,11 +209,13 @@ public class HDLModel implements Iterable { * @param circuit the circuit * @param clockIntegrator the clock integrator. Meybe null * @return this for chained calls - * @throws PinException PinException - * @throws HDLException HDLException - * @throws NodeException NodeException + * @throws PinException PinException + * @throws HDLException HDLException + * @throws NodeException NodeException + * @throws ElementNotFoundException ElementNotFoundException */ - public HDLModel create(Circuit circuit, HDLClockIntegrator clockIntegrator) throws PinException, HDLException, NodeException { + public HDLModel create(Circuit circuit, HDLClockIntegrator clockIntegrator) throws PinException, HDLException, NodeException, ElementNotFoundException { + circuit = fixGenerics(circuit, elementLibrary); main = new HDLCircuit(circuit, "main", this, 0, clockIntegrator); circuitMap.put(circuit, main); return this; diff --git a/src/main/java/de/neemann/digital/hdl/verilog2/VerilogGenerator.java b/src/main/java/de/neemann/digital/hdl/verilog2/VerilogGenerator.java index c3ad94d33..e61cd3228 100644 --- a/src/main/java/de/neemann/digital/hdl/verilog2/VerilogGenerator.java +++ b/src/main/java/de/neemann/digital/hdl/verilog2/VerilogGenerator.java @@ -10,6 +10,7 @@ import de.neemann.digital.core.element.Keys; import de.neemann.digital.draw.elements.Circuit; import de.neemann.digital.draw.elements.PinException; import de.neemann.digital.draw.library.ElementLibrary; +import de.neemann.digital.draw.library.ElementNotFoundException; import de.neemann.digital.hdl.hgs.HGSEvalException; import de.neemann.digital.hdl.model2.HDLCircuit; import de.neemann.digital.hdl.model2.HDLException; @@ -98,7 +99,7 @@ public class VerilogGenerator implements Closeable { } return this; - } catch (PinException | NodeException | HDLException | HGSEvalException | NullPointerException e) { + } catch (PinException | NodeException | HDLException | HGSEvalException | NullPointerException | ElementNotFoundException e) { throw new IOException(Lang.get("err_verilogExporting"), e); } } diff --git a/src/main/java/de/neemann/digital/hdl/vhdl2/VHDLGenerator.java b/src/main/java/de/neemann/digital/hdl/vhdl2/VHDLGenerator.java index 8ff914954..37763fc43 100644 --- a/src/main/java/de/neemann/digital/hdl/vhdl2/VHDLGenerator.java +++ b/src/main/java/de/neemann/digital/hdl/vhdl2/VHDLGenerator.java @@ -10,6 +10,7 @@ import de.neemann.digital.core.element.Keys; import de.neemann.digital.draw.elements.Circuit; import de.neemann.digital.draw.elements.PinException; import de.neemann.digital.draw.library.ElementLibrary; +import de.neemann.digital.draw.library.ElementNotFoundException; import de.neemann.digital.hdl.hgs.HGSEvalException; import de.neemann.digital.hdl.model2.HDLCircuit; import de.neemann.digital.hdl.model2.HDLException; @@ -85,7 +86,7 @@ public class VHDLGenerator implements Closeable { } return this; - } catch (PinException | NodeException | HDLException | HGSEvalException | NullPointerException e) { + } catch (PinException | NodeException | HDLException | HGSEvalException | NullPointerException | ElementNotFoundException e) { throw new IOException(Lang.get("err_vhdlExporting"), e); } } diff --git a/src/main/resources/lang/lang_de.xml b/src/main/resources/lang/lang_de.xml index 7667bcaa1..816f61ece 100644 --- a/src/main/resources/lang/lang_de.xml +++ b/src/main/resources/lang/lang_de.xml @@ -875,22 +875,32 @@ Steuereingang, invertiert - Testfall Beschreibt einen Testfall. In einem Testfall kann beschrieben werden, wie sich eine Schaltung verhalten soll. Es kann dann automatisch überprüft werden, ob das Verhalten der Schaltung tatsächlich - dieser Beschreibung entspricht. Ist das nicht der Fall, wird eine entsprechende Fehlermeldung angezeigt. + dieser Beschreibung entspricht. Ist das nicht der Fall, wird eine entsprechende Fehlermeldung angezeigt. + + Generische Initialisierung + Code der ausgeführt wird, um eine generische Schaltung direkt starten zu + können. + Soll eine generische Schaltung direkt gestartet werden, muss eine solche Komponente vorhanden sein. + + Asynchrones Timing Erlaubt die Konfiguration des Timings eines asynchronen Automaten wie z.B einer - Muller-Pipeline. Die Schaltung muss im Gatterschrittmodus gestartet werden und muss zunächst einen stabilen Zustand + Muller-Pipeline. Die Schaltung muss im Gatterschrittmodus gestartet werden und muss zunächst einen stabilen + Zustand einnehmen. Interaktiv oder mit einem Reset-Element kann dann der Automat gestartet werden. - Die Taktelemente können in diesem Modus nicht verwendet werden. + Die Taktelemente können in diesem Modus nicht verwendet werden. + Versorgung - Hat keine weitere Funktion. Stellt nur sicher, dass VDD und GND angeschlossen sind. + Hat keine weitere Funktion. Stellt nur sicher, dass VDD und GND angeschlossen + sind. Kann im Zusammenhang mit den 74xx Bausteinen verwendet werden, um Anschlüsse für die Spannungsversorgung - zu erzeugen, welche dann auch auf korrekte Beschaltung geprüft werden. + zu erzeugen, welche dann auch auf korrekte Beschaltung geprüft werden. + Muss mit VDD verbunden werden! Muss mit GND verbunden werden! Reset @@ -1112,27 +1122,37 @@ Sind evtl. die Namen der Variablen nicht eindeutig? HDL nicht bekannt: {0} Fehler beim Starten des Kommandos {0} Es gibt einen unbenannten Ein- oder Ausgang. - Der Signalname "{0}" ist ungültig oder mehrfach verwendet! + Der Signalname "{0}" ist ungültig oder mehrfach verwendet! + Fehler bei der Substitution von Elementen für die Analyse. Fehler bei der Auswertung des generischen Codes der Schaltung. Code: {1} in Komponente: {0} Fehler bei der Analyse des generischen Codes. + Kein Initialisierungscode für die generischen Elemente. + Mehrere Initialisierungscodes für die generischen Elemente. + Fehler bei der Analyse des generischen Initialisierungscodes. + Videomodus wurde nicht erkannt ({0}) Es ist kein Dateiname für das automatische Neuladen verfügbar! Adress-Bits Anzahl der Adress-Bits, die verwendet werden. - Daten-Bits + Daten-Bits + Anzahl der Daten-Bits, die verwendet werden. Farbe Die Farbe des Elementes. Hintergrundfarbe - Hintergrundfarbe der Schaltung, wenn sie eingebettet wird. Wird für DILs nicht verwendet. + Hintergrundfarbe der Schaltung, wenn sie eingebettet wird. Wird für DILs nicht + verwendet. + Timeout Zyklen - Wenn nach dieser Anzahl von Takten kein Break eingegangen ist, wird ein Fehler erzeugt + Wenn nach dieser Anzahl von Takten kein Break eingegangen ist, wird ein Fehler + erzeugt + Daten Die Daten, welche in diesem Element gespeichert sind. Vorgabe @@ -1998,6 +2018,12 @@ Stellen Sie sicher, dass der Flash-Vorgang abgeschlossen ist, bevor Sie diesen D Hilfe Name in einer generischen Schaltung: {0} + Konkrete Schaltung erzeugen + Erzeugen + Erzeugt aus dieser generischen Schaltung eine konkrete Schaltung + unter Anwendung der in diesem Element angegebenen Parameter. + + Fehler bei der Erzeugung der konkreten Schaltung! Zentrale ROM Inhalte + Generic Initialization + Code that is executed to start a generic circuit directly. + If a generic circuit is to be started directly, such a component must be present. + + Asynchronous Timing Allows configuration of the timing of an asynchronous sequential circuit such as a Muller-pipeline. The circuit must be started in single gate step mode and must be able to reach a stable state at startup. The sequential circuit can then be started interactively or with a reset gate. - It is not allowed to use a regular clock component in this mode. + It is not allowed to use a regular clock component in this mode. + Power Has no function. Makes sure that VDD and GND are connected. - Can be used in 74xx circuits to generate the pins for the voltage supply, which are tested for correct wiring. + Can be used in 74xx circuits to generate the pins for the voltage supply, which are tested for correct wiring. + Must be connected to VDD! Must be connected to GND! Reset @@ -1132,20 +1139,29 @@ Error when substituting components for the analysis. Error in the evaluation of the generic code of the circuit. Code {1} - at Component: {0} + at Component: {0} + Error while parsing generics code. + No initialization code for the generic components. + Multiple initialization codes for the generic elements. + Error in the analysis of the generic initialization code. + There is no file name available for the automatic reload! Address Bits Number of address bits used. - Data Bits + Data Bits + Number of data bits used. Color The Color of the element. Background color - Background color of the circuit when it is embedded in another circuit. Is not used for DIL packages. + Background color of the circuit when it is embedded in another circuit. Is not + used for DIL packages. + Timeout cycles - If this amount of cycles is reached without a break signal, an error is created. + If this amount of cycles is reached without a break signal, an error is created. + Data The values stored in this element. Default @@ -1845,6 +1861,12 @@ Addr. Bits Name to use in generic circuits: {0} + Create Concrete Circuit + Create + Creates a concrete circuit from this generic circuit using the + parameters specified in this element. + + Error while creating the concrete circuit! <h1>Digital</h1>A simple simulator for digital circuits. Written by H. Neemann in 2016-2020. @@ -1852,9 +1874,11 @@ The icons are taken from the <a href="http://tango.freedesktop.org">Tango Desktop Project</a>. Visit the project at <a href="https://github.com/hneemann/[[name]]">GitHub</a>. - At Github you can also <a href="https://github.com/hneemann/[[name]]/releases/latest">download</a> the latest release. + At Github you can also <a href="https://github.com/hneemann/[[name]]/releases/latest">download</a> + the latest release. - There you also can file an <a href="https://github.com/hneemann/[[name]]/issues/new?body=version:%20[[version]]&labels=bug">issue</a> or suggest + There you also can file an <a href="https://github.com/hneemann/[[name]]/issues/new?body=version:%20[[version]]&labels=bug">issue</a> + or suggest an <a href="https://github.com/hneemann/[[name]]/issues/new?labels=enhancement">enhancement</a>. {0} nodes diff --git a/src/test/java/de/neemann/digital/hdl/TestHDLExportFlag.java b/src/test/java/de/neemann/digital/hdl/TestHDLExportFlag.java index 96f18f7b2..9e93e2bab 100644 --- a/src/test/java/de/neemann/digital/hdl/TestHDLExportFlag.java +++ b/src/test/java/de/neemann/digital/hdl/TestHDLExportFlag.java @@ -12,6 +12,7 @@ import de.neemann.digital.core.wiring.Clock; import de.neemann.digital.core.wiring.Splitter; import de.neemann.digital.draw.elements.Tunnel; import de.neemann.digital.draw.library.ElementLibrary; +import de.neemann.digital.draw.library.GenericInitCode; import de.neemann.digital.hdl.vhdl2.entities.VHDLTemplate; import de.neemann.digital.testing.TestCaseElement; import junit.framework.TestCase; @@ -43,6 +44,7 @@ public class TestHDLExportFlag extends TestCase { implicitSupported.add(Splitter.DESCRIPTION); implicitSupported.add(TestCaseElement.TESTCASEDESCRIPTION); + implicitSupported.add(GenericInitCode.DESCRIPTION); } public void testHDLExportFlag() { 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 ed5cfc796..669151e18 100644 --- a/src/test/java/de/neemann/digital/hdl/hgs/ParserTest.java +++ b/src/test/java/de/neemann/digital/hdl/hgs/ParserTest.java @@ -175,6 +175,23 @@ public class ParserTest extends TestCase { assertEquals("false", exec("").toString()); } + public void testStructLiteral() throws ParserException, IOException, HGSEvalException { + Object str = new Parser("{a:1, b:2, c:{d:3+4}}").parseExp().value(new Context()); + Map m = (Map) str; + assertEquals(3, m.size()); + assertEquals(1L, m.get("a")); + assertEquals(2L, m.get("b")); + Map c = (Map) m.get("c"); + assertEquals(1, c.size()); + assertEquals(7L, c.get("d")); + + str = new Parser("{a:{}}").parseExp().value(new Context()); + m = (Map) str; + assertEquals(1, m.size()); + Map a = (Map) m.get("a"); + assertEquals(0, a.size()); + } + public void testTypeChecking() throws IOException, ParserException, HGSEvalException { assertEquals("5.0", exec("", new Context()).toString()); assertEquals("u", exec("", new Context()).toString()); diff --git a/src/test/java/de/neemann/digital/integration/TestExamples.java b/src/test/java/de/neemann/digital/integration/TestExamples.java index c3cf761c0..2dc450077 100644 --- a/src/test/java/de/neemann/digital/integration/TestExamples.java +++ b/src/test/java/de/neemann/digital/integration/TestExamples.java @@ -7,8 +7,15 @@ package de.neemann.digital.integration; import de.neemann.digital.core.ErrorDetector; import de.neemann.digital.core.Model; +import de.neemann.digital.core.NodeException; import de.neemann.digital.core.element.Keys; +import de.neemann.digital.draw.elements.Circuit; +import de.neemann.digital.draw.elements.PinException; import de.neemann.digital.draw.elements.VisualElement; +import de.neemann.digital.draw.library.ElementLibrary; +import de.neemann.digital.draw.library.ElementNotFoundException; +import de.neemann.digital.draw.library.GenericInitCode; +import de.neemann.digital.draw.library.ResolveGenerics; import de.neemann.digital.draw.model.ModelCreator; import de.neemann.digital.testing.TestCaseDescription; import de.neemann.digital.testing.TestCaseElement; @@ -16,6 +23,7 @@ import de.neemann.digital.testing.TestExecutor; import junit.framework.TestCase; import java.io.File; +import java.util.List; /** * Reads all examples and tries to create the model. @@ -105,5 +113,27 @@ public class TestExamples extends TestCase { } finally { br.close(); } + + if (br.getCircuit().getAttributes().get(Keys.IS_GENERIC)) + checkGeneric(br.getCircuit(), br.getLibrary()); + } + + private void checkGeneric(Circuit circuit, ElementLibrary library) throws NodeException, ElementNotFoundException, PinException { + List initCodeList = circuit.getElements(v -> v.equalsDescription(GenericInitCode.DESCRIPTION) && v.getElementAttributes().get(Keys.ENABLED)); + assertEquals("init code element count", 1, initCodeList.size()); + + VisualElement element = initCodeList.get(0); + + Circuit concreteCircuit = new ResolveGenerics() + .resolveCircuit(element, circuit, library) + .cleanupConcreteCircuit() + .getCircuit(); + + for (VisualElement ve : concreteCircuit.getElements()) { + assertNull(ve.getGenericArgs()); + assertFalse(ve.equalsDescription(GenericInitCode.DESCRIPTION)); + } + + new ModelCreator(concreteCircuit, library).createModel(false).init(); } } diff --git a/src/test/resources/dig/backtrack/AllComponents.dig b/src/test/resources/dig/backtrack/AllComponents.dig index 234b9bb4a..a28026765 100644 --- a/src/test/resources/dig/backtrack/AllComponents.dig +++ b/src/test/resources/dig/backtrack/AllComponents.dig @@ -492,7 +492,7 @@ Testcase - + PowerSupply @@ -658,6 +658,11 @@ + + GenericInitCode + + + diff --git a/src/test/resources/dig/test/generics/count.dig b/src/test/resources/dig/test/generics/count.dig index bfa7e5efc..969515963 100644 --- a/src/test/resources/dig/test/generics/count.dig +++ b/src/test/resources/dig/test/generics/count.dig @@ -168,6 +168,16 @@ + + GenericInitCode + + + generic + bits := 4; + + + + diff --git a/src/test/resources/dig/test/generics/countSplitter.dig b/src/test/resources/dig/test/generics/countSplitter.dig index 26a09cf0a..c88346ba3 100644 --- a/src/test/resources/dig/test/generics/countSplitter.dig +++ b/src/test/resources/dig/test/generics/countSplitter.dig @@ -88,7 +88,7 @@ this.'Input Splitting'=args.bits+","+args.bits; generic - this.Bits=int(args.bits); + this.Bits=int(args.bits*2); @@ -121,6 +121,16 @@ this.'Input Splitting'=args.bits+","+args.bits; + + GenericInitCode + + + generic + bits := 2; + + + + diff --git a/src/test/resources/dig/test/generics/nest.dig b/src/test/resources/dig/test/generics/nest.dig index 826c4271a..6000eefbb 100644 --- a/src/test/resources/dig/test/generics/nest.dig +++ b/src/test/resources/dig/test/generics/nest.dig @@ -23,10 +23,7 @@ generic - bits:=4; -if (isPresent(args)) { - bits=args.bits; -} + bits:=args.bits; @@ -78,6 +75,16 @@ if (isPresent(args)) { + + GenericInitCode + + + generic + bits := 4; + + + + diff --git a/src/test/resources/dig/test/vhdl/barrelShifter/barrelShifter.dig b/src/test/resources/dig/test/vhdl/barrelShifter/barrelShifter.dig index 510601e58..f7b639d3c 100644 --- a/src/test/resources/dig/test/vhdl/barrelShifter/barrelShifter.dig +++ b/src/test/resources/dig/test/vhdl/barrelShifter/barrelShifter.dig @@ -80,9 +80,7 @@ generic - if (isPresent(args)) { - - if (args.direction="right") { + if (args.direction="right") { export circuit:="shift-fixed-right-inc.dig"; } else { if (args.direction="arith") { @@ -91,22 +89,27 @@ if (args.direction="left") { export circuit:="shift-fixed-left-inc.dig"; } else { - panic("only \"left\", \"right\" or \"arith\" is allowed as direction, not \""+args.dir+"\"!"); + panic("only \"left\", \"right\" or \"arith\" is allowed as direction, not \""+args.direction+"\"!"); } } } - export shiftBits:=bitsNeededFor(args.dataBits-1); -} else { - // used if circuit is started as the main circuit - export circuit:="shift-fixed-left-inc.dig"; - export dataBits:=16; - export shiftBits:=int(4); -} + export shiftBits:=bitsNeededFor(args.dataBits-1); + + GenericInitCode + + + generic + dataBits := 5; +direction := "left"; + + + + diff --git a/src/test/resources/dig/test/vhdl/barrelShifter/shift-fixed-arith-right-inc.dig b/src/test/resources/dig/test/vhdl/barrelShifter/shift-fixed-arith-right-inc.dig index 504a1d409..3d39f2baf 100644 --- a/src/test/resources/dig/test/vhdl/barrelShifter/shift-fixed-arith-right-inc.dig +++ b/src/test/resources/dig/test/vhdl/barrelShifter/shift-fixed-arith-right-inc.dig @@ -106,6 +106,17 @@ this.outputBits=int(args.dataBits); + + GenericInitCode + + + generic + dataBits := 8; +shift := 3; + + + + diff --git a/src/test/resources/dig/test/vhdl/barrelShifter/shift-fixed-left-inc.dig b/src/test/resources/dig/test/vhdl/barrelShifter/shift-fixed-left-inc.dig index edff6777c..9e06e6548 100644 --- a/src/test/resources/dig/test/vhdl/barrelShifter/shift-fixed-left-inc.dig +++ b/src/test/resources/dig/test/vhdl/barrelShifter/shift-fixed-left-inc.dig @@ -116,6 +116,17 @@ this.'Output Splitting' = "0-"+(args.dataBits-args.shift-1); + + GenericInitCode + + + generic + dataBits := 8; +shift := 3; + + + + diff --git a/src/test/resources/dig/test/vhdl/barrelShifter/shift-fixed-right-inc.dig b/src/test/resources/dig/test/vhdl/barrelShifter/shift-fixed-right-inc.dig index ed307c078..0da3c4b0d 100644 --- a/src/test/resources/dig/test/vhdl/barrelShifter/shift-fixed-right-inc.dig +++ b/src/test/resources/dig/test/vhdl/barrelShifter/shift-fixed-right-inc.dig @@ -116,6 +116,17 @@ this.'Output Splitting' = args.shift+"-"+(args.dataBits-1);< + + GenericInitCode + + + generic + dataBits := 8; +shift := 3; + + + + diff --git a/src/test/resources/dig/test/vhdl/barrelShifter/shift-inc.dig b/src/test/resources/dig/test/vhdl/barrelShifter/shift-inc.dig index 393b19585..a96a8b2b0 100644 --- a/src/test/resources/dig/test/vhdl/barrelShifter/shift-inc.dig +++ b/src/test/resources/dig/test/vhdl/barrelShifter/shift-inc.dig @@ -13,14 +13,8 @@ generic - if (isPresent(args)) { - export shift := 1<<(args.shiftBits-1); - setCircuit(args.circuit); -} else { - // used if circuit is started as the main circuit - export dataBits:=16; - export shift:=8; -} + export shift := 1<<(args.shiftBits-1); +setCircuit(args.circuit); @@ -92,18 +86,11 @@ generic - if (isPresent(args)) { - if (args.shiftBits=2) { - export shift := 1; - setCircuit(args.circuit); - } else { - export shiftBits := args.shiftBits-1; - } + if (args.shiftBits=2) { + export shift := 1; + setCircuit(args.circuit); } else { - // used if circuit is started as the main circuit - export dataBits:=16; - export shiftBits:=3; - export circuit:="shift-fixed-left-inc.dig"; + export shiftBits := args.shiftBits-1; } @@ -128,6 +115,18 @@ this.'Output Splitting' = (args.shiftBits-1)+"-"+(args.shift + + GenericInitCode + + + generic + circuit := "shift-fixed-left-inc.dig"; +dataBits := 8; +shiftBits := 3; + + + + diff --git a/src/test/resources/dig/test/vhdl/generics/memLeaf.dig b/src/test/resources/dig/test/vhdl/generics/memLeaf.dig index 4daca6dfe..a7e7f81f5 100644 --- a/src/test/resources/dig/test/vhdl/generics/memLeaf.dig +++ b/src/test/resources/dig/test/vhdl/generics/memLeaf.dig @@ -113,6 +113,16 @@ + + GenericInitCode + + + generic + dataBits := 8; + + + + diff --git a/src/test/resources/dig/test/vhdl/generics/memLeaf2.dig b/src/test/resources/dig/test/vhdl/generics/memLeaf2.dig index bd75ad084..746aed613 100644 --- a/src/test/resources/dig/test/vhdl/generics/memLeaf2.dig +++ b/src/test/resources/dig/test/vhdl/generics/memLeaf2.dig @@ -134,6 +134,16 @@ + + GenericInitCode + + + generic + dataBits := 8; + + + + diff --git a/src/test/resources/dig/test/vhdl/generics/memNode.dig b/src/test/resources/dig/test/vhdl/generics/memNode.dig index 596d0606c..deede69a2 100644 --- a/src/test/resources/dig/test/vhdl/generics/memNode.dig +++ b/src/test/resources/dig/test/vhdl/generics/memNode.dig @@ -17,9 +17,7 @@ generic - if (isPresent(args)) { - this.Bits=int(args.dataBits); -} + this.Bits=int(args.dataBits); @@ -37,9 +35,7 @@ generic - if (isPresent(args)) { - this.Bits=int(args.addrBits); -} + this.Bits=int(args.addrBits); @@ -63,9 +59,7 @@ generic - if (isPresent(args)) { - this.Bits=int(args.dataBits); -} + this.Bits=int(args.dataBits); @@ -85,9 +79,7 @@ generic - if (isPresent(args)) { - this.Bits=int(args.dataBits); -} + this.Bits=int(args.dataBits); @@ -122,15 +114,12 @@ generic - if (isPresent(args)) { + if (args.addrBits<2) { + panic("at least two address bits are necessary!"); +} - if (args.addrBits<2) { - panic("at least two address bits are necessary!"); - } - - this.'Input Splitting'=""+args.addrBits; - this.'Output Splitting'=(args.addrBits-1)+",1"; -} +this.'Input Splitting'=""+args.addrBits; +this.'Output Splitting'=(args.addrBits-1)+",1"; @@ -140,13 +129,9 @@ generic - if (isPresent(args)) { - export addrBits:=args.addrBits-1; - if (args.addrBits>2) { - setCircuit("memNode.dig"); - } -} else { - export dataBits:=int(1); + export addrBits:=args.addrBits-1; +if (args.addrBits>2) { + setCircuit("memNode.dig"); } @@ -157,18 +142,25 @@ generic - if (isPresent(args)) { - export addrBits:=args.addrBits-1; - if (args.addrBits>2) { - setCircuit("memNode.dig"); - } -} else { - export dataBits:=int(1); + export addrBits:=args.addrBits-1; +if (args.addrBits>2) { + setCircuit("memNode.dig"); } + + GenericInitCode + + + generic + addrBits := 8; +dataBits := 8; + + + + diff --git a/src/test/resources/dig/test/vhdl/generics/memNode2.dig b/src/test/resources/dig/test/vhdl/generics/memNode2.dig index baada53cc..f505de783 100644 --- a/src/test/resources/dig/test/vhdl/generics/memNode2.dig +++ b/src/test/resources/dig/test/vhdl/generics/memNode2.dig @@ -17,9 +17,7 @@ generic - if (isPresent(args)) { - this.Bits=int(args.dataBits); -} + this.Bits=int(args.dataBits); @@ -37,9 +35,7 @@ generic - if (isPresent(args)) { - this.Bits=int(args.addrBits); -} + this.Bits=int(args.addrBits); @@ -63,9 +59,7 @@ generic - if (isPresent(args)) { - this.Bits=int(args.dataBits); -} + this.Bits=int(args.dataBits); @@ -89,9 +83,7 @@ generic - if (isPresent(args)) { - this.Bits=int(args.dataBits); -} + this.Bits=int(args.dataBits); @@ -109,19 +101,16 @@ generic - if (isPresent(args)) { + if (args.addrBits<4) { + panic("at least two address bits are necessary!"); +} - if (args.addrBits<4) { - panic("at least two address bits are necessary!"); - } +if ((args.addrBits&1)=1) { + panic("number of address bits must be even!"); +} - if ((args.addrBits&1)=1) { - panic("number of address bits must be even!"); - } - - this.'Input Splitting'=""+args.addrBits; - this.'Output Splitting'=(args.addrBits-2)+",2"; -} +this.'Input Splitting'=""+args.addrBits; +this.'Output Splitting'=(args.addrBits-2)+",2"; @@ -141,13 +130,9 @@ generic - if (isPresent(args)) { - export addrBits:=args.addrBits-2; - if (args.addrBits>4) { - setCircuit("memNode2.dig"); - } -} else { - export dataBits:=int(1); + export addrBits:=args.addrBits-2; +if (args.addrBits>4) { + setCircuit("memNode2.dig"); } @@ -158,13 +143,9 @@ generic - if (isPresent(args)) { - export addrBits:=args.addrBits-2; - if (args.addrBits>4) { - setCircuit("memNode2.dig"); - } -} else { - export dataBits:=int(1); + export addrBits:=args.addrBits-2; +if (args.addrBits>4) { + setCircuit("memNode2.dig"); } @@ -175,13 +156,9 @@ generic - if (isPresent(args)) { - export addrBits:=args.addrBits-2; - if (args.addrBits>4) { - setCircuit("memNode2.dig"); - } -} else { - export dataBits:=int(1); + export addrBits:=args.addrBits-2; +if (args.addrBits>4) { + setCircuit("memNode2.dig"); } @@ -192,18 +169,25 @@ generic - if (isPresent(args)) { - export addrBits:=args.addrBits-2; - if (args.addrBits>4) { - setCircuit("memNode2.dig"); - } -} else { - export dataBits:=int(1); + export addrBits:=args.addrBits-2; +if (args.addrBits>4) { + setCircuit("memNode2.dig"); } + + GenericInitCode + + + generic + addrBits := 8; +dataBits := 8; + + + +