use of de.neemann.digital.analyse.expression.format.FormatterException in project Digital by hneemann.
the class CircuitBuilder method addSequential.
/**
* Add a transition function of a state machine
*
* @param name name of the state
* @param expression the expression describing next state
* @return this for chained calls
* @throws BuilderException BuilderException
*/
@Override
public CircuitBuilder addSequential(String name, Expression expression) throws BuilderException {
boolean useDff = true;
if (useJKff) {
try {
DetermineJKStateMachine jk = new DetermineJKStateMachine(name, expression);
useDff = jk.isDFF();
if (!useDff) {
boolean isJequalK = new Equals(jk.getSimplifiedJ(), jk.getSimplifiedK()).isEqual();
if (isJequalK) {
Fragment frJ = createFragment(jk.getSimplifiedJ());
FragmentVisualElement ff = new FragmentVisualElement(FlipflopJK.DESCRIPTION, shapeFactory).ignoreInput(1).setAttr(Keys.LABEL, name);
flipflops.add(ff);
FragmentSameInValue fsv = new FragmentSameInValue(ff);
FragmentExpression fe = new FragmentExpression(fsv, new FragmentVisualElement(Tunnel.DESCRIPTION, shapeFactory).setAttr(Keys.NETNAME, name));
fragments.add(new FragmentExpression(frJ, fe));
} else {
Fragment frJ = createFragment(jk.getSimplifiedJ());
Fragment frK = createFragment(jk.getSimplifiedK());
FragmentVisualElement ff = new FragmentVisualElement(FlipflopJK.DESCRIPTION, shapeFactory).ignoreInput(1).setAttr(Keys.LABEL, name);
flipflops.add(ff);
FragmentExpression fe = new FragmentExpression(ff, new FragmentVisualElement(Tunnel.DESCRIPTION, shapeFactory).setAttr(Keys.NETNAME, name));
fragments.add(new FragmentExpression(Arrays.asList(frJ, frK), fe));
}
}
} catch (ExpressionException | FormatterException e) {
throw new BuilderException(e.getMessage());
}
}
if (useDff) {
Fragment fr = createFragment(expression);
FragmentVisualElement ff = new FragmentVisualElement(FlipflopD.DESCRIPTION, shapeFactory).setAttr(Keys.LABEL, name);
flipflops.add(ff);
FragmentExpression fe = new FragmentExpression(ff, new FragmentVisualElement(Tunnel.DESCRIPTION, shapeFactory).setAttr(Keys.NETNAME, name));
fragments.add(new FragmentExpression(fr, fe));
}
expression.traverse(variableVisitor);
sequentialVars.add(new Variable(name));
return this;
}
use of de.neemann.digital.analyse.expression.format.FormatterException in project Digital by hneemann.
the class CuplExporter method writeTo.
/**
* Writes code to given writer
*
* @param out the stream to write to
* @throws IOException IOException
* @throws PinMapException PinMapException
*/
public void writeTo(Writer out) throws IOException, PinMapException {
out.append("Name ").append(projectName).append(" ;\r\n").append("PartNo 00 ;\r\n").append("Date ").append(formatDate(date)).append(" ;\r\n").append("Revision 01 ;\r\n").append("Designer ").append(username).append(" ;\r\n").append("Company unknown ;\r\n").append("Assembly None ;\r\n").append("Location unknown ;\r\n").append("Device ").append(devName).append(" ;\r\n");
headerWritten(out);
out.append("\r\n/* inputs */\r\n");
if (!builder.getRegistered().isEmpty())
out.append("PIN ").append(String.valueOf(clockPin)).append(" = CLK;\r\n");
for (String in : builder.getInputs()) out.append("PIN ").append(Integer.toString(pinMap.getInputFor(in))).append(" = ").append(in).append(";\r\n");
out.append("\r\n/* outputs */\r\n");
for (String var : builder.getOutputs()) {
if (createNodes) {
int p = pinMap.isOutputAssigned(var);
if (p >= 0)
out.append("PIN ").append(Integer.toString(p)).append(" = ").append(var).append(";\r\n");
else
out.append("NODE ").append(var).append(";\r\n");
} else {
out.append("PIN ").append(Integer.toString(pinMap.getOutputFor(var))).append(" = ").append(var).append(";\r\n");
}
}
try {
if (!builder.getRegistered().isEmpty()) {
out.append("\r\n/* sequential logic */\r\n");
for (Map.Entry<String, Expression> c : builder.getRegistered().entrySet()) {
out.append(c.getKey()).append(".D = ");
breakLines(out, FormatToExpression.FORMATTER_CUPL.format(c.getValue()));
out.append(";\r\n");
sequentialWritten(out, c.getKey());
}
}
if (!builder.getCombinatorial().isEmpty()) {
out.append("\r\n/* combinatorial logic */\r\n");
for (Map.Entry<String, Expression> c : builder.getCombinatorial().entrySet()) {
out.append(c.getKey()).append(" = ");
breakLines(out, FormatToExpression.FORMATTER_CUPL.format(c.getValue()));
out.append(";\r\n");
}
}
} catch (FormatterException e) {
throw new IOException(e);
}
out.flush();
}
use of de.neemann.digital.analyse.expression.format.FormatterException in project Digital by hneemann.
the class TableDialog method createFileMenu.
private JMenu createFileMenu() {
JMenu fileMenu = new JMenu(Lang.get("menu_file"));
fileMenu.add(new ToolTipAction(Lang.get("menu_open")) {
@Override
public void actionPerformed(ActionEvent e) {
JFileChooser fc = new MyFileChooser();
if (TableDialog.this.filename != null)
fc.setSelectedFile(SaveAsHelper.checkSuffix(TableDialog.this.filename, "tru"));
if (fc.showOpenDialog(TableDialog.this) == JFileChooser.APPROVE_OPTION) {
try {
File file = fc.getSelectedFile();
TruthTable truthTable = TruthTable.readFromFile(file);
setModel(new TruthTableTableModel(truthTable));
TableDialog.this.filename = file;
} catch (IOException e1) {
new ErrorMessage().addCause(e1).show(TableDialog.this);
}
}
}
});
fileMenu.add(new ToolTipAction(Lang.get("menu_save")) {
@Override
public void actionPerformed(ActionEvent e) {
JFileChooser fc = new MyFileChooser();
if (TableDialog.this.filename != null)
fc.setSelectedFile(SaveAsHelper.checkSuffix(TableDialog.this.filename, "tru"));
new SaveAsHelper(TableDialog.this, fc, "tru").checkOverwrite(file -> {
model.getTable().save(file);
TableDialog.this.filename = file;
});
}
});
fileMenu.add(new ToolTipAction(Lang.get("menu_table_exportTableLaTeX")) {
@Override
public void actionPerformed(ActionEvent e) {
try {
ExpressionListener expressionListener = new LaTeXExpressionListener(model);
if (createJK.isSelected())
expressionListener = new ExpressionListenerJK(expressionListener);
lastGeneratedExpressions.replayTo(expressionListener);
} catch (ExpressionException | FormatterException e1) {
new ErrorMessage(Lang.get("msg_errorDuringCalculation")).addCause(e1).show(TableDialog.this);
}
}
});
fileMenu.add(new ToolTipAction(Lang.get("menu_table_exportHex")) {
@Override
public void actionPerformed(ActionEvent e) {
int res = JOptionPane.OK_OPTION;
if (model.getTable().getVars().size() > 20)
res = JOptionPane.showConfirmDialog(TableDialog.this, Lang.get("msg_tableHasManyRowsConfirm"));
if (res == JOptionPane.OK_OPTION) {
JFileChooser fc = new MyFileChooser();
if (TableDialog.this.filename != null)
fc.setSelectedFile(SaveAsHelper.checkSuffix(TableDialog.this.filename, "hex"));
new SaveAsHelper(TableDialog.this, fc, "hex").checkOverwrite(file -> model.getTable().saveHex(file));
}
}
}.setToolTip(Lang.get("menu_table_exportHex_tt")).createJMenuItem());
createJK = new JCheckBoxMenuItem(Lang.get("menu_table_JK"));
createJK.addActionListener(e -> calculateExpressions());
fileMenu.add(createJK);
return fileMenu;
}
use of de.neemann.digital.analyse.expression.format.FormatterException in project Digital by hneemann.
the class ExpressionCreator method create.
/**
* Creates the expressions
*
* @param listener the listener to report the found expressions to
* @throws ExpressionException ExpressionException
* @throws FormatterException FormatterException
* @throws AnalyseException AnalyseException
*/
public void create(ExpressionListener listener) throws ExpressionException, FormatterException, AnalyseException {
final List<Variable> vars = Collections.unmodifiableList(theTable.getVars());
long time = System.currentTimeMillis();
if (theTable.getResultCount() > 100) {
ExecutorService ex = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
ThreadSaveExpressionListener threadListener = new ThreadSaveExpressionListener(listener);
for (int table = 0; table < theTable.getResultCount(); table++) {
final int t = table;
ex.submit(() -> {
try {
simplify(listener, vars, theTable.getResultName(t), theTable.getResult(t));
} catch (ExpressionException | FormatterException | AnalyseException e) {
e.printStackTrace();
}
});
}
ex.shutdown();
try {
ex.awaitTermination(100, TimeUnit.HOURS);
} catch (InterruptedException e) {
e.printStackTrace();
}
threadListener.close();
} else {
for (int table = 0; table < theTable.getResultCount(); table++) simplify(listener, vars, theTable.getResultName(table), theTable.getResult(table));
listener.close();
}
time = System.currentTimeMillis() - time;
LOGGER.debug("time: " + time / 1000.0 + " sec");
}
use of de.neemann.digital.analyse.expression.format.FormatterException in project Digital by hneemann.
the class KarnaughMapComponent method paintComponent.
@Override
protected void paintComponent(Graphics graphics) {
gr = (Graphics2D) graphics;
gr.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
gr.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
gr.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
gr.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
int width = getWidth();
int height = getHeight();
gr.setColor(Color.WHITE);
gr.fillRect(0, 0, width, height);
gr.setColor(Color.BLACK);
if (kv != null) {
// store the old transform
AffineTransform trans = gr.getTransform();
int kvWidth = kv.getColumns();
int kvHeight = kv.getRows();
cellSize = (int) Math.min(height / (kvHeight + 2.5f), width / (kvWidth + 2.5f));
Font origFont = gr.getFont();
Font valuesFont = origFont.deriveFont(cellSize * 0.5f);
gr.setFont(valuesFont);
Font headerFont = valuesFont;
try {
int maxHeaderStrWidth = 0;
FontMetrics fontMetrics = gr.getFontMetrics();
for (Variable v : vars) {
int w = fontMetrics.stringWidth(FormatToExpression.defaultFormat(not(v)));
if (w > maxHeaderStrWidth)
maxHeaderStrWidth = w;
}
if (maxHeaderStrWidth > cellSize)
headerFont = origFont.deriveFont(cellSize * 0.5f * cellSize / maxHeaderStrWidth);
} catch (FormatterException e) {
// can not happen
}
xOffs = (width - (kvWidth + 2) * cellSize) / 2;
yOffs = (height - (kvHeight + 2) * cellSize) / 2;
// center the kv map
gr.translate(xOffs, yOffs);
// draw table
gr.setColor(Color.GRAY);
gr.setStroke(new BasicStroke(STROKE_WIDTH / 2));
for (int i = 0; i <= kvWidth; i++) {
int dy1 = isNoHeaderLine(kv.getHeaderTop(), i - 1) ? cellSize : 0;
int dy2 = isNoHeaderLine(kv.getHeaderBottom(), i - 1) ? cellSize : 0;
gr.drawLine((i + 1) * cellSize, dy1, (i + 1) * cellSize, (kvHeight + 2) * cellSize - dy2);
}
for (int i = 0; i <= kvHeight; i++) {
int dx1 = isNoHeaderLine(kv.getHeaderLeft(), i - 1) ? cellSize : 0;
int dx2 = isNoHeaderLine(kv.getHeaderRight(), i - 1) ? cellSize : 0;
gr.drawLine(dx1, (i + 1) * cellSize, (kvWidth + 2) * cellSize - dx2, (i + 1) * cellSize);
}
gr.setStroke(new BasicStroke(STROKE_WIDTH));
// fill in bool table content
for (KarnaughMap.Cell cell : kv.getCells()) {
gr.setColor(Color.BLACK);
gr.setFont(valuesFont);
drawString(boolTable.get(cell.getBoolTableRow()).toString(), cell.getCol() + 1, cell.getRow() + 1);
gr.setColor(Color.GRAY);
gr.setFont(origFont);
gr.drawString(Integer.toString(cell.getBoolTableRow()), (cell.getCol() + 1) * cellSize + 1, (cell.getRow() + 2) * cellSize - 1);
}
// draw the text in the borders
gr.setColor(Color.BLACK);
gr.setFont(headerFont);
drawVerticalHeader(kv.getHeaderLeft(), 0);
drawVerticalHeader(kv.getHeaderRight(), kvWidth + 1);
drawHorizontalHeader(kv.getHeaderTop(), 0);
drawHorizontalHeader(kv.getHeaderBottom(), kvHeight + 1);
// draw the covers
int color = 0;
for (KarnaughMap.Cover c : kv) {
gr.setColor(COVER_COLORS[color++]);
KarnaughMap.Pos p = c.getPos();
int frame = (c.getInset() + 1) * STROKE_WIDTH;
int edgesRadius = cellSize - frame * 2;
if (c.isDisconnected()) {
Rectangle clip = gr.getClipBounds();
gr.setClip(cellSize, cellSize, kvWidth * cellSize, kvHeight * cellSize);
if (c.onlyEdges()) {
gr.drawRoundRect(frame, frame, 2 * cellSize - frame * 2, 2 * cellSize - frame * 2, edgesRadius, edgesRadius);
gr.drawRoundRect(4 * cellSize + frame, frame, 2 * cellSize - frame * 2, 2 * cellSize - frame * 2, edgesRadius, edgesRadius);
gr.drawRoundRect(frame, 4 * cellSize + frame, 2 * cellSize - frame * 2, 2 * cellSize - frame * 2, edgesRadius, edgesRadius);
gr.drawRoundRect(4 * cellSize + frame, 4 * cellSize + frame, 2 * cellSize - frame * 2, 2 * cellSize - frame * 2, edgesRadius, edgesRadius);
} else {
// draw the two parts of the cover
int xofs = 0;
int yOfs = 0;
if (c.isVerticalDivided())
xofs = cellSize * 3;
else
yOfs = cellSize * 3;
gr.drawRoundRect((p.getCol() + 1) * cellSize + frame + xofs, (p.getRow() + 1) * cellSize + frame + yOfs, p.getWidth() * cellSize - frame * 2, p.getHeight() * cellSize - frame * 2, edgesRadius, edgesRadius);
gr.drawRoundRect((p.getCol() + 1) * cellSize + frame - xofs, (p.getRow() + 1) * cellSize + frame - yOfs, p.getWidth() * cellSize - frame * 2, p.getHeight() * cellSize - frame * 2, edgesRadius, edgesRadius);
}
gr.setClip(clip.x, clip.y, clip.width, clip.height);
} else
gr.drawRoundRect((p.getCol() + 1) * cellSize + frame, (p.getRow() + 1) * cellSize + frame, p.getWidth() * cellSize - frame * 2, p.getHeight() * cellSize - frame * 2, edgesRadius, edgesRadius);
}
gr.setTransform(trans);
} else
gr.drawString(message, 10, 20);
}
Aggregations