From 366535ace6a88e7413d2c587b5917cf9ddc2d260 Mon Sep 17 00:00:00 2001 From: hneemann Date: Fri, 23 Mar 2018 18:54:46 +0100 Subject: [PATCH] added splitter to new model --- .../digital/hdl/model2/HDLCircuit.java | 35 ++++++ .../neemann/digital/hdl/model2/HDLNode.java | 2 +- .../hdl/model2/HDLNodeSplitterManyToOne.java | 53 +++++++++ .../hdl/model2/HDLNodeSplitterOneToMany.java | 50 +++++++++ .../digital/hdl/model2/HDLCircuitTest.java | 49 +++++++++ .../digital/hdl/vhdl/TestInSimulator.java | 2 +- .../resources/dig/hdl/model2/splitter2.dig | 104 ++++++++++++++++++ 7 files changed, 293 insertions(+), 2 deletions(-) create mode 100644 src/main/java/de/neemann/digital/hdl/model2/HDLNodeSplitterManyToOne.java create mode 100644 src/main/java/de/neemann/digital/hdl/model2/HDLNodeSplitterOneToMany.java create mode 100644 src/test/resources/dig/hdl/model2/splitter2.dig diff --git a/src/main/java/de/neemann/digital/hdl/model2/HDLCircuit.java b/src/main/java/de/neemann/digital/hdl/model2/HDLCircuit.java index bf5df51dd..c67709c55 100644 --- a/src/main/java/de/neemann/digital/hdl/model2/HDLCircuit.java +++ b/src/main/java/de/neemann/digital/hdl/model2/HDLCircuit.java @@ -5,6 +5,7 @@ */ package de.neemann.digital.hdl.model2; +import de.neemann.digital.core.BitsException; import de.neemann.digital.core.NodeException; import de.neemann.digital.core.basic.Not; import de.neemann.digital.core.element.ElementAttributes; @@ -17,6 +18,7 @@ import de.neemann.digital.core.pld.PullDown; import de.neemann.digital.core.pld.PullUp; import de.neemann.digital.core.wiring.Break; import de.neemann.digital.core.wiring.Clock; +import de.neemann.digital.core.wiring.Splitter; import de.neemann.digital.draw.elements.*; import de.neemann.digital.draw.model.InverterConfig; import de.neemann.digital.draw.model.Net; @@ -77,6 +79,8 @@ public class HDLCircuit implements Iterable, HDLContext.BitProvider, Pr HDLPort.Direction.IN, v.getElementAttributes().getBits()) .setPinNumber(v.getElementAttributes().get(Keys.PINNUMBER))); + else if (v.equalsDescription(Splitter.DESCRIPTION)) + handleSplitter(c.createNode(v, this)); else if (isRealElement(v)) nodes.add(c.createNode(v, this)); } @@ -111,6 +115,37 @@ public class HDLCircuit implements Iterable, HDLContext.BitProvider, Pr } + private void handleSplitter(HDLNode node) throws BitsException, HDLException { + Splitter.Ports inputSplit = new Splitter.Ports(node.getElementAttributes().get(Keys.INPUT_SPLIT)); + Splitter.Ports outputSplit = new Splitter.Ports(node.getElementAttributes().get(Keys.OUTPUT_SPLIT)); + if (node.getInputs().size() == 1) { + nodes.add(new HDLNodeSplitterOneToMany(node, outputSplit)); + return; + } + if (node.getOutputs().size() == 1 && node.getOutput().getBits() == inputSplit.getBits()) { + nodes.add(new HDLNodeSplitterManyToOne(node, inputSplit)); + return; + } + + int bits = inputSplit.getBits(); + HDLNet net = new HDLNet(null); + listOfNets.add(net); + HDLPort left = new HDLPort("single", net, HDLPort.Direction.OUT, bits); + HDLPort right = new HDLPort("single", net, HDLPort.Direction.IN, bits); + + HDLNodeSplitterManyToOne manyToOne = new HDLNodeSplitterManyToOne(node, inputSplit); + HDLNodeSplitterOneToMany oneToMany = new HDLNodeSplitterOneToMany(node, outputSplit); + + manyToOne.getOutputs().clear(); + manyToOne.addOutput(left); + + oneToMany.getInputs().clear(); + oneToMany.addInput(right); + + nodes.add(manyToOne); + nodes.add(oneToMany); + } + private HDLNode createNot(HDLPort p, HDLNode node) throws HDLException, NodeException, PinException { final ElementAttributes attr = new ElementAttributes().setBits(p.getBits()); HDLNodeExpression n = new HDLNodeExpression(Not.DESCRIPTION.getName(), attr, name -> p.getBits()); diff --git a/src/main/java/de/neemann/digital/hdl/model2/HDLNode.java b/src/main/java/de/neemann/digital/hdl/model2/HDLNode.java index 148b1181c..e335c61f5 100644 --- a/src/main/java/de/neemann/digital/hdl/model2/HDLNode.java +++ b/src/main/java/de/neemann/digital/hdl/model2/HDLNode.java @@ -22,7 +22,7 @@ public class HDLNode { private final ArrayList outputs; /** - * Creates e new intance + * Creates e new instance * * @param elementName the instances name * @param elementAttributes the attributes diff --git a/src/main/java/de/neemann/digital/hdl/model2/HDLNodeSplitterManyToOne.java b/src/main/java/de/neemann/digital/hdl/model2/HDLNodeSplitterManyToOne.java new file mode 100644 index 000000000..24e8cee46 --- /dev/null +++ b/src/main/java/de/neemann/digital/hdl/model2/HDLNodeSplitterManyToOne.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2018 Helmut Neemann. + * Use of this source code is governed by the GPL v3 license + * that can be found in the LICENSE file. + */ +package de.neemann.digital.hdl.model2; + +import de.neemann.digital.core.wiring.Splitter; +import de.neemann.digital.hdl.printer.CodePrinter; + +import java.io.IOException; + +/** + * The splitter. + * Either the output split or the input split is always one! + */ +public class HDLNodeSplitterManyToOne extends HDLNode { + private final Splitter.Ports inputSplit; + + /** + * Creates a new instance + * + * @param node the original splitter node + * @param inputSplit input splitting + */ + HDLNodeSplitterManyToOne(HDLNode node, Splitter.Ports inputSplit) { + super(node.getElementName(), node.getElementAttributes(), null); + this.inputSplit = inputSplit; + getInputs().addAll(node.getInputs()); + getOutputs().addAll(node.getOutputs()); + } + + /** + * @return the input splitting + */ + public Splitter.Ports getInputSplit() { + return inputSplit; + } + + @Override + public void print(CodePrinter out) throws IOException { + super.print(out); + int i = 0; + HDLPort o = getOutput(); + for (Splitter.Port sp : inputSplit) { + HDLPort p = getInputs().get(i++); + out.print(o.getNet().getName()) + .print("(").print(sp.getPos()).print("-").print(sp.getPos() + sp.getBits() - 1).print(")") + .print(" := ").println(p.getNet().getName()); + } + } + +} diff --git a/src/main/java/de/neemann/digital/hdl/model2/HDLNodeSplitterOneToMany.java b/src/main/java/de/neemann/digital/hdl/model2/HDLNodeSplitterOneToMany.java new file mode 100644 index 000000000..4f79ad056 --- /dev/null +++ b/src/main/java/de/neemann/digital/hdl/model2/HDLNodeSplitterOneToMany.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2018 Helmut Neemann. + * Use of this source code is governed by the GPL v3 license + * that can be found in the LICENSE file. + */ +package de.neemann.digital.hdl.model2; + +import de.neemann.digital.core.wiring.Splitter; +import de.neemann.digital.hdl.printer.CodePrinter; + +import java.io.IOException; + +/** + * A One to Many splitter + */ +public class HDLNodeSplitterOneToMany extends HDLNode { + private final Splitter.Ports outputSplit; + + /** + * Creates a new instance + * + * @param node the original splitter node + * @param outputSplit output splitting + */ + HDLNodeSplitterOneToMany(HDLNode node, Splitter.Ports outputSplit) { + super(node.getElementName(), node.getElementAttributes(), null); + this.outputSplit = outputSplit; + getInputs().addAll(node.getInputs()); + getOutputs().addAll(node.getOutputs()); + } + + /** + * @return the output splitting + */ + public Splitter.Ports getOutputSplit() { + return outputSplit; + } + + @Override + public void print(CodePrinter out) throws IOException { + super.print(out); + int i = 0; + HDLPort in = getInputs().get(0); + for (Splitter.Port sp : outputSplit) { + HDLPort p = getOutputs().get(i++); + out.print(p.getNet().getName()).print(" := ").print(in.getNet().getName()) + .print("(").print(sp.getPos()).print("-").print(sp.getPos() + sp.getBits() - 1).println(")"); + } + } +} diff --git a/src/test/java/de/neemann/digital/hdl/model2/HDLCircuitTest.java b/src/test/java/de/neemann/digital/hdl/model2/HDLCircuitTest.java index 0d9e6e584..46a45daed 100644 --- a/src/test/java/de/neemann/digital/hdl/model2/HDLCircuitTest.java +++ b/src/test/java/de/neemann/digital/hdl/model2/HDLCircuitTest.java @@ -124,4 +124,53 @@ public class HDLCircuitTest extends TestCase { "end circuit main\n", cp.toString()); } + public void testSplitter() throws IOException, PinException, HDLException, NodeException { + HDLCircuit hdl = getCircuit("dig/hdl/model2/splitter.dig"); + hdl.mergeOperations().nameNets(new HDLCircuit.SimpleNaming()); + + CodePrinterStr cp = new CodePrinterStr(); + hdl.print(cp); + assertEquals("circuit main\n" + + " in(A:4)\n" + + " out(X:2)\n" + + " sig(s0:2, s1:2)\n" + + "\n" + + " node Splitter\n" + + " in(0-3:4 is A:4)\n" + + " out(0,1:2 is s0:2, 2,3:2 is s1:2)\n" + + " s0 := A(0-1)\n" + + " s1 := A(2-3)\n" + + " node merged expression\n" + + " in(In_1:2 is s0:2, in:2 is s1:2)\n" + + " out(out:2 is X:2)\n" + + " X:2 := (s0:2 AND NOT s1:2)\n" + + "\n" + + "end circuit main\n", cp.toString()); + } + + public void testSplitter2() throws IOException, PinException, HDLException, NodeException { + HDLCircuit hdl = getCircuit("dig/hdl/model2/splitter2.dig"); + hdl.mergeOperations().nameNets(new HDLCircuit.SimpleNaming()); + + CodePrinterStr cp = new CodePrinterStr(); + hdl.print(cp); + assertEquals("circuit main\n" + + " in(A:2, B:2)\n" + + " out(X:1, Y:3)\n" + + " sig(s0:4)\n" + + "\n" + + " node Splitter\n" + + " in(0,1:2 is A:2, 2,3:2 is B:2)\n" + + " out(single:4 is s0:4)\n" + + " s0(0-1) := A\n" + + " s0(2-3) := B\n" + + " node Splitter\n" + + " in(single:4 is s0:4)\n" + + " out(0:1 is X:1, 1-3:3 is Y:3)\n" + + " X := s0(0-0)\n" + + " Y := s0(1-3)\n" + + "\n" + + "end circuit main\n", cp.toString()); + } + } \ No newline at end of file diff --git a/src/test/java/de/neemann/digital/hdl/vhdl/TestInSimulator.java b/src/test/java/de/neemann/digital/hdl/vhdl/TestInSimulator.java index 9290ff8f5..87c5d81bc 100644 --- a/src/test/java/de/neemann/digital/hdl/vhdl/TestInSimulator.java +++ b/src/test/java/de/neemann/digital/hdl/vhdl/TestInSimulator.java @@ -57,7 +57,7 @@ public class TestInSimulator extends TestCase { File examples = new File(Resources.getRoot(), "/dig/hdl"); try { int tested = new FileScanner(this::checkVHDLExport).noOutput().scan(examples); - assertEquals(33, tested); + assertEquals(34, tested); } catch (FileScanner.SkipAllException e) { // if ghdl is not installed its also ok } diff --git a/src/test/resources/dig/hdl/model2/splitter2.dig b/src/test/resources/dig/hdl/model2/splitter2.dig new file mode 100644 index 000000000..362e2ed74 --- /dev/null +++ b/src/test/resources/dig/hdl/model2/splitter2.dig @@ -0,0 +1,104 @@ + + + 1 + + + + Out + + + Label + X + + + Inputs + 1 + + + + + + In + + + Label + A + + + Bits + 2 + + + + + + Splitter + + + splitterSpreading + 2 + + + Input Splitting + 2,2 + + + Output Splitting + 1,3 + + + + + + In + + + Label + B + + + Bits + 2 + + + + + + Out + + + Label + Y + + + Bits + 3 + + + Inputs + 1 + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file