mirror of
https://github.com/hneemann/Digital.git
synced 2025-09-28 07:28:20 -04:00
fixed an error in the circuit creation
This commit is contained in:
parent
d337760b1f
commit
70830faebd
@ -51,4 +51,9 @@ public final class Constant implements Expression {
|
|||||||
public String toString() {
|
public String toString() {
|
||||||
return Boolean.toString(value);
|
return Boolean.toString(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Expression copy() {
|
||||||
|
return new Constant(value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -43,4 +43,9 @@ public interface Expression {
|
|||||||
* @return the ordering string
|
* @return the ordering string
|
||||||
*/
|
*/
|
||||||
String getOrderString();
|
String getOrderString();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return a deep copy of this expression
|
||||||
|
*/
|
||||||
|
Expression copy();
|
||||||
}
|
}
|
||||||
|
@ -49,6 +49,11 @@ public class NamedExpression implements Expression {
|
|||||||
return exp.getOrderString();
|
return exp.getOrderString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Expression copy() {
|
||||||
|
return new NamedExpression(name, exp.copy());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return name+"="+exp.toString();
|
return name+"="+exp.toString();
|
||||||
|
@ -82,6 +82,11 @@ public final class Not implements Expression {
|
|||||||
return expression.getOrderString();
|
return expression.getOrderString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Expression copy() {
|
||||||
|
return new Not(expression.copy());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the negated expression
|
* @return the negated expression
|
||||||
*/
|
*/
|
||||||
|
@ -4,7 +4,6 @@ import de.neemann.digital.analyse.expression.modify.ExpressionModifier;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -15,7 +14,7 @@ import java.util.Comparator;
|
|||||||
*/
|
*/
|
||||||
public abstract class Operation implements Expression {
|
public abstract class Operation implements Expression {
|
||||||
private static final Comparator<Expression> EXPRESSION_COMPARATOR
|
private static final Comparator<Expression> EXPRESSION_COMPARATOR
|
||||||
= (a, b) -> a.getOrderString().compareTo(b.getOrderString());
|
= Comparator.comparing(Expression::getOrderString);
|
||||||
|
|
||||||
private final ArrayList<Expression> expr;
|
private final ArrayList<Expression> expr;
|
||||||
|
|
||||||
@ -99,7 +98,7 @@ public abstract class Operation implements Expression {
|
|||||||
case 1:
|
case 1:
|
||||||
return operation.getExpressions().get(0);
|
return operation.getExpressions().get(0);
|
||||||
default:
|
default:
|
||||||
Collections.sort(operation.getExpressions(), EXPRESSION_COMPARATOR);
|
operation.getExpressions().sort(EXPRESSION_COMPARATOR);
|
||||||
return operation;
|
return operation;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -114,6 +113,13 @@ public abstract class Operation implements Expression {
|
|||||||
expr.add(e);
|
expr.add(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Operation(Iterable<Expression> expToCopy) {
|
||||||
|
expr = new ArrayList<>();
|
||||||
|
for (Expression e : expToCopy)
|
||||||
|
if (e != null)
|
||||||
|
expr.add(e.copy());
|
||||||
|
}
|
||||||
|
|
||||||
private void merge(Expression e) {
|
private void merge(Expression e) {
|
||||||
if (e.getClass() == getClass()) {
|
if (e.getClass() == getClass()) {
|
||||||
expr.addAll(((Operation) e).getExpressions());
|
expr.addAll(((Operation) e).getExpressions());
|
||||||
@ -194,6 +200,10 @@ public abstract class Operation implements Expression {
|
|||||||
super(exp, merge);
|
super(exp, merge);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private And(Iterable<Expression> expToCopy) {
|
||||||
|
super(expToCopy);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean getNeutral() {
|
protected boolean getNeutral() {
|
||||||
return true;
|
return true;
|
||||||
@ -208,6 +218,11 @@ public abstract class Operation implements Expression {
|
|||||||
public String toString() {
|
public String toString() {
|
||||||
return "and" + super.toString();
|
return "and" + super.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Expression copy() {
|
||||||
|
return new And(getExpressions());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -219,6 +234,10 @@ public abstract class Operation implements Expression {
|
|||||||
super(exp, merge);
|
super(exp, merge);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Or(Iterable<Expression> expToCopy) {
|
||||||
|
super(expToCopy);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean getNeutral() {
|
protected boolean getNeutral() {
|
||||||
return false;
|
return false;
|
||||||
@ -233,6 +252,11 @@ public abstract class Operation implements Expression {
|
|||||||
public String toString() {
|
public String toString() {
|
||||||
return "or" + super.toString();
|
return "or" + super.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Expression copy() {
|
||||||
|
return new Or(getExpressions());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -244,6 +268,10 @@ public abstract class Operation implements Expression {
|
|||||||
super(Arrays.asList(a, b), false);
|
super(Arrays.asList(a, b), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private XOr(Iterable<Expression> expToCopy) {
|
||||||
|
super(expToCopy);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean getNeutral() {
|
protected boolean getNeutral() {
|
||||||
return false;
|
return false;
|
||||||
@ -258,6 +286,11 @@ public abstract class Operation implements Expression {
|
|||||||
public String toString() {
|
public String toString() {
|
||||||
return "xor" + super.toString();
|
return "xor" + super.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Expression copy() {
|
||||||
|
return new XOr(getExpressions());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -70,6 +70,11 @@ public class Variable implements Comparable<Variable>, Expression {
|
|||||||
return identifier;
|
return identifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Expression copy() {
|
||||||
|
return new Variable(identifier);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the variables name
|
* @return the variables name
|
||||||
*/
|
*/
|
||||||
|
@ -0,0 +1,85 @@
|
|||||||
|
package de.neemann.digital.gui.components.table;
|
||||||
|
|
||||||
|
import de.neemann.digital.analyse.expression.Expression;
|
||||||
|
import de.neemann.digital.analyse.expression.ExpressionException;
|
||||||
|
import de.neemann.digital.analyse.expression.format.FormatterException;
|
||||||
|
import de.neemann.digital.analyse.expression.modify.ExpressionModifier;
|
||||||
|
import de.neemann.digital.builder.BuilderException;
|
||||||
|
import de.neemann.digital.builder.BuilderInterface;
|
||||||
|
import de.neemann.digital.lang.Lang;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper to fill the a {@link BuilderInterface} with pre calculated expressions
|
||||||
|
* stored in {@link ExpressionListenerStore} instance.
|
||||||
|
* <p>
|
||||||
|
* Created by hneemann on 02.04.17.
|
||||||
|
*/
|
||||||
|
public class BuilderExpressionCreator {
|
||||||
|
private final HashSet<String> contained;
|
||||||
|
private final BuilderInterface builder;
|
||||||
|
private final ExpressionModifier[] modifier;
|
||||||
|
private boolean useJKOptimizer = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new instance
|
||||||
|
*
|
||||||
|
* @param builder the builder
|
||||||
|
* @param modifier the modifier tp modify the expression
|
||||||
|
*/
|
||||||
|
public BuilderExpressionCreator(BuilderInterface builder, ExpressionModifier... modifier) {
|
||||||
|
contained = new HashSet<>();
|
||||||
|
this.builder = builder;
|
||||||
|
this.modifier = modifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fills the builder
|
||||||
|
*
|
||||||
|
* @param expressions the expressions to use
|
||||||
|
* @throws ExpressionException ExpressionException
|
||||||
|
* @throws FormatterException FormatterException
|
||||||
|
*/
|
||||||
|
public void create(ExpressionListenerStore expressions) throws ExpressionException, FormatterException {
|
||||||
|
if (expressions == null)
|
||||||
|
throw new ExpressionException(Lang.get("err_noExpressionsAvailable"));
|
||||||
|
|
||||||
|
ExpressionListener el = new ExpressionListener() {
|
||||||
|
@Override
|
||||||
|
public void resultFound(String name, Expression expression) throws FormatterException, ExpressionException {
|
||||||
|
if (!contained.contains(name)) {
|
||||||
|
contained.add(name);
|
||||||
|
try {
|
||||||
|
if (name.endsWith("n+1")) {
|
||||||
|
name = name.substring(0, name.length() - 2);
|
||||||
|
builder.addSequential(name, ExpressionModifier.modifyExpression(expression, modifier));
|
||||||
|
} else
|
||||||
|
builder.addCombinatorial(name, ExpressionModifier.modifyExpression(expression, modifier));
|
||||||
|
} catch (BuilderException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if (useJKOptimizer)
|
||||||
|
el = new ExpressionListenerOptimizeJK(el);
|
||||||
|
|
||||||
|
expressions.replayTo(el);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enables the usage of JK-Flipflops instead of D-Flipflops
|
||||||
|
*
|
||||||
|
* @param useJKOptimizer true if use JK flipflops
|
||||||
|
* @return this for chained calls
|
||||||
|
*/
|
||||||
|
public BuilderExpressionCreator setUseJKOptimizer(boolean useJKOptimizer) {
|
||||||
|
this.useJKOptimizer = useJKOptimizer;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
@ -54,7 +54,7 @@ public class ExpressionListenerStore implements ExpressionListener {
|
|||||||
throw new ExpressionException("ExpressionListenerStore not closed");
|
throw new ExpressionException("ExpressionListenerStore not closed");
|
||||||
|
|
||||||
for (Result r : results)
|
for (Result r : results)
|
||||||
listener.resultFound(r.name, r.expression);
|
listener.resultFound(r.name, r.expression.copy());
|
||||||
listener.close();
|
listener.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,7 +62,7 @@ public class ExpressionListenerStore implements ExpressionListener {
|
|||||||
* @return the first found expression
|
* @return the first found expression
|
||||||
*/
|
*/
|
||||||
public Expression getFirst() {
|
public Expression getFirst() {
|
||||||
return results.get(0).expression;
|
return results.get(0).expression.copy();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final class Result {
|
private static final class Result {
|
||||||
|
@ -16,8 +16,6 @@ import de.neemann.digital.analyse.expression.modify.TwoInputs;
|
|||||||
import de.neemann.digital.analyse.format.TruthTableFormatterLaTeX;
|
import de.neemann.digital.analyse.format.TruthTableFormatterLaTeX;
|
||||||
import de.neemann.digital.analyse.quinemc.BoolTableByteArray;
|
import de.neemann.digital.analyse.quinemc.BoolTableByteArray;
|
||||||
import de.neemann.digital.builder.ATF1502.*;
|
import de.neemann.digital.builder.ATF1502.*;
|
||||||
import de.neemann.digital.builder.BuilderException;
|
|
||||||
import de.neemann.digital.builder.BuilderInterface;
|
|
||||||
import de.neemann.digital.builder.ExpressionToFileExporter;
|
import de.neemann.digital.builder.ExpressionToFileExporter;
|
||||||
import de.neemann.digital.builder.Gal16v8.CuplExporter;
|
import de.neemann.digital.builder.Gal16v8.CuplExporter;
|
||||||
import de.neemann.digital.builder.Gal16v8.Gal16v8JEDECExporter;
|
import de.neemann.digital.builder.Gal16v8.Gal16v8JEDECExporter;
|
||||||
@ -55,7 +53,6 @@ import java.io.File;
|
|||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
|
|
||||||
@ -660,55 +657,6 @@ public class TableDialog extends JDialog {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class BuilderExpressionCreator {
|
|
||||||
private final HashSet<String> contained;
|
|
||||||
private final BuilderInterface builder;
|
|
||||||
private final ExpressionModifier[] modifier;
|
|
||||||
private boolean useJKOptimizer = false;
|
|
||||||
|
|
||||||
BuilderExpressionCreator(BuilderInterface builder, ExpressionModifier... modifier) {
|
|
||||||
contained = new HashSet<>();
|
|
||||||
this.builder = builder;
|
|
||||||
this.modifier = modifier;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void create(ExpressionListenerStore expressions) throws ExpressionException, FormatterException {
|
|
||||||
if (expressions == null)
|
|
||||||
throw new ExpressionException(Lang.get("err_noExpressionsAvailable"));
|
|
||||||
|
|
||||||
ExpressionListener el = new ExpressionListener() {
|
|
||||||
@Override
|
|
||||||
public void resultFound(String name, Expression expression) throws FormatterException, ExpressionException {
|
|
||||||
if (!contained.contains(name)) {
|
|
||||||
contained.add(name);
|
|
||||||
try {
|
|
||||||
if (name.endsWith("n+1")) {
|
|
||||||
name = name.substring(0, name.length() - 2);
|
|
||||||
builder.addSequential(name, ExpressionModifier.modifyExpression(expression, modifier));
|
|
||||||
} else
|
|
||||||
builder.addCombinatorial(name, ExpressionModifier.modifyExpression(expression, modifier));
|
|
||||||
} catch (BuilderException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() {
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if (useJKOptimizer)
|
|
||||||
el = new ExpressionListenerOptimizeJK(el);
|
|
||||||
|
|
||||||
expressions.replayTo(el);
|
|
||||||
}
|
|
||||||
|
|
||||||
BuilderExpressionCreator setUseJKOptimizer(boolean useJKOptimizer) {
|
|
||||||
this.useJKOptimizer = useJKOptimizer;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private final class HTMLExpressionListener implements ExpressionListener {
|
private final class HTMLExpressionListener implements ExpressionListener {
|
||||||
private FormatToExpression htmlFormatter = new HTMLFormatter(FormatToExpression.getDefaultFormat());
|
private FormatToExpression htmlFormatter = new HTMLFormatter(FormatToExpression.getDefaultFormat());
|
||||||
private final StringBuilder html;
|
private final StringBuilder html;
|
||||||
|
@ -0,0 +1,28 @@
|
|||||||
|
package de.neemann.digital.analyse.expression;
|
||||||
|
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
|
import static de.neemann.digital.analyse.expression.Not.not;
|
||||||
|
import static de.neemann.digital.analyse.expression.Operation.and;
|
||||||
|
import static de.neemann.digital.analyse.expression.Operation.or;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by hneemann on 02.04.17.
|
||||||
|
*/
|
||||||
|
public class CopyTest extends TestCase {
|
||||||
|
|
||||||
|
public void testIntegral() throws ExpressionException {
|
||||||
|
Variable a = new Variable("A");
|
||||||
|
Variable b = new Variable("B");
|
||||||
|
Variable c = new Variable("C");
|
||||||
|
Expression e1 = and(not(or(not(a), not(b), c)), not(and(not(a), not(b))));
|
||||||
|
Expression e2 = e1.copy();
|
||||||
|
|
||||||
|
ContextFiller fc = new ContextFiller(e1);
|
||||||
|
|
||||||
|
for (int i = 0; i < fc.getRowCount(); i++) {
|
||||||
|
fc.setContextTo(i);
|
||||||
|
assertEquals(e1.calculate(fc), e2.calculate(fc));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,83 @@
|
|||||||
|
package de.neemann.digital.gui.components.table;
|
||||||
|
|
||||||
|
|
||||||
|
import de.neemann.digital.analyse.AnalyseException;
|
||||||
|
import de.neemann.digital.analyse.ModelAnalyser;
|
||||||
|
import de.neemann.digital.analyse.TruthTable;
|
||||||
|
import de.neemann.digital.analyse.expression.Expression;
|
||||||
|
import de.neemann.digital.analyse.expression.ExpressionException;
|
||||||
|
import de.neemann.digital.analyse.expression.Variable;
|
||||||
|
import de.neemann.digital.analyse.expression.format.FormatterException;
|
||||||
|
import de.neemann.digital.analyse.expression.modify.ExpressionModifier;
|
||||||
|
import de.neemann.digital.analyse.quinemc.BoolTable;
|
||||||
|
import de.neemann.digital.analyse.quinemc.ThreeStateValue;
|
||||||
|
import de.neemann.digital.builder.circuit.CircuitBuilder;
|
||||||
|
import de.neemann.digital.core.Model;
|
||||||
|
import de.neemann.digital.core.NodeException;
|
||||||
|
import de.neemann.digital.core.basic.*;
|
||||||
|
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.draw.model.ModelCreator;
|
||||||
|
import de.neemann.digital.draw.shapes.ShapeFactory;
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
|
import static de.neemann.digital.analyse.expression.Not.not;
|
||||||
|
import static de.neemann.digital.analyse.expression.Operation.and;
|
||||||
|
import static de.neemann.digital.analyse.expression.Operation.or;
|
||||||
|
import static de.neemann.digital.analyse.expression.Variable.v;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by hneemann on 02.04.17.
|
||||||
|
*/
|
||||||
|
public class BuilderExpressionCreatorTest extends TestCase {
|
||||||
|
private ElementLibrary libary = new ElementLibrary();
|
||||||
|
private ShapeFactory shapeFactory = new ShapeFactory(libary);
|
||||||
|
|
||||||
|
public void testSimple() throws FormatterException, ExpressionException, ElementNotFoundException, PinException, NodeException, AnalyseException {
|
||||||
|
Variable a = v("A");
|
||||||
|
Variable b = v("B");
|
||||||
|
Expression xor = or(and(a, not(b)), and(not(a), b));
|
||||||
|
|
||||||
|
ExpressionListenerStore els = new ExpressionListenerStore(null);
|
||||||
|
els.resultFound("xor", xor);
|
||||||
|
els.close();
|
||||||
|
|
||||||
|
Model m = create(els, ExpressionModifier.IDENTITY);
|
||||||
|
assertEquals(5, m.size());
|
||||||
|
assertEquals(2, m.findNode(And.class).size());
|
||||||
|
assertEquals(1, m.findNode(Or.class).size());
|
||||||
|
assertEquals(2, m.findNode(Not.class).size());
|
||||||
|
check(m);
|
||||||
|
|
||||||
|
m = create(els, new de.neemann.digital.analyse.expression.modify.NAnd());
|
||||||
|
assertEquals(5, m.size());
|
||||||
|
assertEquals(2, m.findNode(Not.class).size());
|
||||||
|
assertEquals(3, m.findNode(NAnd.class).size());
|
||||||
|
check(m);
|
||||||
|
|
||||||
|
m = create(els, new de.neemann.digital.analyse.expression.modify.NOr());
|
||||||
|
assertEquals(6, m.size());
|
||||||
|
assertEquals(3, m.findNode(Not.class).size());
|
||||||
|
assertEquals(3, m.findNode(NOr.class).size());
|
||||||
|
check(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void check(Model m) throws AnalyseException, NodeException {
|
||||||
|
TruthTable tt = new ModelAnalyser(m).analyse();
|
||||||
|
assertEquals(1,tt.getResultCount());
|
||||||
|
BoolTable r = tt.getResult(0);
|
||||||
|
assertEquals(4, r.size());
|
||||||
|
assertEquals(ThreeStateValue.zero ,r.get(0));
|
||||||
|
assertEquals(ThreeStateValue.one ,r.get(1));
|
||||||
|
assertEquals(ThreeStateValue.one ,r.get(2));
|
||||||
|
assertEquals(ThreeStateValue.zero ,r.get(3));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Model create(ExpressionListenerStore els, ExpressionModifier modifier) throws ExpressionException, FormatterException, ElementNotFoundException, PinException, NodeException {
|
||||||
|
CircuitBuilder circuitBuilder = new CircuitBuilder(shapeFactory, false);
|
||||||
|
new BuilderExpressionCreator(circuitBuilder, modifier).create(els);
|
||||||
|
return new ModelCreator(circuitBuilder.createCircuit(), libary).createModel(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user