Give circuit and module custom syntax, making them much nicer to read and write.

This commit is contained in:
Chris Lattner 2020-03-07 19:51:52 -08:00
parent 288b0c10c7
commit 6dfa2793f0
3 changed files with 90 additions and 18 deletions

View File

@ -56,6 +56,9 @@ def CircuitOp : FIRRTLOp<"circuit",
return OpBuilder(&bodyBlock, std::prev(bodyBlock.end()));
}
}];
let printer = [{ return ::print(p, *this); }];
let parser = [{ return ::parse$cppClass(parser, result); }];
}
def FModuleOp : FIRRTLOp<"module",
@ -77,6 +80,9 @@ def FModuleOp : FIRRTLOp<"module",
return OpBuilder(&bodyBlock, std::prev(bodyBlock.end()));
}
}];
let printer = [{ return ::print(p, *this); }];
let parser = [{ return ::parse$cppClass(parser, result); }];
}
def DoneOp : FIRRTLOp<"done", [Terminator]> {

View File

@ -9,6 +9,10 @@
using namespace spt;
using namespace firrtl;
//===----------------------------------------------------------------------===//
// Dialect specification.
//===----------------------------------------------------------------------===//
FIRRTLDialect::FIRRTLDialect(MLIRContext *context)
: Dialect(getDialectNamespace(), context) {
addTypes<UIntType>();
@ -25,6 +29,10 @@ FIRRTLDialect::FIRRTLDialect(MLIRContext *context)
FIRRTLDialect::~FIRRTLDialect() {
}
//===----------------------------------------------------------------------===//
// Type specifications.
//===----------------------------------------------------------------------===//
/// Parse a type registered to this dialect.
Type FIRRTLDialect::parseType(DialectAsmParser &parser) const {
StringRef tyData = parser.getFullSymbolSpec();
@ -42,6 +50,70 @@ void FIRRTLDialect::printType(Type type, DialectAsmPrinter &os) const {
os.getStream() << "uint";
}
//===----------------------------------------------------------------------===//
// Module and Circuit Ops.
//===----------------------------------------------------------------------===//
static void print(OpAsmPrinter &p, CircuitOp op) {
p << op.getOperationName() << " ";
p.printAttribute(op.nameAttr());
p.printOptionalAttrDictWithKeyword(op.getAttrs(), {"name"});
p.printRegion(op.body(),
/*printEntryBlockArgs=*/false,
/*printBlockTerminators=*/false);
}
static ParseResult parseCircuitOp(OpAsmParser &parser, OperationState &result) {
// Parse the module name.
StringAttr nameAttr;
if (parser.parseAttribute(nameAttr, "name", result.attributes))
return failure();
// Parse the optional attribute list.
if (parser.parseOptionalAttrDictWithKeyword(result.attributes))
return failure();
// Parse the body region.
Region *body = result.addRegion();
if (parser.parseRegion(*body, /*regionArgs*/{}, /*argTypes*/{}))
return failure();
CircuitOp::ensureTerminator(*body, parser.getBuilder(), result.location);
return success();
}
static void print(OpAsmPrinter &p, FModuleOp op) {
p << op.getOperationName() << " ";
p.printAttribute(op.nameAttr());
p.printOptionalAttrDictWithKeyword(op.getAttrs(), {"name"});
p.printRegion(op.body(),
/*printEntryBlockArgs=*/false,
/*printBlockTerminators=*/false);
}
static ParseResult parseFModuleOp(OpAsmParser &parser, OperationState &result) {
// Parse the module name.
StringAttr nameAttr;
if (parser.parseAttribute(nameAttr, "name", result.attributes))
return failure();
// Parse the optional attribute list.
if (parser.parseOptionalAttrDictWithKeyword(result.attributes))
return failure();
// Parse the body region.
Region *body = result.addRegion();
if (parser.parseRegion(*body, /*regionArgs*/{}, /*argTypes*/{}))
return failure();
FModuleOp::ensureTerminator(*body, parser.getBuilder(), result.location);
return success();
}
#define GET_OP_CLASSES
#include "spt/Dialect/FIRRTL/IR/FIRRTL.cpp.inc"

View File

@ -5,19 +5,17 @@
// output out: UInt<8>
// out <= in
"firrtl.module"() ( {
firrtl.module "MyModule" {
%0 = "firrtl.input"() {name = "in"} : () -> ui8
%1 = "firrtl.output"() {name = "out"} : () -> ui8
"firrtl.connect"(%1, %0) : (ui8, ui8) -> ()
"firrtl.done"() : () -> ()
}) {name = "MyModule"} : () -> ()
}
// CHECK-LABEL: "firrtl.module"() ( {
// CHECK-LABEL: firrtl.module "MyModule" {
// CHECK-NEXT: %0 = "firrtl.input"() {name = "in"} : () -> ui8
// CHECK-NEXT: %1 = "firrtl.output"() {name = "out"} : () -> ui8
// CHECK-NEXT: "firrtl.connect"(%1, %0) : (ui8, ui8) -> ()
// CHECK-NEXT: "firrtl.done"() : () -> ()
// CHECK-NEXT: }) {name = "MyModule"} : () -> ()
// CHECK-NEXT: }
//circuit Top :
@ -27,27 +25,23 @@
// input d:UInt<16>
// out <= add(b,d)
"firrtl.circuit"() ( {
"firrtl.module"() ( {
firrtl.circuit "Top" {
firrtl.module "Top" {
%0 = "firrtl.output"() {name = "out"} : () -> !firrtl.uint
%1 = "firrtl.input"() {name = "b"} : () -> ui32
%2 = "firrtl.input"() {name = "d"} : () -> ui16
%3 = "firrtl.add"(%1, %2) : (ui32, ui16) -> ui32
"firrtl.connect"(%0, %3) : (!firrtl.uint, ui32) -> ()
"firrtl.done"() : () -> ()
}) {name = "Top"} : () -> ()
"firrtl.done"() : () -> ()
}) {name = "Top"} : () -> ()
}
}
// CHECK-LABEL: "firrtl.circuit"() ( {
// CHECK-NEXT: "firrtl.module"() ( {
// CHECK-LABEL: firrtl.circuit "Top" {
// CHECK-NEXT: firrtl.module "Top" {
// CHECK-NEXT: %0 = "firrtl.output"() {name = "out"} : () -> !firrtl.uint
// CHECK-NEXT: %1 = "firrtl.input"() {name = "b"} : () -> ui32
// CHECK-NEXT: %2 = "firrtl.input"() {name = "d"} : () -> ui16
// CHECK-NEXT: %3 = "firrtl.add"(%1, %2) : (ui32, ui16) -> ui32
// CHECK-NEXT: "firrtl.connect"(%0, %3) : (!firrtl.uint, ui32) -> ()
// CHECK-NEXT: "firrtl.done"() : () -> ()
// CHECK-NEXT: }) {name = "Top"} : () -> ()
// CHECK-NEXT: "firrtl.done"() : () -> ()
// CHECK-NEXT: }) {name = "Top"} : () -> ()
// CHECK-NEXT: }
// CHECK-NEXT: }