[RTL] Add support for an "inout" type in the RTL dialect.

This runs into some limitations and issues with the ODS TypeDef support,
filed as https://bugs.llvm.org/show_bug.cgi?id=48262
This commit is contained in:
Chris Lattner 2020-11-22 12:01:55 -08:00
parent 8612153972
commit e2f1a7d8c7
5 changed files with 99 additions and 3 deletions

View File

@ -15,7 +15,19 @@ class DialectAsmParser;
class DialectAsmPrinter;
} // namespace mlir
// FIXME: This is a workaround for MLIR bug #48262
namespace circt {
namespace rtl {
using Location = ::mlir::Location;
}
} // namespace circt
#define GET_TYPEDEF_CLASSES
#include "circt/Dialect/RTL/RTLTypes.h.inc"
/// Return true if the specified type can be used as an RTL value type, that is
/// the set of types that can be composed together to represent synthesized,
/// hardware but not marker types like InOutType.
bool isRTLValueType(mlir::Type type);
#endif // CIRCT_DIALECT_RTL_TYPES_H

View File

@ -19,4 +19,18 @@ def ArrayType : RTLType<"Array"> {
let mnemonic = "array";
let parameters = (ins "::mlir::Type":$innerType, "size_t":$size);
let genVerifyInvariantsDecl = 1;
}
def InOutType : RTLType<"InOut"> {
let summary = "bidirectional type for ports and wires";
let description = [{
InOut type is used for model operations and values that have "connection"
semantics, instead of typical dataflow behavior. This is used for wires
and inout ports in Verilog.
}];
let mnemonic = "inout";
let parameters = (ins "::mlir::Type":$innerType);
let genVerifyInvariantsDecl = 1;
}

View File

@ -1,17 +1,34 @@
//===- Types.cpp - RTL types code defs ------------------------------------===//
//
// Definitions for RTL data types. Anything which doesn't have to be public
// should go in here.
// Implementation logic for RTL data types.
//
//===----------------------------------------------------------------------===//
#include "circt/Dialect/RTL/Types.h"
#include "mlir/IR/DialectImplementation.h"
#include "mlir/IR/StandardTypes.h"
#include "llvm/ADT/TypeSwitch.h"
using namespace mlir;
using namespace circt::rtl;
/// Return true if the specified type can be used as an RTL value type, that is
/// the set of types that can be composed together to represent synthesized,
/// hardware but not marker types like InOutType.
bool isRTLValueType(Type type) {
if (auto intType = type.dyn_cast<IntegerType>())
return intType.isSignless();
if (type.isa<ArrayType>())
return true;
return false;
}
//===----------------------------------------------------------------------===//
// ArrayType
//===----------------------------------------------------------------------===//
Type ArrayType::parse(MLIRContext *ctxt, DialectAsmParser &p) {
SmallVector<int64_t, 2> dims;
Type inner;
@ -22,13 +39,55 @@ Type ArrayType::parse(MLIRContext *ctxt, DialectAsmParser &p) {
p.emitError(p.getNameLoc(), "rtl.array only supports one dimension");
return Type();
}
auto loc = p.getEncodedSourceLoc(p.getCurrentLocation());
if (failed(verifyConstructionInvariants(loc, inner, dims[0])))
return Type();
return get(ctxt, inner, dims[0]);
}
void ArrayType::print(DialectAsmPrinter &p) const {
p << "array<" << getSize() << "x";
p.printType(getInnerType());
p << ">";
p << '>';
}
LogicalResult ArrayType::verifyConstructionInvariants(Location loc,
Type innerType,
size_t size) {
if (!isRTLValueType(innerType))
return emitError(loc, "invalid element for rtl.array type");
return success();
}
//===----------------------------------------------------------------------===//
// InOutType
//===----------------------------------------------------------------------===//
Type InOutType::parse(MLIRContext *ctxt, DialectAsmParser &p) {
Type inner;
if (p.parseLess() || p.parseType(inner) || p.parseGreater())
return Type();
auto loc = p.getEncodedSourceLoc(p.getCurrentLocation());
if (failed(verifyConstructionInvariants(loc, inner)))
return Type();
return get(ctxt, inner);
}
void InOutType::print(DialectAsmPrinter &p) const {
p << "inout<";
p.printType(getInnerType());
p << '>';
}
LogicalResult InOutType::verifyConstructionInvariants(Location loc,
Type innerType) {
if (!isRTLValueType(innerType))
return emitError(loc, "invalid element for rtl.inout type");
return success();
}
#define GET_TYPEDEF_CLASSES

View File

@ -70,3 +70,9 @@ rtl.module @B() {
// expected-error @+2 {{rtl.array only supports one dimension}}
// expected-error @+1 {{Could not parse rtl.array}}
func @arrayDims(%a: !rtl.array<3 x 4 x i5>) { }
// -----
// expected-error @+2 {{invalid element for rtl.inout type}}
// expected-error @+1 {{Could not parse rtl.inout}}
func @invalidInout(%arg0: !rtl.inout<tensor<*xf32>>) { }

View File

@ -6,4 +6,9 @@ module {
func @i20x5array(%A: !rtl.array<5 x i20>) {
return
}
// CHECK-LABEL: func @inoutType(%arg0: !rtl.inout<i42>) {
func @inoutType(%arg0: !rtl.inout<i42>) {
return
}
}