mirror of
https://github.com/hneemann/Digital.git
synced 2025-09-13 14:56:29 -04:00
added a node sorter
This commit is contained in:
parent
57228748d4
commit
28dc6a583d
@ -122,6 +122,7 @@ public class HDLCircuit implements Iterable<HDLNode>, HDLModel.BitProvider, Prin
|
|||||||
if (o.getNet().needsVariable())
|
if (o.getNet().needsVariable())
|
||||||
o.getNet().setIsOutput(o.getName(), o.getNet().getInputs().size() == 1);
|
o.getNet().setIsOutput(o.getName(), o.getNet().getInputs().size() == 1);
|
||||||
|
|
||||||
|
nodes = new NodeSorter(inputs, nodes).sort();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleSplitter(HDLNode node) throws BitsException, HDLException {
|
private void handleSplitter(HDLNode node) throws BitsException, HDLException {
|
||||||
|
85
src/main/java/de/neemann/digital/hdl/model2/NodeSorter.java
Normal file
85
src/main/java/de/neemann/digital/hdl/model2/NodeSorter.java
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
/*
|
||||||
|
* 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 java.util.ArrayList;
|
||||||
|
import java.util.HashSet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to sort the nodes in a more "human typical" order.
|
||||||
|
* Sorts the nodes from the input side to the output side.
|
||||||
|
*/
|
||||||
|
public class NodeSorter {
|
||||||
|
private final ArrayList<HDLPort> inputs;
|
||||||
|
private final ArrayList<HDLNode> nodes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance.
|
||||||
|
*
|
||||||
|
* @param inputs the initial inputs
|
||||||
|
* @param nodes the nodes to sort
|
||||||
|
*/
|
||||||
|
public NodeSorter(ArrayList<HDLPort> inputs, ArrayList<HDLNode> nodes) {
|
||||||
|
this.inputs = inputs;
|
||||||
|
this.nodes = nodes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs the sorting and returns a sorted list.
|
||||||
|
*
|
||||||
|
* @return the sorted list
|
||||||
|
*/
|
||||||
|
public ArrayList<HDLNode> sort() {
|
||||||
|
HashSet<HDLNet> nets = new HashSet<>();
|
||||||
|
for (HDLPort p : inputs)
|
||||||
|
nets.add(p.getNet());
|
||||||
|
|
||||||
|
ArrayList<HDLNode> newOrder = new ArrayList<>();
|
||||||
|
|
||||||
|
// all nodes without an input at top!
|
||||||
|
for (HDLNode n : nodes)
|
||||||
|
if (n.getInputs().isEmpty()) {
|
||||||
|
newOrder.add(n);
|
||||||
|
for (HDLPort p : n.getOutputs())
|
||||||
|
if (p.getNet() != null)
|
||||||
|
nets.add(p.getNet());
|
||||||
|
}
|
||||||
|
nodes.removeAll(newOrder);
|
||||||
|
|
||||||
|
// than a layer sorting
|
||||||
|
while (!nodes.isEmpty()) {
|
||||||
|
ArrayList<HDLNode> layer = new ArrayList<>();
|
||||||
|
for (HDLNode n : nodes) {
|
||||||
|
if (dependsOnlyOn(n, nets))
|
||||||
|
layer.add(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (layer.isEmpty())
|
||||||
|
break;
|
||||||
|
|
||||||
|
newOrder.addAll(layer);
|
||||||
|
nodes.removeAll(layer);
|
||||||
|
for (HDLNode n : layer)
|
||||||
|
for (HDLPort p : n.getOutputs())
|
||||||
|
if (p.getNet() != null)
|
||||||
|
nets.add(p.getNet());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// if there are circular dependencies, keep old order
|
||||||
|
if (!nodes.isEmpty())
|
||||||
|
newOrder.addAll(nodes);
|
||||||
|
|
||||||
|
return newOrder;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean dependsOnlyOn(HDLNode n, HashSet<HDLNet> nets) {
|
||||||
|
for (HDLPort p : n.getInputs())
|
||||||
|
if (!nets.contains(p.getNet()))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
@ -40,25 +40,25 @@ public class HDLCircuitTest extends TestCase {
|
|||||||
" out(X:1, Y:1, Z:1, Aident:1)\n" +
|
" out(X:1, Y:1, Z:1, Aident:1)\n" +
|
||||||
" sig(Y_temp:1, s0:1, Z_temp:1, s1:1)\n" +
|
" sig(Y_temp:1, s0:1, Z_temp:1, s1:1)\n" +
|
||||||
"\n" +
|
"\n" +
|
||||||
" node merged expression\n" +
|
|
||||||
" in(In_5:1 is Y_temp:1, In_1:1 is A:1, In_2:1 is C:1, In_1:1 is Z_temp:1, In_1:1 is B:1)\n" +
|
|
||||||
" out(out:1 is s0:1)\n" +
|
|
||||||
" s0:1 := ((A:1 OR C:1) AND (Z_temp:1 OR C:1) AND 1:1 AND NOT (B:1 OR C:1) AND Y_temp:1)\n" +
|
|
||||||
" node merged expression\n" +
|
|
||||||
" in(In_1:1 is B:1, in:1 is C:1)\n" +
|
|
||||||
" out(out:1 is Y_temp:1)\n" +
|
|
||||||
" Y_temp:1 := (B:1 OR NOT C:1)\n" +
|
|
||||||
" node Not\n" +
|
|
||||||
" in(in:1 is A:1)\n" +
|
|
||||||
" out(out:1 is Z_temp:1)\n" +
|
|
||||||
" Z_temp:1 := NOT A:1\n" +
|
|
||||||
" node D_FF\n" +
|
|
||||||
" in(D:1 is s0:1, C:1 is s1:1)\n" +
|
|
||||||
" out(Q:1 is X:1, ~Q:1 is not used)\n" +
|
|
||||||
" node Const\n" +
|
" node Const\n" +
|
||||||
" in()\n" +
|
" in()\n" +
|
||||||
" out(out:1 is s1:1)\n" +
|
" out(out:1 is s1:1)\n" +
|
||||||
" s1:1 := 1:1\n" +
|
" s1:1 := 1:1\n" +
|
||||||
|
" node Not\n" +
|
||||||
|
" in(in:1 is A:1)\n" +
|
||||||
|
" out(out:1 is Z_temp:1)\n" +
|
||||||
|
" Z_temp:1 := NOT A:1\n" +
|
||||||
|
" node merged expression\n" +
|
||||||
|
" in(In_1:1 is B:1, in:1 is C:1)\n" +
|
||||||
|
" out(out:1 is Y_temp:1)\n" +
|
||||||
|
" Y_temp:1 := (B:1 OR NOT C:1)\n" +
|
||||||
|
" node merged expression\n" +
|
||||||
|
" in(In_5:1 is Y_temp:1, In_1:1 is A:1, In_2:1 is C:1, In_1:1 is Z_temp:1, In_1:1 is B:1)\n" +
|
||||||
|
" out(out:1 is s0:1)\n" +
|
||||||
|
" s0:1 := ((A:1 OR C:1) AND (Z_temp:1 OR C:1) AND 1:1 AND NOT (B:1 OR C:1) AND Y_temp:1)\n" +
|
||||||
|
" node D_FF\n" +
|
||||||
|
" in(D:1 is s0:1, C:1 is s1:1)\n" +
|
||||||
|
" out(Q:1 is X:1, ~Q:1 is not used)\n" +
|
||||||
"\n" +
|
"\n" +
|
||||||
" Y:1 := Y_temp:1\n" +
|
" Y:1 := Y_temp:1\n" +
|
||||||
" Z:1 := Z_temp:1\n" +
|
" Z:1 := Z_temp:1\n" +
|
||||||
|
@ -40,7 +40,7 @@ public class VHDLGeneratorTest extends TestCase {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
public void testDebug() throws Exception {
|
public void testDebug() throws Exception {
|
||||||
File file = new File(Resources.getRoot(), "dig/hdl/splitter2.dig");
|
File file = new File(Resources.getRoot(), "../../main/dig/processor/VHDLExample.dig");
|
||||||
|
|
||||||
ToBreakRunner br = new ToBreakRunner(file);
|
ToBreakRunner br = new ToBreakRunner(file);
|
||||||
System.out.println(new VHDLGenerator(br.getLibrary(), new CodePrinterStr(true)).export(br.getCircuit()));
|
System.out.println(new VHDLGenerator(br.getLibrary(), new CodePrinterStr(true)).export(br.getCircuit()));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user