diff --git a/include/circt/Dialect/Ibis/CMakeLists.txt b/include/circt/Dialect/Ibis/CMakeLists.txt index d45735b8ea..51d1012fd5 100644 --- a/include/circt/Dialect/Ibis/CMakeLists.txt +++ b/include/circt/Dialect/Ibis/CMakeLists.txt @@ -11,3 +11,9 @@ mlir_tablegen(IbisInterfaces.h.inc -gen-op-interface-decls) mlir_tablegen(IbisInterfaces.cpp.inc -gen-op-interface-defs) add_public_tablegen_target(MLIRIbisInterfacIbisncGen) add_dependencies(circt-headers MLIRIbisInterfacIbisncGen) + +set(LLVM_TARGET_DEFINITIONS Ibis.td) +mlir_tablegen(IbisEnums.h.inc -gen-enum-decls) +mlir_tablegen(IbisEnums.cpp.inc -gen-enum-defs) +add_public_tablegen_target(MLIRIbisEnumsIncGen) +add_dependencies(circt-headers MLIRIbisEnumsIncGen) diff --git a/include/circt/Dialect/Ibis/IbisDialect.h b/include/circt/Dialect/Ibis/IbisDialect.h index da0016d732..7607eeb4eb 100644 --- a/include/circt/Dialect/Ibis/IbisDialect.h +++ b/include/circt/Dialect/Ibis/IbisDialect.h @@ -14,4 +14,7 @@ // Pull in the dialect definition. #include "circt/Dialect/Ibis/IbisDialect.h.inc" +// Pull in all enum type definitions and utility function declarations. +#include "circt/Dialect/Ibis/IbisEnums.h.inc" + #endif // CIRCT_DIALECT_IBIS_IBISDIALECT_H diff --git a/include/circt/Dialect/Ibis/IbisOps.td b/include/circt/Dialect/Ibis/IbisOps.td index b7064acb51..dc311363b7 100644 --- a/include/circt/Dialect/Ibis/IbisOps.td +++ b/include/circt/Dialect/Ibis/IbisOps.td @@ -346,7 +346,7 @@ def PortReadOp : IbisOp<"port.read", [ class InnerTypeToPortRefTypeConstraint : TypesMatchWith<"the type of the lhs value dictates the rhs portref type", - lhs, rhs, "PortRefType::get($_ctxt, $_self)">; + lhs, rhs, "PortRefType::get($_ctxt, $_self, ibis::Direction::Input)">; def PortWriteOp : IbisOp<"port.write", [ InnerTypeToPortRefTypeConstraint<"value", "port"> diff --git a/include/circt/Dialect/Ibis/IbisTypes.h b/include/circt/Dialect/Ibis/IbisTypes.h index 7835a0c241..63f6e7af90 100644 --- a/include/circt/Dialect/Ibis/IbisTypes.h +++ b/include/circt/Dialect/Ibis/IbisTypes.h @@ -9,6 +9,7 @@ #ifndef CIRCT_DIALECT_IBIS_IBISTYPES_H #define CIRCT_DIALECT_IBIS_IBISTYPES_H +#include "circt/Dialect/Ibis/IbisDialect.h" #include "circt/Support/LLVM.h" #include "mlir/IR/BuiltinAttributes.h" #include "mlir/IR/Types.h" diff --git a/include/circt/Dialect/Ibis/IbisTypes.td b/include/circt/Dialect/Ibis/IbisTypes.td index 4cb11593ad..530f883e07 100644 --- a/include/circt/Dialect/Ibis/IbisTypes.td +++ b/include/circt/Dialect/Ibis/IbisTypes.td @@ -11,6 +11,7 @@ include "circt/Dialect/Ibis/IbisDialect.td" include "mlir/IR/AttrTypeBase.td" +include "mlir/IR/EnumAttr.td" class IbisTypeDef : TypeDef { } @@ -52,10 +53,17 @@ def OpaqueScopeRefType : Type< BuildableType<"$_builder.getType()"> { } +def Input : I32EnumAttrCase<"Input", 0, "in">; +def Output : I32EnumAttrCase<"Output", 1, "out">; +def Direction : I32EnumAttr<"Direction", "Ibis port direction", + [Input, Output]> { + let cppNamespace = "::circt::ibis"; +} + def PortRefType : IbisTypeDef<"PortRef"> { let mnemonic = "portref"; - let parameters = (ins "TypeAttr":$portTypeAttr); - let assemblyFormat = "`<` $portTypeAttr `>`"; + let parameters = (ins "TypeAttr":$portTypeAttr, "ibis::Direction":$direction); + let assemblyFormat = "`<` $direction $portTypeAttr `>`"; let description = [{ A reference to an Ibis port. }]; @@ -67,8 +75,8 @@ def PortRefType : IbisTypeDef<"PortRef"> { }]; let builders = [ - TypeBuilder<(ins "Type":$t), [{ - return $_get($_ctxt, TypeAttr::get(t)); + TypeBuilder<(ins "Type":$t, "ibis::Direction":$d), [{ + return $_get($_ctxt, TypeAttr::get(t), d); }]> ]; } diff --git a/lib/Dialect/Ibis/IbisDialect.cpp b/lib/Dialect/Ibis/IbisDialect.cpp index 2d7e573b3d..f5ba970739 100644 --- a/lib/Dialect/Ibis/IbisDialect.cpp +++ b/lib/Dialect/Ibis/IbisDialect.cpp @@ -24,3 +24,6 @@ void IbisDialect::initialize() { #include "circt/Dialect/Ibis/Ibis.cpp.inc" >(); } + +// Provide implementations for the enums we use. +#include "circt/Dialect/Ibis/IbisEnums.cpp.inc" diff --git a/test/Dialect/Ibis/errors.mlir b/test/Dialect/Ibis/errors.mlir index a4de7f8a82..0e703a7373 100644 --- a/test/Dialect/Ibis/errors.mlir +++ b/test/Dialect/Ibis/errors.mlir @@ -34,7 +34,7 @@ ibis.class @C { ibis.class @MissingPort { %this = ibis.this @MissingPort // expected-error @+1 {{'ibis.get_port' op port '@C_in' does not exist in MissingPort}} - %c_in = ibis.get_port %this, @C_in : !ibis.scoperef<@MissingPort> -> !ibis.portref + %c_in = ibis.get_port %this, @C_in : !ibis.scoperef<@MissingPort> -> !ibis.portref } // ----- @@ -43,7 +43,7 @@ ibis.class @PortTypeMismatch { %this = ibis.this @PortTypeMismatch ibis.port.input @in : i1 // expected-error @+1 {{'ibis.get_port' op symbol '@in' refers to a port of type 'i1', but this op has type 'i2'}} - %c_in = ibis.get_port %this, @in : !ibis.scoperef<@PortTypeMismatch> -> !ibis.portref + %c_in = ibis.get_port %this, @in : !ibis.scoperef<@PortTypeMismatch> -> !ibis.portref } // ----- diff --git a/test/Dialect/Ibis/round-trip.mlir b/test/Dialect/Ibis/round-trip.mlir index 9ad00c6907..79b7f3af6d 100644 --- a/test/Dialect/Ibis/round-trip.mlir +++ b/test/Dialect/Ibis/round-trip.mlir @@ -13,21 +13,21 @@ // CHECK-NEXT: %1 = ibis.instance @a, @A // CHECK-NEXT: %2 = ibis.get_parent_of_ref %1 : !ibis.scoperef<@A> -> !ibis.scoperef // CHECK-NEXT: %3 = ibis.get_instance_in_ref @a : @A in %0 : !ibis.scoperef<@C> -// CHECK-NEXT: %4 = ibis.get_port %1, @A_in : !ibis.scoperef<@A> -> !ibis.portref +// CHECK-NEXT: %4 = ibis.get_port %1, @A_in : !ibis.scoperef<@A> -> !ibis.portref // CHECK-NEXT: %5 = ibis.get_instance_in_ref @a : @A in %2 : !ibis.scoperef // CHECK-NEXT: ibis.container @D { // CHECK-NEXT: %6 = ibis.this @D // CHECK-NEXT: %7 = ibis.get_parent_of_ref %6 : !ibis.scoperef<@D> -> !ibis.scoperef<@C> -// CHECK-NEXT: %8 = ibis.get_port %7, @C_in : !ibis.scoperef<@C> -> !ibis.portref -// CHECK-NEXT: %9 = ibis.get_port %7, @C_out : !ibis.scoperef<@C> -> !ibis.portref +// CHECK-NEXT: %8 = ibis.get_port %7, @C_in : !ibis.scoperef<@C> -> !ibis.portref +// CHECK-NEXT: %9 = ibis.get_port %7, @C_out : !ibis.scoperef<@C> -> !ibis.portref // CHECK-NEXT: %true = hw.constant true -// CHECK-NEXT: ibis.port.write %9, %true : i1 -// CHECK-NEXT: %10 = ibis.port.read %8 : !ibis.portref +// CHECK-NEXT: ibis.port.write %8, %true : i1 +// CHECK-NEXT: %10 = ibis.port.read %9 : !ibis.portref // CHECK-NEXT: %11 = ibis.get_instance_in_ref @a : @A in %7 : !ibis.scoperef<@C> -// CHECK-NEXT: %12 = ibis.get_port %11, @A_in : !ibis.scoperef<@A> -> !ibis.portref -// CHECK-NEXT: %13 = ibis.get_port %11, @A_out : !ibis.scoperef<@A> -> !ibis.portref +// CHECK-NEXT: %12 = ibis.get_port %11, @A_in : !ibis.scoperef<@A> -> !ibis.portref +// CHECK-NEXT: %13 = ibis.get_port %11, @A_out : !ibis.scoperef<@A> -> !ibis.portref // CHECK-NEXT: ibis.port.write %12, %10 : i1 -// CHECK-NEXT: %14 = ibis.port.read %13 : !ibis.portref +// CHECK-NEXT: %14 = ibis.port.read %13 : !ibis.portref // CHECK-NEXT: } // CHECK-NEXT: } @@ -48,7 +48,7 @@ ibis.class @C { // Test get parent/child %parent = ibis.get_parent_of_ref %a : !ibis.scoperef<@A> -> !ibis.scoperef %child = ibis.get_instance_in_ref @a : @A in %this : !ibis.scoperef<@C> - %a_in_cp = ibis.get_port %a, @A_in : !ibis.scoperef<@A> -> !ibis.portref + %a_in_cp = ibis.get_port %a, @A_in : !ibis.scoperef<@A> -> !ibis.portref // Test siblings %sibling = ibis.get_instance_in_ref @a : @A in %parent : !ibis.scoperef @@ -57,17 +57,17 @@ ibis.class @C { %this_d = ibis.this @D %parent_C = ibis.get_parent_of_ref %this_d : !ibis.scoperef<@D> -> !ibis.scoperef<@C> // Test local read/writes - %c_in_p = ibis.get_port %parent_C, @C_in : !ibis.scoperef<@C> -> !ibis.portref - %c_out_p = ibis.get_port %parent_C, @C_out : !ibis.scoperef<@C> -> !ibis.portref + %c_in_p = ibis.get_port %parent_C, @C_in : !ibis.scoperef<@C> -> !ibis.portref + %c_out_p = ibis.get_port %parent_C, @C_out : !ibis.scoperef<@C> -> !ibis.portref %true = hw.constant true - ibis.port.write %c_out_p, %true : i1 - %c_out = ibis.port.read %c_in_p : !ibis.portref + ibis.port.write %c_in_p, %true : i1 + %c_out = ibis.port.read %c_out_p : !ibis.portref // Test cross-container read/writes %a_in_parent = ibis.get_instance_in_ref @a : @A in %parent_C : !ibis.scoperef<@C> - %a_in_p = ibis.get_port %a_in_parent, @A_in : !ibis.scoperef<@A> -> !ibis.portref - %a_out_p = ibis.get_port %a_in_parent, @A_out : !ibis.scoperef<@A> -> !ibis.portref + %a_in_p = ibis.get_port %a_in_parent, @A_in : !ibis.scoperef<@A> -> !ibis.portref + %a_out_p = ibis.get_port %a_in_parent, @A_out : !ibis.scoperef<@A> -> !ibis.portref ibis.port.write %a_in_p, %c_out : i1 - %a_out = ibis.port.read %a_out_p : !ibis.portref + %a_out = ibis.port.read %a_out_p : !ibis.portref } }