mirror of https://github.com/llvm/circt.git
[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:
parent
8612153972
commit
e2f1a7d8c7
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>>) { }
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue