CIRCT 24.0.0git
Loading...
Searching...
No Matches
SVTypes.cpp
Go to the documentation of this file.
1//===- SVTypes.cpp - Implement the SV types -------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implement the SV dialect type system.
10//
11//===----------------------------------------------------------------------===//
12
16#include "circt/Support/LLVM.h"
17#include "mlir/IR/Builders.h"
18#include "mlir/IR/Diagnostics.h"
19#include "mlir/IR/DialectImplementation.h"
20#include "llvm/ADT/TypeSwitch.h"
21
22using namespace circt;
23using namespace circt::sv;
24
25/// Return the element type of an ArrayType or UnpackedArrayType, or null if the
26/// operand isn't an array.
28 if (!type)
29 return {};
30 if (auto array = hw::type_dyn_cast<hw::ArrayType>(type))
31 return array.getElementType();
32 if (auto array = hw::type_dyn_cast<hw::UnpackedArrayType>(type))
33 return array.getElementType();
34
35 return {};
36}
37
38/// Return true if the specified type has a packed layout, i.e. it
39/// represents a contiguous, bit-sliceable vector: basic bit-vectors, or
40/// packed aggregates (hw.array, hw.struct, hw.union) built up entirely out of
41/// packed element types.
42static bool isPackedType(Type type) {
43
44 if (isa<hw::IntType, IntegerType, hw::EnumType>(type))
45 return true;
46
47 if (auto array = dyn_cast<hw::ArrayType>(type))
48 return isPackedType(array.getElementType());
49
50 if (auto t = dyn_cast<hw::StructType>(type))
51 return llvm::all_of(t.getElements(),
52 [](auto f) { return isPackedType(f.type); });
53
54 if (auto t = dyn_cast<hw::UnionType>(type))
55 return llvm::all_of(t.getElements(),
56 [](auto m) { return isPackedType(m.type); });
57
58 return false;
59}
60
61//===----------------------------------------------------------------------===//
62// InOut type logic.
63//===----------------------------------------------------------------------===//
64
65/// Return the element type of an InOutType or null if the operand isn't an
66/// InOut type.
67mlir::Type circt::sv::getInOutElementType(mlir::Type type) {
68 if (auto inout = dyn_cast_or_null<InOutType>(type))
69 return inout.getElementType();
70 return {};
71}
72
73//===----------------------------------------------------------------------===//
74// NetType type logic.
75//===----------------------------------------------------------------------===//
76
77/// Return the element type of a NetType or null if the operand isn't a Net
78/// type.
79mlir::Type circt::sv::getNetElementType(mlir::Type type) {
80 if (auto net = dyn_cast_or_null<NetType>(type))
81 return net.getElementType();
82 return {};
83}
84
85/// Return the innermost non-unpacked element type.
86static Type stripUnpackedDimensions(Type type) {
87 type = hw::getCanonicalType(type);
88 while (auto uarray = dyn_cast<hw::UnpackedArrayType>(type))
89 type = uarray.getElementType();
90 return type;
91}
92
93/// Return whether a type is valid as the element type of a NetType.
96}
97
98LogicalResult NetType::verify(function_ref<InFlightDiagnostic()> emitError,
99 Type elementType) {
100 if (isa_and_present<NetType, VarType>(elementType))
101 return emitError() << "sv.net element type may not be itself an sv.net or "
102 "sv.var handle";
103
104 Type packedElementType = stripUnpackedDimensions(elementType);
105 if (!isPackedType(packedElementType))
106 return emitError()
107 << "sv.net element type must have a packed base type, but got "
108 << packedElementType;
109
110 return success();
111}
112
113//===----------------------------------------------------------------------===//
114// VarType type logic.
115//===----------------------------------------------------------------------===//
116
117/// Return the element type of a VarType or null if the operand isn't a Var
118/// type.
119mlir::Type circt::sv::getVarElementType(mlir::Type type) {
120 if (auto var = dyn_cast_or_null<VarType>(type))
121 return var.getElementType();
122 return {};
123}
124
125static bool isValidVarElementTypeImpl(Type type) {
126 if (isPackedType(type) || isa<hw::StringType>(type))
127 return true;
128
129 if (auto uarray = dyn_cast<hw::UnpackedArrayType>(type))
130 return isValidVarElementTypeImpl(uarray.getElementType());
131
132 return false;
133}
134
135/// Return true if the type can be stored in a variable, including
136/// simulation-only and unpacked data types that are not valid net elements.
137bool circt::sv::isValidVarElementType(Type type) {
138 return isValidVarElementTypeImpl(hw::getCanonicalType(type));
139}
140
141LogicalResult VarType::verify(function_ref<InFlightDiagnostic()> emitError,
142 Type elementType) {
143 if (isa_and_present<VarType, NetType>(elementType))
144 return emitError() << "sv.var element type may not be itself an sv.var or "
145 "sv.net handle";
147 return emitError() << "sv.var element type must be a valid value type, "
148 "but got "
149 << elementType;
150 return success();
151}
152
153//===----------------------------------------------------------------------===//
154// TableGen generated logic.
155//===----------------------------------------------------------------------===//
156
157// Provide the autogenerated implementation guts for the Op classes.
158#define GET_TYPEDEF_CLASSES
159#include "circt/Dialect/SV/SVTypes.cpp.inc"
160
161void SVDialect::registerTypes() {
162 addTypes<
163#define GET_TYPEDEF_LIST
164#include "circt/Dialect/SV/SVTypes.cpp.inc"
165 >();
166}
MlirType elementType
Definition CHIRRTL.cpp:29
static bool isValidVarElementTypeImpl(Type type)
Definition SVTypes.cpp:125
static bool isPackedType(Type type)
Return true if the specified type has a packed layout, i.e.
Definition SVTypes.cpp:42
static Type stripUnpackedDimensions(Type type)
Return the innermost non-unpacked element type.
Definition SVTypes.cpp:86
mlir::Type getVarElementType(mlir::Type type)
Return the element type of a VarType or null if the operand isn't a Var type.
Definition SVTypes.cpp:119
bool isValidNetElementType(mlir::Type type)
Return true if a type is a valid element type of a NetType.
mlir::Type getAnyHWArrayElementType(mlir::Type type)
Return the element type of an ArrayType or UnpackedArrayType, or null if the operand isn't an array.
mlir::Type getNetElementType(mlir::Type type)
Return the element type of a NetType or null if the operand isn't a Net type.
Definition SVTypes.cpp:79
mlir::Type getInOutElementType(mlir::Type type)
Return the element type of an InOutType or null if the operand isn't an InOut type.
Definition SVTypes.cpp:67
bool isValidVarElementType(mlir::Type type)
Return true if a type is a valid element type of a VarType.
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.