mirror of
https://github.com/hneemann/Digital.git
synced 2025-09-16 16:34:47 -04:00
added simple analyser for circuits which creates a truth table
This commit is contained in:
parent
b68570030c
commit
6e5728ca2a
@ -1,311 +1,311 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<circuit>
|
||||
<version>1</version>
|
||||
<visualElements>
|
||||
<visualElement>
|
||||
<elementName>In</elementName>
|
||||
<elementAttributes>
|
||||
<entry>
|
||||
<string>Label</string>
|
||||
<string>A_0</string>
|
||||
</entry>
|
||||
</elementAttributes>
|
||||
<pos x="160" y="60"/>
|
||||
<rotate>0</rotate>
|
||||
</visualElement>
|
||||
<visualElement>
|
||||
<elementName>In</elementName>
|
||||
<elementAttributes>
|
||||
<entry>
|
||||
<string>Label</string>
|
||||
<string>A_1</string>
|
||||
</entry>
|
||||
</elementAttributes>
|
||||
<pos x="160" y="120"/>
|
||||
<rotate>0</rotate>
|
||||
</visualElement>
|
||||
<visualElement>
|
||||
<elementName>Not</elementName>
|
||||
<elementAttributes>
|
||||
<entry>
|
||||
<string>rotation</string>
|
||||
<rotation rotation="3"/>
|
||||
</entry>
|
||||
</elementAttributes>
|
||||
<pos x="220" y="140"/>
|
||||
<rotate>3</rotate>
|
||||
</visualElement>
|
||||
<visualElement>
|
||||
<elementName>Not</elementName>
|
||||
<elementAttributes>
|
||||
<entry>
|
||||
<string>rotation</string>
|
||||
<rotation reference="../../../../visualElement[3]/elementAttributes/entry/rotation"/>
|
||||
</entry>
|
||||
</elementAttributes>
|
||||
<pos x="280" y="140"/>
|
||||
<rotate>3</rotate>
|
||||
</visualElement>
|
||||
<visualElement>
|
||||
<elementName>And</elementName>
|
||||
<elementAttributes>
|
||||
<entry>
|
||||
<string>Inputs</string>
|
||||
<int>3</int>
|
||||
</entry>
|
||||
</elementAttributes>
|
||||
<pos x="360" y="200"/>
|
||||
<rotate>0</rotate>
|
||||
</visualElement>
|
||||
<visualElement>
|
||||
<elementName>In</elementName>
|
||||
<elementAttributes>
|
||||
<entry>
|
||||
<string>Label</string>
|
||||
<string>D</string>
|
||||
</entry>
|
||||
</elementAttributes>
|
||||
<pos x="160" y="340"/>
|
||||
<rotate>0</rotate>
|
||||
</visualElement>
|
||||
<visualElement>
|
||||
<elementName>And</elementName>
|
||||
<elementAttributes>
|
||||
<entry>
|
||||
<string>Inputs</string>
|
||||
<int>3</int>
|
||||
</entry>
|
||||
</elementAttributes>
|
||||
<pos x="360" y="280"/>
|
||||
<rotate>0</rotate>
|
||||
</visualElement>
|
||||
<visualElement>
|
||||
<elementName>And</elementName>
|
||||
<elementAttributes>
|
||||
<entry>
|
||||
<string>Inputs</string>
|
||||
<int>3</int>
|
||||
</entry>
|
||||
</elementAttributes>
|
||||
<pos x="360" y="360"/>
|
||||
<rotate>0</rotate>
|
||||
</visualElement>
|
||||
<visualElement>
|
||||
<elementName>And</elementName>
|
||||
<elementAttributes>
|
||||
<entry>
|
||||
<string>Inputs</string>
|
||||
<int>3</int>
|
||||
</entry>
|
||||
</elementAttributes>
|
||||
<pos x="360" y="440"/>
|
||||
<rotate>0</rotate>
|
||||
</visualElement>
|
||||
<visualElement>
|
||||
<elementName>Out</elementName>
|
||||
<elementAttributes>
|
||||
<entry>
|
||||
<string>Label</string>
|
||||
<string>Y_0</string>
|
||||
</entry>
|
||||
</elementAttributes>
|
||||
<pos x="460" y="220"/>
|
||||
<rotate>0</rotate>
|
||||
</visualElement>
|
||||
<visualElement>
|
||||
<elementName>Out</elementName>
|
||||
<elementAttributes>
|
||||
<entry>
|
||||
<string>Label</string>
|
||||
<string>Y_1</string>
|
||||
</entry>
|
||||
</elementAttributes>
|
||||
<pos x="460" y="300"/>
|
||||
<rotate>0</rotate>
|
||||
</visualElement>
|
||||
<visualElement>
|
||||
<elementName>Out</elementName>
|
||||
<elementAttributes>
|
||||
<entry>
|
||||
<string>Label</string>
|
||||
<string>Y_2</string>
|
||||
</entry>
|
||||
</elementAttributes>
|
||||
<pos x="460" y="380"/>
|
||||
<rotate>0</rotate>
|
||||
</visualElement>
|
||||
<visualElement>
|
||||
<elementName>Out</elementName>
|
||||
<elementAttributes>
|
||||
<entry>
|
||||
<string>Label</string>
|
||||
<string>Y_3</string>
|
||||
</entry>
|
||||
</elementAttributes>
|
||||
<pos x="460" y="460"/>
|
||||
<rotate>0</rotate>
|
||||
</visualElement>
|
||||
</visualElements>
|
||||
<wires>
|
||||
<wire>
|
||||
<p1 x="340" y="320"/>
|
||||
<p2 x="360" y="320"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="340" y="480"/>
|
||||
<p2 x="360" y="480"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="280" y="200"/>
|
||||
<p2 x="360" y="200"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="280" y="360"/>
|
||||
<p2 x="360" y="360"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="220" y="300"/>
|
||||
<p2 x="360" y="300"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="420" y="300"/>
|
||||
<p2 x="460" y="300"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="200" y="460"/>
|
||||
<p2 x="360" y="460"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="420" y="460"/>
|
||||
<p2 x="460" y="460"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="340" y="240"/>
|
||||
<p2 x="360" y="240"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="340" y="400"/>
|
||||
<p2 x="360" y="400"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="160" y="340"/>
|
||||
<p2 x="340" y="340"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="160" y="120"/>
|
||||
<p2 x="200" y="120"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="260" y="120"/>
|
||||
<p2 x="280" y="120"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="200" y="120"/>
|
||||
<p2 x="220" y="120"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="260" y="280"/>
|
||||
<p2 x="360" y="280"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="260" y="440"/>
|
||||
<p2 x="360" y="440"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="220" y="220"/>
|
||||
<p2 x="360" y="220"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="420" y="220"/>
|
||||
<p2 x="460" y="220"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="200" y="380"/>
|
||||
<p2 x="360" y="380"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="420" y="380"/>
|
||||
<p2 x="460" y="380"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="160" y="60"/>
|
||||
<p2 x="260" y="60"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="340" y="240"/>
|
||||
<p2 x="340" y="320"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="340" y="340"/>
|
||||
<p2 x="340" y="400"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="340" y="400"/>
|
||||
<p2 x="340" y="480"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="340" y="320"/>
|
||||
<p2 x="340" y="340"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="260" y="60"/>
|
||||
<p2 x="260" y="120"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="260" y="280"/>
|
||||
<p2 x="260" y="440"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="260" y="440"/>
|
||||
<p2 x="260" y="520"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="260" y="120"/>
|
||||
<p2 x="260" y="280"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="200" y="120"/>
|
||||
<p2 x="200" y="380"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="200" y="460"/>
|
||||
<p2 x="200" y="520"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="200" y="380"/>
|
||||
<p2 x="200" y="460"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="280" y="120"/>
|
||||
<p2 x="280" y="140"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="280" y="180"/>
|
||||
<p2 x="280" y="200"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="280" y="200"/>
|
||||
<p2 x="280" y="360"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="280" y="360"/>
|
||||
<p2 x="280" y="520"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="220" y="120"/>
|
||||
<p2 x="220" y="140"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="220" y="180"/>
|
||||
<p2 x="220" y="220"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="220" y="220"/>
|
||||
<p2 x="220" y="300"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="220" y="300"/>
|
||||
<p2 x="220" y="520"/>
|
||||
</wire>
|
||||
</wires>
|
||||
<version>1</version>
|
||||
<visualElements>
|
||||
<visualElement>
|
||||
<elementName>In</elementName>
|
||||
<elementAttributes>
|
||||
<entry>
|
||||
<string>Label</string>
|
||||
<string>A_1</string>
|
||||
</entry>
|
||||
</elementAttributes>
|
||||
<pos x="160" y="120"/>
|
||||
<rotate>0</rotate>
|
||||
</visualElement>
|
||||
<visualElement>
|
||||
<elementName>In</elementName>
|
||||
<elementAttributes>
|
||||
<entry>
|
||||
<string>Label</string>
|
||||
<string>A_0</string>
|
||||
</entry>
|
||||
</elementAttributes>
|
||||
<pos x="160" y="60"/>
|
||||
<rotate>0</rotate>
|
||||
</visualElement>
|
||||
<visualElement>
|
||||
<elementName>Not</elementName>
|
||||
<elementAttributes>
|
||||
<entry>
|
||||
<string>rotation</string>
|
||||
<rotation rotation="3"/>
|
||||
</entry>
|
||||
</elementAttributes>
|
||||
<pos x="220" y="140"/>
|
||||
<rotate>3</rotate>
|
||||
</visualElement>
|
||||
<visualElement>
|
||||
<elementName>Not</elementName>
|
||||
<elementAttributes>
|
||||
<entry>
|
||||
<string>rotation</string>
|
||||
<rotation reference="../../../../visualElement[3]/elementAttributes/entry/rotation"/>
|
||||
</entry>
|
||||
</elementAttributes>
|
||||
<pos x="280" y="140"/>
|
||||
<rotate>3</rotate>
|
||||
</visualElement>
|
||||
<visualElement>
|
||||
<elementName>And</elementName>
|
||||
<elementAttributes>
|
||||
<entry>
|
||||
<string>Inputs</string>
|
||||
<int>3</int>
|
||||
</entry>
|
||||
</elementAttributes>
|
||||
<pos x="360" y="200"/>
|
||||
<rotate>0</rotate>
|
||||
</visualElement>
|
||||
<visualElement>
|
||||
<elementName>In</elementName>
|
||||
<elementAttributes>
|
||||
<entry>
|
||||
<string>Label</string>
|
||||
<string>D</string>
|
||||
</entry>
|
||||
</elementAttributes>
|
||||
<pos x="160" y="340"/>
|
||||
<rotate>0</rotate>
|
||||
</visualElement>
|
||||
<visualElement>
|
||||
<elementName>And</elementName>
|
||||
<elementAttributes>
|
||||
<entry>
|
||||
<string>Inputs</string>
|
||||
<int>3</int>
|
||||
</entry>
|
||||
</elementAttributes>
|
||||
<pos x="360" y="280"/>
|
||||
<rotate>0</rotate>
|
||||
</visualElement>
|
||||
<visualElement>
|
||||
<elementName>And</elementName>
|
||||
<elementAttributes>
|
||||
<entry>
|
||||
<string>Inputs</string>
|
||||
<int>3</int>
|
||||
</entry>
|
||||
</elementAttributes>
|
||||
<pos x="360" y="360"/>
|
||||
<rotate>0</rotate>
|
||||
</visualElement>
|
||||
<visualElement>
|
||||
<elementName>And</elementName>
|
||||
<elementAttributes>
|
||||
<entry>
|
||||
<string>Inputs</string>
|
||||
<int>3</int>
|
||||
</entry>
|
||||
</elementAttributes>
|
||||
<pos x="360" y="440"/>
|
||||
<rotate>0</rotate>
|
||||
</visualElement>
|
||||
<visualElement>
|
||||
<elementName>Out</elementName>
|
||||
<elementAttributes>
|
||||
<entry>
|
||||
<string>Label</string>
|
||||
<string>Y_0</string>
|
||||
</entry>
|
||||
</elementAttributes>
|
||||
<pos x="460" y="220"/>
|
||||
<rotate>0</rotate>
|
||||
</visualElement>
|
||||
<visualElement>
|
||||
<elementName>Out</elementName>
|
||||
<elementAttributes>
|
||||
<entry>
|
||||
<string>Label</string>
|
||||
<string>Y_1</string>
|
||||
</entry>
|
||||
</elementAttributes>
|
||||
<pos x="460" y="300"/>
|
||||
<rotate>0</rotate>
|
||||
</visualElement>
|
||||
<visualElement>
|
||||
<elementName>Out</elementName>
|
||||
<elementAttributes>
|
||||
<entry>
|
||||
<string>Label</string>
|
||||
<string>Y_2</string>
|
||||
</entry>
|
||||
</elementAttributes>
|
||||
<pos x="460" y="380"/>
|
||||
<rotate>0</rotate>
|
||||
</visualElement>
|
||||
<visualElement>
|
||||
<elementName>Out</elementName>
|
||||
<elementAttributes>
|
||||
<entry>
|
||||
<string>Label</string>
|
||||
<string>Y_3</string>
|
||||
</entry>
|
||||
</elementAttributes>
|
||||
<pos x="460" y="460"/>
|
||||
<rotate>0</rotate>
|
||||
</visualElement>
|
||||
</visualElements>
|
||||
<wires>
|
||||
<wire>
|
||||
<p1 x="340" y="320"/>
|
||||
<p2 x="360" y="320"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="340" y="480"/>
|
||||
<p2 x="360" y="480"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="280" y="200"/>
|
||||
<p2 x="360" y="200"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="280" y="360"/>
|
||||
<p2 x="360" y="360"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="220" y="300"/>
|
||||
<p2 x="360" y="300"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="420" y="300"/>
|
||||
<p2 x="460" y="300"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="200" y="460"/>
|
||||
<p2 x="360" y="460"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="420" y="460"/>
|
||||
<p2 x="460" y="460"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="340" y="240"/>
|
||||
<p2 x="360" y="240"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="340" y="400"/>
|
||||
<p2 x="360" y="400"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="160" y="340"/>
|
||||
<p2 x="340" y="340"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="160" y="120"/>
|
||||
<p2 x="200" y="120"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="260" y="120"/>
|
||||
<p2 x="280" y="120"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="200" y="120"/>
|
||||
<p2 x="220" y="120"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="260" y="280"/>
|
||||
<p2 x="360" y="280"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="260" y="440"/>
|
||||
<p2 x="360" y="440"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="220" y="220"/>
|
||||
<p2 x="360" y="220"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="420" y="220"/>
|
||||
<p2 x="460" y="220"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="200" y="380"/>
|
||||
<p2 x="360" y="380"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="420" y="380"/>
|
||||
<p2 x="460" y="380"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="160" y="60"/>
|
||||
<p2 x="260" y="60"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="340" y="240"/>
|
||||
<p2 x="340" y="320"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="340" y="340"/>
|
||||
<p2 x="340" y="400"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="340" y="400"/>
|
||||
<p2 x="340" y="480"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="340" y="320"/>
|
||||
<p2 x="340" y="340"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="260" y="60"/>
|
||||
<p2 x="260" y="120"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="260" y="280"/>
|
||||
<p2 x="260" y="440"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="260" y="440"/>
|
||||
<p2 x="260" y="520"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="260" y="120"/>
|
||||
<p2 x="260" y="280"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="200" y="120"/>
|
||||
<p2 x="200" y="380"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="200" y="460"/>
|
||||
<p2 x="200" y="520"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="200" y="380"/>
|
||||
<p2 x="200" y="460"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="280" y="120"/>
|
||||
<p2 x="280" y="140"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="280" y="180"/>
|
||||
<p2 x="280" y="200"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="280" y="200"/>
|
||||
<p2 x="280" y="360"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="280" y="360"/>
|
||||
<p2 x="280" y="520"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="220" y="120"/>
|
||||
<p2 x="220" y="140"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="220" y="180"/>
|
||||
<p2 x="220" y="220"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="220" y="220"/>
|
||||
<p2 x="220" y="300"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="220" y="300"/>
|
||||
<p2 x="220" y="520"/>
|
||||
</wire>
|
||||
</wires>
|
||||
</circuit>
|
@ -76,10 +76,10 @@
|
||||
<elementAttributes>
|
||||
<entry>
|
||||
<string>Label</string>
|
||||
<string>C_i</string>
|
||||
<string>S_i</string>
|
||||
</entry>
|
||||
</elementAttributes>
|
||||
<pos x="940" y="280"/>
|
||||
<pos x="940" y="440"/>
|
||||
<rotate>0</rotate>
|
||||
</visualElement>
|
||||
<visualElement>
|
||||
@ -87,10 +87,10 @@
|
||||
<elementAttributes>
|
||||
<entry>
|
||||
<string>Label</string>
|
||||
<string>S_i</string>
|
||||
<string>C_i</string>
|
||||
</entry>
|
||||
</elementAttributes>
|
||||
<pos x="940" y="440"/>
|
||||
<pos x="940" y="280"/>
|
||||
<rotate>0</rotate>
|
||||
</visualElement>
|
||||
</visualElements>
|
||||
|
@ -0,0 +1,17 @@
|
||||
package de.neemann.digital.analyse;
|
||||
|
||||
/**
|
||||
* Exception thrown if there problems analysing the circuit
|
||||
*
|
||||
* @author hneemann
|
||||
*/
|
||||
public class AnalyseException extends Exception {
|
||||
/**
|
||||
* Creates a new instance
|
||||
*
|
||||
* @param message the message
|
||||
*/
|
||||
public AnalyseException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
138
src/main/java/de/neemann/digital/analyse/ModelAnalyser.java
Normal file
138
src/main/java/de/neemann/digital/analyse/ModelAnalyser.java
Normal file
@ -0,0 +1,138 @@
|
||||
package de.neemann.digital.analyse;
|
||||
|
||||
import de.neemann.digital.core.Model;
|
||||
import de.neemann.digital.core.NodeException;
|
||||
import de.neemann.digital.lang.Lang;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Analyses a given model.
|
||||
* Calculates the truth table which generated by the given model
|
||||
*
|
||||
* @author hneemann
|
||||
*/
|
||||
public class ModelAnalyser {
|
||||
|
||||
private final Model model;
|
||||
private final ArrayList<Model.Signal> inputs;
|
||||
private final ArrayList<Model.Signal> outputs;
|
||||
private final int rows;
|
||||
private final int cols;
|
||||
private final boolean[][] data;
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new instance
|
||||
*
|
||||
* @param model the model
|
||||
* @throws AnalyseException AnalyseException
|
||||
*/
|
||||
public ModelAnalyser(Model model) throws AnalyseException {
|
||||
this.model = model;
|
||||
inputs = checkBinary(model.getInputs());
|
||||
if (inputs.size() == 0)
|
||||
throw new AnalyseException(Lang.get("err_analyseNoInputs"));
|
||||
outputs = checkBinary(model.getOutputs());
|
||||
if (outputs.size() == 0)
|
||||
throw new AnalyseException(Lang.get("err_analyseNoOutputs"));
|
||||
rows = 1 << inputs.size();
|
||||
cols = inputs.size() + outputs.size();
|
||||
data = new boolean[rows][cols];
|
||||
}
|
||||
|
||||
private ArrayList<Model.Signal> checkBinary(ArrayList<Model.Signal> list) throws AnalyseException {
|
||||
for (Model.Signal s : list)
|
||||
if (s.getValue().getBits() != 1)
|
||||
throw new AnalyseException(Lang.get("err_analyseValue_N_IsNotBinary", s.getName()));
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Analyses the circuit
|
||||
*
|
||||
* @return this for call chaining
|
||||
* @throws NodeException NodeException
|
||||
*/
|
||||
public ModelAnalyser analyse() throws NodeException {
|
||||
model.init();
|
||||
for (int row = 0; row < rows; row++) {
|
||||
for (int i = 0; i < inputs.size(); i++) {
|
||||
int pos = inputs.size() - 1 - i;
|
||||
boolean bool = (row & (1 << pos)) != 0;
|
||||
inputs.get(i).getValue().setBool(bool);
|
||||
data[row][i] = bool;
|
||||
}
|
||||
model.doStep();
|
||||
for (int i = 0; i < outputs.size(); i++) {
|
||||
data[row][inputs.size() + i] = outputs.get(i).getValue().getBool();
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return returns the models inputs
|
||||
*/
|
||||
public ArrayList<Model.Signal> getInputs() {
|
||||
return inputs;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return returns the models outputs
|
||||
*/
|
||||
public ArrayList<Model.Signal> getOutputs() {
|
||||
return outputs;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the truth table
|
||||
*/
|
||||
public boolean[][] getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (Model.Signal s : inputs)
|
||||
sb.append(s.getName()).append("\t");
|
||||
for (Model.Signal s : outputs)
|
||||
sb.append(s.getName()).append("\t");
|
||||
sb.append('\n');
|
||||
for (int row = 0; row < rows; row++) {
|
||||
for (int col = 0; col < cols; col++) {
|
||||
if (data[row][col])
|
||||
sb.append("1\t");
|
||||
else
|
||||
sb.append("0\t");
|
||||
}
|
||||
sb.append("\n");
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the number of rows
|
||||
*/
|
||||
public int getRows() {
|
||||
return rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the number of columns
|
||||
*/
|
||||
public int getCols() {
|
||||
return cols;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return returns one value of the truth table
|
||||
*/
|
||||
public int getValue(int rowIndex, int columnIndex) {
|
||||
if (data[rowIndex][columnIndex])
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
package de.neemann.digital.analyse;
|
||||
|
||||
import javax.swing.event.TableModelListener;
|
||||
import javax.swing.table.TableModel;
|
||||
|
||||
/**
|
||||
* @author hneemann
|
||||
*/
|
||||
public class ModelAnalyzerTableModel implements TableModel {
|
||||
private final ModelAnalyser analyzer;
|
||||
|
||||
public ModelAnalyzerTableModel(ModelAnalyser analyzer) {
|
||||
this.analyzer = analyzer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRowCount() {
|
||||
return analyzer.getRows();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getColumnCount() {
|
||||
return analyzer.getCols();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getColumnName(int columnIndex) {
|
||||
if (columnIndex < analyzer.getInputs().size())
|
||||
return analyzer.getInputs().get(columnIndex).getName();
|
||||
else
|
||||
return analyzer.getOutputs().get(columnIndex - analyzer.getInputs().size()).getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getColumnClass(int columnIndex) {
|
||||
return Integer.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCellEditable(int rowIndex, int columnIndex) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getValueAt(int rowIndex, int columnIndex) {
|
||||
return analyzer.getValue(rowIndex, columnIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTableModelListener(TableModelListener l) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeTableModelListener(TableModelListener l) {
|
||||
}
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
/**
|
||||
* Classes used to analyse the actual circuit
|
||||
*
|
||||
* @author hneemann
|
||||
*/
|
||||
package de.neemann.digital.analyse;
|
@ -48,6 +48,8 @@ public class Model {
|
||||
private final ArrayList<Break> breaks;
|
||||
private final ArrayList<Reset> resets;
|
||||
private final ArrayList<Signal> signals;
|
||||
private final ArrayList<Signal> inputs;
|
||||
private final ArrayList<Signal> outputs;
|
||||
private final ArrayList<ROM> roms;
|
||||
|
||||
private final ArrayList<Node> nodes;
|
||||
@ -65,6 +67,8 @@ public class Model {
|
||||
this.breaks = new ArrayList<>();
|
||||
this.resets = new ArrayList<>();
|
||||
this.signals = new ArrayList<>();
|
||||
this.outputs = new ArrayList<>();
|
||||
this.inputs = new ArrayList<>();
|
||||
this.roms = new ArrayList<>();
|
||||
this.nodes = new ArrayList<>();
|
||||
this.nodesToUpdateAct = new ArrayList<>();
|
||||
@ -100,8 +104,7 @@ public class Model {
|
||||
|
||||
/**
|
||||
* Needs to be called after all nodes are added.
|
||||
* If not called it es called automatically.
|
||||
* Calles <code>init(true);</code>
|
||||
* Calls <code>init(true);</code>
|
||||
*
|
||||
* @throws NodeException NodeException
|
||||
*/
|
||||
@ -373,10 +376,56 @@ public class Model {
|
||||
* @param value the signals value
|
||||
*/
|
||||
public void addSignal(String name, ObservableValue value) {
|
||||
if (name != null && name.length() > 0 && value != null)
|
||||
if (isSignal(name, value))
|
||||
signals.add(new Signal(name, value));
|
||||
}
|
||||
|
||||
private static boolean isSignal(String name, ObservableValue value) {
|
||||
return name != null && name.length() > 0 && value != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* registers a input to the model
|
||||
*
|
||||
* @param name the signals name
|
||||
* @param value the signals value
|
||||
*/
|
||||
public void addInput(String name, ObservableValue value) {
|
||||
if (isSignal(name, value)) {
|
||||
Signal signal = new Signal(name, value);
|
||||
signals.add(signal);
|
||||
inputs.add(signal);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the models inputs
|
||||
*/
|
||||
public ArrayList<Signal> getInputs() {
|
||||
return inputs;
|
||||
}
|
||||
|
||||
/**
|
||||
* registers a output to the model
|
||||
*
|
||||
* @param name the signals name
|
||||
* @param value the signals value
|
||||
*/
|
||||
public void addOutput(String name, ObservableValue value) {
|
||||
if (isSignal(name, value)) {
|
||||
Signal signal = new Signal(name, value);
|
||||
signals.add(signal);
|
||||
outputs.add(signal);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the models outputs
|
||||
*/
|
||||
public ArrayList<Signal> getOutputs() {
|
||||
return outputs;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return all registered Signals
|
||||
*/
|
||||
@ -431,7 +480,10 @@ public class Model {
|
||||
* @param value the signals value
|
||||
*/
|
||||
public Signal(String name, ObservableValue value) {
|
||||
this.name = name;
|
||||
if (name.length() > 2 && name.charAt(0) == '$' && name.charAt(name.length() - 1) == '$')
|
||||
this.name = name.substring(1, name.length() - 1);
|
||||
else
|
||||
this.name = name;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
|
@ -59,6 +59,6 @@ public class In implements Element {
|
||||
|
||||
@Override
|
||||
public void registerNodes(Model model) {
|
||||
model.addSignal(label, output);
|
||||
model.addInput(label, output);
|
||||
}
|
||||
}
|
||||
|
@ -104,6 +104,6 @@ public class Out implements Element {
|
||||
|
||||
@Override
|
||||
public void registerNodes(Model model) {
|
||||
model.addSignal(label, value);
|
||||
model.addOutput(label, value);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
package de.neemann.digital.gui;
|
||||
|
||||
import de.neemann.digital.analyse.AnalyseException;
|
||||
import de.neemann.digital.analyse.ModelAnalyser;
|
||||
import de.neemann.digital.core.*;
|
||||
import de.neemann.digital.core.element.ElementAttributes;
|
||||
import de.neemann.digital.core.element.Key;
|
||||
@ -320,6 +322,8 @@ public class Main extends JFrame implements ClosingWindowListener.ConfirmSave, E
|
||||
run.add(speedTest.createJMenuItem());
|
||||
doStep.setEnabled(false);
|
||||
|
||||
bar.add(createAanalyseMenu());
|
||||
|
||||
JToolBar toolBar = new JToolBar();
|
||||
toolBar.add(newFile.createJButtonNoText());
|
||||
toolBar.add(open.createJButtonNoText());
|
||||
@ -348,6 +352,26 @@ public class Main extends JFrame implements ClosingWindowListener.ConfirmSave, E
|
||||
setLocationRelativeTo(parent);
|
||||
}
|
||||
|
||||
private JMenu createAanalyseMenu() {
|
||||
JMenu analyse = new JMenu(Lang.get("menu_analyse"));
|
||||
analyse.add(new ToolTipAction(Lang.get("menu_analyse")) {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
try {
|
||||
Model model = new ModelDescription(circuitComponent.getCircuit(), library).createModel();
|
||||
new TableDialog(Main.this, new ModelAnalyser(model).analyse()).setVisible(true);
|
||||
elementState.activate();
|
||||
} catch (PinException | NodeException | AnalyseException e1) {
|
||||
showErrorAndStopModel(Lang.get("msg_annalyseErr"), e1);
|
||||
}
|
||||
}
|
||||
}
|
||||
.setToolTip(Lang.get("menu_analyse_tt"))
|
||||
.createJMenuItem());
|
||||
|
||||
return analyse;
|
||||
}
|
||||
|
||||
private void orderMeasurements() {
|
||||
try {
|
||||
Model m = new ModelDescription(circuitComponent.getCircuit(), library).createModel();
|
||||
|
@ -0,0 +1,30 @@
|
||||
package de.neemann.digital.gui.components;
|
||||
|
||||
import de.neemann.digital.analyse.ModelAnalyser;
|
||||
import de.neemann.digital.analyse.ModelAnalyzerTableModel;
|
||||
import de.neemann.digital.lang.Lang;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
|
||||
/**
|
||||
* Dialog to visualise a truth table.
|
||||
*
|
||||
* @author hneemann
|
||||
*/
|
||||
public class TableDialog extends JDialog {
|
||||
/**
|
||||
* Creates a new instance
|
||||
*
|
||||
* @param owner the owner of this dialog
|
||||
* @param analyzer the truth table
|
||||
*/
|
||||
public TableDialog(Frame owner, ModelAnalyser analyzer) {
|
||||
super(owner, Lang.get("win_table"));
|
||||
JTable table = new JTable(new ModelAnalyzerTableModel(analyzer));
|
||||
table.setPreferredScrollableViewportSize(table.getPreferredSize());
|
||||
getContentPane().add(new JScrollPane(table));
|
||||
pack();
|
||||
setLocationRelativeTo(owner);
|
||||
}
|
||||
}
|
@ -168,6 +168,9 @@ err_notAllOutputsSameBits=Es haben nicht alle Ausg\u00E4nge die gleiche Bitbreit
|
||||
err_notAllOutputsSupportHighZ=Wenn mehrere Ausg\u00E4nge verbunden sind, m\u00FCssen alle Ausg\u00E4nge Tri-State Ausg\u00E4nge sein
|
||||
err_breakTimeOut=Nach {0} Zyklen ist kein Break aufgetreten
|
||||
err_labelNotConnectedToNet_N=Ein Tunnel {0} ist nicht verbunden!
|
||||
err_analyseNoInputs=Die Schaltung hat keine benannten Eing\u00E4nge
|
||||
err_analyseNoOutputs=Die Schaltung hat keine benannten Ausg\u00E4nge
|
||||
err_analyseValue_N_IsNotBinary=Der Wert {0} hat mehr als ein Bit.
|
||||
|
||||
attr_dialogTitle=Eigenschaften
|
||||
msg_errorEditingValue=Fehler bei der Eingabe eines Wertes
|
||||
@ -178,10 +181,11 @@ msg_errorWritingFile=Fehler beim Schreiben einer Datei
|
||||
msg_errorReadingFile=Fehler beim Lesen einer Datei
|
||||
msg_errorCalculatingStep=Fehler beim Berechnen eines Schrittes
|
||||
msg_missingShape_N=Es fehlt ein Diagramm f\u00FCr {0}
|
||||
msg_fastRunError=Ein Fehler beim Schnellen Lauf
|
||||
msg_fastRunError=Ein Fehler beim schnellen Lauf
|
||||
msg_errorReadingListing_N0=Fehler beim Laden des Listings {0}
|
||||
msg_clockError=Fehler bei der Berechnung einer Takt\u00E4nderung
|
||||
msg_frequency_N=Die maximale Frequenz ber\u00E4gt {0}Hz.
|
||||
msg_annalyseErr=Fehler bei der Analyse der Schaltung
|
||||
|
||||
|
||||
stat_clocks={0} Halbzyklen
|
||||
@ -244,6 +248,8 @@ menu_editRunAttributes=Simulationseinstellungen
|
||||
menu_editRunAttributes_tt=Einstellungen f\u00FCr den Start der Simulation
|
||||
menu_saveData=Daten speichern
|
||||
menu_saveData_tt=Speichert die Daten als CSV Datei
|
||||
menu_analyse=Analyse
|
||||
menu_analyse_tt=Analyse der aktuellen Schaltung
|
||||
|
||||
menu_about=\u00DCber Digital
|
||||
|
||||
@ -255,3 +261,4 @@ win_measures_microstep=Messwerte im Einzelgattermodus
|
||||
win_measures_fullstep=Messwerte im Vollschrittmodus
|
||||
|
||||
win_listing=Listing
|
||||
win_table=Tabelle
|
@ -228,6 +228,8 @@ menu_editRunAttributes=Simulation Settings
|
||||
menu_editRunAttributes_tt=Settings used to start the simulation
|
||||
menu_saveData=Save Data
|
||||
menu_saveData_tt=Save data as CSV file
|
||||
menu_analyse=Analyse
|
||||
menu_analyse_tt=Analyses the actual circuit
|
||||
|
||||
win_saveChanges=Save Changes?
|
||||
win_confirmExit=Confirm Exit!
|
||||
@ -252,3 +254,8 @@ elem_Text_tt=Shows a text in the circuit
|
||||
key_Default_tt=Is set if the model is started
|
||||
err_labelNotConnectedToNet_N=A tunnel {0} is not connected!
|
||||
key_Width_tt=With of symbol if this circuit is used in an element ins an other circuit.
|
||||
err_analyseNoInputs=The circuit has no Inputs
|
||||
err_analyseNoOutputs=The circuit has no outputs
|
||||
err_analyseValue_N_IsNotBinary=The value {0} has more the one bit.
|
||||
msg_annalyseErr=Error analysing the circuit
|
||||
win_table=Table
|
||||
|
@ -0,0 +1,31 @@
|
||||
package de.neemann.digital.analyse;
|
||||
|
||||
import de.neemann.digital.core.Model;
|
||||
import de.neemann.digital.integration.ToBreakRunner;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* @author hneemann
|
||||
*/
|
||||
public class ModelAnalyserTest extends TestCase {
|
||||
|
||||
public void testAnalyzer() throws Exception {
|
||||
Model model = new ToBreakRunner("dig/analyzeTest.dig").getModel();
|
||||
ModelAnalyser ma = new ModelAnalyser(model).analyse();
|
||||
|
||||
assertEquals(4, ma.getRows());
|
||||
assertEquals(3, ma.getCols());
|
||||
|
||||
// circuit is XOr:
|
||||
assertEquals(0, ma.getValue(0, 2));
|
||||
assertEquals(1, ma.getValue(1, 2));
|
||||
assertEquals(1, ma.getValue(2, 2));
|
||||
assertEquals(0, ma.getValue(3, 2));
|
||||
|
||||
assertEquals("A\tB\tY\t\n" +
|
||||
"0\t0\t0\t\n" +
|
||||
"0\t1\t1\t\n" +
|
||||
"1\t0\t1\t\n" +
|
||||
"1\t1\t0\t\n", ma.toString());
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user