added inverted inputs

This commit is contained in:
hneemann 2017-05-31 20:11:56 +02:00
parent d6e1a3e510
commit cf31464026
28 changed files with 767 additions and 135 deletions

View File

@ -36,7 +36,7 @@
<int>1</int>
</entry>
</elementAttributes>
<pos x="620" y="260"/>
<pos x="640" y="260"/>
</visualElement>
<visualElement>
<elementName>Out</elementName>
@ -82,7 +82,7 @@
<int>1</int>
</entry>
</elementAttributes>
<pos x="620" y="300"/>
<pos x="640" y="300"/>
</visualElement>
<visualElement>
<elementName>In</elementName>
@ -104,7 +104,7 @@
<int>1</int>
</entry>
</elementAttributes>
<pos x="620" y="340"/>
<pos x="640" y="340"/>
</visualElement>
<visualElement>
<elementName>In</elementName>
@ -126,11 +126,6 @@
<int>1</int>
</entry>
</elementAttributes>
<pos x="620" y="380"/>
</visualElement>
<visualElement>
<elementName>Not</elementName>
<elementAttributes/>
<pos x="640" y="380"/>
</visualElement>
<visualElement>
@ -153,11 +148,6 @@
<int>1</int>
</entry>
</elementAttributes>
<pos x="620" y="220"/>
</visualElement>
<visualElement>
<elementName>Not</elementName>
<elementAttributes/>
<pos x="640" y="220"/>
</visualElement>
<visualElement>
@ -180,7 +170,7 @@
<int>1</int>
</entry>
</elementAttributes>
<pos x="620" y="480"/>
<pos x="640" y="480"/>
</visualElement>
<visualElement>
<elementName>Out</elementName>
@ -226,7 +216,7 @@
<int>6</int>
</entry>
</elementAttributes>
<pos x="620" y="520"/>
<pos x="640" y="520"/>
</visualElement>
<visualElement>
<elementName>In</elementName>
@ -248,7 +238,7 @@
<int>1</int>
</entry>
</elementAttributes>
<pos x="620" y="560"/>
<pos x="640" y="560"/>
</visualElement>
<visualElement>
<elementName>In</elementName>
@ -270,7 +260,7 @@
<int>1</int>
</entry>
</elementAttributes>
<pos x="620" y="600"/>
<pos x="640" y="600"/>
</visualElement>
<visualElement>
<elementName>In</elementName>
@ -292,38 +282,36 @@
<int>1</int>
</entry>
</elementAttributes>
<pos x="620" y="440"/>
</visualElement>
<visualElement>
<elementName>JK_FF_AS</elementName>
<elementAttributes/>
<pos x="720" y="260"/>
</visualElement>
<visualElement>
<elementName>Not</elementName>
<elementAttributes/>
<pos x="640" y="600"/>
</visualElement>
<visualElement>
<elementName>Not</elementName>
<elementAttributes/>
<pos x="640" y="440"/>
</visualElement>
<visualElement>
<elementName>JK_FF_AS</elementName>
<elementAttributes/>
<elementAttributes>
<entry>
<string>inverterConfig</string>
<inverterConfig>
<string>Set</string>
<string>C</string>
<string>Clr</string>
</inverterConfig>
</entry>
</elementAttributes>
<pos x="720" y="260"/>
</visualElement>
<visualElement>
<elementName>JK_FF_AS</elementName>
<elementAttributes>
<entry>
<string>inverterConfig</string>
<inverterConfig>
<string>Set</string>
<string>C</string>
<string>Clr</string>
</inverterConfig>
</entry>
</elementAttributes>
<pos x="720" y="480"/>
</visualElement>
<visualElement>
<elementName>Not</elementName>
<elementAttributes/>
<pos x="640" y="300"/>
</visualElement>
<visualElement>
<elementName>Not</elementName>
<elementAttributes/>
<pos x="640" y="520"/>
</visualElement>
</visualElements>
<wires>
<wire>
@ -331,11 +319,11 @@
<p2 x="720" y="320"/>
</wire>
<wire>
<p1 x="700" y="480"/>
<p2 x="720" y="480"/>
<p1 x="680" y="480"/>
<p2 x="700" y="480"/>
</wire>
<wire>
<p1 x="620" y="480"/>
<p1 x="640" y="480"/>
<p2 x="660" y="480"/>
</wire>
<wire>
@ -343,11 +331,11 @@
<p2 x="820" y="480"/>
</wire>
<wire>
<p1 x="700" y="260"/>
<p2 x="720" y="260"/>
<p1 x="680" y="260"/>
<p2 x="700" y="260"/>
</wire>
<wire>
<p1 x="620" y="260"/>
<p1 x="640" y="260"/>
<p2 x="660" y="260"/>
</wire>
<wire>
@ -355,35 +343,27 @@
<p2 x="820" y="260"/>
</wire>
<wire>
<p1 x="680" y="520"/>
<p2 x="720" y="520"/>
</wire>
<wire>
<p1 x="620" y="520"/>
<p2 x="640" y="520"/>
<p1 x="640" y="520"/>
<p2 x="700" y="520"/>
</wire>
<wire>
<p1 x="800" y="520"/>
<p2 x="820" y="520"/>
</wire>
<wire>
<p1 x="680" y="300"/>
<p2 x="720" y="300"/>
</wire>
<wire>
<p1 x="620" y="300"/>
<p2 x="640" y="300"/>
<p1 x="640" y="300"/>
<p2 x="700" y="300"/>
</wire>
<wire>
<p1 x="800" y="300"/>
<p2 x="820" y="300"/>
</wire>
<wire>
<p1 x="700" y="560"/>
<p2 x="720" y="560"/>
<p1 x="680" y="560"/>
<p2 x="700" y="560"/>
</wire>
<wire>
<p1 x="620" y="560"/>
<p1 x="640" y="560"/>
<p2 x="660" y="560"/>
</wire>
<wire>
@ -395,11 +375,11 @@
<p2 x="800" y="500"/>
</wire>
<wire>
<p1 x="700" y="340"/>
<p2 x="720" y="340"/>
<p1 x="680" y="340"/>
<p2 x="700" y="340"/>
</wire>
<wire>
<p1 x="620" y="340"/>
<p1 x="640" y="340"/>
<p2 x="660" y="340"/>
</wire>
<wire>
@ -411,40 +391,24 @@
<p2 x="720" y="280"/>
</wire>
<wire>
<p1 x="620" y="600"/>
<p2 x="640" y="600"/>
<p1 x="640" y="600"/>
<p2 x="680" y="600"/>
</wire>
<wire>
<p1 x="680" y="600"/>
<p2 x="700" y="600"/>
</wire>
<wire>
<p1 x="620" y="440"/>
<p2 x="640" y="440"/>
</wire>
<wire>
<p1 x="680" y="440"/>
<p2 x="700" y="440"/>
<p1 x="640" y="440"/>
<p2 x="680" y="440"/>
</wire>
<wire>
<p1 x="660" y="540"/>
<p2 x="720" y="540"/>
</wire>
<wire>
<p1 x="620" y="380"/>
<p2 x="640" y="380"/>
<p1 x="640" y="380"/>
<p2 x="680" y="380"/>
</wire>
<wire>
<p1 x="680" y="380"/>
<p2 x="700" y="380"/>
</wire>
<wire>
<p1 x="620" y="220"/>
<p2 x="640" y="220"/>
</wire>
<wire>
<p1 x="680" y="220"/>
<p2 x="700" y="220"/>
<p1 x="640" y="220"/>
<p2 x="680" y="220"/>
</wire>
<wire>
<p1 x="800" y="280"/>
@ -471,20 +435,21 @@
<p2 x="660" y="560"/>
</wire>
<wire>
<p1 x="700" y="220"/>
<p2 x="700" y="260"/>
<p1 x="680" y="220"/>
<p2 x="680" y="260"/>
</wire>
<wire>
<p1 x="700" y="340"/>
<p2 x="700" y="380"/>
<p1 x="680" y="340"/>
<p2 x="680" y="380"/>
</wire>
<wire>
<p1 x="700" y="440"/>
<p2 x="700" y="480"/>
<p1 x="680" y="440"/>
<p2 x="680" y="480"/>
</wire>
<wire>
<p1 x="700" y="560"/>
<p2 x="700" y="600"/>
<p1 x="680" y="560"/>
<p2 x="680" y="600"/>
</wire>
</wires>
<measurementOrdering/>
</circuit>

