created test case description handles multi bit signals correctly, see #351

This commit is contained in:
hneemann 2019-09-28 21:35:14 +02:00
parent 8a75744578
commit dccf93db85
4 changed files with 280 additions and 23 deletions

View File

@ -5,55 +5,113 @@
*/
package de.neemann.digital.analyse.format;
import de.neemann.digital.analyse.ModelAnalyserInfo;
import de.neemann.digital.analyse.TruthTable;
import de.neemann.digital.analyse.expression.ContextFiller;
import de.neemann.digital.analyse.expression.ExpressionException;
import de.neemann.digital.analyse.expression.Variable;
import de.neemann.digital.analyse.quinemc.ThreeStateValue;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
/**
* Creates a test case which represents the truth table
*/
public class TruthTableFormatterTestCase implements TruthTableFormatter {
private enum Type {NORMAL, FIRSTBIN, BIN}
private final HashMap<String, ArrayList<String>> inputBusMap;
private final HashMap<String, ArrayList<String>> outputBusMap;
/**
* Creates a new instance.
*
* @param modelAnalyzerInfo the information about the usage of multi bit signals
*/
public TruthTableFormatterTestCase(ModelAnalyserInfo modelAnalyzerInfo) {
if (modelAnalyzerInfo == null) {
inputBusMap = new HashMap<>();
outputBusMap = new HashMap<>();
} else {
inputBusMap = modelAnalyzerInfo.getInputBusMap();
outputBusMap = modelAnalyzerInfo.getOutputBusMap();
}
}
@Override
public String format(TruthTable truthTable) throws ExpressionException {
StringBuilder sb = new StringBuilder();
for (Variable v : truthTable.getVars())
sb.append(v.getIdentifier()).append(" ");
for (int i = 0; i < truthTable.getResultCount(); i++) {
sb.append(truthTable.getResultName(i));
if (i < truthTable.getResultCount() - 1)
sb.append(" ");
}
ArrayList<String> inputs = new ArrayList<>();
for (Variable v : truthTable.getVars())
inputs.add(v.getIdentifier());
ArrayList<Type> inputOutType = outVars(sb, inputs, inputBusMap);
ArrayList<String> outputs = new ArrayList<>();
for (int i = 0; i < truthTable.getResultCount(); i++)
outputs.add(truthTable.getResultName(i));
ArrayList<Type> outputOutType = outVars(sb, outputs, outputBusMap);
sb.append("\n\n");
ContextFiller cf = new ContextFiller(truthTable.getVars());
for (int i = 0; i < cf.getRowCount(); i++) {
cf.setContextTo(i);
for (Variable v : cf) {
sb.append(format(cf.get(v)));
for (int j = 0; j < v.getIdentifier().length(); j++)
sb.append(" ");
}
int ind = 0;
for (Variable v : cf)
outValue(sb, inputOutType.get(ind++), ThreeStateValue.value(cf.get(v)));
for (int j = 0; j < truthTable.getResultCount(); j++) {
ThreeStateValue r = truthTable.getResult(j).get(i);
sb.append(format(r));
if (j < truthTable.getResultCount() - 1)
for (int k = 0; k < truthTable.getResultName(j).length(); k++)
sb.append(" ");
}
ind = 0;
for (int j = 0; j < truthTable.getResultCount(); j++)
outValue(sb, outputOutType.get(ind++), truthTable.getResult(j).get(i));
sb.append("\n");
}
return sb.toString();
}
private String format(boolean b) {
return format(ThreeStateValue.value(b));
private void outValue(StringBuilder sb, Type type, ThreeStateValue b) {
switch (type) {
case NORMAL:
sb.append(" ").append(formatValue(b));
break;
case FIRSTBIN:
sb.append(" 0b").append(formatValue(b));
break;
case BIN:
sb.append(formatValue(b));
break;
}
}
private String format(ThreeStateValue r) {
private ArrayList<Type> outVars(StringBuilder sb, ArrayList<String> vars, HashMap<String, ArrayList<String>> busMap) {
ArrayList<Type> types = new ArrayList<>(vars.size());
HashMap<String, String> map = new HashMap<>();
for (Map.Entry<String, ArrayList<String>> e : busMap.entrySet()) {
String last = null;
for (String s : e.getValue()) {
map.put(s, "");
last = s;
}
map.put(last, e.getKey());
}
for (String n : vars) {
String r = map.get(n);
if (r == null) {
sb.append(n).append(" ");
types.add(Type.NORMAL);
} else if (!r.isEmpty()) {
sb.append(r).append(" ");
types.add(Type.FIRSTBIN);
} else
types.add(Type.BIN);
}
return types;
}
private String formatValue(ThreeStateValue r) {
switch (r) {
case one:
return "1";

View File

@ -427,7 +427,7 @@ public class TableDialog extends JDialog {
@Override
public void actionPerformed(ActionEvent e) {
try {
TruthTableFormatter test = new TruthTableFormatterTestCase();
TruthTableFormatter test = new TruthTableFormatterTestCase(undoManager.getActual().getModelAnalyzerInfo());
String testCase = test.format(undoManager.getActual());
new ShowStringDialog(TableDialog.this, Lang.get("win_table_exportDialog"),
testCase).setVisible(true);

View File

@ -0,0 +1,73 @@
/*
* Copyright (c) 2019 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.analyse.format;
import de.neemann.digital.analyse.ModelAnalyser;
import de.neemann.digital.analyse.TruthTable;
import de.neemann.digital.core.Model;
import de.neemann.digital.integration.ToBreakRunner;
import junit.framework.TestCase;
public class TruthTableFormatterTestCaseTest extends TestCase {
public void testFormat() throws Exception {
TruthTable tt = new TruthTable(3);
tt.addResult("Y_0");
tt.addResult("Y_1");
assertEquals("A B C Y_0 Y_1 \n" +
"\n" +
" 0 0 0 0 0\n" +
" 0 0 1 0 0\n" +
" 0 1 0 0 0\n" +
" 0 1 1 0 0\n" +
" 1 0 0 0 0\n" +
" 1 0 1 0 0\n" +
" 1 1 0 0 0\n" +
" 1 1 1 0 0\n", new TruthTableFormatterTestCase(null).format(tt));
}
public void testBus() throws Exception {
Model m = new ToBreakRunner("dig/analyze/testCaseCreation.dig").getModel();
TruthTable tt = new ModelAnalyser(m).analyse();
assertEquals("b a C_i C_o S \n" +
"\n" +
" 0b00 0b00 0 0 0b00\n" +
" 0b00 0b00 1 0 0b01\n" +
" 0b00 0b01 0 0 0b01\n" +
" 0b00 0b01 1 0 0b10\n" +
" 0b00 0b10 0 0 0b10\n" +
" 0b00 0b10 1 0 0b11\n" +
" 0b00 0b11 0 0 0b11\n" +
" 0b00 0b11 1 1 0b00\n" +
" 0b01 0b00 0 0 0b01\n" +
" 0b01 0b00 1 0 0b10\n" +
" 0b01 0b01 0 0 0b10\n" +
" 0b01 0b01 1 0 0b11\n" +
" 0b01 0b10 0 0 0b11\n" +
" 0b01 0b10 1 1 0b00\n" +
" 0b01 0b11 0 1 0b00\n" +
" 0b01 0b11 1 1 0b01\n" +
" 0b10 0b00 0 0 0b10\n" +
" 0b10 0b00 1 0 0b11\n" +
" 0b10 0b01 0 0 0b11\n" +
" 0b10 0b01 1 1 0b00\n" +
" 0b10 0b10 0 1 0b00\n" +
" 0b10 0b10 1 1 0b01\n" +
" 0b10 0b11 0 1 0b01\n" +
" 0b10 0b11 1 1 0b10\n" +
" 0b11 0b00 0 0 0b11\n" +
" 0b11 0b00 1 1 0b00\n" +
" 0b11 0b01 0 1 0b00\n" +
" 0b11 0b01 1 1 0b01\n" +
" 0b11 0b10 0 1 0b01\n" +
" 0b11 0b10 1 1 0b10\n" +
" 0b11 0b11 0 1 0b10\n" +
" 0b11 0b11 1 1 0b11\n", new TruthTableFormatterTestCase(tt.getModelAnalyzerInfo()).format(tt));
}
}

View File

@ -0,0 +1,126 @@
<?xml version="1.0" encoding="utf-8"?>
<circuit>
<version>1</version>
<attributes/>
<visualElements>
<visualElement>
<elementName>Add</elementName>
<elementAttributes>
<entry>
<string>Bits</string>
<int>2</int>
</entry>
</elementAttributes>
<pos x="280" y="200"/>
</visualElement>
<visualElement>
<elementName>Out</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>C_o</string>
</entry>
</elementAttributes>
<pos x="380" y="240"/>
</visualElement>
<visualElement>
<elementName>Out</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>S</string>
</entry>
<entry>
<string>Bits</string>
<int>2</int>
</entry>
</elementAttributes>
<pos x="380" y="200"/>
</visualElement>
<visualElement>
<elementName>In</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>b</string>
</entry>
<entry>
<string>Bits</string>
<int>2</int>
</entry>
</elementAttributes>
<pos x="240" y="220"/>
</visualElement>
<visualElement>
<elementName>In</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>a</string>
</entry>
<entry>
<string>Bits</string>
<int>2</int>
</entry>
</elementAttributes>
<pos x="240" y="180"/>
</visualElement>
<visualElement>
<elementName>In</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>C_i</string>
</entry>
</elementAttributes>
<pos x="240" y="260"/>
</visualElement>
</visualElements>
<wires>
<wire>
<p1 x="360" y="240"/>
<p2 x="380" y="240"/>
</wire>
<wire>
<p1 x="260" y="240"/>
<p2 x="280" y="240"/>
</wire>
<wire>
<p1 x="240" y="180"/>
<p2 x="260" y="180"/>
</wire>
<wire>
<p1 x="240" y="260"/>
<p2 x="260" y="260"/>
</wire>
<wire>
<p1 x="340" y="200"/>
<p2 x="380" y="200"/>
</wire>
<wire>
<p1 x="260" y="200"/>
<p2 x="280" y="200"/>
</wire>
<wire>
<p1 x="340" y="220"/>
<p2 x="360" y="220"/>
</wire>
<wire>
<p1 x="240" y="220"/>
<p2 x="280" y="220"/>
</wire>
<wire>
<p1 x="260" y="180"/>
<p2 x="260" y="200"/>
</wire>
<wire>
<p1 x="260" y="240"/>
<p2 x="260" y="260"/>
</wire>
<wire>
<p1 x="360" y="220"/>
<p2 x="360" y="240"/>
</wire>
</wires>
<measurementOrdering/>
</circuit>