some speed improvements and added some new test cases

This commit is contained in:
hneemann 2019-06-29 11:42:54 +02:00
parent 3354028b11
commit ab62c35628
9 changed files with 574 additions and 44 deletions

View File

@ -12,7 +12,6 @@ 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.CustomElement;
import de.neemann.digital.draw.library.ElementLibrary;
import de.neemann.digital.draw.library.ElementNotFoundException;
import de.neemann.digital.draw.library.LibraryInterface;
@ -138,10 +137,7 @@ public class SubstituteLibrary implements LibraryInterface {
Circuit circuit = Circuit.loadCircuit(in, library.getShapeFactory());
typeDescriptionCustom =
new ElementLibrary.ElementTypeDescriptionCustom(new File(filename),
attributes -> new CustomElement(circuit, library),
circuit);
typeDescriptionCustom = ElementLibrary.createCustomDescription(new File(filename), circuit, library);
}
return typeDescriptionCustom;
}
@ -170,9 +166,7 @@ public class SubstituteLibrary implements LibraryInterface {
Circuit c = circuit.createDeepCopy();
generify(attr, c);
return new ElementLibrary.ElementTypeDescriptionCustom(new File(filename),
attributes -> new CustomElement(c, library),
c);
return ElementLibrary.createCustomDescription(new File(filename), c, library);
}
private void generify(ElementAttributes attr, Circuit circuit) throws IOException {

View File

@ -22,7 +22,7 @@ public class ElementTypeDescription {
private final String name;
private final String langKey;
private String shortName;
private final ElementFactory elementFactory;
private ElementFactory elementFactory;
private final PinDescriptions inputPins;
private final ArrayList<Key> attributeList;
@ -72,6 +72,15 @@ public class ElementTypeDescription {
attributeList = new ArrayList<>();
}
/**
* Sets the factory to create elements.
*
* @param elementFactory the factory
*/
public void setElementFactory(ElementFactory elementFactory) {
this.elementFactory = elementFactory;
}
/**
* Returns a short name which should be used to draw on the shape.
* If not set, the elements name is used instead.

View File

@ -13,8 +13,6 @@ 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.model.ModelCreator;
import de.neemann.digital.draw.model.NetList;
import de.neemann.digital.lang.Lang;
/**
* This class represents a custom, nested element.
@ -22,20 +20,17 @@ import de.neemann.digital.lang.Lang;
* existing circuit. So you can build hierarchical circuits.
*/
public class CustomElement implements Element {
private static final int MAX_DEPTH = 30;
private final Circuit circuit;
private final ElementLibrary.ElementTypeDescriptionCustom descriptionCustom;
private final ElementLibrary library;
private NetList netList;
/**
* Creates a new custom element
*
* @param circuit the inner circuit
* @param library the library to use.
* @param descriptionCustom the inner circuit
* @param library the library to use.
*/
public CustomElement(Circuit circuit, ElementLibrary library) {
this.circuit = circuit;
public CustomElement(ElementLibrary.ElementTypeDescriptionCustom descriptionCustom, ElementLibrary library) {
this.descriptionCustom = descriptionCustom;
this.library = library;
}
@ -52,13 +47,7 @@ public class CustomElement implements Element {
* @throws ElementNotFoundException ElementNotFoundException
*/
public ModelCreator getModelCreator(String subName, int depth, VisualElement containingVisualElement) throws PinException, NodeException, ElementNotFoundException {
if (netList == null)
netList = new NetList(circuit);
if (depth > MAX_DEPTH)
throw new NodeException(Lang.get("err_recursiveNestingAt_N0", circuit.getOrigin()));
return new ModelCreator(circuit, library, true, new NetList(netList, containingVisualElement), subName, depth, containingVisualElement);
return descriptionCustom.getModelCreator(subName, depth, containingVisualElement, library);
}
@Override
@ -68,7 +57,7 @@ public class CustomElement implements Element {
@Override
public ObservableValues getOutputs() throws PinException {
return circuit.getOutputNames();
return descriptionCustom.getCircuit().getOutputNames();
}
@Override
@ -80,6 +69,6 @@ public class CustomElement implements Element {
* @return the circuit which is represented by this element
*/
public Circuit getCircuit() {
return circuit;
return descriptionCustom.getCircuit();
}
}

View File

@ -5,6 +5,7 @@
*/
package de.neemann.digital.draw.library;
import de.neemann.digital.core.NodeException;
import de.neemann.digital.core.arithmetic.*;
import de.neemann.digital.core.arithmetic.Comparator;
import de.neemann.digital.core.basic.*;
@ -25,6 +26,9 @@ import de.neemann.digital.core.wiring.*;
import de.neemann.digital.draw.elements.Circuit;
import de.neemann.digital.draw.elements.PinException;
import de.neemann.digital.draw.elements.Tunnel;
import de.neemann.digital.draw.elements.VisualElement;
import de.neemann.digital.draw.model.ModelCreator;
import de.neemann.digital.draw.model.NetList;
import de.neemann.digital.draw.shapes.ShapeFactory;
import de.neemann.digital.gui.Settings;
import de.neemann.digital.gui.components.data.DummyElement;
@ -570,10 +574,8 @@ public class ElementLibrary implements Iterable<ElementLibrary.ElementContainer>
} catch (FileNotFoundException e) {
throw new IOException(Lang.get("err_couldNotFindIncludedFile_N0", file));
}
ElementTypeDescriptionCustom description =
new ElementTypeDescriptionCustom(file,
attributes -> new CustomElement(circuit, ElementLibrary.this),
circuit);
ElementTypeDescriptionCustom description = createCustomDescription(file, circuit, this);
description.setShortName(createShortName(file));
String descriptionText = Lang.evalMultilingualContent(circuit.getAttributes().get(Keys.DESCRIPTION));
@ -600,25 +602,41 @@ public class ElementLibrary implements Iterable<ElementLibrary.ElementContainer>
return transName;
}
/**
* Creates a custom element description.
*
* @param file the file
* @param circuit the circuit
* @param library the used library
* @return the type description
* @throws PinException PinException
*/
public static ElementTypeDescriptionCustom createCustomDescription(File file, Circuit circuit, ElementLibrary library) throws PinException {
ElementTypeDescriptionCustom d = new ElementTypeDescriptionCustom(file, circuit);
d.setElementFactory(attributes -> new CustomElement(d, library));
return d;
}
/**
* The description of a nested element.
* This is a complete circuit which is used as a element.
*/
public static class ElementTypeDescriptionCustom extends ElementTypeDescription {
public static final class ElementTypeDescriptionCustom extends ElementTypeDescription {
private static final int MAX_DEPTH = 30;
private final File file;
private final Circuit circuit;
private String description;
private NetList netList;
/**
* Creates a new element
*
* @param file the file which is loaded
* @param elementFactory a element factory which is used to create concrete elements if needed
* @param circuit the circuit
* @param file the file which is loaded
* @param circuit the circuit
* @throws PinException PinException
*/
public ElementTypeDescriptionCustom(File file, ElementFactory elementFactory, Circuit circuit) throws PinException {
super(file.getName(), elementFactory, circuit.getInputNames());
private ElementTypeDescriptionCustom(File file, Circuit circuit) throws PinException {
super(file.getName(), (ElementFactory) null, circuit.getInputNames());
this.file = file;
this.circuit = circuit;
setShortName(file.getName());
@ -668,6 +686,29 @@ public class ElementLibrary implements Iterable<ElementLibrary.ElementContainer>
return super.getDescription(elementAttributes);
}
/**
* Gets a {@link ModelCreator} of this circuit.
* Every time this method is called a new {@link ModelCreator} is created.
*
* @param subName name of the circuit, used to name unique elements
* @param depth recursion depth, used to detect a circuit which contains itself
* @param containingVisualElement the containing visual element
* @param library the library used
* @return the {@link ModelCreator}
* @throws PinException PinException
* @throws NodeException NodeException
* @throws ElementNotFoundException ElementNotFoundException
*/
public ModelCreator getModelCreator(String subName, int depth, VisualElement containingVisualElement, ElementLibrary library) throws PinException, NodeException, ElementNotFoundException {
if (netList == null)
netList = new NetList(circuit);
if (depth > MAX_DEPTH)
throw new NodeException(Lang.get("err_recursiveNestingAt_N0", circuit.getOrigin()));
return new ModelCreator(circuit, library, true, new NetList(netList, containingVisualElement), subName, depth, containingVisualElement);
}
}

View File

@ -5,9 +5,9 @@
*/
package de.neemann.digital.gui;
import de.neemann.digital.analyse.SubstituteLibrary;
import de.neemann.digital.analyse.AnalyseException;
import de.neemann.digital.analyse.ModelAnalyser;
import de.neemann.digital.analyse.SubstituteLibrary;
import de.neemann.digital.analyse.TruthTable;
import de.neemann.digital.analyse.expression.format.FormatToExpression;
import de.neemann.digital.core.*;
@ -21,7 +21,6 @@ import de.neemann.digital.core.wiring.Clock;
import de.neemann.digital.draw.elements.*;
import de.neemann.digital.draw.gif.GifExporter;
import de.neemann.digital.draw.graphics.*;
import de.neemann.digital.draw.library.CustomElement;
import de.neemann.digital.draw.library.ElementLibrary;
import de.neemann.digital.draw.library.ElementNotFoundException;
import de.neemann.digital.draw.model.AsyncSequentialClock;
@ -51,10 +50,10 @@ import de.neemann.digital.gui.state.StateManager;
import de.neemann.digital.hdl.printer.CodePrinter;
import de.neemann.digital.hdl.verilog2.VerilogGenerator;
import de.neemann.digital.hdl.vhdl2.VHDLGenerator;
import de.neemann.digital.toolchain.Configuration;
import de.neemann.digital.lang.Lang;
import de.neemann.digital.testing.TestCaseElement;
import de.neemann.digital.testing.TestingDataException;
import de.neemann.digital.toolchain.Configuration;
import de.neemann.digital.undo.ChangedListener;
import de.neemann.digital.undo.Modifications;
import de.neemann.gui.*;
@ -370,9 +369,7 @@ public final class Main extends JFrame implements ClosingWindowListener.ConfirmS
file = new File(name);
try {
ElementLibrary.ElementTypeDescriptionCustom description =
new ElementLibrary.ElementTypeDescriptionCustom(file,
attributes -> new CustomElement(circuit, library),
circuit);
ElementLibrary.createCustomDescription(file, circuit, library);
description.setShortName(name);
description.setDescription(Lang.evalMultilingualContent(circuit.getAttributes().get(Keys.DESCRIPTION)));
new ElementHelpDialog(Main.this, description, circuit.getAttributes()).setVisible(true);

View File

@ -71,12 +71,24 @@ public class ModelAnalyserTest extends TestCase {
check2BitCounter(tt);
}
public void testAnalyzerDFFInvIn() throws Exception {
Model model = createModel("dig/analyze/analyzeTestDFFInvIn.dig");
TruthTable tt = new ModelAnalyser(model).analyse();
check2BitCounter(tt);
}
public void testAnalyzerJKFF() throws Exception {
Model model = createModel("dig/analyze/analyzeTestJKFF.dig");
TruthTable tt = new ModelAnalyser(model).analyse();
check2BitCounter(tt);
}
public void testAnalyzerJKFFInvInput() throws Exception {
Model model = createModel("dig/analyze/analyzeTestJKFFInvIn.dig");
TruthTable tt = new ModelAnalyser(model).analyse();
check2BitCounter(tt);
}
public void testAnalyzerTFF() throws Exception {
Model model = createModel("dig/analyze/analyzeTestTFF.dig");
TruthTable tt = new ModelAnalyser(model).analyse();
@ -89,6 +101,12 @@ public class ModelAnalyserTest extends TestCase {
check2BitCounter(tt);
}
public void testAnalyzerTFFEnableInvIn() throws Exception {
Model model = createModel("dig/analyze/analyzeTestTFFEnableInvIn.dig");
TruthTable tt = new ModelAnalyser(model).analyse();
check2BitCounter(tt);
}
private void check2BitCounter(TruthTable tt) {
assertEquals(4, tt.getRows());
assertEquals(4, tt.getCols());

View File

@ -0,0 +1,285 @@
<?xml version="1.0" encoding="utf-8"?>
<circuit>
<version>1</version>
<attributes/>
<visualElements>
<visualElement>
<elementName>Tunnel</elementName>
<elementAttributes>
<entry>
<string>Inputs</string>
<int>1</int>
</entry>
<entry>
<string>NetName</string>
<string>Q_1n</string>
</entry>
</elementAttributes>
<pos x="340" y="60"/>
</visualElement>
<visualElement>
<elementName>D_FF</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>Q_1n</string>
</entry>
<entry>
<string>inverterConfig</string>
<inverterConfig>
<string>D</string>
</inverterConfig>
</entry>
<entry>
<string>Inputs</string>
<int>1</int>
</entry>
</elementAttributes>
<pos x="260" y="60"/>
</visualElement>
<visualElement>
<elementName>And</elementName>
<elementAttributes/>
<pos x="20" y="0"/>
</visualElement>
<visualElement>
<elementName>And</elementName>
<elementAttributes/>
<pos x="20" y="80"/>
</visualElement>
<visualElement>
<elementName>Tunnel</elementName>
<elementAttributes>
<entry>
<string>Inputs</string>
<int>1</int>
</entry>
<entry>
<string>NetName</string>
<string>Q_0n</string>
</entry>
</elementAttributes>
<pos x="340" y="160"/>
</visualElement>
<visualElement>
<elementName>D_FF</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>Q_0n</string>
</entry>
<entry>
<string>Inputs</string>
<int>1</int>
</entry>
</elementAttributes>
<pos x="260" y="160"/>
</visualElement>
<visualElement>
<elementName>Tunnel</elementName>
<elementAttributes>
<entry>
<string>rotation</string>
<rotation rotation="1"/>
</entry>
<entry>
<string>NetName</string>
<string>Q_0n</string>
</entry>
</elementAttributes>
<pos x="-80" y="-100"/>
</visualElement>
<visualElement>
<elementName>Not</elementName>
<elementAttributes>
<entry>
<string>rotation</string>
<rotation rotation="3"/>
</entry>
</elementAttributes>
<pos x="-60" y="-60"/>
</visualElement>
<visualElement>
<elementName>Tunnel</elementName>
<elementAttributes>
<entry>
<string>rotation</string>
<rotation rotation="1"/>
</entry>
<entry>
<string>NetName</string>
<string>Q_1n</string>
</entry>
</elementAttributes>
<pos x="-40" y="-100"/>
</visualElement>
<visualElement>
<elementName>Not</elementName>
<elementAttributes>
<entry>
<string>rotation</string>
<rotation rotation="3"/>
</entry>
</elementAttributes>
<pos x="-20" y="-60"/>
</visualElement>
<visualElement>
<elementName>Clock</elementName>
<elementAttributes>
<entry>
<string>runRealTime</string>
<boolean>true</boolean>
</entry>
<entry>
<string>rotation</string>
<rotation rotation="3"/>
</entry>
<entry>
<string>Label</string>
<string>C</string>
</entry>
</elementAttributes>
<pos x="220" y="0"/>
</visualElement>
<visualElement>
<elementName>NOr</elementName>
<elementAttributes/>
<pos x="120" y="40"/>
</visualElement>
</visualElements>
<wires>
<wire>
<p1 x="-80" y="0"/>
<p2 x="20" y="0"/>
</wire>
<wire>
<p1 x="-60" y="80"/>
<p2 x="20" y="80"/>
</wire>
<wire>
<p1 x="100" y="80"/>
<p2 x="120" y="80"/>
</wire>
<wire>
<p1 x="220" y="80"/>
<p2 x="260" y="80"/>
</wire>
<wire>
<p1 x="320" y="160"/>
<p2 x="340" y="160"/>
</wire>
<wire>
<p1 x="-60" y="160"/>
<p2 x="260" y="160"/>
</wire>
<wire>
<p1 x="80" y="20"/>
<p2 x="100" y="20"/>
</wire>
<wire>
<p1 x="80" y="100"/>
<p2 x="100" y="100"/>
</wire>
<wire>
<p1 x="220" y="180"/>
<p2 x="260" y="180"/>
</wire>
<wire>
<p1 x="-20" y="40"/>
<p2 x="20" y="40"/>
</wire>
<wire>
<p1 x="100" y="40"/>
<p2 x="120" y="40"/>
</wire>
<wire>
<p1 x="-40" y="120"/>
<p2 x="20" y="120"/>
</wire>
<wire>
<p1 x="320" y="60"/>
<p2 x="340" y="60"/>
</wire>
<wire>
<p1 x="200" y="60"/>
<p2 x="240" y="60"/>
</wire>
<wire>
<p1 x="-80" y="-80"/>
<p2 x="-60" y="-80"/>
</wire>
<wire>
<p1 x="-40" y="-80"/>
<p2 x="-20" y="-80"/>
</wire>
<wire>
<p1 x="-20" y="-80"/>
<p2 x="-20" y="-60"/>
</wire>
<wire>
<p1 x="-20" y="-20"/>
<p2 x="-20" y="40"/>
</wire>
<wire>
<p1 x="-20" y="40"/>
<p2 x="-20" y="200"/>
</wire>
<wire>
<p1 x="100" y="20"/>
<p2 x="100" y="40"/>
</wire>
<wire>
<p1 x="100" y="80"/>
<p2 x="100" y="100"/>
</wire>
<wire>
<p1 x="-40" y="-100"/>
<p2 x="-40" y="-80"/>
</wire>
<wire>
<p1 x="-40" y="120"/>
<p2 x="-40" y="200"/>
</wire>
<wire>
<p1 x="-40" y="-80"/>
<p2 x="-40" y="120"/>
</wire>
<wire>
<p1 x="-60" y="-80"/>
<p2 x="-60" y="-60"/>
</wire>
<wire>
<p1 x="-60" y="-20"/>
<p2 x="-60" y="80"/>
</wire>
<wire>
<p1 x="-60" y="160"/>
<p2 x="-60" y="200"/>
</wire>
<wire>
<p1 x="-60" y="80"/>
<p2 x="-60" y="160"/>
</wire>
<wire>
<p1 x="220" y="0"/>
<p2 x="220" y="80"/>
</wire>
<wire>
<p1 x="220" y="80"/>
<p2 x="220" y="180"/>
</wire>
<wire>
<p1 x="-80" y="-100"/>
<p2 x="-80" y="-80"/>
</wire>
<wire>
<p1 x="-80" y="0"/>
<p2 x="-80" y="200"/>
</wire>
<wire>
<p1 x="-80" y="-80"/>
<p2 x="-80" y="0"/>
</wire>
</wires>
<measurementOrdering/>
</circuit>

View File

@ -0,0 +1,107 @@
<?xml version="1.0" encoding="utf-8"?>
<circuit>
<version>1</version>
<attributes/>
<visualElements>
<visualElement>
<elementName>JK_FF</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>Q_1n</string>
</entry>
<entry>
<string>inverterConfig</string>
<inverterConfig>
<string>J</string>
<string>K</string>
</inverterConfig>
</entry>
</elementAttributes>
<pos x="180" y="-60"/>
</visualElement>
<visualElement>
<elementName>JK_FF</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>Q_0n</string>
</entry>
</elementAttributes>
<pos x="160" y="80"/>
</visualElement>
<visualElement>
<elementName>Clock</elementName>
<elementAttributes/>
<pos x="80" y="100"/>
</visualElement>
<visualElement>
<elementName>Const</elementName>
<elementAttributes/>
<pos x="120" y="120"/>
</visualElement>
</visualElements>
<wires>
<wire>
<p1 x="140" y="80"/>
<p2 x="160" y="80"/>
</wire>
<wire>
<p1 x="140" y="-20"/>
<p2 x="160" y="-20"/>
</wire>
<wire>
<p1 x="220" y="100"/>
<p2 x="240" y="100"/>
</wire>
<wire>
<p1 x="80" y="100"/>
<p2 x="120" y="100"/>
</wire>
<wire>
<p1 x="120" y="100"/>
<p2 x="160" y="100"/>
</wire>
<wire>
<p1 x="140" y="20"/>
<p2 x="240" y="20"/>
</wire>
<wire>
<p1 x="120" y="-40"/>
<p2 x="180" y="-40"/>
</wire>
<wire>
<p1 x="120" y="120"/>
<p2 x="140" y="120"/>
</wire>
<wire>
<p1 x="140" y="120"/>
<p2 x="160" y="120"/>
</wire>
<wire>
<p1 x="140" y="-60"/>
<p2 x="160" y="-60"/>
</wire>
<wire>
<p1 x="240" y="20"/>
<p2 x="240" y="100"/>
</wire>
<wire>
<p1 x="120" y="-40"/>
<p2 x="120" y="100"/>
</wire>
<wire>
<p1 x="140" y="80"/>
<p2 x="140" y="120"/>
</wire>
<wire>
<p1 x="140" y="-60"/>
<p2 x="140" y="-20"/>
</wire>
<wire>
<p1 x="140" y="-20"/>
<p2 x="140" y="20"/>
</wire>
</wires>
<measurementOrdering/>
</circuit>

View File

@ -0,0 +1,90 @@
<?xml version="1.0" encoding="utf-8"?>
<circuit>
<version>1</version>
<attributes/>
<visualElements>
<visualElement>
<elementName>Clock</elementName>
<elementAttributes/>
<pos x="80" y="100"/>
</visualElement>
<visualElement>
<elementName>T_FF</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>Q_1n</string>
</entry>
<entry>
<string>inverterConfig</string>
<inverterConfig>
<string>T</string>
</inverterConfig>
</entry>
</elementAttributes>
<pos x="180" y="-60"/>
</visualElement>
<visualElement>
<elementName>T_FF</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>Q_0n</string>
</entry>
</elementAttributes>
<pos x="160" y="80"/>
</visualElement>
<visualElement>
<elementName>VDD</elementName>
<elementAttributes/>
<pos x="140" y="60"/>
</visualElement>
</visualElements>
<wires>
<wire>
<p1 x="140" y="80"/>
<p2 x="160" y="80"/>
</wire>
<wire>
<p1 x="220" y="100"/>
<p2 x="240" y="100"/>
</wire>
<wire>
<p1 x="80" y="100"/>
<p2 x="120" y="100"/>
</wire>
<wire>
<p1 x="120" y="100"/>
<p2 x="160" y="100"/>
</wire>
<wire>
<p1 x="140" y="20"/>
<p2 x="240" y="20"/>
</wire>
<wire>
<p1 x="120" y="-40"/>
<p2 x="180" y="-40"/>
</wire>
<wire>
<p1 x="140" y="-60"/>
<p2 x="160" y="-60"/>
</wire>
<wire>
<p1 x="240" y="20"/>
<p2 x="240" y="100"/>
</wire>
<wire>
<p1 x="120" y="-40"/>
<p2 x="120" y="100"/>
</wire>
<wire>
<p1 x="140" y="-60"/>
<p2 x="140" y="20"/>
</wire>
<wire>
<p1 x="140" y="60"/>
<p2 x="140" y="80"/>
</wire>
</wires>
<measurementOrdering/>
</circuit>