View File

@ -18,6 +18,11 @@ import static de.neemann.digital.core.element.PinInfo.input;
*/
public abstract class FanIn extends Node implements Element {
/**
* The inputs name prefix
*/
public static final String PREFIX = "In_";
private final ArrayList<ObservableValue> inputs;
private final ObservableValue output;
private final int bits;
@ -71,6 +76,7 @@ public abstract class FanIn extends Node implements Element {
addAttribute(Keys.ROTATE);
addAttribute(Keys.BITS);
addAttribute(Keys.INPUT_COUNT);
addAttribute(Keys.INVERTERCONFIG);
}
@Override
@ -78,7 +84,7 @@ public abstract class FanIn extends Node implements Element {
int count = elementAttributes.get(Keys.INPUT_COUNT);
PinDescription[] names = new PinDescription[count];
for (int i = 0; i < count; i++)
names[i] = input("in_" + i, Lang.get("elem_Basic_In", i));
names[i] = input(PREFIX + (i+1), Lang.get("elem_Basic_In", i));
return new PinDescriptions(names);
}
}

View File

@ -19,7 +19,8 @@ public class XNOr extends XOr {
public static final ElementTypeDescription DESCRIPTION
= new ElementTypeDescription(XNOr.class, input("a"), input("b"))
.addAttribute(Keys.ROTATE)
.addAttribute(Keys.BITS);
.addAttribute(Keys.BITS)
.addAttribute(Keys.INVERTERCONFIG);
/**
* Creates a new instance

View File

@ -19,7 +19,8 @@ public class XOr extends Node implements Element {
public static final ElementTypeDescription DESCRIPTION
= new ElementTypeDescription(XOr.class, input("a"), input("b"))
.addAttribute(Keys.ROTATE)
.addAttribute(Keys.BITS);
.addAttribute(Keys.BITS)
.addAttribute(Keys.INVERTERCONFIG);
private final int bits;
private final ObservableValue out;

View File

@ -3,6 +3,7 @@ package de.neemann.digital.core.element;
import de.neemann.digital.analyse.expression.format.FormatToExpression;
import de.neemann.digital.core.io.IntFormat;
import de.neemann.digital.core.memory.DataField;
import de.neemann.digital.draw.model.InverterConfig;
import de.neemann.gui.language.Language;
import java.awt.*;
@ -353,4 +354,11 @@ public final class Keys {
public static final Key<Boolean> IS_DIL
= new Key<>("isDIL", false);
/**
* contains the input inverter config
*/
public static final Key<InverterConfig> INVERTERCONFIG
= new Key<>("inverterConfig", new InverterConfig());
}

View File

