mirror of
https://github.com/hneemann/Digital.git
synced 2025-09-19 09:54:49 -04:00
improved exception handling in the cycle detector
This commit is contained in:
parent
4a405cfb5e
commit
0400e40ba1
@ -7,7 +7,7 @@ HEAD, planned as v0.17
|
||||
- Added an "export to zip" function.
|
||||
- If an input or output is several bits wide, all pin numbers can be specified by a comma-separated list.
|
||||
- Added a chapter "First Steps" to the documentation.
|
||||
- The model analyzer now detects circles and creates an error message if a circle is detected.
|
||||
- The model analyzer now detects cycles and creates an error message if a cycle is detected.
|
||||
- Bug fixes
|
||||
- Splitter, BarrelShifter and Comparator now are working with 64 bit.
|
||||
- fixed a bug in library IC 74198
|
||||
|
@ -10,22 +10,25 @@ import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
|
||||
/**
|
||||
* Helper to check a circuit for circles
|
||||
* Helper to check a circuit for cycles.
|
||||
* A cycle is a situation where a gate input depends somehow on one of its outputs.
|
||||
* If a cycle is detected an exception is thrown.
|
||||
*/
|
||||
public final class CircleDetector {
|
||||
public final class CycleDetector {
|
||||
|
||||
private CircleDetector() {
|
||||
private CycleDetector() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the circuit has circles.
|
||||
* Checks a circuit for circles.
|
||||
* If a circle is detected, en exception is thrown.
|
||||
*
|
||||
* @param values the input signals of the circuit
|
||||
* @return if the circuit has circles
|
||||
* @throws BacktrackException BacktrackException
|
||||
* @throws PinException PinException
|
||||
* @throws CycleException is thrown if a circle is detected
|
||||
*/
|
||||
public static boolean hasCircles(ArrayList<Signal> values) throws BacktrackException, PinException {
|
||||
public static void checkForCycles(ArrayList<Signal> values) throws BacktrackException, PinException, CycleException {
|
||||
HashMap<NodeInterface, Node> nodes = new HashMap<>();
|
||||
HashSet<ObservableValue> visited = new HashSet<>();
|
||||
|
||||
@ -35,12 +38,7 @@ public final class CircleDetector {
|
||||
traverse(root, s.getValue(), nodes, visited);
|
||||
}
|
||||
|
||||
try {
|
||||
checkForCircles(nodes.values());
|
||||
return false;
|
||||
} catch (CircleException e) {
|
||||
return true;
|
||||
}
|
||||
checkGraphForCycles(nodes.values());
|
||||
}
|
||||
|
||||
private static void traverse(Node parent, ObservableValue val, HashMap<NodeInterface, Node> nodes, HashSet<ObservableValue> visited) throws PinException, BacktrackException {
|
||||
@ -83,7 +81,7 @@ public final class CircleDetector {
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkForCircles(Collection<Node> nodes) throws CircleException {
|
||||
private static void checkGraphForCycles(Collection<Node> nodes) throws CycleException {
|
||||
ArrayList<Node> remaining = new ArrayList<>(nodes);
|
||||
|
||||
int layer = 1;
|
||||
@ -104,12 +102,15 @@ public final class CircleDetector {
|
||||
}
|
||||
|
||||
if (ableToPlace.isEmpty())
|
||||
throw new CircleException();
|
||||
throw new CycleException();
|
||||
|
||||
remaining.removeAll(ableToPlace);
|
||||
}
|
||||
}
|
||||
|
||||
private static class CircleException extends Exception {
|
||||
final static class CycleException extends AnalyseException {
|
||||
private CycleException() {
|
||||
super(Lang.get("err_circuitHasCycles"));
|
||||
}
|
||||
}
|
||||
}
|
@ -362,8 +362,7 @@ public class ModelAnalyser {
|
||||
for (Signal s : outputs)
|
||||
getModelAnalyzerInfo().addPinNumber(s);
|
||||
|
||||
if (CircleDetector.hasCircles(inputs))
|
||||
throw new AnalyseException(Lang.get("err_circuitHasCircles"));
|
||||
CycleDetector.checkForCycles(inputs);
|
||||
|
||||
DependencyAnalyser da = new DependencyAnalyser(this);
|
||||
long steps = da.getRequiredSteps(this);
|
||||
|
@ -804,7 +804,7 @@ Sind evtl. die Namen der Variablen nicht eindeutig?</string>
|
||||
<string name="err_tableHasToManyResultColumns">Die Tabelle hat zu viele Spalten!</string>
|
||||
<string name="err_errorExportingZip">Fehler beim Schreiben der ZIP-Datei.</string>
|
||||
<string name="err_moreThanOneFastClock">Es ist nur ein Taktelement mit hoher Frequenz erlaubt.</string>
|
||||
<string name="err_circuitHasCircles">Die Schaltung enthält Zyklen und kann daher nicht analysiert werden.</string>
|
||||
<string name="err_circuitHasCycles">Die Schaltung enthält Zyklen und kann daher nicht analysiert werden.</string>
|
||||
|
||||
<string name="key_AddrBits">Adress-Bits</string><!-- ROM, RAMDualPort, RAMSinglePort, RAMSinglePortSel, EEPROM -->
|
||||
<string name="key_AddrBits_tt">Anzahl der Adress-Bits, die verwendet werden.</string>
|
||||
|
@ -800,7 +800,7 @@ The names of the variables may not be unique.</string>
|
||||
<string name="err_tableHasToManyResultColumns">The table has too many columns!</string>
|
||||
<string name="err_errorExportingZip">Error writing the zip file.</string>
|
||||
<string name="err_moreThanOneFastClock">Only one clock component with high frequency is allowed.</string>
|
||||
<string name="err_circuitHasCircles">The circuit contains circles. It's not possible to analyze such a circuit.</string>
|
||||
<string name="err_circuitHasCycles">The circuit contains cycles. It's not possible to analyze such a circuit.</string>
|
||||
|
||||
<string name="key_AddrBits">Address Bits</string><!-- ROM, RAMDualPort, RAMSinglePort, RAMSinglePortSel, EEPROM -->
|
||||
<string name="key_AddrBits_tt">Number of address bits used.</string>
|
||||
|
@ -2,10 +2,9 @@ package de.neemann.digital.analyse;
|
||||
|
||||
import de.neemann.digital.core.Model;
|
||||
import de.neemann.digital.integration.ToBreakRunner;
|
||||
import de.neemann.digital.lang.Lang;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
public class CircleDetectorTest extends TestCase {
|
||||
public class CycleDetectorTest extends TestCase {
|
||||
|
||||
private static final String[] nameTableSequential = {
|
||||
"D.dig",
|
||||
@ -61,10 +60,10 @@ public class CircleDetectorTest extends TestCase {
|
||||
for (String name : nameTableSequential) {
|
||||
Model model = new ToBreakRunner("../../main/dig/sequential/" + name, false).getModel();
|
||||
try {
|
||||
TruthTable tt = new ModelAnalyser(model).analyse();
|
||||
new ModelAnalyser(model).analyse();
|
||||
fail();
|
||||
} catch (AnalyseException e) {
|
||||
assertTrue(e.getMessage().contains(Lang.get("err_circuitHasCircles")));
|
||||
} catch (CycleDetector.CycleException e) {
|
||||
assertTrue(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -72,7 +71,7 @@ public class CircleDetectorTest extends TestCase {
|
||||
public void testCirclesOk() throws Exception {
|
||||
for (String name : nameTableCombinatorial) {
|
||||
Model model = new ToBreakRunner("../../main/dig/combinatorial/" + name, false).getModel();
|
||||
TruthTable tt = new ModelAnalyser(model).analyse();
|
||||
new ModelAnalyser(model).analyse();
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user