mirror of
https://github.com/hneemann/Digital.git
synced 2025-09-16 08:25:09 -04:00
improved node ordering
This commit is contained in:
parent
9d628be2ce
commit
f7521228c8
@ -157,14 +157,6 @@ 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);
|
||||||
|
|
||||||
sortNodes();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sorts the nodes
|
|
||||||
*/
|
|
||||||
public void sortNodes() {
|
|
||||||
nodes = new NodeSorter(inputs, nodes).sort();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleSplitter(HDLNode node) throws BitsException, HDLException {
|
private void handleSplitter(HDLNode node) throws BitsException, HDLException {
|
||||||
@ -320,7 +312,6 @@ public class HDLCircuit implements Iterable<HDLNode>, HDLModel.BitProvider, Prin
|
|||||||
for (HDLNet n : listOfNets)
|
for (HDLNet n : listOfNets)
|
||||||
if (n.getName() == null)
|
if (n.getName() == null)
|
||||||
n.setName(netNaming.createName(n));
|
n.setName(netNaming.createName(n));
|
||||||
sortNodes();
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -525,6 +516,7 @@ public class HDLCircuit implements Iterable<HDLNode>, HDLModel.BitProvider, Prin
|
|||||||
apply(new RemoveConstantSignals());
|
apply(new RemoveConstantSignals());
|
||||||
apply(new MergeConstants()); // under certain circumstances there are still constants
|
apply(new MergeConstants()); // under certain circumstances there are still constants
|
||||||
apply(new NameConstantSignals());
|
apply(new NameConstantSignals());
|
||||||
|
apply(new NodeSorterExpressionBased());
|
||||||
return nameUnnamedSignals();
|
return nameUnnamedSignals();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,99 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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
|
|
||||||
*/
|
|
||||||
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()) {
|
|
||||||
// circular dependency detected
|
|
||||||
for (HDLNode n : nodes)
|
|
||||||
if (dependsAtLeastAtOne(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 (!p.getNet().isClock() && !nets.contains(p.getNet()))
|
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean dependsAtLeastAtOne(HDLNode n, HashSet<HDLNet> nets) {
|
|
||||||
for (HDLPort p : n.getInputs())
|
|
||||||
if (!p.getNet().isClock() && nets.contains(p.getNet()))
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,18 @@
|
|||||||
|
/*
|
||||||
|
* 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.expression;
|
||||||
|
|
||||||
|
import de.neemann.digital.hdl.model2.HDLNet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implemented by all expressions using a net
|
||||||
|
*/
|
||||||
|
public interface ExprUsingNet {
|
||||||
|
/**
|
||||||
|
* @return the used net
|
||||||
|
*/
|
||||||
|
HDLNet getNet();
|
||||||
|
}
|
@ -13,7 +13,7 @@ import java.io.IOException;
|
|||||||
/**
|
/**
|
||||||
* A reference to a net
|
* A reference to a net
|
||||||
*/
|
*/
|
||||||
public class ExprVar implements Expression {
|
public class ExprVar implements Expression, ExprUsingNet {
|
||||||
private HDLNet net;
|
private HDLNet net;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -27,9 +27,7 @@ public class ExprVar implements Expression {
|
|||||||
this.net = net;
|
this.net = net;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* @return the net
|
|
||||||
*/
|
|
||||||
public HDLNet getNet() {
|
public HDLNet getNet() {
|
||||||
return net;
|
return net;
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@ import java.io.IOException;
|
|||||||
/**
|
/**
|
||||||
* A reference to a net slice
|
* A reference to a net slice
|
||||||
*/
|
*/
|
||||||
public class ExprVarRange implements Expression {
|
public class ExprVarRange implements Expression, ExprUsingNet {
|
||||||
private HDLNet net;
|
private HDLNet net;
|
||||||
private final int msb;
|
private final int msb;
|
||||||
private final int lsb;
|
private final int lsb;
|
||||||
@ -31,9 +31,7 @@ public class ExprVarRange implements Expression {
|
|||||||
this.lsb = lsb;
|
this.lsb = lsb;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* @return the net
|
|
||||||
*/
|
|
||||||
public HDLNet getNet() {
|
public HDLNet getNet() {
|
||||||
return net;
|
return net;
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,136 @@
|
|||||||
|
/*
|
||||||
|
* 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.optimizations;
|
||||||
|
|
||||||
|
import de.neemann.digital.hdl.model2.HDLCircuit;
|
||||||
|
import de.neemann.digital.hdl.model2.HDLNet;
|
||||||
|
import de.neemann.digital.hdl.model2.HDLNode;
|
||||||
|
import de.neemann.digital.hdl.model2.HDLPort;
|
||||||
|
import de.neemann.digital.hdl.model2.expression.ExprUsingNet;
|
||||||
|
import de.neemann.digital.hdl.model2.expression.Expression;
|
||||||
|
import de.neemann.digital.hdl.model2.expression.Visitor;
|
||||||
|
|
||||||
|
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 NodeSorterExpressionBased implements Optimization {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void optimize(HDLCircuit circuit) {
|
||||||
|
ArrayList<HDLNode> nodes = circuit.getNodes();
|
||||||
|
ArrayList<HDLNode> nodesAvail = new ArrayList<>(nodes);
|
||||||
|
nodes.clear();
|
||||||
|
|
||||||
|
HashSet<HDLNet> nets = new HashSet<>();
|
||||||
|
for (HDLPort p : circuit.getInputs())
|
||||||
|
nets.add(p.getNet());
|
||||||
|
|
||||||
|
|
||||||
|
// all nodes without an input at top!
|
||||||
|
for (HDLNode n : nodesAvail)
|
||||||
|
if (n.getInputs().isEmpty()) {
|
||||||
|
nodes.add(n);
|
||||||
|
for (HDLPort p : n.getOutputs())
|
||||||
|
if (p.getNet() != null)
|
||||||
|
nets.add(p.getNet());
|
||||||
|
}
|
||||||
|
nodesAvail.removeAll(nodes);
|
||||||
|
|
||||||
|
// then a layer sorting
|
||||||
|
while (!nodesAvail.isEmpty()) {
|
||||||
|
ArrayList<HDLNode> layer = new ArrayList<>();
|
||||||
|
for (HDLNode n : nodesAvail) {
|
||||||
|
if (n.traverseExpressions(new DependsOnlyOn(nets)).ok())
|
||||||
|
layer.add(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (layer.isEmpty()) {
|
||||||
|
// circular dependency detected
|
||||||
|
for (HDLNode n : nodesAvail)
|
||||||
|
if (n.traverseExpressions(new DependsAtLeastOnOneOf(nets)).ok())
|
||||||
|
layer.add(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (layer.isEmpty())
|
||||||
|
break;
|
||||||
|
|
||||||
|
nodes.addAll(layer);
|
||||||
|
nodesAvail.removeAll(layer);
|
||||||
|
for (HDLNode n : layer)
|
||||||
|
for (HDLPort p : n.getOutputs())
|
||||||
|
if (p.getNet() != null)
|
||||||
|
nets.add(p.getNet());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// if there are unsolvable circular dependencies, keep old order
|
||||||
|
if (!nodesAvail.isEmpty())
|
||||||
|
nodes.addAll(nodesAvail);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final class DependsOnlyOn implements Visitor {
|
||||||
|
private final HashSet<HDLNet> nets;
|
||||||
|
private boolean dependsOnlyOn = true;
|
||||||
|
|
||||||
|
private DependsOnlyOn(HashSet<HDLNet> nets) {
|
||||||
|
this.nets = nets;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(Expression expression) {
|
||||||
|
if (expression instanceof ExprUsingNet) {
|
||||||
|
final HDLNet net = ((ExprUsingNet) expression).getNet();
|
||||||
|
if (!net.isClock() && !nets.contains(net))
|
||||||
|
dependsOnlyOn = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean ok() {
|
||||||
|
return dependsOnlyOn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final class DependsAtLeastOnOneOf implements Visitor {
|
||||||
|
private final HashSet<HDLNet> nets;
|
||||||
|
private boolean dependsAtLeastOnOne = false;
|
||||||
|
|
||||||
|
private DependsAtLeastOnOneOf(HashSet<HDLNet> nets) {
|
||||||
|
this.nets = nets;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(Expression expression) {
|
||||||
|
if (expression instanceof ExprUsingNet) {
|
||||||
|
final HDLNet net = ((ExprUsingNet) expression).getNet();
|
||||||
|
if (!net.isClock() && nets.contains(net))
|
||||||
|
dependsAtLeastOnOne = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean ok() {
|
||||||
|
return dependsAtLeastOnOne;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean dependsOnlyOn(HDLNode n, HashSet<HDLNet> nets) {
|
||||||
|
for (HDLPort p : n.getInputs())
|
||||||
|
if (!p.getNet().isClock() && !nets.contains(p.getNet()))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean dependsAtLeastAtOne(HDLNode n, HashSet<HDLNet> nets) {
|
||||||
|
for (HDLPort p : n.getInputs())
|
||||||
|
if (!p.getNet().isClock() && nets.contains(p.getNet()))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -10,10 +10,7 @@ import de.neemann.digital.draw.elements.PinException;
|
|||||||
import de.neemann.digital.draw.library.ElementNotFoundException;
|
import de.neemann.digital.draw.library.ElementNotFoundException;
|
||||||
import de.neemann.digital.hdl.model2.clock.ClockIntegratorGeneric;
|
import de.neemann.digital.hdl.model2.clock.ClockIntegratorGeneric;
|
||||||
import de.neemann.digital.hdl.model2.clock.HDLClockIntegrator;
|
import de.neemann.digital.hdl.model2.clock.HDLClockIntegrator;
|
||||||
import de.neemann.digital.hdl.model2.optimizations.MergeConstants;
|
import de.neemann.digital.hdl.model2.optimizations.*;
|
||||||
import de.neemann.digital.hdl.model2.optimizations.MergeAssignements;
|
|
||||||
import de.neemann.digital.hdl.model2.optimizations.NameConstantSignals;
|
|
||||||
import de.neemann.digital.hdl.model2.optimizations.ReplaceOneToMany;
|
|
||||||
import de.neemann.digital.hdl.printer.CodePrinterStr;
|
import de.neemann.digital.hdl.printer.CodePrinterStr;
|
||||||
import de.neemann.digital.integration.ToBreakRunner;
|
import de.neemann.digital.integration.ToBreakRunner;
|
||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
@ -30,6 +27,7 @@ public class HDLModelTest extends TestCase {
|
|||||||
public void testSimple() throws IOException, PinException, HDLException, NodeException, ElementNotFoundException {
|
public void testSimple() throws IOException, PinException, HDLException, NodeException, ElementNotFoundException {
|
||||||
HDLCircuit hdl = getCircuit("dig/hdl/model2/comb.dig", null)
|
HDLCircuit hdl = getCircuit("dig/hdl/model2/comb.dig", null)
|
||||||
.apply(new MergeAssignements())
|
.apply(new MergeAssignements())
|
||||||
|
.apply(new NodeSorterExpressionBased())
|
||||||
.nameUnnamedSignals();
|
.nameUnnamedSignals();
|
||||||
|
|
||||||
CodePrinterStr cp = new CodePrinterStr();
|
CodePrinterStr cp = new CodePrinterStr();
|
||||||
@ -43,14 +41,14 @@ public class HDLModelTest extends TestCase {
|
|||||||
" in()\n" +
|
" in()\n" +
|
||||||
" out(out:1 defines (s1->1))\n" +
|
" out(out:1 defines (s1->1))\n" +
|
||||||
" s1->1 := 1:1\n" +
|
" s1->1 := 1:1\n" +
|
||||||
" node Not\n" +
|
|
||||||
" in(in:1 reads (A->3))\n" +
|
|
||||||
" out(out:1 defines (Z_temp->2))\n" +
|
|
||||||
" Z_temp->2 := NOT A\n" +
|
|
||||||
" node merged expression\n" +
|
" node merged expression\n" +
|
||||||
" in(In_1:1 reads (B->2), in:1 reads (C->2))\n" +
|
" in(In_1:1 reads (B->2), in:1 reads (C->2))\n" +
|
||||||
" out(out:1 defines (Y_temp->2))\n" +
|
" out(out:1 defines (Y_temp->2))\n" +
|
||||||
" Y_temp->2 := (B OR NOT C)\n" +
|
" Y_temp->2 := (B OR NOT C)\n" +
|
||||||
|
" node Not\n" +
|
||||||
|
" in(in:1 reads (A->3))\n" +
|
||||||
|
" out(out:1 defines (Z_temp->2))\n" +
|
||||||
|
" Z_temp->2 := NOT A\n" +
|
||||||
" node merged expression\n" +
|
" node merged expression\n" +
|
||||||
" in(In_5:1 reads (Y_temp->2), In_1:1 reads (A->3), In_2:1 reads (C->2), In_1:1 reads (Z_temp->2), In_1:1 reads (B->2))\n" +
|
" in(In_5:1 reads (Y_temp->2), In_1:1 reads (A->3), In_2:1 reads (C->2), In_1:1 reads (Z_temp->2), In_1:1 reads (B->2))\n" +
|
||||||
" out(out:1 defines (s0->1))\n" +
|
" out(out:1 defines (s0->1))\n" +
|
||||||
@ -220,6 +218,7 @@ public class HDLModelTest extends TestCase {
|
|||||||
.apply(new MergeAssignements())
|
.apply(new MergeAssignements())
|
||||||
.apply(new MergeConstants())
|
.apply(new MergeConstants())
|
||||||
.apply(new NameConstantSignals())
|
.apply(new NameConstantSignals())
|
||||||
|
.apply(new NodeSorterExpressionBased())
|
||||||
.nameUnnamedSignals();
|
.nameUnnamedSignals();
|
||||||
|
|
||||||
CodePrinterStr cp = new CodePrinterStr();
|
CodePrinterStr cp = new CodePrinterStr();
|
||||||
@ -294,6 +293,7 @@ public class HDLModelTest extends TestCase {
|
|||||||
HDLCircuit hdl = getCircuit("dig/hdl/model2/splitter3.dig", null)
|
HDLCircuit hdl = getCircuit("dig/hdl/model2/splitter3.dig", null)
|
||||||
.apply(new ReplaceOneToMany())
|
.apply(new ReplaceOneToMany())
|
||||||
.apply(new MergeAssignements())
|
.apply(new MergeAssignements())
|
||||||
|
.apply(new NodeSorterExpressionBased())
|
||||||
.nameUnnamedSignals();
|
.nameUnnamedSignals();
|
||||||
|
|
||||||
CodePrinterStr cp = new CodePrinterStr();
|
CodePrinterStr cp = new CodePrinterStr();
|
||||||
@ -324,6 +324,7 @@ public class HDLModelTest extends TestCase {
|
|||||||
HDLCircuit hdl = getCircuit("dig/hdl/model2/splitter4.dig", null)
|
HDLCircuit hdl = getCircuit("dig/hdl/model2/splitter4.dig", null)
|
||||||
.apply(new ReplaceOneToMany())
|
.apply(new ReplaceOneToMany())
|
||||||
.apply(new MergeAssignements())
|
.apply(new MergeAssignements())
|
||||||
|
.apply(new NodeSorterExpressionBased())
|
||||||
.nameUnnamedSignals();
|
.nameUnnamedSignals();
|
||||||
|
|
||||||
CodePrinterStr cp = new CodePrinterStr();
|
CodePrinterStr cp = new CodePrinterStr();
|
||||||
|
@ -291,7 +291,7 @@ public class ClockTest extends TestCase {
|
|||||||
new HDLModel(br.getLibrary()),
|
new HDLModel(br.getLibrary()),
|
||||||
ci);
|
ci);
|
||||||
|
|
||||||
c.apply(new MergeAssignements()).nameUnnamedSignals();
|
c.applyDefaultOptimizations();
|
||||||
|
|
||||||
CodePrinter out = new CodePrinterStr();
|
CodePrinter out = new CodePrinterStr();
|
||||||
new VHDLCreator(out).printHDLCircuit(c);
|
new VHDLCreator(out).printHDLCircuit(c);
|
||||||
|
@ -29,9 +29,7 @@ public class DescriptionTest extends TestCase {
|
|||||||
"main"
|
"main"
|
||||||
, new HDLModel(br.getLibrary()),
|
, new HDLModel(br.getLibrary()),
|
||||||
null)
|
null)
|
||||||
.apply(new MergeConstants())
|
.applyDefaultOptimizations();
|
||||||
.apply(new MergeAssignements())
|
|
||||||
.nameUnnamedSignals();
|
|
||||||
CodePrinterStr out = new CodePrinterStr();
|
CodePrinterStr out = new CodePrinterStr();
|
||||||
new VHDLCreator(out).printHDLCircuit(circuit);
|
new VHDLCreator(out).printHDLCircuit(circuit);
|
||||||
|
|
||||||
|
@ -70,8 +70,8 @@ public class VHDLGeneratorTest extends TestCase {
|
|||||||
" signal s0: std_logic;\n" +
|
" signal s0: std_logic;\n" +
|
||||||
" signal Z_temp: std_logic;\n" +
|
" signal Z_temp: std_logic;\n" +
|
||||||
"begin\n" +
|
"begin\n" +
|
||||||
" Z_temp <= NOT A;\n" +
|
|
||||||
" Y_temp <= (B OR NOT C);\n" +
|
" Y_temp <= (B OR NOT C);\n" +
|
||||||
|
" Z_temp <= NOT A;\n"+
|
||||||
" s0 <= ((A OR C) AND (Z_temp OR C) AND '1' AND NOT (B OR C) AND Y_temp);\n" +
|
" s0 <= ((A OR C) AND (Z_temp OR C) AND '1' AND NOT (B OR C) AND Y_temp);\n" +
|
||||||
" gate0: entity work.DIG_D_FF\n" +
|
" gate0: entity work.DIG_D_FF\n" +
|
||||||
" port map (\n" +
|
" port map (\n" +
|
||||||
|
Loading…
x
Reference in New Issue
Block a user