1 /* 2 * Copyright (c) 2016 Helmut Neemann 3 * Use of this source code is governed by the GPL v3 license 4 * that can be found in the LICENSE file. 5 */ 6 package de.neemann.digital.builder.circuit; 7 8 import de.neemann.digital.TestExecuter; 9 import de.neemann.digital.analyse.ModelAnalyser; 10 import de.neemann.digital.analyse.TruthTable; 11 import de.neemann.digital.analyse.expression.Constant; 12 import de.neemann.digital.analyse.expression.Expression; 13 import de.neemann.digital.analyse.expression.NamedExpression; 14 import de.neemann.digital.analyse.expression.Variable; 15 import de.neemann.digital.analyse.parser.ParseException; 16 import de.neemann.digital.analyse.parser.Parser; 17 import de.neemann.digital.builder.BuilderException; 18 import de.neemann.digital.core.NodeException; 19 import de.neemann.digital.core.element.Keys; 20 import de.neemann.digital.core.io.Const; 21 import de.neemann.digital.core.io.In; 22 import de.neemann.digital.core.io.Out; 23 import de.neemann.digital.core.memory.LookUpTable; 24 import de.neemann.digital.draw.elements.Circuit; 25 import de.neemann.digital.draw.elements.PinException; 26 import de.neemann.digital.draw.elements.Tunnel; 27 import de.neemann.digital.draw.elements.VisualElement; 28 import de.neemann.digital.draw.library.ElementLibrary; 29 import de.neemann.digital.draw.library.ElementNotFoundException; 30 import de.neemann.digital.draw.model.ModelCreator; 31 import de.neemann.digital.draw.shapes.ShapeFactory; 32 import de.neemann.digital.gui.components.table.BuilderExpressionCreator; 33 import de.neemann.digital.gui.components.table.ExpressionCreator; 34 import de.neemann.digital.gui.components.table.ExpressionListenerStore; 35 import de.neemann.digital.integration.ToBreakRunner; 36 import junit.framework.TestCase; 37 38 import java.io.IOException; 39 import java.util.ArrayList; 40 import java.util.List; 41 42 import static de.neemann.digital.analyse.expression.Not.not; 43 import static de.neemann.digital.analyse.expression.Operation.and; 44 import static de.neemann.digital.analyse.expression.Operation.or; 45 46 /** 47 * 48 */ 49 public class CircuitBuilderTest extends TestCase { 50 testBuilderCombinatorial()51 public void testBuilderCombinatorial() throws Exception { 52 53 Variable a = new Variable("a"); 54 Variable b = new Variable("b"); 55 56 // xor 57 Expression y = and(or(a, b), not(and(a, b))); 58 59 ElementLibrary library = new ElementLibrary(); 60 Circuit circuit = new CircuitBuilder(new ShapeFactory(library)) 61 .addCombinatorial("y", y) 62 .createCircuit(); 63 64 ModelCreator m = new ModelCreator(circuit, library); 65 66 TestExecuter te = new TestExecuter(m.createModel(false)).setUp(m); 67 te.check(0, 0, 0); 68 te.check(0, 1, 1); 69 te.check(1, 0, 1); 70 te.check(1, 1, 0); 71 } 72 testBuilderSequential()73 public void testBuilderSequential() throws Exception { 74 Variable y0 = new Variable("Y_0"); 75 Variable y1 = new Variable("Y_1"); 76 77 // counter 78 Expression y0s = not(y0); 79 Expression y1s = or(and(not(y0), y1), and(y0, not(y1))); 80 81 ElementLibrary library = new ElementLibrary(); 82 Circuit circuit = new CircuitBuilder(new ShapeFactory(library)) 83 .addSequential("Y_0", y0s) 84 .addSequential("Y_1", y1s) 85 .createCircuit(); 86 87 ModelCreator m = new ModelCreator(circuit, library); 88 TestExecuter te = new TestExecuter(m.createModel(false)).setUp(m); 89 te.check(0, 0); 90 te.checkC(1, 0); 91 te.checkC(0, 1); 92 te.checkC(1, 1); 93 te.checkC(0, 0); 94 } 95 testBuilderSequentialLUT()96 public void testBuilderSequentialLUT() throws Exception { 97 Variable y0 = new Variable("Y_0"); 98 Variable y1 = new Variable("Y_1"); 99 Variable y2 = new Variable("Y_2"); 100 101 // counter 102 Expression y0s = not(y0); 103 Expression y1s = or(and(not(y0), y1), and(y0, not(y1))); 104 Expression y2s = or(and(y0, y1, not(y2)), and(not(y0), y2), and(not(y1), y2)); 105 106 ElementLibrary library = new ElementLibrary(); 107 Circuit circuit = new CircuitBuilder(new ShapeFactory(library)) 108 .setUseLUTs(true) 109 .addSequential("Y_0", y0s) 110 .addSequential("Y_1", y1s) 111 .addSequential("Y_2", y2s) 112 .createCircuit(); 113 114 final ArrayList<VisualElement> el = circuit.getElements(); 115 assertEquals(19, el.size()); 116 assertEquals(1, el.stream().filter(visualElement -> visualElement.equalsDescription(LookUpTable.DESCRIPTION)).count()); 117 118 ModelCreator m = new ModelCreator(circuit, library); 119 TestExecuter te = new TestExecuter(m.createModel(false)).setUp(m); 120 te.check(0, 0, 0); 121 te.checkC(1, 0, 0); 122 te.checkC(0, 1, 0); 123 te.checkC(1, 1, 0); 124 te.checkC(0, 0, 1); 125 te.checkC(1, 0, 1); 126 te.checkC(0, 1, 1); 127 te.checkC(1, 1, 1); 128 te.checkC(0, 0, 0); 129 } 130 testBuilderSequentialJK_JequalsK()131 public void testBuilderSequentialJK_JequalsK() throws Exception { 132 Variable y0 = new Variable("Y_0"); 133 Variable y1 = new Variable("Y_1"); 134 135 // counter 136 Expression y0s = not(y0); 137 Expression y1s = or(and(not(y0), y1), and(y0, not(y1))); 138 139 ElementLibrary library = new ElementLibrary(); 140 Circuit circuit = new CircuitBuilder(new ShapeFactory(library)) 141 .setUseJK(true) 142 .addSequential("Y_0", y0s) 143 .addSequential("Y_1", y1s) 144 .createCircuit(); 145 146 ModelCreator m = new ModelCreator(circuit, library); 147 TestExecuter te = new TestExecuter(m.createModel(false)).setUp(m); 148 te.check(0, 0); 149 te.checkC(1, 0); 150 te.checkC(0, 1); 151 te.checkC(1, 1); 152 te.checkC(0, 0); 153 } 154 testBuilderSequentialJK()155 public void testBuilderSequentialJK() throws Exception { 156 Variable y0 = new Variable("Y_0"); 157 Variable y1 = new Variable("Y_1"); 158 159 // counter 160 Expression y0s = not(y0); 161 Expression y1s = or(not(y0), not(y1)); 162 163 ElementLibrary library = new ElementLibrary(); 164 Circuit circuit = new CircuitBuilder(new ShapeFactory(library)) 165 .setUseJK(true) 166 .addSequential("Y_0", y0s) 167 .addSequential("Y_1", y1s) 168 .createCircuit(); 169 170 ModelCreator m = new ModelCreator(circuit, library); 171 TestExecuter te = new TestExecuter(m.createModel(false)).setUp(m); 172 te.check(0, 0); 173 te.checkC(1, 1); 174 te.checkC(0, 0); 175 te.checkC(1, 1); 176 te.checkC(0, 0); 177 } 178 testBuilderSequentialConstant()179 public void testBuilderSequentialConstant() throws Exception { 180 ElementLibrary library = new ElementLibrary(); 181 Circuit circuit = new CircuitBuilder(new ShapeFactory(library)) 182 .addSequential("Y_0", Constant.ONE) 183 .addSequential("Y_1", Constant.ZERO) 184 .createCircuit(); 185 186 final ArrayList<VisualElement> el = circuit.getElements(); 187 assertEquals(8, el.size()); 188 assertEquals(4, el.stream().filter(visualElement -> visualElement.equalsDescription(Tunnel.DESCRIPTION)).count()); 189 assertEquals(2, el.stream().filter(visualElement -> visualElement.equalsDescription(Const.DESCRIPTION)).count()); 190 assertEquals(2, el.stream().filter(visualElement -> visualElement.equalsDescription(Out.DESCRIPTION)).count()); 191 } 192 testBuilderSequentialConstantJK()193 public void testBuilderSequentialConstantJK() throws Exception { 194 ElementLibrary library = new ElementLibrary(); 195 Circuit circuit = new CircuitBuilder(new ShapeFactory(library)) 196 .setUseJK(true) 197 .addSequential("Y_0", Constant.ONE) 198 .addSequential("Y_1", Constant.ZERO) 199 .createCircuit(); 200 201 final ArrayList<VisualElement> el = circuit.getElements(); 202 assertEquals(8, el.size()); 203 assertEquals(4, el.stream().filter(visualElement -> visualElement.equalsDescription(Tunnel.DESCRIPTION)).count()); 204 assertEquals(2, el.stream().filter(visualElement -> visualElement.equalsDescription(Const.DESCRIPTION)).count()); 205 assertEquals(2, el.stream().filter(visualElement -> visualElement.equalsDescription(Out.DESCRIPTION)).count()); 206 } 207 testBus()208 public void testBus() throws Exception { 209 final ToBreakRunner runner = new ToBreakRunner("dig/circuitBuilder/busTest.dig", false); 210 // create truth table incl. ModelAnalyzerInfo 211 TruthTable tt = new ModelAnalyser(runner.getModel()).analyse(); 212 213 assertEquals(8, tt.getVars().size()); 214 assertEquals(8, tt.getResultCount()); 215 216 // create expressions based on truth table 217 ExpressionListenerStore expr = new ExpressionListenerStore(null); 218 new ExpressionCreator(tt).create(expr); 219 220 // build a new circuit 221 CircuitBuilder circuitBuilder = new CircuitBuilder(runner.getLibrary().getShapeFactory(), tt.getVars()) 222 .setModelAnalyzerInfo(tt.getModelAnalyzerInfo()); 223 new BuilderExpressionCreator(circuitBuilder).create(expr); 224 Circuit circuit = circuitBuilder.createCircuit(); 225 226 // check 227 List<VisualElement> in = circuit.getElements(v -> v.equalsDescription(In.DESCRIPTION)); 228 assertEquals(2, in.size()); 229 checkPin(in.get(0), "A", "1,2,3,4"); 230 checkPin(in.get(1), "B", "5,6,7,8"); 231 232 List<VisualElement> out = circuit.getElements(v -> v.equalsDescription(Out.DESCRIPTION)); 233 assertEquals(2, out.size()); 234 checkPin(out.get(0), "S", "9,10,11,12"); 235 checkPin(out.get(1), "U", "13,14,15,16"); 236 } 237 checkPin(VisualElement e, String label, String pins)238 private void checkPin(VisualElement e, String label, String pins) { 239 assertEquals(label, e.getElementAttributes().getLabel()); 240 assertEquals(4, e.getElementAttributes().getBits()); 241 assertEquals(pins, e.getElementAttributes().get(Keys.PINNUMBER)); 242 } 243 testIsXor()244 public void testIsXor() { 245 assertFalse(CircuitBuilder.isXor(new long[]{0, 0, 0, 0})); 246 assertFalse(CircuitBuilder.isXor(new long[]{0, 0, 0, 1})); 247 assertFalse(CircuitBuilder.isXor(new long[]{0, 0, 1, 0})); 248 assertFalse(CircuitBuilder.isXor(new long[]{0, 0, 1, 1})); 249 assertFalse(CircuitBuilder.isXor(new long[]{0, 1, 0, 0})); 250 assertFalse(CircuitBuilder.isXor(new long[]{0, 1, 0, 1})); 251 assertTrue(CircuitBuilder.isXor(new long[]{0, 1, 1, 0})); 252 assertFalse(CircuitBuilder.isXor(new long[]{0, 1, 1, 1})); 253 assertFalse(CircuitBuilder.isXor(new long[]{1, 0, 0, 0})); 254 assertFalse(CircuitBuilder.isXor(new long[]{1, 0, 0, 1})); 255 assertFalse(CircuitBuilder.isXor(new long[]{1, 0, 1, 0})); 256 assertFalse(CircuitBuilder.isXor(new long[]{1, 0, 1, 1})); 257 assertFalse(CircuitBuilder.isXor(new long[]{1, 1, 0, 0})); 258 assertFalse(CircuitBuilder.isXor(new long[]{1, 1, 0, 1})); 259 assertFalse(CircuitBuilder.isXor(new long[]{1, 1, 1, 0})); 260 assertFalse(CircuitBuilder.isXor(new long[]{1, 1, 1, 1})); 261 262 assertTrue(CircuitBuilder.isXor(new long[]{0, 1, 1, 0, 1, 0, 0, 1})); 263 assertFalse(CircuitBuilder.isXor(new long[]{1, 1, 1, 0, 1, 0, 0, 1})); 264 assertFalse(CircuitBuilder.isXor(new long[]{0, 0, 1, 0, 1, 0, 0, 1})); 265 assertFalse(CircuitBuilder.isXor(new long[]{0, 1, 0, 0, 1, 0, 0, 1})); 266 assertFalse(CircuitBuilder.isXor(new long[]{0, 1, 1, 1, 1, 0, 0, 1})); 267 assertFalse(CircuitBuilder.isXor(new long[]{0, 1, 1, 0, 0, 0, 0, 1})); 268 assertFalse(CircuitBuilder.isXor(new long[]{0, 1, 1, 0, 1, 1, 0, 1})); 269 assertFalse(CircuitBuilder.isXor(new long[]{0, 1, 1, 0, 1, 0, 1, 1})); 270 assertFalse(CircuitBuilder.isXor(new long[]{0, 1, 1, 0, 1, 0, 0, 0})); 271 } 272 testIsXNor()273 public void testIsXNor() { 274 assertFalse(CircuitBuilder.isXNor(new long[]{0, 0, 0, 0})); 275 assertFalse(CircuitBuilder.isXNor(new long[]{0, 0, 0, 1})); 276 assertFalse(CircuitBuilder.isXNor(new long[]{0, 0, 1, 0})); 277 assertFalse(CircuitBuilder.isXNor(new long[]{0, 0, 1, 1})); 278 assertFalse(CircuitBuilder.isXNor(new long[]{0, 1, 0, 0})); 279 assertFalse(CircuitBuilder.isXNor(new long[]{0, 1, 0, 1})); 280 assertFalse(CircuitBuilder.isXNor(new long[]{0, 1, 1, 0})); 281 assertFalse(CircuitBuilder.isXNor(new long[]{0, 1, 1, 1})); 282 assertFalse(CircuitBuilder.isXNor(new long[]{1, 0, 0, 0})); 283 assertTrue(CircuitBuilder.isXNor(new long[]{1, 0, 0, 1})); 284 assertFalse(CircuitBuilder.isXNor(new long[]{1, 0, 1, 0})); 285 assertFalse(CircuitBuilder.isXNor(new long[]{1, 0, 1, 1})); 286 assertFalse(CircuitBuilder.isXNor(new long[]{1, 1, 0, 0})); 287 assertFalse(CircuitBuilder.isXNor(new long[]{1, 1, 0, 1})); 288 assertFalse(CircuitBuilder.isXNor(new long[]{1, 1, 1, 0})); 289 assertFalse(CircuitBuilder.isXNor(new long[]{1, 1, 1, 1})); 290 291 assertTrue(CircuitBuilder.isXNor(new long[]{1, 0, 0, 1, 0, 1, 1, 0})); 292 assertFalse(CircuitBuilder.isXNor(new long[]{0, 0, 0, 1, 0, 1, 1, 0})); 293 assertFalse(CircuitBuilder.isXNor(new long[]{1, 1, 0, 1, 0, 1, 1, 0})); 294 assertFalse(CircuitBuilder.isXNor(new long[]{1, 0, 1, 1, 0, 1, 1, 0})); 295 assertFalse(CircuitBuilder.isXNor(new long[]{1, 0, 0, 0, 0, 1, 1, 0})); 296 assertFalse(CircuitBuilder.isXNor(new long[]{1, 0, 0, 1, 1, 1, 1, 0})); 297 assertFalse(CircuitBuilder.isXNor(new long[]{1, 0, 0, 1, 0, 0, 1, 0})); 298 assertFalse(CircuitBuilder.isXNor(new long[]{1, 0, 0, 1, 0, 1, 0, 0})); 299 assertFalse(CircuitBuilder.isXNor(new long[]{1, 0, 0, 1, 0, 1, 1, 1})); 300 301 } 302 testLocalVar()303 public void testLocalVar() throws IOException, ParseException, BuilderException, ElementNotFoundException, PinException, NodeException { 304 ArrayList<Expression> expList = new Parser("let a1=a+b;\nlet a2=c+d;\nlet y=a1^a2").parse(); 305 ElementLibrary library = new ElementLibrary(); 306 CircuitBuilder circuitBuilder = new CircuitBuilder(new ShapeFactory(library)).setResolveLocalVars(true); 307 for (Expression exp : expList) { 308 assertTrue(exp instanceof NamedExpression); 309 NamedExpression ne = (NamedExpression) exp; 310 circuitBuilder.addCombinatorial(ne.getName(), ne.getExpression()); 311 } 312 Circuit circuit = circuitBuilder.createCircuit(); 313 List<VisualElement> outs = circuit.getElements(v -> v.equalsDescription(Out.DESCRIPTION)); 314 assertEquals(1, outs.size()); 315 assertEquals("y", outs.get(0).getElementAttributes().getLabel()); 316 List<VisualElement> tunnels = circuit.getElements(v -> v.equalsDescription(Tunnel.DESCRIPTION)); 317 assertEquals(4, tunnels.size()); 318 319 ModelCreator m = new ModelCreator(circuit, library); 320 TestExecuter te = new TestExecuter(m.createModel(false)).setUp(m); 321 te.check(0, 0, 0, 0, 0); 322 te.check(0, 0, 0, 1, 1); 323 te.check(0, 0, 1, 0, 1); 324 te.check(0, 0, 1, 1, 1); 325 te.check(0, 1, 0, 0, 1); 326 te.check(0, 1, 0, 1, 0); 327 te.check(0, 1, 1, 0, 0); 328 te.check(0, 1, 1, 1, 0); 329 te.check(1, 0, 0, 0, 1); 330 te.check(1, 0, 0, 1, 0); 331 te.check(1, 0, 1, 0, 0); 332 te.check(1, 0, 1, 1, 0); 333 te.check(1, 1, 0, 0, 1); 334 te.check(1, 1, 0, 1, 0); 335 te.check(1, 1, 1, 0, 0); 336 te.check(1, 1, 1, 1, 0); 337 } 338 } 339