mirror of
https://github.com/hneemann/Digital.git
synced 2025-09-18 01:14:42 -04:00
initial commit
This commit is contained in:
commit
49ea08144e
72
.gitignore
vendored
Normal file
72
.gitignore
vendored
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
# Created by .ignore support plugin (hsz.mobi)
|
||||||
|
### Java template
|
||||||
|
*.class
|
||||||
|
|
||||||
|
# Mobile Tools for Java (J2ME)
|
||||||
|
.mtj.tmp/
|
||||||
|
|
||||||
|
# Package Files #
|
||||||
|
*.jar
|
||||||
|
*.war
|
||||||
|
*.ear
|
||||||
|
|
||||||
|
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||||
|
hs_err_pid*
|
||||||
|
### JetBrains template
|
||||||
|
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio
|
||||||
|
|
||||||
|
*.iml
|
||||||
|
|
||||||
|
## Directory-based project format:
|
||||||
|
.idea/
|
||||||
|
# if you remove the above rule, at least ignore the following:
|
||||||
|
|
||||||
|
# User-specific stuff:
|
||||||
|
# .idea/workspace.xml
|
||||||
|
# .idea/tasks.xml
|
||||||
|
# .idea/dictionaries
|
||||||
|
|
||||||
|
# Sensitive or high-churn files:
|
||||||
|
# .idea/dataSources.ids
|
||||||
|
# .idea/dataSources.xml
|
||||||
|
# .idea/sqlDataSources.xml
|
||||||
|
# .idea/dynamic.xml
|
||||||
|
# .idea/uiDesigner.xml
|
||||||
|
|
||||||
|
# Gradle:
|
||||||
|
# .idea/gradle.xml
|
||||||
|
# .idea/libraries
|
||||||
|
|
||||||
|
# Mongo Explorer plugin:
|
||||||
|
# .idea/mongoSettings.xml
|
||||||
|
|
||||||
|
## File-based project format:
|
||||||
|
*.ipr
|
||||||
|
*.iws
|
||||||
|
|
||||||
|
## Plugin-specific files:
|
||||||
|
|
||||||
|
# IntelliJ
|
||||||
|
/out/
|
||||||
|
|
||||||
|
# mpeltonen/sbt-idea plugin
|
||||||
|
.idea_modules/
|
||||||
|
|
||||||
|
# JIRA plugin
|
||||||
|
atlassian-ide-plugin.xml
|
||||||
|
|
||||||
|
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||||
|
com_crashlytics_export_strings.xml
|
||||||
|
crashlytics.properties
|
||||||
|
crashlytics-build.properties
|
||||||
|
### Maven template
|
||||||
|
target/
|
||||||
|
pom.xml.tag
|
||||||
|
pom.xml.releaseBackup
|
||||||
|
pom.xml.versionsBackup
|
||||||
|
pom.xml.next
|
||||||
|
release.properties
|
||||||
|
dependency-reduced-pom.xml
|
||||||
|
buildNumber.properties
|
||||||
|
.mvn/timing.properties
|
||||||
|
|
211
pom.xml
Normal file
211
pom.xml
Normal file
@ -0,0 +1,211 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<groupId>de.neemann.digital</groupId>
|
||||||
|
<artifactId>digital</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.build.timestamp.format>yyyy-MM-dd HH:mm</maven.build.timestamp.format>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<version.org.slf4j>1.7.12</version.org.slf4j>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<distributionManagement>
|
||||||
|
<site>
|
||||||
|
<id></id>
|
||||||
|
<url>file://${pom.basedir}/_stage</url>
|
||||||
|
</site>
|
||||||
|
</distributionManagement>
|
||||||
|
|
||||||
|
<reporting>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.codehaus.mojo</groupId>
|
||||||
|
<artifactId>cobertura-maven-plugin</artifactId>
|
||||||
|
<version>2.7</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.codehaus.mojo</groupId>
|
||||||
|
<artifactId>findbugs-maven-plugin</artifactId>
|
||||||
|
<version>3.0.1</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-checkstyle-plugin</artifactId>
|
||||||
|
<version>2.15</version>
|
||||||
|
<configuration>
|
||||||
|
<configLocation>sun_checks_neemann.xml</configLocation>
|
||||||
|
</configuration>
|
||||||
|
<reportSets>
|
||||||
|
<reportSet>
|
||||||
|
<reports>
|
||||||
|
<report>checkstyle</report>
|
||||||
|
</reports>
|
||||||
|
</reportSet>
|
||||||
|
</reportSets>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-javadoc-plugin</artifactId>
|
||||||
|
<version>2.10.2</version>
|
||||||
|
<configuration>
|
||||||
|
<doclet>org.umlgraph.doclet.UmlGraphDoc</doclet>
|
||||||
|
<docletArtifact>
|
||||||
|
<groupId>org.umlgraph</groupId>
|
||||||
|
<artifactId>umlgraph</artifactId>
|
||||||
|
<version>5.6</version>
|
||||||
|
</docletArtifact>
|
||||||
|
<additionalparam>-views -all</additionalparam>
|
||||||
|
<useStandardDocletOptions>true</useStandardDocletOptions>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</reporting>
|
||||||
|
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>3.1</version>
|
||||||
|
<configuration>
|
||||||
|
<source>1.8</source>
|
||||||
|
<target>1.8</target>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<!--plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
|
<version>2.5</version>
|
||||||
|
<configuration>
|
||||||
|
<archive>
|
||||||
|
<manifest>
|
||||||
|
<addClasspath>true</addClasspath>
|
||||||
|
<mainClass>de.neemann.assembler.gui.Main</mainClass>
|
||||||
|
</manifest>
|
||||||
|
<manifestEntries>
|
||||||
|
<Build-SCM-Revision>${buildNumber}</Build-SCM-Revision>
|
||||||
|
<Build-Time>${maven.build.timestamp}</Build-Time>
|
||||||
|
</manifestEntries>
|
||||||
|
</archive>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.codehaus.mojo</groupId>
|
||||||
|
<artifactId>buildnumber-maven-plugin</artifactId>
|
||||||
|
<version>1.3</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<phase>validate</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>create</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
<configuration>
|
||||||
|
<doCheck>true</doCheck>
|
||||||
|
<doUpdate>false</doUpdate>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-assembly-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<finalName>digital</finalName>
|
||||||
|
<appendAssemblyId>false</appendAssemblyId>
|
||||||
|
<attach>false</attach>
|
||||||
|
<descriptorRefs>
|
||||||
|
<descriptorRef>jar-with-dependencies</descriptorRef>
|
||||||
|
</descriptorRefs>
|
||||||
|
<archive>
|
||||||
|
<manifest>
|
||||||
|
<addClasspath>true</addClasspath>
|
||||||
|
<mainClass>de.neemann.assembler.gui.Main</mainClass>
|
||||||
|
</manifest>
|
||||||
|
<manifestEntries>
|
||||||
|
<Build-SCM-Revision>${buildNumber}</Build-SCM-Revision>
|
||||||
|
<Build-Time>${maven.build.timestamp}</Build-Time>
|
||||||
|
</manifestEntries>
|
||||||
|
</archive>
|
||||||
|
<appendAssemblyId>false</appendAssemblyId>
|
||||||
|
</configuration>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>make-assembly</id>
|
||||||
|
<phase>install</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>single</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.codehaus.mojo</groupId>
|
||||||
|
<artifactId>exec-maven-plugin</artifactId>
|
||||||
|
<version>1.3.2</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>script-chmod</id>
|
||||||
|
<phase>install</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>exec</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<executable>chmod</executable>
|
||||||
|
<arguments>
|
||||||
|
<argument>+x</argument>
|
||||||
|
<argument>target/digital.jar</argument>
|
||||||
|
</arguments>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
<execution>
|
||||||
|
<id>script-cp</id>
|
||||||
|
<phase>install</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>exec</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<executable>cp</executable>
|
||||||
|
<arguments>
|
||||||
|
<argument>target/digital.jar</argument>
|
||||||
|
<argument>/home/hneemann/Dokumente/DHBW/Software/</argument>
|
||||||
|
</arguments>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin-->
|
||||||
|
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<!--dependency>
|
||||||
|
<groupId>de.neemann.process</groupId>
|
||||||
|
<artifactId>utils</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
</dependency-->
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<version>4.0</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
|
||||||
|
<scm>
|
||||||
|
<connection>scm:git:file://localhost/${pom.basedir}</connection>
|
||||||
|
</scm>
|
||||||
|
|
||||||
|
|
||||||
|
</project>
|
10
src/main/java/de/neemann/digital/BitsException.java
Normal file
10
src/main/java/de/neemann/digital/BitsException.java
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
package de.neemann.digital;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author hneemann
|
||||||
|
*/
|
||||||
|
public class BitsException extends Exception {
|
||||||
|
public BitsException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
}
|
8
src/main/java/de/neemann/digital/Listener.java
Normal file
8
src/main/java/de/neemann/digital/Listener.java
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
package de.neemann.digital;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author hneemann
|
||||||
|
*/
|
||||||
|
public interface Listener {
|
||||||
|
void needsUpdate() throws NodeException;
|
||||||
|
}
|
80
src/main/java/de/neemann/digital/Model.java
Normal file
80
src/main/java/de/neemann/digital/Model.java
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
package de.neemann.digital;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author hneemann
|
||||||
|
*/
|
||||||
|
public class Model {
|
||||||
|
|
||||||
|
private ArrayList<Node> nodes;
|
||||||
|
private ArrayList<Node> nodesToUpdateAct;
|
||||||
|
private ArrayList<Node> nodesToUpdateNext;
|
||||||
|
private int version;
|
||||||
|
private int maxCounter = 1000;
|
||||||
|
|
||||||
|
public Model() {
|
||||||
|
this.nodes = new ArrayList<>();
|
||||||
|
this.nodesToUpdateAct = new ArrayList<>();
|
||||||
|
this.nodesToUpdateNext = new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getVersion() {
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T extends Node> T add(T node) {
|
||||||
|
nodes.add(node);
|
||||||
|
node.setModel(this);
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addToUpdateList(Node node) {
|
||||||
|
nodesToUpdateNext.add(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void doStep() throws NodeException {
|
||||||
|
doStep(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void doStep(boolean noise) throws NodeException {
|
||||||
|
int counter = 0;
|
||||||
|
while (!nodesToUpdateNext.isEmpty()) {
|
||||||
|
version++;
|
||||||
|
// swap lists
|
||||||
|
ArrayList<Node> nl = nodesToUpdateNext;
|
||||||
|
nodesToUpdateNext = nodesToUpdateAct;
|
||||||
|
nodesToUpdateAct = nl;
|
||||||
|
|
||||||
|
nodesToUpdateNext.clear();
|
||||||
|
|
||||||
|
if (noise) {
|
||||||
|
Collections.shuffle(nodesToUpdateAct);
|
||||||
|
for (Node n : nodesToUpdateAct) {
|
||||||
|
n.readInputs();
|
||||||
|
n.writeOutputs();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (Node n : nodesToUpdateAct) {
|
||||||
|
n.readInputs();
|
||||||
|
}
|
||||||
|
for (Node n : nodesToUpdateAct) {
|
||||||
|
n.writeOutputs();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (counter++ > maxCounter) {
|
||||||
|
throw new NodeException("seemsToOscillate");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void init() throws NodeException {
|
||||||
|
init(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void init(boolean noise) throws NodeException {
|
||||||
|
nodesToUpdateNext.addAll(nodes);
|
||||||
|
doStep(noise);
|
||||||
|
}
|
||||||
|
}
|
42
src/main/java/de/neemann/digital/Node.java
Normal file
42
src/main/java/de/neemann/digital/Node.java
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
package de.neemann.digital;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author hneemann
|
||||||
|
*/
|
||||||
|
public abstract class Node implements Listener {
|
||||||
|
|
||||||
|
private Model model;
|
||||||
|
private int version;
|
||||||
|
|
||||||
|
public void setModel(Model model) {
|
||||||
|
this.model = model;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void needsUpdate() throws NodeException {
|
||||||
|
if (model == null)
|
||||||
|
throw new NodeException("no model set");
|
||||||
|
|
||||||
|
if (model.getVersion() != version) {
|
||||||
|
model.addToUpdateList(this);
|
||||||
|
version = model.getVersion();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Only read the input!
|
||||||
|
* It is not allowed to write to the outputs!!!
|
||||||
|
*
|
||||||
|
* @throws NodeException
|
||||||
|
*/
|
||||||
|
public abstract void readInputs() throws NodeException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Only write to the output!
|
||||||
|
* It is not allowed to read from the inputs!!!
|
||||||
|
*
|
||||||
|
* @throws NodeException
|
||||||
|
*/
|
||||||
|
public abstract void writeOutputs() throws NodeException;
|
||||||
|
|
||||||
|
}
|
10
src/main/java/de/neemann/digital/NodeException.java
Normal file
10
src/main/java/de/neemann/digital/NodeException.java
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
package de.neemann.digital;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author hneemann
|
||||||
|
*/
|
||||||
|
public class NodeException extends Exception {
|
||||||
|
public NodeException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
}
|
69
src/main/java/de/neemann/digital/ObservableValue.java
Normal file
69
src/main/java/de/neemann/digital/ObservableValue.java
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
package de.neemann.digital;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author hneemann
|
||||||
|
*/
|
||||||
|
public class ObservableValue {
|
||||||
|
|
||||||
|
private final int bits;
|
||||||
|
private int value;
|
||||||
|
private ArrayList<Listener> listeners;
|
||||||
|
|
||||||
|
public ObservableValue(int bits) {
|
||||||
|
this.bits = bits;
|
||||||
|
listeners = new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addListener(Listener listener) throws NodeException {
|
||||||
|
listeners.add(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeListener(Listener listener) {
|
||||||
|
listeners.remove(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void hasChanged() throws NodeException {
|
||||||
|
for (Listener l : listeners) {
|
||||||
|
l.needsUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValue(int value) throws NodeException {
|
||||||
|
if (this.value != value) {
|
||||||
|
this.value = value;
|
||||||
|
hasChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getBits() {
|
||||||
|
return bits;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getValueBits() {
|
||||||
|
return getValueBits(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getValueBits(int value) {
|
||||||
|
return value & (1 << bits) - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void checkBits(ObservableValue value) throws BitsException {
|
||||||
|
if (value.getBits() != bits) {
|
||||||
|
throw new BitsException("needs " + bits + " bits, found " + value.getBits());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "ObservableValue{" +
|
||||||
|
"value=" + value +
|
||||||
|
", bits=" + bits +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
24
src/main/java/de/neemann/digital/basic/And.java
Normal file
24
src/main/java/de/neemann/digital/basic/And.java
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
package de.neemann.digital.basic;
|
||||||
|
|
||||||
|
import de.neemann.digital.ObservableValue;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author hneemann
|
||||||
|
*/
|
||||||
|
public class And extends Function {
|
||||||
|
|
||||||
|
public And(int bits) {
|
||||||
|
super(bits);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int calculate(ArrayList<ObservableValue> inputs) {
|
||||||
|
int f = -1;
|
||||||
|
for (ObservableValue i : inputs) {
|
||||||
|
f &= i.getValue();
|
||||||
|
}
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
}
|
52
src/main/java/de/neemann/digital/basic/Function.java
Normal file
52
src/main/java/de/neemann/digital/basic/Function.java
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
package de.neemann.digital.basic;
|
||||||
|
|
||||||
|
import de.neemann.digital.BitsException;
|
||||||
|
import de.neemann.digital.Node;
|
||||||
|
import de.neemann.digital.NodeException;
|
||||||
|
import de.neemann.digital.ObservableValue;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author hneemann
|
||||||
|
*/
|
||||||
|
public abstract class Function extends Node {
|
||||||
|
|
||||||
|
private final ArrayList<ObservableValue> inputs;
|
||||||
|
private final ObservableValue output;
|
||||||
|
private int value;
|
||||||
|
|
||||||
|
public Function(int bits) {
|
||||||
|
output = new ObservableValue(bits);
|
||||||
|
inputs = new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Function addInput(ObservableValue value) throws BitsException, NodeException {
|
||||||
|
output.checkBits(value);
|
||||||
|
inputs.add(value);
|
||||||
|
value.addListener(this);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeInput(ObservableValue value) {
|
||||||
|
inputs.remove(value);
|
||||||
|
value.removeListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ObservableValue getOutput() {
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void readInputs() throws NodeException {
|
||||||
|
value = calculate(inputs);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeOutputs() throws NodeException {
|
||||||
|
output.setValue(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract int calculate(ArrayList<ObservableValue> inputs);
|
||||||
|
}
|
24
src/main/java/de/neemann/digital/basic/NAnd.java
Normal file
24
src/main/java/de/neemann/digital/basic/NAnd.java
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
package de.neemann.digital.basic;
|
||||||
|
|
||||||
|
import de.neemann.digital.ObservableValue;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author hneemann
|
||||||
|
*/
|
||||||
|
public class NAnd extends Function {
|
||||||
|
|
||||||
|
public NAnd(int bits) {
|
||||||
|
super(bits);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int calculate(ArrayList<ObservableValue> inputs) {
|
||||||
|
int f = -1;
|
||||||
|
for (ObservableValue i : inputs) {
|
||||||
|
f &= i.getValue();
|
||||||
|
}
|
||||||
|
return ~f;
|
||||||
|
}
|
||||||
|
}
|
23
src/main/java/de/neemann/digital/basic/NOr.java
Normal file
23
src/main/java/de/neemann/digital/basic/NOr.java
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
package de.neemann.digital.basic;
|
||||||
|
|
||||||
|
import de.neemann.digital.ObservableValue;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author hneemann
|
||||||
|
*/
|
||||||
|
public class NOr extends Function {
|
||||||
|
public NOr(int bits) {
|
||||||
|
super(bits);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int calculate(ArrayList<ObservableValue> inputs) {
|
||||||
|
int f = 0;
|
||||||
|
for (ObservableValue i : inputs) {
|
||||||
|
f |= i.getValue();
|
||||||
|
}
|
||||||
|
return ~f;
|
||||||
|
}
|
||||||
|
}
|
31
src/main/java/de/neemann/digital/basic/Not.java
Normal file
31
src/main/java/de/neemann/digital/basic/Not.java
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
package de.neemann.digital.basic;
|
||||||
|
|
||||||
|
import de.neemann.digital.Node;
|
||||||
|
import de.neemann.digital.NodeException;
|
||||||
|
import de.neemann.digital.ObservableValue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author hneemann
|
||||||
|
*/
|
||||||
|
public class Not extends Node {
|
||||||
|
|
||||||
|
private final ObservableValue input;
|
||||||
|
private final ObservableValue output;
|
||||||
|
private int value;
|
||||||
|
|
||||||
|
public Not(ObservableValue input) throws NodeException {
|
||||||
|
this.input = input;
|
||||||
|
output = new ObservableValue(input.getBits());
|
||||||
|
input.addListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void readInputs() throws NodeException {
|
||||||
|
value = input.getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeOutputs() throws NodeException {
|
||||||
|
output.setValue(~value);
|
||||||
|
}
|
||||||
|
}
|
24
src/main/java/de/neemann/digital/basic/Or.java
Normal file
24
src/main/java/de/neemann/digital/basic/Or.java
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
package de.neemann.digital.basic;
|
||||||
|
|
||||||
|
import de.neemann.digital.ObservableValue;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author hneemann
|
||||||
|
*/
|
||||||
|
public class Or extends Function {
|
||||||
|
|
||||||
|
public Or(int bits) {
|
||||||
|
super(bits);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int calculate(ArrayList<ObservableValue> inputs) {
|
||||||
|
int f = 0;
|
||||||
|
for (ObservableValue i : inputs) {
|
||||||
|
f |= i.getValue();
|
||||||
|
}
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
}
|
58
src/test/java/de/neemann/digital/FlipFlops.java
Normal file
58
src/test/java/de/neemann/digital/FlipFlops.java
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
package de.neemann.digital;
|
||||||
|
|
||||||
|
import de.neemann.digital.basic.Function;
|
||||||
|
import de.neemann.digital.basic.NAnd;
|
||||||
|
import de.neemann.digital.basic.NOr;
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author hneemann
|
||||||
|
*/
|
||||||
|
public class FlipFlops extends TestCase {
|
||||||
|
|
||||||
|
public void testFlipFlopNOr() throws Exception {
|
||||||
|
ObservableValue r = new ObservableValue(1);
|
||||||
|
ObservableValue s = new ObservableValue(1);
|
||||||
|
|
||||||
|
Model model = new Model();
|
||||||
|
Function a1 = model.add(new NOr(1)).addInput(r);
|
||||||
|
Function a2 = model.add(new NOr(1)).addInput(s);
|
||||||
|
|
||||||
|
a1.addInput(a2.getOutput());
|
||||||
|
a2.addInput(a1.getOutput());
|
||||||
|
|
||||||
|
TestExecuter sc = new TestExecuter(model, true).setInputs(r, s).setOutputs(a1.getOutput(), a2.getOutput());
|
||||||
|
sc.check(0, 1, 1, 0);
|
||||||
|
sc.check(0, 0, 1, 0);
|
||||||
|
sc.check(1, 0, 0, 1);
|
||||||
|
sc.check(0, 0, 0, 1);
|
||||||
|
sc.check(0, 1, 1, 0);
|
||||||
|
sc.check(1, 1, 0, 0); // verbotener Zustand!!
|
||||||
|
r.setValue(0); // gehe aus verbotenem Zustand raus!!!
|
||||||
|
s.setValue(0);
|
||||||
|
model.doStep(true); // geht nur mit noise!
|
||||||
|
|
||||||
|
assertTrue((a1.getOutput().getValueBits() == 1 && a2.getOutput().getValueBits() == 0) || // endzustand ist undefiniert!
|
||||||
|
(a1.getOutput().getValueBits() == 0 && a2.getOutput().getValueBits() == 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testFlipFlopNAnd() throws Exception {
|
||||||
|
ObservableValue r = new ObservableValue(1);
|
||||||
|
ObservableValue s = new ObservableValue(1);
|
||||||
|
|
||||||
|
Model model = new Model();
|
||||||
|
Function a1 = model.add(new NAnd(1)).addInput(r);
|
||||||
|
Function a2 = model.add(new NAnd(1)).addInput(s);
|
||||||
|
|
||||||
|
a1.addInput(a2.getOutput());
|
||||||
|
a2.addInput(a1.getOutput());
|
||||||
|
|
||||||
|
TestExecuter sc = new TestExecuter(model).setInputs(r, s).setOutputs(a1.getOutput(), a2.getOutput());
|
||||||
|
sc.check(1, 0, 0, 1);
|
||||||
|
sc.check(1, 1, 0, 1);
|
||||||
|
sc.check(0, 1, 1, 0);
|
||||||
|
sc.check(1, 1, 1, 0);
|
||||||
|
sc.check(1, 0, 0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
44
src/test/java/de/neemann/digital/TestExecuter.java
Normal file
44
src/test/java/de/neemann/digital/TestExecuter.java
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
package de.neemann.digital;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author hneemann
|
||||||
|
*/
|
||||||
|
public class TestExecuter {
|
||||||
|
|
||||||
|
private final Model model;
|
||||||
|
private ObservableValue[] inputs;
|
||||||
|
private ObservableValue[] outputs;
|
||||||
|
|
||||||
|
public TestExecuter(Model model) throws NodeException {
|
||||||
|
this(model, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TestExecuter(Model model, boolean noise) throws NodeException {
|
||||||
|
this.model = model;
|
||||||
|
model.init(noise);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TestExecuter setInputs(ObservableValue... values) {
|
||||||
|
inputs = values;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TestExecuter setOutputs(ObservableValue... values) {
|
||||||
|
outputs = values;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void check(int... val) throws NodeException {
|
||||||
|
for (int i = 0; i < inputs.length; i++) {
|
||||||
|
inputs[i].setValue(val[i]);
|
||||||
|
}
|
||||||
|
model.doStep();
|
||||||
|
|
||||||
|
for (int i = 0; i < outputs.length; i++) {
|
||||||
|
assertEquals("Value " + i, outputs[i].getValueBits(val[i + inputs.length]), outputs[i].getValueBits());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
29
src/test/java/de/neemann/digital/basic/AndTest.java
Normal file
29
src/test/java/de/neemann/digital/basic/AndTest.java
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
package de.neemann.digital.basic;
|
||||||
|
|
||||||
|
import de.neemann.digital.Model;
|
||||||
|
import de.neemann.digital.ObservableValue;
|
||||||
|
import de.neemann.digital.TestExecuter;
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author hneemann
|
||||||
|
*/
|
||||||
|
public class AndTest extends TestCase {
|
||||||
|
|
||||||
|
public void testAnd() throws Exception {
|
||||||
|
ObservableValue a = new ObservableValue(1);
|
||||||
|
ObservableValue b = new ObservableValue(1);
|
||||||
|
|
||||||
|
|
||||||
|
Model model = new Model();
|
||||||
|
Function and = model.add(new And(1)).addInput(a).addInput(b);
|
||||||
|
|
||||||
|
TestExecuter sc = new TestExecuter(model).setInputs(a, b).setOutputs(and.getOutput());
|
||||||
|
sc.check(0, 0, 0);
|
||||||
|
sc.check(1, 0, 0);
|
||||||
|
sc.check(0, 1, 0);
|
||||||
|
sc.check(1, 1, 1);
|
||||||
|
sc.check(1, 0, 0);
|
||||||
|
sc.check(0, 1, 0);
|
||||||
|
}
|
||||||
|
}
|
28
src/test/java/de/neemann/digital/basic/NAndTest.java
Normal file
28
src/test/java/de/neemann/digital/basic/NAndTest.java
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
package de.neemann.digital.basic;
|
||||||
|
|
||||||
|
import de.neemann.digital.Model;
|
||||||
|
import de.neemann.digital.ObservableValue;
|
||||||
|
import de.neemann.digital.TestExecuter;
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author hneemann
|
||||||
|
*/
|
||||||
|
public class NAndTest extends TestCase {
|
||||||
|
|
||||||
|
public void testAnd() throws Exception {
|
||||||
|
ObservableValue a = new ObservableValue(1);
|
||||||
|
ObservableValue b = new ObservableValue(1);
|
||||||
|
|
||||||
|
Model model = new Model();
|
||||||
|
Function nand = model.add(new NAnd(1)).addInput(a).addInput(b);
|
||||||
|
|
||||||
|
TestExecuter sc = new TestExecuter(model).setInputs(a, b).setOutputs(nand.getOutput());
|
||||||
|
sc.check(0, 0, 1);
|
||||||
|
sc.check(1, 0, 1);
|
||||||
|
sc.check(0, 1, 1);
|
||||||
|
sc.check(1, 1, 0);
|
||||||
|
sc.check(1, 0, 1);
|
||||||
|
sc.check(0, 1, 1);
|
||||||
|
}
|
||||||
|
}
|
29
src/test/java/de/neemann/digital/basic/NOrTest.java
Normal file
29
src/test/java/de/neemann/digital/basic/NOrTest.java
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
package de.neemann.digital.basic;
|
||||||
|
|
||||||
|
import de.neemann.digital.Model;
|
||||||
|
import de.neemann.digital.ObservableValue;
|
||||||
|
import de.neemann.digital.TestExecuter;
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author hneemann
|
||||||
|
*/
|
||||||
|
public class NOrTest extends TestCase {
|
||||||
|
|
||||||
|
public void testNOr() throws Exception {
|
||||||
|
ObservableValue a = new ObservableValue(1);
|
||||||
|
ObservableValue b = new ObservableValue(1);
|
||||||
|
|
||||||
|
Model model = new Model();
|
||||||
|
Function nor = model.add(new NOr(1)).addInput(a).addInput(b);
|
||||||
|
|
||||||
|
TestExecuter sc = new TestExecuter(model).setInputs(a, b).setOutputs(nor.getOutput());
|
||||||
|
sc.check(0, 0, 1);
|
||||||
|
sc.check(1, 0, 0);
|
||||||
|
sc.check(0, 1, 0);
|
||||||
|
sc.check(1, 1, 0);
|
||||||
|
sc.check(1, 0, 0);
|
||||||
|
sc.check(0, 1, 0);
|
||||||
|
sc.check(0, 0, 1);
|
||||||
|
}
|
||||||
|
}
|
29
src/test/java/de/neemann/digital/basic/OrTest.java
Normal file
29
src/test/java/de/neemann/digital/basic/OrTest.java
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
package de.neemann.digital.basic;
|
||||||
|
|
||||||
|
import de.neemann.digital.Model;
|
||||||
|
import de.neemann.digital.ObservableValue;
|
||||||
|
import de.neemann.digital.TestExecuter;
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author hneemann
|
||||||
|
*/
|
||||||
|
public class OrTest extends TestCase {
|
||||||
|
|
||||||
|
public void testOr() throws Exception {
|
||||||
|
ObservableValue a = new ObservableValue(1);
|
||||||
|
ObservableValue b = new ObservableValue(1);
|
||||||
|
|
||||||
|
Model model = new Model();
|
||||||
|
Function and = model.add(new Or(1)).addInput(a).addInput(b);
|
||||||
|
|
||||||
|
TestExecuter sc = new TestExecuter(model).setInputs(a, b).setOutputs(and.getOutput());
|
||||||
|
sc.check(0, 0, 0);
|
||||||
|
sc.check(1, 0, 1);
|
||||||
|
sc.check(0, 1, 1);
|
||||||
|
sc.check(1, 1, 1);
|
||||||
|
sc.check(1, 0, 1);
|
||||||
|
sc.check(0, 1, 1);
|
||||||
|
sc.check(0, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user