|
11 | 11 | /// |
12 | 12 | //===----------------------------------------------------------------------===// |
13 | 13 |
|
| 14 | +#include "circt/Conversion/ImportAIGER.h" |
14 | 15 | #include "circt/Conversion/SynthToComb.h" |
15 | 16 | #include "circt/Dialect/Comb/CombDialect.h" |
16 | 17 | #include "circt/Dialect/Comb/CombOps.h" |
|
33 | 34 | #include "circt/Support/Passes.h" |
34 | 35 | #include "circt/Support/Version.h" |
35 | 36 | #include "circt/Transforms/Passes.h" |
| 37 | +#include "mlir/Bytecode/BytecodeReader.h" |
36 | 38 | #include "mlir/Bytecode/BytecodeWriter.h" |
37 | 39 | #include "mlir/IR/Diagnostics.h" |
38 | 40 | #include "mlir/IR/OwningOpRef.h" |
@@ -61,6 +63,19 @@ using namespace synth; |
61 | 63 |
|
62 | 64 | static cl::OptionCategory mainCategory("circt-synth Options"); |
63 | 65 |
|
| 66 | +/// Allow the user to specify the input file format. This can be used to |
| 67 | +/// override the input, and can be used to specify ambiguous cases like standard |
| 68 | +/// input. |
| 69 | +enum InputFormatKind { InputUnspecified, InputAIGERFile, InputMLIRFile }; |
| 70 | + |
| 71 | +static cl::opt<InputFormatKind> inputFormat( |
| 72 | + "input-format", cl::desc("Specify the input file format"), |
| 73 | + cl::values(clEnumValN(InputUnspecified, "unspecified", |
| 74 | + "Unspecified input format"), |
| 75 | + clEnumValN(InputAIGERFile, "aiger", "AIGER input format"), |
| 76 | + clEnumValN(InputMLIRFile, "mlir", "MLIR input format")), |
| 77 | + cl::init(InputUnspecified), cl::cat(mainCategory)); |
| 78 | + |
64 | 79 | static cl::opt<std::string> inputFilename(cl::Positional, cl::init("-"), |
65 | 80 | cl::desc("Specify an input file"), |
66 | 81 | cl::value_desc("filename"), |
@@ -300,11 +315,48 @@ static LogicalResult executeSynthesis(MLIRContext &context) { |
300 | 315 | applyDefaultTimingManagerCLOptions(tm); |
301 | 316 | auto ts = tm.getRootScope(); |
302 | 317 |
|
| 318 | + // Set up the input file. |
| 319 | + std::unique_ptr<llvm::MemoryBuffer> input; |
| 320 | + |
| 321 | + { |
| 322 | + std::string errorMessage; |
| 323 | + input = openInputFile(inputFilename, &errorMessage); |
| 324 | + if (!input) { |
| 325 | + llvm::errs() << errorMessage << "\n"; |
| 326 | + return failure(); |
| 327 | + } |
| 328 | + } |
| 329 | + |
| 330 | + // Figure out the input format if unspecified. |
| 331 | + if (inputFormat == InputUnspecified) { |
| 332 | + if (StringRef(inputFilename).ends_with(".aig")) |
| 333 | + inputFormat = InputAIGERFile; |
| 334 | + else if (StringRef(inputFilename).ends_with(".mlir") || |
| 335 | + StringRef(inputFilename).ends_with(".mlirbc") || |
| 336 | + mlir::isBytecode(*input)) |
| 337 | + inputFormat = InputMLIRFile; |
| 338 | + else { |
| 339 | + llvm::errs() << "unknown input format: " |
| 340 | + "specify with -format=aiger or -format=mlir\n"; |
| 341 | + return failure(); |
| 342 | + } |
| 343 | + } |
| 344 | + llvm::SourceMgr sourceMgr; |
| 345 | + sourceMgr.AddNewSourceBuffer(std::move(input), llvm::SMLoc()); |
303 | 346 | OwningOpRef<ModuleOp> module; |
304 | 347 | { |
305 | | - auto parserTimer = ts.nest("Parse MLIR input"); |
306 | 348 | // Parse the provided input files. |
307 | | - module = parseSourceFile<ModuleOp>(inputFilename, &context); |
| 349 | + if (inputFormat == InputAIGERFile) { |
| 350 | + circt::aiger::ImportAIGEROptions options; |
| 351 | + module = |
| 352 | + OwningOpRef<ModuleOp>(ModuleOp::create(UnknownLoc::get(&context))); |
| 353 | + if (failed(aiger::importAIGER(sourceMgr, &context, ts, module.get(), |
| 354 | + &options))) |
| 355 | + module = {}; |
| 356 | + } else { |
| 357 | + auto parserTimer = ts.nest("Parse MLIR input"); |
| 358 | + module = parseSourceFile<ModuleOp>(sourceMgr, &context); |
| 359 | + } |
308 | 360 | } |
309 | 361 | if (!module) |
310 | 362 | return failure(); |
|
0 commit comments