@ -25,6 +25,7 @@ public class FlipflopD extends Node implements Element {
.addAttribute(Keys.BITS)
.addAttribute(Keys.LABEL)
.addAttribute(Keys.DEFAULT)
.addAttribute(Keys.INVERTERCONFIG)
.addAttribute(Keys.VALUE_IS_PROBE);
private final int bits;

View File

@ -25,6 +25,7 @@ public class FlipflopDAsync extends Node implements Element {
.addAttribute(Keys.BITS)
.addAttribute(Keys.LABEL)
.addAttribute(Keys.DEFAULT)
.addAttribute(Keys.INVERTERCONFIG)
.addAttribute(Keys.VALUE_IS_PROBE);
private final int bits;

View File

@ -24,6 +24,7 @@ public class FlipflopJK extends Node implements Element {
.addAttribute(Keys.ROTATE)
.addAttribute(Keys.LABEL)
.addAttribute(Keys.DEFAULT)
.addAttribute(Keys.INVERTERCONFIG)
.addAttribute(Keys.VALUE_IS_PROBE);
private final Boolean isProbe;

View File

@ -29,6 +29,7 @@ public class FlipflopJKAsync extends Node implements Element {
.addAttribute(Keys.ROTATE)
.addAttribute(Keys.LABEL)
.addAttribute(Keys.DEFAULT)
.addAttribute(Keys.INVERTERCONFIG)
.addAttribute(Keys.VALUE_IS_PROBE);
private final Boolean isProbe;

View File

@ -23,6 +23,7 @@ public class FlipflopRS extends Node implements Element {
= new ElementTypeDescription("RS_FF", FlipflopRS.class, input("S"), input("C"), input("R"))
.addAttribute(Keys.ROTATE)
.addAttribute(Keys.LABEL)
.addAttribute(Keys.INVERTERCONFIG)
.addAttribute(Keys.VALUE_IS_PROBE);
private final boolean isProbe;

View File

@ -23,6 +23,7 @@ public class FlipflopT extends Node implements Element {
= new ElementTypeDescription("T_FF", FlipflopT.class, input("C"))
.addAttribute(Keys.ROTATE)
.addAttribute(Keys.LABEL)
.addAttribute(Keys.INVERTERCONFIG)
.addAttribute(Keys.VALUE_IS_PROBE);
private final boolean isProbe;

View File

@ -20,6 +20,7 @@ import de.neemann.digital.draw.graphics.Graphic;
import de.neemann.digital.draw.graphics.Polygon;
import de.neemann.digital.draw.graphics.Style;
import de.neemann.digital.draw.graphics.Vector;
import de.neemann.digital.draw.model.InverterConfig;
import de.neemann.digital.draw.shapes.Drawable;
import de.neemann.digital.draw.shapes.ShapeFactory;
import de.neemann.digital.gui.sync.NoSync;
@ -77,6 +78,8 @@ public class Circuit {
xStream.alias("data", DataField.class);
xStream.registerConverter(new DataFieldConverter());
xStream.alias("testData", TestData.class);
xStream.alias("inverterConfig", InverterConfig.class);
xStream.addImplicitCollection(InverterConfig.class, "inputs");
xStream.ignoreUnknownElements();
return xStream;
}

View File

@ -0,0 +1,103 @@
package de.neemann.digital.draw.model;
import de.neemann.digital.core.ObservableValue;
import java.util.HashSet;
/**
* Manages the input inverting of a component
* Created by hneemann on 28.05.17.
*/
public class InverterConfig {
private HashSet<String> inputs;
/**
* Creates a new instance.
* No input is inverted.
*/
public InverterConfig() {
inputs = null;
}
/**
* Adds a signal to invert
*
* @param name the signale
* @return this for chained calls
*/
public InverterConfig add(String name) {
if (inputs == null)
inputs = new HashSet<>();
inputs.add(name);
return this;
}
/**
* Handles the inverting of a input signal
* if the given input is not to invert, the original input is returned,
* If the input is to invert, a inverted input is returned. This invert does not add
* a additional delay time.
*
* @param name the name of the signal
* @param orig the original input signal
* @return the inverted or the original input
*/
public ObservableValue invert(String name, ObservableValue orig) {
if (inputs == null)
return orig;
if (!inputs.contains(name))
return orig;
ObservableValue out = new ObservableValue("~" + orig.getName(), orig.getBits());
orig.addObserver(() -> out.set(~orig.getValue(), orig.isHighZ()));
out.set(~orig.getValue(), orig.isHighZ());
return out;
}
/**
* @return the string representation of the inverter config
*/
public String toString() {
return inputs.toString();
}
/**
* Returns true if the input with the given name is to invert.
*
* @param name the name of the signal
* @return true if the given input is to invert.
*/
public boolean contains(String name) {
if (inputs == null)
return false;
return inputs.contains(name);
}
/**
* @return true if no signal is to invert
*/
public boolean isEmpty() {
if (inputs == null)
return true;
return inputs.isEmpty();
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
InverterConfig that = (InverterConfig) o;
return inputs != null ? inputs.equals(that.inputs) : that.inputs == null;
}
@Override
public int hashCode() {
return inputs != null ? inputs.hashCode() : 0;
}
}

View File

@ -5,6 +5,7 @@ import de.neemann.digital.core.ObservableValue;
import de.neemann.digital.core.ObservableValues;
import de.neemann.digital.core.Observer;
import de.neemann.digital.core.element.Element;
import de.neemann.digital.core.element.Keys;
import de.neemann.digital.core.element.PinDescription;
import de.neemann.digital.core.element.PinDescriptions;
import de.neemann.digital.draw.elements.*;
@ -54,6 +55,8 @@ public class ModelEntry {
public void applyInputs() throws PinException, NodeException {
HashMap<String, Pin> ins = pins.getInputs();
InverterConfig ic = visualElement.getElementAttributes().get(Keys.INVERTERCONFIG);
ObservableValues values = ObservableValues.EMPTY_LIST;
ArrayList<ObservableValue> inputs = new ArrayList<>();
for (PinDescription inputName : inputNames) {
@ -65,7 +68,7 @@ public class ModelEntry {
if (value == null)
throw new PinException(Lang.get("err_noValueSetFor_N0_atElement_N1", inputName, visualElement), visualElement);
inputs.add(value);
inputs.add(ic.invert(inputName.getName(), value));
}
ArrayList<ObservableValue> bidirect = null;

View File

@ -7,6 +7,7 @@ import de.neemann.digital.draw.elements.Pin;
import de.neemann.digital.draw.elements.Pins;
import de.neemann.digital.draw.graphics.*;
import de.neemann.digital.draw.graphics.Polygon;
import de.neemann.digital.draw.model.InverterConfig;
import java.awt.*;
@ -38,6 +39,7 @@ public class GenericShape implements Shape {
private transient Pins pins;
private boolean showPinLabels;
private InverterConfig inverterConfig;
/**
* Creates a new generic shape.
@ -112,7 +114,7 @@ public class GenericShape implements Shape {
@Override
public Pins getPins() {
if (pins == null) {
pins = createPins(inputs, outputs, invert, width, symmetric);
pins = createPins(inputs, outputs, invert, width, symmetric, inverterConfig);
}
return pins;
}
@ -123,10 +125,11 @@ public class GenericShape implements Shape {
* @param inputs the inputs
* @param outputs the outputs
* @param invert true if invert output
* @param ic iput inverter configuration
* @return the pins
*/
public static Pins createPins(PinDescriptions inputs, PinDescriptions outputs, boolean invert) {
return createPins(inputs, outputs, invert, 3, true);
public static Pins createPins(PinDescriptions inputs, PinDescriptions outputs, boolean invert, InverterConfig ic) {
return createPins(inputs, outputs, invert, 3, true, ic);
}
/**
@ -137,19 +140,25 @@ public class GenericShape implements Shape {
* @param invert true if invert output
* @param width with of symbol
* @param symmetric true if outputs in the center
* @param ic iput inverter configuration
* @return the pins
*/
public static Pins createPins(PinDescriptions inputs, PinDescriptions outputs, boolean invert, int width, boolean symmetric) {
public static Pins createPins(PinDescriptions inputs, PinDescriptions outputs, boolean invert, int width, boolean symmetric, InverterConfig ic) {
Pins pins = new Pins();
int offs = symmetric ? inputs.size() / 2 * SIZE : 0;
for (int i = 0; i < inputs.size(); i++) {
int correct = 0;
if (symmetric && ((inputs.size() & 1) == 0) && i >= inputs.size() / 2)
correct = SIZE;
pins.add(new Pin(new Vector(0, i * SIZE + correct), inputs.get(i)));
int dx = 0;
if (isInverted(inputs.get(i).getName(), ic))
dx = -SIZE;
pins.add(new Pin(new Vector(dx, i * SIZE + correct), inputs.get(i)));
}
@ -165,6 +174,10 @@ public class GenericShape implements Shape {
return pins;
}
private static boolean isInverted(String name, InverterConfig ic) {
return ic != null && ic.contains(name);
}
@Override
public Interactor applyStateMonitor(IOState ioState, Observer guiObserver) {
return null;
@ -202,8 +215,11 @@ public class GenericShape implements Shape {
if (showPinLabels) {
for (Pin p : getPins()) {
int dx = 4;
if (isInverted(p.getName(), inverterConfig))
dx += SIZE;
if (p.getDirection() == Pin.Direction.input)
graphic.drawText(p.getPos().add(4, 0), p.getPos().add(5, 0), p.getName(), Orientation.LEFTCENTER, Style.SHAPE_PIN);
graphic.drawText(p.getPos().add(dx, 0), p.getPos().add(dx + 1, 0), p.getName(), Orientation.LEFTCENTER, Style.SHAPE_PIN);
else
graphic.drawText(p.getPos().add(-4, 0), p.getPos().add(5, 0), p.getName(), Orientation.RIGHTCENTER, Style.SHAPE_PIN);
}
@ -217,6 +233,42 @@ public class GenericShape implements Shape {
graphic.drawText(pos, pos.add(1, 0), name, Orientation.CENTERTOP, Style.SHAPE_PIN);
}
}
drawInputInvert(graphic, inverterConfig, getPins());
}
/**
* Draw the inverted inputs
*
* @param graphic the graphic to paint on
* @param inverterConfig the inverter configuration
* @param pins the pins containing the inputs
*/
public static void drawInputInvert(Graphic graphic, InverterConfig inverterConfig, Pins pins) {
if (inverterConfig != null && !inverterConfig.isEmpty())
for (Pin p : pins) {
if (p.getDirection() == Pin.Direction.input) {
if (inverterConfig.contains(p.getName())) {
graphic.drawCircle(p.getPos().add(2, -SIZE2 + 2),
p.getPos().add(SIZE - 2, SIZE2 - 2), Style.NORMAL);
}
}
}
}
/**
* Sets the inverter config
*
* @param inverterConfig the inverter config
* @return this for chained calls
*/
public GenericShape setInverterConfig(InverterConfig inverterConfig) {
if (inverterConfig.isEmpty())
this.inverterConfig = null;
else
this.inverterConfig = inverterConfig;
return this;
}
}

View File

@ -55,12 +55,12 @@ public final class ShapeFactory {
this.library = library;
library.setShapeFactory(this);
if (ieee) {
map.put(And.DESCRIPTION.getName(), (attributes, inputs, outputs) -> new IEEEAndShape(inputs, outputs, false));
map.put(NAnd.DESCRIPTION.getName(), (attributes, inputs, outputs) -> new IEEEAndShape(inputs, outputs, true));
map.put(Or.DESCRIPTION.getName(), (attributes, inputs, outputs) -> new IEEEOrShape(inputs, outputs, false));
map.put(NOr.DESCRIPTION.getName(), (attributes, inputs, outputs) -> new IEEEOrShape(inputs, outputs, true));
map.put(XOr.DESCRIPTION.getName(), (attributes, inputs, outputs) -> new IEEEXOrShape(inputs, outputs, false));
map.put(XNOr.DESCRIPTION.getName(), (attributes, inputs, outputs) -> new IEEEXOrShape(inputs, outputs, true));
map.put(And.DESCRIPTION.getName(), (attributes, inputs, outputs) -> new IEEEAndShape(inputs, outputs, false, attributes));
map.put(NAnd.DESCRIPTION.getName(), (attributes, inputs, outputs) -> new IEEEAndShape(inputs, outputs, true, attributes));
map.put(Or.DESCRIPTION.getName(), (attributes, inputs, outputs) -> new IEEEOrShape(inputs, outputs, false, attributes));
map.put(NOr.DESCRIPTION.getName(), (attributes, inputs, outputs) -> new IEEEOrShape(inputs, outputs, true, attributes));
map.put(XOr.DESCRIPTION.getName(), (attributes, inputs, outputs) -> new IEEEXOrShape(inputs, outputs, false, attributes));
map.put(XNOr.DESCRIPTION.getName(), (attributes, inputs, outputs) -> new IEEEXOrShape(inputs, outputs, true, attributes));
map.put(Not.DESCRIPTION.getName(), (attributes, inputs, outputs) -> new IEEENotShape(inputs, outputs));
} else {
map.put(And.DESCRIPTION.getName(), new CreatorSimple("&", false));
@ -157,13 +157,15 @@ public final class ShapeFactory {
customDescr.getAttributes().get(Keys.WIDTH))
.setColor(customDescr.getAttributes().get(Keys.BACKGROUND_COLOR));
}
} else
} else {
return new GenericShape(
pt.getShortName(),
pt.getInputDescription(elementAttributes),
pt.getOutputDescriptions(elementAttributes),
elementAttributes.getLabel(),
true);
true)
.setInverterConfig(elementAttributes.get(Keys.INVERTERCONFIG));
}
}
} else {
ElementTypeDescription pt = library.getElementType(elementName);
@ -194,7 +196,9 @@ public final class ShapeFactory {
@Override
public Shape create(ElementAttributes attributes, PinDescriptions inputs, PinDescriptions outputs) throws NodeException {
return new GenericShape(name, inputs, outputs).invert(invers);
return new GenericShape(name, inputs, outputs)
.invert(invers)
.setInverterConfig(attributes.get(Keys.INVERTERCONFIG));
}
}
}

View File

@ -1,5 +1,6 @@
package de.neemann.digital.draw.shapes.ieee;
import de.neemann.digital.core.element.ElementAttributes;
import de.neemann.digital.core.element.PinDescriptions;
import de.neemann.digital.draw.graphics.Graphic;
import de.neemann.digital.draw.graphics.Polygon;
@ -34,9 +35,10 @@ public class IEEEAndShape extends IEEEGenericShape {
* @param inputs inputs
* @param outputs outputs
* @param invert true if NAnd
* @param attr the attributes
*/
public IEEEAndShape(PinDescriptions inputs, PinDescriptions outputs, boolean invert) {
super(inputs, outputs, invert);
public IEEEAndShape(PinDescriptions inputs, PinDescriptions outputs, boolean invert, ElementAttributes attr) {
super(inputs, outputs, invert, attr);
}
@Override

View File

@ -1,6 +1,8 @@
package de.neemann.digital.draw.shapes.ieee;
import de.neemann.digital.core.Observer;
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;
@ -8,6 +10,7 @@ import de.neemann.digital.draw.graphics.Graphic;
import de.neemann.digital.draw.graphics.GraphicTransform;
import de.neemann.digital.draw.graphics.Style;
import de.neemann.digital.draw.graphics.Vector;
import de.neemann.digital.draw.model.InverterConfig;
import de.neemann.digital.draw.shapes.GenericShape;
import de.neemann.digital.draw.shapes.InteractorInterface;
import de.neemann.digital.draw.shapes.Shape;
@ -25,6 +28,7 @@ public abstract class IEEEGenericShape implements Shape {
private final PinDescriptions inputs;
private final PinDescriptions outputs;
private final boolean invert;
private final InverterConfig inverterConfig;
private Pins pins;
@ -34,17 +38,19 @@ public abstract class IEEEGenericShape implements Shape {
* @param inputs inputs
* @param outputs outputs
* @param invert true if NAnd, NOr
* @param attr the elements attributes
*/
public IEEEGenericShape(PinDescriptions inputs, PinDescriptions outputs, boolean invert) {
public IEEEGenericShape(PinDescriptions inputs, PinDescriptions outputs, boolean invert, ElementAttributes attr) {
this.inputs = inputs;
this.outputs = outputs;
this.invert = invert;
inverterConfig = attr.get(Keys.INVERTERCONFIG);
}
@Override
public Pins getPins() {
if (pins == null)
pins = GenericShape.createPins(inputs, outputs, invert);
pins = GenericShape.createPins(inputs, outputs, invert, inverterConfig);
return pins;
}
@ -64,6 +70,8 @@ public abstract class IEEEGenericShape implements Shape {
graphic.drawLine(new Vector(1, h), new Vector(1, h - offs + SIZE2 + 1), Style.NORMAL);
}
GenericShape.drawInputInvert(graphic, inverterConfig, getPins());
if (invert) {
int o = inputs.size() / 2 * SIZE;
for (int i = 0; i < outputs.size(); i++)

View File

@ -1,5 +1,6 @@
package de.neemann.digital.draw.shapes.ieee;
import de.neemann.digital.core.element.ElementAttributes;
import de.neemann.digital.core.element.PinDescriptions;
import de.neemann.digital.draw.graphics.Graphic;
import de.neemann.digital.draw.graphics.Polygon;
@ -38,13 +39,13 @@ public class IEEEOrShape extends IEEEGenericShape {
/**
* Creates a new instance
*
* @param inputs inputs
* @param inputs inputs
* @param outputs outputs
* @param invert true if NOr
* @param attr the elements attributes
*/
public IEEEOrShape(PinDescriptions inputs, PinDescriptions outputs, boolean invert) {
super(inputs, outputs, invert);
public IEEEOrShape(PinDescriptions inputs, PinDescriptions outputs, boolean invert, ElementAttributes attr) {
super(inputs, outputs, invert, attr);
center = (inputs.size() & 1) != 0;
}

View File

@ -1,5 +1,6 @@
package de.neemann.digital.draw.shapes.ieee;
import de.neemann.digital.core.element.ElementAttributes;
import de.neemann.digital.core.element.PinDescriptions;
import de.neemann.digital.draw.graphics.Graphic;
import de.neemann.digital.draw.graphics.Polygon;
@ -47,9 +48,10 @@ public class IEEEXOrShape extends IEEEGenericShape {
* @param inputs inputs
* @param outputs outputs
* @param invert true if XNOr
* @param attr the elements attributes
*/
public IEEEXOrShape(PinDescriptions inputs, PinDescriptions outputs, boolean invert) {
super(inputs, outputs, invert);
public IEEEXOrShape(PinDescriptions inputs, PinDescriptions outputs, boolean invert, ElementAttributes attr) {
super(inputs, outputs, invert, attr);
}
@Override

View File

@ -923,6 +923,13 @@ public class CircuitComponent extends JComponent implements Circuit.ChangedListe
return ve;
}
/**
* @return the used element library
*/
public ElementLibrary getLibrary() {
return library;
}
private final class PlusMinusAction extends ToolTipAction {
private final int delta;

View File

@ -1,13 +1,14 @@
package de.neemann.digital.gui.components;
import de.neemann.digital.analyse.expression.format.FormatToExpression;
import de.neemann.digital.core.element.ElementAttributes;
import de.neemann.digital.core.element.Key;
import de.neemann.digital.core.element.Keys;
import de.neemann.digital.core.element.Rotation;
import de.neemann.digital.core.NodeException;
import de.neemann.digital.core.element.*;
import de.neemann.digital.core.io.IntFormat;
import de.neemann.digital.core.memory.DataField;
import de.neemann.digital.core.memory.ROM;
import de.neemann.digital.draw.elements.VisualElement;
import de.neemann.digital.draw.library.ElementNotFoundException;
import de.neemann.digital.draw.model.InverterConfig;
import de.neemann.digital.gui.SaveAsHelper;
import de.neemann.digital.gui.components.testing.TestDataEditor;
import de.neemann.digital.gui.sync.NoSync;
@ -25,6 +26,7 @@ import java.awt.event.ActionEvent;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@ -51,6 +53,7 @@ public final class EditorFactory {
add(Language.class, LanguageEditor.class);
add(TestData.class, TestDataEditor.class);
add(FormatToExpression.class, FormatEditor.class);
add(InverterConfig.class, InverterConfigEditor.class);
}
private <T> void add(Class<T> clazz, Class<? extends Editor<T>> editor) {
@ -477,4 +480,100 @@ public final class EditorFactory {
return (FormatToExpression) comb.getSelectedItem();
}
}
private static class InverterConfigEditor extends LabelEditor<InverterConfig> {
private final JButton button;
private InverterConfig inverterConfig;
private ElementAttributes elementAttributes;
public InverterConfigEditor(InverterConfig aInverterConfig, Key<InverterConfig> key) {
this.inverterConfig = aInverterConfig;
button = new JButton(new ToolTipAction(getButtonText()) {
@Override
public void actionPerformed(ActionEvent actionEvent) {
VisualElement ve = getAttributeDialog().getVisualElement();
Component p = getAttributeDialog().getDialogParent();
if (ve != null && p instanceof CircuitComponent) {
try {
getAttributeDialog().storeEditedValues();
ElementTypeDescription d = ((CircuitComponent) p).getLibrary().getElementType(ve.getElementName());
PinDescriptions in = d.getInputDescription(elementAttributes);
InputSelectDialog dialog = new InputSelectDialog(getAttributeDialog(), in, inverterConfig);
if (dialog.showDialog()) {
inverterConfig = dialog.getInverterConfig();
button.setText(getButtonText());
}
} catch (ElementNotFoundException | NodeException e) {
new ErrorMessage(Lang.get("msg_errGettingPinNames")).addCause(e).show(getAttributeDialog());
}
}
}
});
}
private String getButtonText() {
if (inverterConfig.isEmpty())
return Lang.get("msg_none");
return inverterConfig.toString();
}
@Override
public InverterConfig getValue() {
return inverterConfig;
}
@Override
protected JComponent getComponent(ElementAttributes elementAttributes) {
this.elementAttributes = elementAttributes;
return button;
}
}
private final static class InputSelectDialog extends JDialog {
private final ArrayList<JCheckBox> boxes;
private boolean ok = false;
private InputSelectDialog(JDialog parent, PinDescriptions pins, InverterConfig inverterConfig) {
super(parent, Lang.get("msg_inputsToInvert"), true);
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
JPanel panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
boxes = new ArrayList<>();
for (PinDescription p : pins) {
JCheckBox cb = new JCheckBox(p.getName());
cb.setSelected(inverterConfig.contains(p.getName()));
boxes.add(cb);
panel.add(cb);
}
int pad = Screen.getInstance().getFontSize();
panel.setBorder(BorderFactory.createEmptyBorder(pad, pad, pad, pad));
getContentPane().add(panel);
getContentPane().add(new JButton(new AbstractAction(Lang.get("ok")) {
@Override
public void actionPerformed(ActionEvent actionEvent) {
ok = true;
dispose();
}
}), BorderLayout.SOUTH);
pack();
setLocationRelativeTo(parent);
}
public boolean showDialog() {
setVisible(true);
return ok;
}
private InverterConfig getInverterConfig() {
InverterConfig ic = new InverterConfig();
for (JCheckBox cb : boxes) {
if (cb.isSelected())
ic.add(cb.getText());
}
return ic;
}
}
}

View File

@ -644,6 +644,8 @@ Sind evtl. die Namen der Variablen nicht eindeutig?</string>
<string name="key_pinCount_tt">Anzahl der Pins des DILs. Wird hier eine 0 eingetragen, wird die Anzahl automatisch bestimmt.</string>
<string name="key_defTreeSelect">Baumansicht beim Start aktivieren.</string>
<string name="key_defTreeSelect_tt">Wenn gesetzt, wird die Baumansicht beim Start automatisch aktiviert.</string>
<string name="key_inverterConfig">inverse Eingänge</string>
<string name="key_inverterConfig_tt">Es können die Eingänge ausgewählt werden, welche invertiert werden sollen.</string>
<string name="mod_insertWire">Leitung eingefügt.</string>
<string name="mod_insertCopied">Aus Zwischenablage eingefügt.</string>
@ -890,6 +892,9 @@ Die Icons stammen aus dem Tango Desktop Project.</string>
<string name="btn_gifComplete_tt">Die GIF-Datei wird abgeschlossen.</string>
<string name="msg_gifExport">GIF-Export</string>
<string name="msg_errCausedBy">verursacht durch</string>
<string name="msg_inputsToInvert">Zu invertierende Eingänge</string>
<string name="msg_none">keine</string>
<string name="msg_errGettingPinNames">Die Namen der Pins konnten nicht ermittelt werden.</string>
<string name="ok">Ok</string>
<string name="rot_0"></string>

View File

@ -634,6 +634,8 @@ The names of the variables may not be unique.</string>
<string name="key_pinCount_tt">Number of pins. A zero means that the number od pins is determined automatically.</string>
<string name="key_defTreeSelect">Component tree view is visible at startup.</string>
<string name="key_defTreeSelect_tt">If set, the component tree view is enabled at startup.</string>
<string name="key_inverterConfig">inverted Inputs</string>
<string name="key_inverterConfig_tt">You can select the inputs that are to be inverted.</string>
<string name="mod_insertWire">Inserted wire.</string>
<string name="mod_insertCopied">Insert from clipboard.</string>
@ -878,6 +880,9 @@ The icons are taken from the Tango Desktop Project.</string>
<string name="btn_gifComplete_tt">The GIF file is finalized and closed.</string>
<string name="msg_gifExport">GIF Export</string>
<string name="msg_errCausedBy">caused by</string>
<string name="msg_inputsToInvert">Inputs to invert</string>
<string name="msg_none">none</string>
<string name="msg_errGettingPinNames">Could not determine the names of the pins.</string>
<string name="ok">Ok</string>
<string name="rot_0"></string>

View File

@ -39,13 +39,13 @@ public class TestExamples extends TestCase {
*/
public void testTestExamples() throws Exception {
File examples = new File(Resources.getRoot(), "/dig/test");
assertEquals(62, new FileScanner(this::check).scan(examples));
assertEquals(58, testCasesInFiles);
assertEquals(65, new FileScanner(this::check).scan(examples));
assertEquals(62, testCasesInFiles);
}
/**
* Loads the model and initializes and tests it if test cases are present
* Loads the model and initializes and test it if test cases are present
*
* @param dig the model file
*/

View File

@ -0,0 +1,88 @@
<?xml version="1.0" encoding="utf-8"?>
<circuit>
<version>1</version>
<attributes/>
<visualElements>
<visualElement>
<elementName>Out</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>Y</string>
</entry>
</elementAttributes>
<pos x="480" y="160"/>
</visualElement>
<visualElement>
<elementName>Clock</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>C</string>
</entry>
</elementAttributes>
<pos x="360" y="160"/>
</visualElement>
<visualElement>
<elementName>D_FF</elementName>
<elementAttributes>
<entry>
<string>inverterConfig</string>
<inverterConfig>
<string>C</string>
<string>D</string>
</inverterConfig>
</entry>
</elementAttributes>
<pos x="400" y="140"/>
</visualElement>
<visualElement>
<elementName>Testcase</elementName>
<elementAttributes>
<entry>
<string>Testdata</string>
<testData>
<dataString>C Y
0 0
1 0
0 1
1 1
0 0
1 0</dataString>
</testData>
</entry>
</elementAttributes>
<pos x="380" y="200"/>
</visualElement>
</visualElements>
<wires>
<wire>
<p1 x="360" y="160"/>
<p2 x="380" y="160"/>
</wire>
<wire>
<p1 x="460" y="160"/>
<p2 x="480" y="160"/>
</wire>
<wire>
<p1 x="360" y="100"/>
<p2 x="480" y="100"/>
</wire>
<wire>
<p1 x="360" y="140"/>
<p2 x="380" y="140"/>
</wire>
<wire>
<p1 x="460" y="140"/>
<p2 x="480" y="140"/>
</wire>
<wire>
<p1 x="480" y="100"/>
<p2 x="480" y="140"/>
</wire>
<wire>
<p1 x="360" y="100"/>
<p2 x="360" y="140"/>
</wire>
</wires>
</circuit>

View File

@ -0,0 +1,159 @@
<?xml version="1.0" encoding="utf-8"?>
<circuit>
<version>1</version>
<attributes/>
<visualElements>
<visualElement>
<elementName>Out</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>2Y</string>
</entry>
</elementAttributes>
<pos x="480" y="240"/>
</visualElement>
<visualElement>
<elementName>In</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>2A</string>
</entry>
</elementAttributes>
<pos x="360" y="220"/>
</visualElement>
<visualElement>
<elementName>In</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>2B</string>
</entry>
</elementAttributes>
<pos x="360" y="260"/>
</visualElement>
<visualElement>
<elementName>XOr</elementName>
<elementAttributes>
<entry>
<string>inverterConfig</string>
<inverterConfig>
<string>a</string>
</inverterConfig>
</entry>
</elementAttributes>
<pos x="400" y="220"/>
</visualElement>
<visualElement>
<elementName>Out</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>1Y</string>
</entry>
</elementAttributes>
<pos x="480" y="160"/>
</visualElement>
<visualElement>
<elementName>In</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>1A</string>
</entry>
</elementAttributes>
<pos x="360" y="140"/>
</visualElement>
<visualElement>
<elementName>In</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>1B</string>
</entry>
</elementAttributes>
<pos x="360" y="180"/>
</visualElement>
<visualElement>
<elementName>And</elementName>
<elementAttributes>
<entry>
<string>inverterConfig</string>
<inverterConfig>
<string>In_1</string>
</inverterConfig>
</entry>
</elementAttributes>
<pos x="400" y="140"/>
</visualElement>
<visualElement>
<elementName>Testcase</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>AND</string>
</entry>
<entry>
<string>Testdata</string>
<testData>
<dataString>1A 1B 1Y
0 0 0
0 1 1
1 0 0
1 1 0
</dataString>
</testData>
</entry>
</elementAttributes>
<pos x="580" y="140"/>
</visualElement>
<visualElement>
<elementName>Testcase</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>XOR</string>
</entry>
<entry>
<string>Testdata</string>
<testData>
<dataString>2A 2B 2Y
0 0 1
0 1 0
1 0 0
1 1 1
</dataString>
</testData>
</entry>
</elementAttributes>
<pos x="580" y="220"/>
</visualElement>
</visualElements>
<wires>
<wire>
<p1 x="460" y="240"/>
<p2 x="480" y="240"/>
</wire>
<wire>
<p1 x="460" y="160"/>
<p2 x="480" y="160"/>
</wire>
<wire>
<p1 x="360" y="260"/>
<p2 x="400" y="260"/>
</wire>
<wire>
<p1 x="360" y="180"/>
<p2 x="400" y="180"/>
</wire>
<wire>
<p1 x="360" y="220"/>
<p2 x="380" y="220"/>
</wire>
<wire>
<p1 x="360" y="140"/>
<p2 x="380" y="140"/>
</wire>
</wires>
</circuit>

View File

@ -0,0 +1,104 @@
<?xml version="1.0" encoding="utf-8"?>
<circuit>
<version>1</version>
<attributes/>
<visualElements>
<visualElement>
<elementName>JK_FF_AS</elementName>
<elementAttributes>
<entry>
<string>inverterConfig</string>
<inverterConfig>
<string>Set</string>
<string>Clr</string>
</inverterConfig>
</entry>
</elementAttributes>
<pos x="460" y="120"/>
</visualElement>
<visualElement>
<elementName>VDD</elementName>
<elementAttributes/>
<pos x="420" y="100"/>
</visualElement>
<visualElement>
<elementName>In</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>C</string>
</entry>
</elementAttributes>
<pos x="400" y="160"/>
</visualElement>
<visualElement>
<elementName>Out</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>Q</string>
</entry>
</elementAttributes>
<pos x="540" y="120"/>
</visualElement>
<visualElement>
<elementName>Testcase</elementName>
<elementAttributes>
<entry>
<string>Testdata</string>
<testData>
<dataString>C Q
0 0
C 1
C 0
C 1
</dataString>
</testData>
</entry>
</elementAttributes>
<pos x="640" y="140"/>
</visualElement>
</visualElements>
<wires>
<wire>
<p1 x="400" y="160"/>
<p2 x="460" y="160"/>
</wire>
<wire>
<p1 x="420" y="180"/>
<p2 x="460" y="180"/>
</wire>
<wire>
<p1 x="420" y="120"/>
<p2 x="440" y="120"/>
</wire>
<wire>
<p1 x="520" y="120"/>
<p2 x="540" y="120"/>
</wire>
<wire>
<p1 x="420" y="200"/>
<p2 x="440" y="200"/>
</wire>
<wire>
<p1 x="420" y="140"/>
<p2 x="460" y="140"/>
</wire>
<wire>
<p1 x="420" y="100"/>
<p2 x="420" y="120"/>
</wire>
<wire>
<p1 x="420" y="180"/>
<p2 x="420" y="200"/>
</wire>
<wire>
<p1 x="420" y="120"/>
<p2 x="420" y="140"/>
</wire>
<wire>
<p1 x="420" y="140"/>
<p2 x="420" y="180"/>
</wire>
</wires>
</circuit>