Skip to content

Commit

Permalink
Merge 09e3bcc into af330a8
Browse files Browse the repository at this point in the history
  • Loading branch information
mtrberzi committed Mar 10, 2015
2 parents af330a8 + 09e3bcc commit 598bed5
Show file tree
Hide file tree
Showing 13 changed files with 890 additions and 137 deletions.
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ targetCompatibility = 1.8

group = "org.manifold"
// name = "manifold-backend-digital"
version = '0.4.0-SNAPSHOT'
version = '0.5.0-SNAPSHOT'

mainClassName = "org.manifold.compiler.back.digital.DigitalBackend"

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
package org.manifold.compiler.back.digital;

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.OptionBuilder;
Expand All @@ -8,15 +14,22 @@
import org.apache.log4j.Logger;
import org.manifold.compiler.Backend;
import org.manifold.compiler.OptionError;
import org.manifold.compiler.TypeMismatchException;
import org.manifold.compiler.UndeclaredIdentifierException;
import org.manifold.compiler.middle.Schematic;
import org.manifold.compiler.middle.SchematicException;

public class DigitalBackend implements Backend {

private static Logger log = LogManager.getLogger("DigitalBackend");

private void err(String message) {
throw new CodeGenerationError(message);
}

public enum TargetHDL {
VHDL,
SMT2,
};

private TargetHDL targetHDL = null;
Expand All @@ -25,7 +38,7 @@ public TargetHDL getTargetHDL() {
}

private void createOptionTargetHDL(Options options) {
Option hdl = new Option("h", "hdl", true, "target HDL type (vhdl)");
Option hdl = new Option("h", "hdl", true, "target HDL type (vhdl, smt2)");
options.addOption(hdl);
}

Expand All @@ -38,13 +51,16 @@ private void collectOptionTargetHDL(CommandLine cmd) {
hdl = hdl.toLowerCase();
if (hdl.equals("vhdl")) {
targetHDL = TargetHDL.VHDL;
} else if (hdl.equals("smt2")) {
targetHDL = TargetHDL.SMT2;
} else {
throw new OptionError("target HDL '" + hdl + "' not recognized");
}
}
}

String outputDirectory = null;
// default to current working directory
String outputDirectory = Paths.get("").toAbsolutePath().toString();;

private void createOptionOutputDirectory(Options options) {
Option outDir = new Option("o", "output", true,
Expand Down Expand Up @@ -89,10 +105,73 @@ private void collectOptions(CommandLine cmd) {
collectOptionNoChecks(cmd);
}

private List<Check> buildStandardChecks(
Schematic schematic, Netlist netlist) {
List<Check> checks = new ArrayList<Check>();
checks.add(new NoMultipleDriversCheck(schematic, netlist));
checks.add(new NoUnconnectedInputsCheck(schematic, netlist));
return checks;
}

public void run(Schematic schematic) throws SchematicException {
// check if directory exists
Path outDir = Paths.get(outputDirectory);
if (!Files.exists(outDir)) {
err("output directory '" + outputDirectory + "' does not exist");
}
if (!Files.isWritable(outDir)) {
err("output directory '" + outputDirectory + "' is not writable");
}
log.info("Will generate output products in '" + outputDirectory + "'");

// build netlist from schematic
Netlist netlist = null;
try {
log.info("Building netlist");
netlist = new Netlist(schematic);
} catch (UndeclaredIdentifierException | TypeMismatchException e) {
err(e.getMessage());
}

log.info("Building type table");
PrimitiveTypeTable typeTable = new PrimitiveTypeTable(schematic);

if (!noChecks) {
log.info("constructing design checklist");
// checks we always run
List<Check> checks = buildStandardChecks(schematic, netlist);
int numChecks = checks.size();
int successes = 0;
int failures = 0;
log.info(Integer.toString(numChecks) + " checks to run");
for (Check check : checks) {
log.info("running check: " + check.getName());
boolean result = check.run();
if (result) {
++successes;
log.info("check passed: " + check.getName());
} else {
++failures;
log.error("check failed: " + check.getName());
}
log.info("check summary: "
+ Integer.toString(successes) + "/" + Integer.toString(numChecks)
+ " checks successful, "
+ Integer.toString(failures) + "/" + Integer.toString(numChecks)
+ " checks failed");
// if there were any failures, abort
if (failures > 0) {
err("design check failed");
}
}
} else {
log.warn("skipping all design checks");
}

switch (targetHDL) {
case VHDL: {
VHDLCodeGenerator vhdlGen = new VHDLCodeGenerator(schematic);
VHDLCodeGenerator vhdlGen = new VHDLCodeGenerator(
schematic, netlist, typeTable);
if (outputDirectory != null) {
vhdlGen.setOutputDirectory(outputDirectory);
}
Expand All @@ -101,6 +180,19 @@ public void run(Schematic schematic) throws SchematicException {
}
vhdlGen.generateOutputProducts();
} // end case VHDL
break;
case SMT2: {
SMT2CodeGenerator smtgen = new SMT2CodeGenerator(
schematic, netlist, typeTable);
if (outputDirectory != null) {
smtgen.setOutputDirectory(outputDirectory);
}
if (noChecks) {
smtgen.setRunChecks(false);
}
smtgen.generateOutputProducts();
} // end case SMT2
break;
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package org.manifold.compiler.back.digital;

import org.manifold.compiler.NodeTypeValue;
import org.manifold.compiler.PortTypeValue;
import org.manifold.compiler.UndeclaredIdentifierException;
import org.manifold.compiler.middle.Schematic;

public class PrimitiveTypeTable {

private PortTypeValue inputPortType = null;
private PortTypeValue outputPortType = null;

private NodeTypeValue inputPinType = null;
private NodeTypeValue outputPinType = null;

private NodeTypeValue registerType = null;
private NodeTypeValue andType = null;
private NodeTypeValue orType = null;
private NodeTypeValue notType = null;

public PortTypeValue getInputPortType() {
return inputPortType;
}

public PortTypeValue getOutputPortType() {
return outputPortType;
}

public NodeTypeValue getInputPinType() {
return inputPinType;
}

public NodeTypeValue getOutputPinType() {
return outputPinType;
}

public NodeTypeValue getRegisterType() {
return registerType;
}

public NodeTypeValue getAndType() {
return andType;
}

public NodeTypeValue getOrType() {
return orType;
}

public NodeTypeValue getNotType() {
return notType;
}

public PrimitiveTypeTable(Schematic schematic) {
// get information from the schematic about which node types to use
try {
inputPortType = schematic.getPortType("digitalIn");
outputPortType = schematic.getPortType("digitalOut");
inputPinType = schematic.getNodeType("inputPin");
outputPinType = schematic.getNodeType("outputPin");
registerType = schematic.getNodeType("register");
andType = schematic.getNodeType("and");
orType = schematic.getNodeType("or");
notType = schematic.getNodeType("not");
} catch (UndeclaredIdentifierException e) {
throw new CodeGenerationError(
"could not find required digital design type '"
+ e.getIdentifier() + "'; schematic version mismatch or "
+ " not a digital schematic");
}
}

}

0 comments on commit 598bed5

Please sign in to comment.