Skip to content

Commit 8a35dee

Browse files
authored
[circt-synth] Allow AIGER file to be an input file (#9054)
Similar to firtool taking fir file as an input file this commit changes circt-synth to parse an aiger file directly.
1 parent 187f4e8 commit 8a35dee

File tree

3 files changed

+63
-2
lines changed

3 files changed

+63
-2
lines changed

test/circt-synth/aiger.mlir

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// RUN: circt-translate --export-aiger %s | circt-synth --input-format=aiger | FileCheck %s
2+
// RUN: circt-translate --export-aiger %s -o %t.aig && circt-synth %t.aig | FileCheck %s
3+
// CHECK-LABEL: @aiger_top(
4+
// CHECK: synth.aig.and_inv %a, not %b : i1
5+
hw.module @and(in %a: i1, in %b: i1, out and: i1) {
6+
%0 = synth.aig.and_inv %a, not %b : i1
7+
hw.output %0 : i1
8+
}

tools/circt-synth/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ target_link_libraries(circt-synth
1212
CIRCTDebug
1313
CIRCTEmit
1414
CIRCTHW
15+
CIRCTImportAIGER
1516
CIRCTLTL
1617
CIRCTOM
1718
CIRCTSeq

tools/circt-synth/circt-synth.cpp

Lines changed: 54 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
///
1212
//===----------------------------------------------------------------------===//
1313

14+
#include "circt/Conversion/ImportAIGER.h"
1415
#include "circt/Conversion/SynthToComb.h"
1516
#include "circt/Dialect/Comb/CombDialect.h"
1617
#include "circt/Dialect/Comb/CombOps.h"
@@ -33,6 +34,7 @@
3334
#include "circt/Support/Passes.h"
3435
#include "circt/Support/Version.h"
3536
#include "circt/Transforms/Passes.h"
37+
#include "mlir/Bytecode/BytecodeReader.h"
3638
#include "mlir/Bytecode/BytecodeWriter.h"
3739
#include "mlir/IR/Diagnostics.h"
3840
#include "mlir/IR/OwningOpRef.h"
@@ -61,6 +63,19 @@ using namespace synth;
6163

6264
static cl::OptionCategory mainCategory("circt-synth Options");
6365

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+
6479
static cl::opt<std::string> inputFilename(cl::Positional, cl::init("-"),
6580
cl::desc("Specify an input file"),
6681
cl::value_desc("filename"),
@@ -300,11 +315,48 @@ static LogicalResult executeSynthesis(MLIRContext &context) {
300315
applyDefaultTimingManagerCLOptions(tm);
301316
auto ts = tm.getRootScope();
302317

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());
303346
OwningOpRef<ModuleOp> module;
304347
{
305-
auto parserTimer = ts.nest("Parse MLIR input");
306348
// 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+
}
308360
}
309361
if (!module)
310362
return failure();

0 commit comments

Comments
 (0)