Introduce op definitions for module, circuit and a 'done' terminator. Add

testcases to show things it catches.
This commit is contained in:
Chris Lattner 2020-03-07 19:27:37 -08:00
parent 24c3b33447
commit 288b0c10c7
4 changed files with 79 additions and 0 deletions

View File

@ -38,6 +38,59 @@ def FIRRTL_UIntType : DialectType<FIRRTLDialect,
class FIRRTLOp<string mnemonic, list<OpTrait> traits = []> :
Op<FIRRTLDialect, mnemonic, traits>;
def CircuitOp : FIRRTLOp<"circuit",
[SingleBlockImplicitTerminator<"DoneOp">]> {
let summary = "FIRRTL Circuit";
let description = [{
The "firrtl.circuit" operation represents an overall Verilog circuit,
containing a list of modules.
}];
let arguments = (ins StrAttr:$name);
let results = (outs);
let regions = (region SizedRegion<1>:$body);
let extraClassDeclaration = [{
OpBuilder getBodyBuilder() {
assert(!body().empty() && "Unexpected empty 'body' region.");
Block &bodyBlock = body().front();
return OpBuilder(&bodyBlock, std::prev(bodyBlock.end()));
}
}];
}
def FModuleOp : FIRRTLOp<"module",
[SingleBlockImplicitTerminator<"DoneOp">]> {
let summary = "FIRRTL Module";
let description = [{
The "firrtl.module" operation represents a Verilog module, including a given
name, a list of ports, and a body that represents the connections within
the module.
}];
let arguments = (ins StrAttr:$name);
let results = (outs);
let regions = (region SizedRegion<1>:$body);
let extraClassDeclaration = [{
OpBuilder getBodyBuilder() {
assert(!body().empty() && "Unexpected empty 'body' region.");
Block &bodyBlock = body().front();
return OpBuilder(&bodyBlock, std::prev(bodyBlock.end()));
}
}];
}
def DoneOp : FIRRTLOp<"done", [Terminator]> {
let summary = "FIRRTL termination operation";
let description = [{
"firrtl.done" marks the end of a region in the FIRRTL dialect.
}];
let arguments = (ins);
}
//===----------------------------------------------------------------------===//
// Primitive Operations
//===----------------------------------------------------------------------===//
// TODO: Should this be split out to addu/adds?
def FIRRTLAddOp : FIRRTLOp<"add", [Commutative]> {

View File

@ -9,6 +9,7 @@
#include "mlir/IR/Dialect.h"
#include "mlir/IR/OpDefinition.h"
#include "mlir/IR/Builders.h"
namespace spt {
namespace firrtl {

View File

@ -3,6 +3,7 @@
"firrtl.module"() ( {
// expected-error @+1 {{unknown firrtl type}}
%0 = "firrtl.input"() {name = "in"} : () -> !firrtl.unknowntype
"firrtl.done"() : () -> ()
}) {name = "MyModule"} : () -> ()
// -----
@ -13,4 +14,22 @@
%2 = "firrtl.input"() {name = "d"} : () -> ui16
// expected-error @+1 {{'firrtl.add' op expected 2 operands, but found 3}}
%3 = "firrtl.add"(%1, %2, %3) : (ui32, ui16, ui32) -> ui32
"firrtl.done"() : () -> ()
}) {name = "Top"} : () -> ()
// -----
// expected-error @+2 {{'firrtl.module' op expects regions to end with 'firrtl.done'}}
// expected-note @+1 {{implies 'firrtl.done'}}
"firrtl.module"() ( {
%0 = "firrtl.output"() {name = "out"} : () -> !firrtl.uint
}) {name = "MyModule"} : () -> ()
// -----
// expected-error @+1 {{'firrtl.module' op requires attribute 'name'}}
"firrtl.module"() ( {
"firrtl.done"() : () -> ()
}) {no_name = "MyModule"} : () -> ()

View File

@ -9,12 +9,14 @@
%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-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"} : () -> ()
@ -32,7 +34,9 @@
%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"() ( {
@ -42,6 +46,8 @@
// 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"} : () -> ()