mirror of
https://github.com/hneemann/Digital.git
synced 2025-09-13 06:49:36 -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())
|
||||
o.getNet().setIsOutput(o.getName(), o.getNet().getInputs().size() == 1);
|
||||
|
||||
nodes = new NodeSorter(inputs, nodes).sort();
|
||||
}
|
||||
|
||||
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" +
|
||||
" sig(Y_temp:1, s0:1, Z_temp:1, s1:1)\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" +
|
||||
" in()\n" +
|
||||
" out(out:1 is s1: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" +
|
||||
" Y:1 := Y_temp:1\n" +
|
||||
" Z:1 := Z_temp:1\n" +
|
||||
|
@ -40,7 +40,7 @@ public class VHDLGeneratorTest extends TestCase {
|
||||
|
||||
/*
|
||||
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);
|
||||
System.out.println(new VHDLGenerator(br.getLibrary(), new CodePrinterStr(true)).export(br.getCircuit()));
|
||||
|
Loading…
x
Reference in New Issue
Block a user