diff --git a/distribution/ReleaseNotes.txt b/distribution/ReleaseNotes.txt index d577c8b98..64561bc16 100644 --- a/distribution/ReleaseNotes.txt +++ b/distribution/ReleaseNotes.txt @@ -3,6 +3,10 @@ Release Notes planned as v0.13 - In case of oscillations almost all affected components are shown. - If an error occurs, the name of the affected circuit file is shown. +- An input can have "high z" value as its default value. + CAUTION: All default values are lost! If you have built a circuit that contains + test cases that depend on a non-null default value, this tests will fail. To + resolve this issue, reset the default value. v0.12.1, released on 05. Jun 2016 - added a fuse to simulate a PROM or PAL. diff --git a/src/main/dig/cmos/eprom.dig b/src/main/dig/cmos/eprom.dig index 178d93e16..bd0ec7cda 100644 --- a/src/main/dig/cmos/eprom.dig +++ b/src/main/dig/cmos/eprom.dig @@ -213,6 +213,10 @@ Default 1 + + InDefault + + diff --git a/src/main/dig/cmos/prom.dig b/src/main/dig/cmos/prom.dig index e2ac477e3..a8408f13c 100644 --- a/src/main/dig/cmos/prom.dig +++ b/src/main/dig/cmos/prom.dig @@ -543,6 +543,10 @@ Default 1 + + InDefault + + diff --git a/src/main/dig/cmos/rom.dig b/src/main/dig/cmos/rom.dig index 0d5b34c88..a88490e69 100644 --- a/src/main/dig/cmos/rom.dig +++ b/src/main/dig/cmos/rom.dig @@ -283,6 +283,10 @@ Default 1 + + InDefault + + diff --git a/src/main/dig/sequential/conway/Conway.dig b/src/main/dig/sequential/conway/Conway.dig index 7de30b288..6e940057c 100644 --- a/src/main/dig/sequential/conway/Conway.dig +++ b/src/main/dig/sequential/conway/Conway.dig @@ -44420,8 +44420,8 @@ In - Default - 1 + InDefault + @@ -44477,8 +44477,8 @@ In - Default - 1 + InDefault + @@ -44690,8 +44690,8 @@ In - Default - 1 + InDefault + @@ -44747,8 +44747,8 @@ In - Default - 1 + InDefault + @@ -47612,8 +47612,8 @@ In - Default - 1 + InDefault + @@ -47877,8 +47877,8 @@ In - Default - 1 + InDefault + @@ -49026,8 +49026,8 @@ In - Default - 1 + InDefault + @@ -49343,8 +49343,8 @@ In - Default - 1 + InDefault + @@ -49400,8 +49400,8 @@ In - Default - 1 + InDefault + @@ -50237,8 +50237,8 @@ In - Default - 1 + InDefault + @@ -50502,8 +50502,8 @@ In - Default - 1 + InDefault + @@ -50923,8 +50923,8 @@ In - Default - 1 + InDefault + @@ -50980,8 +50980,8 @@ In - Default - 1 + InDefault + @@ -51193,8 +51193,8 @@ In - Default - 1 + InDefault + @@ -51250,8 +51250,8 @@ In - Default - 1 + InDefault + @@ -51411,8 +51411,8 @@ In - Default - 1 + InDefault + @@ -52560,8 +52560,8 @@ In - Default - 1 + InDefault + @@ -52773,8 +52773,8 @@ In - Default - 1 + InDefault + @@ -52986,8 +52986,8 @@ In - Default - 1 + InDefault + @@ -53043,8 +53043,8 @@ In - Default - 1 + InDefault + @@ -53152,8 +53152,8 @@ In - Default - 1 + InDefault + @@ -53313,8 +53313,8 @@ In - Default - 1 + InDefault + @@ -53474,8 +53474,8 @@ In - Default - 1 + InDefault + @@ -53531,8 +53531,8 @@ In - Default - 1 + InDefault + @@ -53848,8 +53848,8 @@ In - Default - 1 + InDefault + @@ -54165,8 +54165,8 @@ In - Default - 1 + InDefault + @@ -54430,8 +54430,8 @@ In - Default - 1 + InDefault + @@ -54695,8 +54695,8 @@ In - Default - 1 + InDefault + @@ -54960,8 +54960,8 @@ In - Default - 1 + InDefault + @@ -56213,8 +56213,8 @@ In - Default - 1 + InDefault + @@ -56374,8 +56374,8 @@ In - Default - 1 + InDefault + @@ -56431,8 +56431,8 @@ In - Default - 1 + InDefault + @@ -59608,8 +59608,8 @@ In - Default - 1 + InDefault + @@ -59665,8 +59665,8 @@ In - Default - 1 + InDefault + @@ -59878,8 +59878,8 @@ In - Default - 1 + InDefault + @@ -59935,8 +59935,8 @@ In - Default - 1 + InDefault + diff --git a/src/main/java/de/neemann/digital/core/ObservableValue.java b/src/main/java/de/neemann/digital/core/ObservableValue.java index 4e4bf4ac0..943f729fe 100644 --- a/src/main/java/de/neemann/digital/core/ObservableValue.java +++ b/src/main/java/de/neemann/digital/core/ObservableValue.java @@ -261,7 +261,7 @@ public class ObservableValue extends Observable implements PinDescription { * * @return the actual value. */ - public long getValueIgnoreBurn() { + public long getValueIgnoreHighZ() { return value; } diff --git a/src/main/java/de/neemann/digital/core/element/Keys.java b/src/main/java/de/neemann/digital/core/element/Keys.java index e8ce389ed..1f9cbfbc1 100644 --- a/src/main/java/de/neemann/digital/core/element/Keys.java +++ b/src/main/java/de/neemann/digital/core/element/Keys.java @@ -1,6 +1,7 @@ package de.neemann.digital.core.element; import de.neemann.digital.analyse.expression.format.FormatToExpression; +import de.neemann.digital.core.io.InValue; import de.neemann.digital.core.io.IntFormat; import de.neemann.digital.core.memory.DataField; import de.neemann.digital.draw.model.InverterConfig; @@ -56,11 +57,17 @@ public final class Keys { = new Key<>("Value", 1); /** - * The default value of inputs + * The default value of elements */ public static final Key DEFAULT = new Key<>("Default", 0); + /** + * The default value of inputs + */ + public static final Key INPUT_DEFAULT + = new Key<>("InDefault", new InValue(0)); + /** * Color of LEDs */ diff --git a/src/main/java/de/neemann/digital/core/io/In.java b/src/main/java/de/neemann/digital/core/io/In.java index b9aab0977..42c0a1318 100644 --- a/src/main/java/de/neemann/digital/core/io/In.java +++ b/src/main/java/de/neemann/digital/core/io/In.java @@ -21,17 +21,17 @@ public class In implements Element { @Override public String getDescription(ElementAttributes elementAttributes) { String d = elementAttributes.get(Keys.DESCRIPTION); - if (d.length()>0) + if (d.length() > 0) return d; else return super.getDescription(elementAttributes); } } .addAttribute(Keys.ROTATE) - .addAttribute(Keys.IS_HIGH_Z) .addAttribute(Keys.BITS) .addAttribute(Keys.LABEL) - .addAttribute(Keys.DEFAULT) + .addAttribute(Keys.INPUT_DEFAULT) + .addAttribute(Keys.IS_HIGH_Z) .addAttribute(Keys.DESCRIPTION) .addAttribute(Keys.PINNUMBER); @@ -45,10 +45,11 @@ public class In implements Element { * @param attributes the inputs attributes */ public In(ElementAttributes attributes) { - boolean highZ = attributes.get(Keys.IS_HIGH_Z); + InValue value = attributes.get(Keys.INPUT_DEFAULT); + boolean highZ = attributes.get(Keys.IS_HIGH_Z) || value.isHighZ(); pinNumber = attributes.get(Keys.PINNUMBER); output = new ObservableValue("out", attributes.get(Keys.BITS), highZ).setPinDescription(DESCRIPTION).setPinNumber(pinNumber); - output.setValue(attributes.get(Keys.DEFAULT)); + output.set(value.getValue(), value.isHighZ()); label = attributes.getCleanLabel(); } diff --git a/src/main/java/de/neemann/digital/core/io/InValue.java b/src/main/java/de/neemann/digital/core/io/InValue.java new file mode 100644 index 000000000..e99a98301 --- /dev/null +++ b/src/main/java/de/neemann/digital/core/io/InValue.java @@ -0,0 +1,106 @@ +package de.neemann.digital.core.io; + +import de.neemann.digital.core.ObservableValue; + +/** + * A simple value. + *

+ * Created by hneemann on 19.06.17. + */ +public class InValue { + + private final long value; + private final boolean highZ; + + /** + * Creates a new value + * + * @param value the value + */ + public InValue(long value) { + this.value = value; + this.highZ = false; + } + + /** + * Creates a new value + * + * @param highZ ht ehigh z state + */ + public InValue(boolean highZ) { + this.value = 0; + this.highZ = true; + } + + /** + * Creates a new value + * + * @param value the value + */ + public InValue(ObservableValue value) { + if (value.isHighZ()) { + this.highZ = true; + this.value = 0; + } else { + this.highZ = false; + this.value = value.getValueIgnoreHighZ(); + } + } + + /** + * Creates a new instance + * + * @param value the value a "Z" means "high z" + * @throws NumberFormatException NumberFormatException + */ + public InValue(String value) { + if (value.toLowerCase().trim().equalsIgnoreCase("z")) { + this.highZ = true; + this.value = 0; + } else { + this.highZ = false; + this.value = Long.decode(value.trim()); + } + + } + + /** + * @return the value + */ + public long getValue() { + return value; + } + + /** + * @return High Z State + */ + public boolean isHighZ() { + return highZ; + } + + @Override + public String toString() { + if (highZ) + return "Z"; + else + return Long.toString(value); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + InValue inValue = (InValue) o; + + if (value != inValue.value) return false; + return highZ == inValue.highZ; + } + + @Override + public int hashCode() { + int result = (int) (value ^ (value >>> 32)); + result = 31 * result + (highZ ? 1 : 0); + return result; + } +} diff --git a/src/main/java/de/neemann/digital/draw/elements/Circuit.java b/src/main/java/de/neemann/digital/draw/elements/Circuit.java index f3f654687..509bce980 100644 --- a/src/main/java/de/neemann/digital/draw/elements/Circuit.java +++ b/src/main/java/de/neemann/digital/draw/elements/Circuit.java @@ -11,6 +11,7 @@ import de.neemann.digital.core.element.Keys; import de.neemann.digital.core.element.PinDescription; import de.neemann.digital.core.element.Rotation; import de.neemann.digital.core.io.In; +import de.neemann.digital.core.io.InValue; import de.neemann.digital.core.io.IntFormat; import de.neemann.digital.core.io.Out; import de.neemann.digital.core.memory.DataField; @@ -74,6 +75,9 @@ public class Circuit { xStream.alias("vector", Vector.class); xStream.aliasAttribute(Vector.class, "x", "x"); xStream.aliasAttribute(Vector.class, "y", "y"); + xStream.alias("value", InValue.class); + xStream.aliasAttribute(InValue.class, "value", "v"); + xStream.aliasAttribute(InValue.class, "highZ", "z"); xStream.addImplicitCollection(ElementAttributes.class, "attributes"); xStream.alias("data", DataField.class); xStream.registerConverter(new DataFieldConverter()); diff --git a/src/main/java/de/neemann/digital/draw/graphics/Style.java b/src/main/java/de/neemann/digital/draw/graphics/Style.java index 231c4c5a8..a2c7c162a 100644 --- a/src/main/java/de/neemann/digital/draw/graphics/Style.java +++ b/src/main/java/de/neemann/digital/draw/graphics/Style.java @@ -186,10 +186,10 @@ public class Style { */ public static Style getWireStyle(ObservableValue value) { if (value == null) return WIRE; - if (value.getBits() > 1) return WIRE_BUS; if (value.isHighZ()) return WIRE_HIGHZ; + if (value.getBits() > 1) return WIRE_BUS; - if (value.getValueIgnoreBurn() == 1) return WIRE_HIGH; + if (value.getValueIgnoreHighZ() == 1) return WIRE_HIGH; else return WIRE_LOW; } diff --git a/src/main/java/de/neemann/digital/draw/shapes/SevenSegHexShape.java b/src/main/java/de/neemann/digital/draw/shapes/SevenSegHexShape.java index e471ba72f..0f1ecf85c 100644 --- a/src/main/java/de/neemann/digital/draw/shapes/SevenSegHexShape.java +++ b/src/main/java/de/neemann/digital/draw/shapes/SevenSegHexShape.java @@ -43,7 +43,7 @@ public class SevenSegHexShape extends SevenShape { if (i == 7) { return dp.getBool(); } else { - int v = (int) input.getValueIgnoreBurn() & 0xf; + int v = (int) input.getValueIgnoreHighZ() & 0xf; v = TABLE[v]; return (v & (1 << i)) != 0; } diff --git a/src/main/java/de/neemann/digital/draw/shapes/SevenSegShape.java b/src/main/java/de/neemann/digital/draw/shapes/SevenSegShape.java index 816e51d96..f3503a34c 100644 --- a/src/main/java/de/neemann/digital/draw/shapes/SevenSegShape.java +++ b/src/main/java/de/neemann/digital/draw/shapes/SevenSegShape.java @@ -89,13 +89,13 @@ public class SevenSegShape extends SevenShape { if (persistence && commonCatode) { if (!ccin.isHighZ() && !ccin.getBool()) - data[i] = inputs.get(i).getValueIgnoreBurn() > 0; + data[i] = inputs.get(i).getValueIgnoreHighZ() > 0; return data[i]; } else { if (commonCatode && (ccin.isHighZ() || ccin.getBool())) return false; - return inputs.get(i).getValueIgnoreBurn() > 0; + return inputs.get(i).getValueIgnoreHighZ() > 0; } } 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 8c2d988bd..a0f22c806 100644 --- a/src/main/java/de/neemann/digital/gui/components/CircuitComponent.java +++ b/src/main/java/de/neemann/digital/gui/components/CircuitComponent.java @@ -5,6 +5,7 @@ import de.neemann.digital.core.ObservableValue; import de.neemann.digital.core.Observer; import de.neemann.digital.core.element.*; import de.neemann.digital.core.io.In; +import de.neemann.digital.core.io.InValue; import de.neemann.digital.draw.elements.*; import de.neemann.digital.draw.shapes.InputShape; import de.neemann.digital.gui.components.modification.*; @@ -911,10 +912,10 @@ public class CircuitComponent extends JComponent implements Circuit.ChangedListe if (ve.equalsDescription(In.DESCRIPTION)) { ObservableValue ov = ((InputShape) ve.getShape()).getObservableValue(); if (ov != null) { - int newValue = (int) ov.getValue(); - int oldValue = ve.getElementAttributes().get(Keys.DEFAULT); - if (newValue != oldValue) - builder.add(new ModifyAttribute<>(ve, Keys.DEFAULT, newValue)); + InValue newValue = new InValue(ov); + InValue oldValue = ve.getElementAttributes().get(Keys.INPUT_DEFAULT); + if (!newValue.equals(oldValue)) + builder.add(new ModifyAttribute<>(ve, Keys.INPUT_DEFAULT, newValue)); } } modify(builder.build()); diff --git a/src/main/java/de/neemann/digital/gui/components/EditorFactory.java b/src/main/java/de/neemann/digital/gui/components/EditorFactory.java index f432d7615..ef4c30b02 100644 --- a/src/main/java/de/neemann/digital/gui/components/EditorFactory.java +++ b/src/main/java/de/neemann/digital/gui/components/EditorFactory.java @@ -3,6 +3,7 @@ package de.neemann.digital.gui.components; import de.neemann.digital.analyse.expression.format.FormatToExpression; import de.neemann.digital.core.NodeException; import de.neemann.digital.core.element.*; +import de.neemann.digital.core.io.InValue; import de.neemann.digital.core.io.IntFormat; import de.neemann.digital.core.memory.DataField; import de.neemann.digital.core.memory.ROM; @@ -44,6 +45,7 @@ public final class EditorFactory { private EditorFactory() { add(String.class, StringEditor.class); add(Integer.class, IntegerEditor.class); + add(InValue.class, InValueEditor.class); add(File.class, FileEditor.class); add(Color.class, ColorEditor.class); add(Boolean.class, BooleanEditor.class); @@ -209,6 +211,28 @@ public final class EditorFactory { } } + private final static class InValueEditor extends LabelEditor { + private static final String[] DEFAULTS = {"Z", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16"}; + private final JComboBox comboBox; + + public InValueEditor(InValue value, Key key) { + comboBox = new JComboBox<>(DEFAULTS); + comboBox.setEditable(true); + comboBox.setSelectedItem(value.toString()); + } + + @Override + public JComponent getComponent(ElementAttributes attr) { + return comboBox; + } + + @Override + public InValue getValue() { + Object item = comboBox.getSelectedItem(); + return new InValue(item.toString()); + } + } + private final static class BooleanEditor implements Editor { private final JCheckBox bool; diff --git a/src/main/java/de/neemann/digital/gui/components/data/DataSample.java b/src/main/java/de/neemann/digital/gui/components/data/DataSample.java index 8eeaf6363..f7b32dc5c 100644 --- a/src/main/java/de/neemann/digital/gui/components/data/DataSample.java +++ b/src/main/java/de/neemann/digital/gui/components/data/DataSample.java @@ -73,7 +73,7 @@ public class DataSample { */ public DataSample fillWith(ArrayList signals) { for (int i = 0; i < signals.size(); i++) - values[i] = signals.get(i).getValue().getValueIgnoreBurn(); + values[i] = signals.get(i).getValue().getValueIgnoreHighZ(); return this; } diff --git a/src/main/resources/lang/lang_de.xml b/src/main/resources/lang/lang_de.xml index 6066a3ea1..e3e05e8bd 100644 --- a/src/main/resources/lang/lang_de.xml +++ b/src/main/resources/lang/lang_de.xml @@ -555,6 +555,11 @@ Sind evtl. die Namen der Variablen nicht eindeutig? Die Daten, welche in diesem Element gespeichert sind. Vorgabe Dieser Wert wird beim Schaltungsstart gesetzt + Vorgabe + Dieser Wert wird beim Schaltungsstart gesetzt. Ein "Z" steht für "hochohmig". + Eingang kann hochohmig sein + Wenn gesetzt ist ein hochohmiger Eingang erlaubt. Ein hochohmiger Eingang ist auch + erlaubt, wenn der Vorgabewert auf hochohmig ("Z") gesetzt wird. Beschreibung Eine kurze Beschreibung des Elementes. Frequenz/Hz @@ -601,8 +606,6 @@ Sind evtl. die Namen der Variablen nicht eindeutig? Dezimal Vorgabe Hexadezimal - Eingang kann hochohmig sein - Wenn gesetzt ist ein hochohmiger Eingang erlaubt. Maximale Messpunktezahl Die maximale Anzahl an Messpunkten die gespeichert werden, bevor die ältesten Messungen verworfen werden. Zeige Einzelgatterschritte diff --git a/src/main/resources/lang/lang_en.xml b/src/main/resources/lang/lang_en.xml index 7a3d4eef3..5fd3391fc 100644 --- a/src/main/resources/lang/lang_en.xml +++ b/src/main/resources/lang/lang_en.xml @@ -545,6 +545,11 @@ The names of the variables may not be unique. The values stored in this element. Default This value is set if the circuit is started + Default + This value is set if the circuit is started. A "Z" means high-z state. + Is three-state input + If set the input is allowed to be in high-z state. This is also allowed + if high-z ("Z") is set as the default value. Description A short description of this element and its usage. Frequency/Hz @@ -591,8 +596,6 @@ The names of the variables may not be unique. decimal default hex - Is three-state input - If set the input is allowed to be in high-z state. Max number of steps to show The maximal number of values stored. If the maximum number is reached, the oldest values are discarded. Show single gate steps diff --git a/src/test/java/de/neemann/digital/integration/FileScanner.java b/src/test/java/de/neemann/digital/integration/FileScanner.java index 462f13e75..58376dfcf 100644 --- a/src/test/java/de/neemann/digital/integration/FileScanner.java +++ b/src/test/java/de/neemann/digital/integration/FileScanner.java @@ -23,7 +23,7 @@ public class FileScanner { if (errors.isEmpty()) return count; - System.out.println("errors:"); + System.err.println("errors:"); for (Error e : errors) { System.err.println("----> error in: " + e.f); e.e.printStackTrace();