mirror of
https://github.com/hneemann/Digital.git
synced 2025-09-14 15:26:52 -04:00
added splitter to new model
This commit is contained in:
parent
3abfbe460b
commit
366535ace6
@ -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<HDLNode>, 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<HDLNode>, 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());
|
||||
|
@ -22,7 +22,7 @@ public class HDLNode {
|
||||
private final ArrayList<HDLPort> outputs;
|
||||
|
||||
/**
|
||||
* Creates e new intance
|
||||
* Creates e new instance
|
||||
*
|
||||
* @param elementName the instances name
|
||||
* @param elementAttributes the attributes
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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(")");
|
||||
}
|
||||
}
|
||||
}
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
@ -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
|
||||
}
|
||||
|
104
src/test/resources/dig/hdl/model2/splitter2.dig
Normal file
104
src/test/resources/dig/hdl/model2/splitter2.dig
Normal file
@ -0,0 +1,104 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<circuit>
|
||||
<version>1</version>
|
||||
<attributes/>
|
||||
<visualElements>
|
||||
<visualElement>
|
||||
<elementName>Out</elementName>
|
||||
<elementAttributes>
|
||||
<entry>
|
||||
<string>Label</string>
|
||||
<string>X</string>
|
||||
</entry>
|
||||
<entry>
|
||||
<string>Inputs</string>
|
||||
<int>1</int>
|
||||
</entry>
|
||||
</elementAttributes>
|
||||
<pos x="0" y="60"/>
|
||||
</visualElement>
|
||||
<visualElement>
|
||||
<elementName>In</elementName>
|
||||
<elementAttributes>
|
||||
<entry>
|
||||
<string>Label</string>
|
||||
<string>A</string>
|
||||
</entry>
|
||||
<entry>
|
||||
<string>Bits</string>
|
||||
<int>2</int>
|
||||
</entry>
|
||||
</elementAttributes>
|
||||
<pos x="-100" y="60"/>
|
||||
</visualElement>
|
||||
<visualElement>
|
||||
<elementName>Splitter</elementName>
|
||||
<elementAttributes>
|
||||
<entry>
|
||||
<string>splitterSpreading</string>
|
||||
<int>2</int>
|
||||
</entry>
|
||||
<entry>
|
||||
<string>Input Splitting</string>
|
||||
<string>2,2</string>
|
||||
</entry>
|
||||
<entry>
|
||||
<string>Output Splitting</string>
|
||||
<string>1,3</string>
|
||||
</entry>
|
||||
</elementAttributes>
|
||||
<pos x="-60" y="60"/>
|
||||
</visualElement>
|
||||
<visualElement>
|
||||
<elementName>In</elementName>
|
||||
<elementAttributes>
|
||||
<entry>
|
||||
<string>Label</string>
|
||||
<string>B</string>
|
||||
</entry>
|
||||
<entry>
|
||||
<string>Bits</string>
|
||||
<int>2</int>
|
||||
</entry>
|
||||
</elementAttributes>
|
||||
<pos x="-100" y="100"/>
|
||||
</visualElement>
|
||||
<visualElement>
|
||||
<elementName>Out</elementName>
|
||||
<elementAttributes>
|
||||
<entry>
|
||||
<string>Label</string>
|
||||
<string>Y</string>
|
||||
</entry>
|
||||
<entry>
|
||||
<string>Bits</string>
|
||||
<int>3</int>
|
||||
</entry>
|
||||
<entry>
|
||||
<string>Inputs</string>
|
||||
<int>1</int>
|
||||
</entry>
|
||||
</elementAttributes>
|
||||
<pos x="0" y="100"/>
|
||||
</visualElement>
|
||||
</visualElements>
|
||||
<wires>
|
||||
<wire>
|
||||
<p1 x="-100" y="100"/>
|
||||
<p2 x="-60" y="100"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="-40" y="100"/>
|
||||
<p2 x="0" y="100"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="-100" y="60"/>
|
||||
<p2 x="-60" y="60"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="-40" y="60"/>
|
||||
<p2 x="0" y="60"/>
|
||||
</wire>
|
||||
</wires>
|
||||
<measurementOrdering/>
|
||||
</circuit>
|
Loading…
x
Reference in New Issue
Block a user