mirror of
https://github.com/hneemann/Digital.git
synced 2025-09-19 01:44:44 -04:00
Refactoring of passing data from the model to the generators. See #108
This commit is contained in:
parent
856f78bf88
commit
2080fe57b9
@ -34,6 +34,7 @@ public class ModelAnalyser {
|
||||
private final ArrayList<Signal> inputs;
|
||||
private final ArrayList<Signal> outputs;
|
||||
private int uniqueIndex = 0;
|
||||
private ModelAnalyserInfo modelAnalyzerInfo;
|
||||
|
||||
/**
|
||||
* Creates a new instance
|
||||
@ -96,6 +97,12 @@ public class ModelAnalyser {
|
||||
throw new AnalyseException(Lang.get("err_analyseNoInputs"));
|
||||
if (outputs.size() == 0)
|
||||
throw new AnalyseException(Lang.get("err_analyseNoOutputs"));
|
||||
|
||||
modelAnalyzerInfo = new ModelAnalyserInfo(model, inputs, outputs);
|
||||
}
|
||||
|
||||
private ModelAnalyserInfo getModelAnalyzerInfo() {
|
||||
return modelAnalyzerInfo;
|
||||
}
|
||||
|
||||
private String createUniqueName(FlipflopD ff) {
|
||||
@ -332,17 +339,15 @@ public class ModelAnalyser {
|
||||
public TruthTable analyse() throws NodeException, PinException, BacktrackException, AnalyseException {
|
||||
LOGGER.debug("start to analyse the model...");
|
||||
|
||||
TruthTable tt = new TruthTable().setPinsWithoutNumber(model.getPinsWithoutNumber());
|
||||
TruthTable tt = new TruthTable();
|
||||
tt.setModelAnalyzerInfo(getModelAnalyzerInfo());
|
||||
for (Signal s : inputs)
|
||||
tt.addVariable(s.getName());
|
||||
|
||||
for (Signal s : inputs)
|
||||
tt.addPinNumber(s);
|
||||
getModelAnalyzerInfo().addPinNumber(s);
|
||||
for (Signal s : outputs)
|
||||
tt.addPinNumber(s);
|
||||
|
||||
if (model.getClocks().size() == 1)
|
||||
tt.setClockPin(model.getClocks().get(0).getClockPin());
|
||||
getModelAnalyzerInfo().addPinNumber(s);
|
||||
|
||||
DependencyAnalyser da = new DependencyAnalyser(this);
|
||||
long steps = da.getRequiredSteps(this);
|
||||
|
@ -0,0 +1,93 @@
|
||||
package de.neemann.digital.analyse;
|
||||
|
||||
import de.neemann.digital.core.Model;
|
||||
import de.neemann.digital.core.NodeException;
|
||||
import de.neemann.digital.core.Signal;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.TreeMap;
|
||||
|
||||
/**
|
||||
* Additional infos obtained from the model
|
||||
*/
|
||||
public class ModelAnalyserInfo {
|
||||
private final String clockPin;
|
||||
private final TreeMap<String, String> pins;
|
||||
private final ArrayList<Signal> inputs;
|
||||
private final ArrayList<Signal> outputs;
|
||||
private ArrayList<String> pinsWithoutNumber;
|
||||
|
||||
/**
|
||||
* creates a new instance
|
||||
*
|
||||
* @param model the model used
|
||||
* @param inputs input singnales
|
||||
* @param outputs output signals
|
||||
*/
|
||||
ModelAnalyserInfo(Model model, ArrayList<Signal> inputs, ArrayList<Signal> outputs) {
|
||||
this.inputs = inputs;
|
||||
this.outputs = outputs;
|
||||
pins = new TreeMap<>();
|
||||
|
||||
if (model.getClocks().size() == 1)
|
||||
clockPin = model.getClocks().get(0).getClockPin();
|
||||
else
|
||||
clockPin = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the signals pin number to the table
|
||||
*
|
||||
* @param s the signal
|
||||
* @throws NodeException NodeException
|
||||
*/
|
||||
public void addPinNumber(Signal s) throws NodeException {
|
||||
String p = s.getPinNumber();
|
||||
if (p != null && p.length() > 0) pins.put(s.getName(), p);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the assigned pins
|
||||
*/
|
||||
public TreeMap<String, String> getPins() {
|
||||
return pins;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return list of pins without a number. Never null, maybe a empty list
|
||||
*/
|
||||
public ArrayList<String> getPinsWithoutNumber() {
|
||||
if (pinsWithoutNumber == null) {
|
||||
pinsWithoutNumber = new ArrayList<>();
|
||||
for (Signal s : inputs)
|
||||
if (s.missingPinNumber())
|
||||
pinsWithoutNumber.add((s.getName()));
|
||||
for (Signal s : outputs)
|
||||
if (s.missingPinNumber())
|
||||
pinsWithoutNumber.add((s.getName()));
|
||||
}
|
||||
return pinsWithoutNumber;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the clock pin
|
||||
*/
|
||||
public String getClockPin() {
|
||||
return clockPin;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the clock pin
|
||||
*/
|
||||
public int getClockPinInt() {
|
||||
if (clockPin == null || clockPin.length() == 0)
|
||||
return 0;
|
||||
|
||||
try {
|
||||
return Integer.parseInt(clockPin);
|
||||
} catch (NumberFormatException e) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -10,13 +10,10 @@ import de.neemann.digital.analyse.expression.Variable;
|
||||
import de.neemann.digital.analyse.quinemc.BoolTable;
|
||||
import de.neemann.digital.analyse.quinemc.BoolTableByteArray;
|
||||
import de.neemann.digital.analyse.quinemc.ThreeStateValue;
|
||||
import de.neemann.digital.core.NodeException;
|
||||
import de.neemann.digital.core.Signal;
|
||||
import de.neemann.digital.lang.Lang;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.TreeMap;
|
||||
|
||||
/**
|
||||
* The description of a truth table.
|
||||
@ -27,10 +24,8 @@ public class TruthTable {
|
||||
|
||||
private final ArrayList<Variable> variables;
|
||||
private final ArrayList<Result> results;
|
||||
private final TreeMap<String, String> pins;
|
||||
private transient BitSetter bitSetter;
|
||||
private ArrayList<String> pinsWithoutNumber = null;
|
||||
private String clockPin;
|
||||
private transient ModelAnalyserInfo modelAnalyzerInfo;
|
||||
|
||||
/**
|
||||
* Load the given file and returns a truth table instance
|
||||
@ -134,7 +129,6 @@ public class TruthTable {
|
||||
public TruthTable(ArrayList<Variable> vars) {
|
||||
this.variables = vars;
|
||||
results = new ArrayList<>();
|
||||
pins = new TreeMap<>();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -470,70 +464,21 @@ public class TruthTable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the signals pin number to the table
|
||||
* Sets additional data obtained from the model
|
||||
*
|
||||
* @param s the signal
|
||||
* @throws NodeException NodeException
|
||||
* @param modelAnalyzerInfo the data obtained from the model
|
||||
*/
|
||||
public void addPinNumber(Signal s) throws NodeException {
|
||||
String p = s.getPinNumber();
|
||||
if (p != null && p.length() > 0) pins.put(s.getName(), p);
|
||||
public void setModelAnalyzerInfo(ModelAnalyserInfo modelAnalyzerInfo) {
|
||||
this.modelAnalyzerInfo = modelAnalyzerInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the assigned pins
|
||||
*/
|
||||
public TreeMap<String, String> getPins() {
|
||||
return pins;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the missing pin number flag
|
||||
* returns additional model infos
|
||||
*
|
||||
* @param pinsWithoutNumber list of pins without a number or null
|
||||
* @return this for chained calls
|
||||
* @return infos obtained from the analysed model, maybe null
|
||||
*/
|
||||
public TruthTable setPinsWithoutNumber(ArrayList<String> pinsWithoutNumber) {
|
||||
this.pinsWithoutNumber = pinsWithoutNumber;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return list of pins without a number or null
|
||||
*/
|
||||
public ArrayList<String> getPinsWithoutNumber() {
|
||||
return pinsWithoutNumber;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the clock pin
|
||||
*
|
||||
* @param clockPin the clock pin
|
||||
*/
|
||||
public void setClockPin(String clockPin) {
|
||||
this.clockPin = clockPin;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the clock pin
|
||||
*/
|
||||
public String getClockPin() {
|
||||
return clockPin;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the clock pin
|
||||
*/
|
||||
public int getClockPinInt() {
|
||||
if (clockPin == null || clockPin.length() == 0)
|
||||
return 0;
|
||||
|
||||
try {
|
||||
return Integer.parseInt(clockPin);
|
||||
} catch (NumberFormatException e) {
|
||||
return 0;
|
||||
}
|
||||
public ModelAnalyserInfo getModelAnalyzerInfo() {
|
||||
return modelAnalyzerInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,6 +1,7 @@
|
||||
package de.neemann.digital.builder.circuit;
|
||||
|
||||
import de.neemann.digital.analyse.DetermineJKStateMachine;
|
||||
import de.neemann.digital.analyse.ModelAnalyserInfo;
|
||||
import de.neemann.digital.analyse.expression.*;
|
||||
import de.neemann.digital.analyse.expression.Not;
|
||||
import de.neemann.digital.analyse.expression.format.FormatterException;
|
||||
@ -410,13 +411,14 @@ public class CircuitBuilder implements BuilderInterface<CircuitBuilder> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the pin mapping
|
||||
* Sets the infos obtained from the model
|
||||
*
|
||||
* @param pins the pin mapping
|
||||
* @param modelAnalyserInfo the model analyzer infos
|
||||
* @return this for chained calls
|
||||
*/
|
||||
public CircuitBuilder setPins(TreeMap<String, String> pins) {
|
||||
this.pins = pins;
|
||||
public CircuitBuilder setModelAnalyzerInfo(ModelAnalyserInfo modelAnalyserInfo) {
|
||||
if (modelAnalyserInfo != null)
|
||||
this.pins = modelAnalyserInfo.getPins();
|
||||
return this;
|
||||
|
||||
}
|
||||
|
@ -621,19 +621,6 @@ public class Model implements Iterable<Node> {
|
||||
return found;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return list of pins without a number
|
||||
*/
|
||||
public ArrayList<String> getPinsWithoutNumber() {
|
||||
ArrayList<String> sigWithoutPinNumber = null;
|
||||
for (Signal s : signals)
|
||||
if (s.missingPinNumber()) {
|
||||
if (sigWithoutPinNumber == null) sigWithoutPinNumber = new ArrayList<>();
|
||||
sigWithoutPinNumber.add(s.getName());
|
||||
}
|
||||
return sigWithoutPinNumber;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a button which is to map to a keyboard key
|
||||
*
|
||||
|
@ -22,9 +22,6 @@ import de.neemann.digital.builder.Gal16v8.Gal16v8JEDECExporter;
|
||||
import de.neemann.digital.builder.Gal22v10.Gal22v10CuplExporter;
|
||||
import de.neemann.digital.builder.Gal22v10.Gal22v10JEDECExporter;
|
||||
import de.neemann.digital.builder.circuit.CircuitBuilder;
|
||||
import de.neemann.digital.gui.components.table.hardware.GenerateCUPL;
|
||||
import de.neemann.digital.gui.components.table.hardware.GenerateFile;
|
||||
import de.neemann.digital.gui.components.table.hardware.HardwareDescriptionGenerator;
|
||||
import de.neemann.digital.core.element.ElementAttributes;
|
||||
import de.neemann.digital.core.element.Key;
|
||||
import de.neemann.digital.core.element.Keys;
|
||||
@ -36,6 +33,9 @@ import de.neemann.digital.gui.SaveAsHelper;
|
||||
import de.neemann.digital.gui.components.AttributeDialog;
|
||||
import de.neemann.digital.gui.components.ElementOrderer;
|
||||
import de.neemann.digital.gui.components.karnaugh.KarnaughMapDialog;
|
||||
import de.neemann.digital.gui.components.table.hardware.GenerateCUPL;
|
||||
import de.neemann.digital.gui.components.table.hardware.GenerateFile;
|
||||
import de.neemann.digital.gui.components.table.hardware.HardwareDescriptionGenerator;
|
||||
import de.neemann.digital.lang.Lang;
|
||||
import de.neemann.gui.ErrorMessage;
|
||||
import de.neemann.gui.MyFileChooser;
|
||||
@ -53,8 +53,10 @@ import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.prefs.Preferences;
|
||||
|
||||
/**
|
||||
@ -67,7 +69,6 @@ public class TableDialog extends JDialog {
|
||||
|
||||
static {
|
||||
LIST.add(Keys.LABEL);
|
||||
LIST.add(Keys.PINNUMBER);
|
||||
}
|
||||
|
||||
private final JTextPane statusBar;
|
||||
@ -248,17 +249,9 @@ public class TableDialog extends JDialog {
|
||||
ElementAttributes attr = new ElementAttributes();
|
||||
final String name = model.getColumnName(columnIndex);
|
||||
attr.set(Keys.LABEL, name);
|
||||
final TreeMap<String, String> pins = model.getTable().getPins();
|
||||
if (pins.containsKey(name))
|
||||
attr.set(Keys.PINNUMBER, pins.get(name));
|
||||
ElementAttributes modified = new AttributeDialog(this, pos, LIST, attr).showDialog();
|
||||
if (modified != null) {
|
||||
pins.remove(name);
|
||||
final String newName = modified.get(Keys.LABEL).trim().replace(' ', '_');
|
||||
final String pinStr = modified.get(Keys.PINNUMBER).trim();
|
||||
if (pinStr.length() > 0)
|
||||
pins.put(newName, pinStr);
|
||||
|
||||
if (!newName.equals(name))
|
||||
model.setColumnName(columnIndex, newName);
|
||||
}
|
||||
@ -493,7 +486,7 @@ public class TableDialog extends JDialog {
|
||||
private void createCircuit(boolean useJKff, ExpressionModifier... modifier) {
|
||||
try {
|
||||
CircuitBuilder circuitBuilder = new CircuitBuilder(shapeFactory, useJKff, model.getTable().getVars())
|
||||
.setPins(model.getTable().getPins());
|
||||
.setModelAnalyzerInfo(model.getTable().getModelAnalyzerInfo());
|
||||
new BuilderExpressionCreator(circuitBuilder, modifier)
|
||||
.setUseJKOptimizer(useJKff)
|
||||
.create(lastGeneratedExpressions);
|
||||
|
@ -1,5 +1,6 @@
|
||||
package de.neemann.digital.gui.components.table.hardware;
|
||||
|
||||
import de.neemann.digital.analyse.ModelAnalyserInfo;
|
||||
import de.neemann.digital.analyse.TruthTable;
|
||||
import de.neemann.digital.analyse.expression.modify.ExpressionModifier;
|
||||
import de.neemann.digital.builder.Gal16v8.CuplExporter;
|
||||
@ -74,7 +75,9 @@ public class GenerateCUPL implements HardwareDescriptionGenerator {
|
||||
File f = new File(cuplPath, "CUPL.PLD");
|
||||
CuplExporter cuplExporter = cuplExporterFactory.create();
|
||||
cuplExporter.setProjectName(circuitFile.getName());
|
||||
cuplExporter.getPinMapping().addAll(table.getPins());
|
||||
final ModelAnalyserInfo modelAnalyzerInfo = table.getModelAnalyzerInfo();
|
||||
if (modelAnalyzerInfo != null)
|
||||
cuplExporter.getPinMapping().addAll(modelAnalyzerInfo.getPins());
|
||||
new BuilderExpressionCreator(cuplExporter.getBuilder(), ExpressionModifier.IDENTITY).create(expressions);
|
||||
try (FileOutputStream out = new FileOutputStream(f)) {
|
||||
cuplExporter.writeTo(out);
|
||||
|
@ -1,5 +1,6 @@
|
||||
package de.neemann.digital.gui.components.table.hardware;
|
||||
|
||||
import de.neemann.digital.analyse.ModelAnalyserInfo;
|
||||
import de.neemann.digital.analyse.TruthTable;
|
||||
import de.neemann.digital.analyse.expression.modify.ExpressionModifier;
|
||||
import de.neemann.digital.builder.ExpressionToFileExporter;
|
||||
@ -52,16 +53,24 @@ public class GenerateFile implements HardwareDescriptionGenerator {
|
||||
|
||||
@Override
|
||||
public void generate(JDialog parent, File circuitFile, TruthTable table, ExpressionListenerStore expressions) throws Exception {
|
||||
|
||||
ArrayList<String> pinsWithoutNumber = table.getPinsWithoutNumber();
|
||||
if (pinsWithoutNumber != null) {
|
||||
int res = JOptionPane.showConfirmDialog(parent,
|
||||
new LineBreaker().toHTML().breakLines(Lang.get("msg_thereAreMissingPinNumbers", pinsWithoutNumber)),
|
||||
ModelAnalyserInfo mai = table.getModelAnalyzerInfo();
|
||||
if (mai == null) {
|
||||
JOptionPane.showMessageDialog(parent,
|
||||
new LineBreaker().toHTML().breakLines(Lang.get("msg_circuitIsRequired")),
|
||||
Lang.get("msg_warning"),
|
||||
JOptionPane.OK_CANCEL_OPTION,
|
||||
JOptionPane.WARNING_MESSAGE);
|
||||
if (res != JOptionPane.OK_OPTION)
|
||||
return;
|
||||
return;
|
||||
} else {
|
||||
ArrayList<String> pinsWithoutNumber = mai.getPinsWithoutNumber();
|
||||
if (!pinsWithoutNumber.isEmpty()) {
|
||||
int res = JOptionPane.showConfirmDialog(parent,
|
||||
new LineBreaker().toHTML().breakLines(Lang.get("msg_thereAreMissingPinNumbers", pinsWithoutNumber)),
|
||||
Lang.get("msg_warning"),
|
||||
JOptionPane.OK_CANCEL_OPTION,
|
||||
JOptionPane.WARNING_MESSAGE);
|
||||
if (res != JOptionPane.OK_OPTION)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (circuitFile == null)
|
||||
@ -74,8 +83,8 @@ public class GenerateFile implements HardwareDescriptionGenerator {
|
||||
fileChooser.setSelectedFile(circuitFile);
|
||||
if (fileChooser.showSaveDialog(parent) == JFileChooser.APPROVE_OPTION) {
|
||||
ExpressionToFileExporter expressionExporter = factory.create();
|
||||
expressionExporter.getPinMapping().addAll(table.getPins());
|
||||
expressionExporter.getPinMapping().setClockPin(table.getClockPinInt());
|
||||
expressionExporter.getPinMapping().addAll(mai.getPins());
|
||||
expressionExporter.getPinMapping().setClockPin(mai.getClockPinInt());
|
||||
new BuilderExpressionCreator(expressionExporter.getBuilder(), ExpressionModifier.IDENTITY).create(expressions);
|
||||
expressionExporter.export(SaveAsHelper.checkSuffix(fileChooser.getSelectedFile(), suffix));
|
||||
}
|
||||
|
@ -1285,6 +1285,8 @@ eine <a href="https://github.com/hneemann/Digital/issues/new?labels=enha
|
||||
<string name="msg_create CHNFile">Erzeugen der CHN-Datei</string>
|
||||
<string name="msg_tableHasManyRowsConfirm">Die Tabelle ist sehr groß, der Export kann etwas dauern.
|
||||
Soll dennoch exportiert werden?</string>
|
||||
<string name="msg_circuitIsRequired">Um eine Hardwarebeschreibung zu erzeugen, muss zuvor eine Schaltung erstellt
|
||||
und analysiert werden. Aus nur einer Wahrheitstabelle kann keine Hardwarebeschreibung erzeugt werden.</string>
|
||||
|
||||
<string name="ok">Ok</string>
|
||||
<string name="rot_0">0°</string>
|
||||
|
@ -1272,6 +1272,8 @@ an <a href="https://github.com/hneemann/Digital/issues/new?labels=enhanc
|
||||
<string name="msg_create CHNFile">Creation of CHN file.</string>
|
||||
<string name="msg_tableHasManyRowsConfirm">The table is very large, the export may take a while.
|
||||
Start export anyway?</string>
|
||||
<string name="msg_circuitIsRequired">To create a hardware description, a circuit must first be created and analyzed.
|
||||
A standalone truth table can not be used to generate a hardware description.</string>
|
||||
|
||||
<string name="ok">Ok</string>
|
||||
<string name="rot_0">0°</string>
|
||||
|
@ -128,7 +128,7 @@ public class ModelAnalyserTest extends TestCase {
|
||||
TruthTable tt = new ModelAnalyser(model).analyse();
|
||||
checkIdent(tt);
|
||||
|
||||
TreeMap<String, String> p = tt.getPins();
|
||||
TreeMap<String, String> p = tt.getModelAnalyzerInfo().getPins();
|
||||
assertEquals("i1",p.get("A0"));
|
||||
assertEquals("i2",p.get("A1"));
|
||||
assertEquals("o1",p.get("B0"));
|
||||
|
Loading…
x
Reference in New Issue
Block a user