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// SV handle type logic.
75//===----------------------------------------------------------------------===//
76
77/// Return the element type of an SV handle type or null if the operand is not
78/// an SV handle (NetType or VarType).
79/// Note: InOutType to be removed.
80mlir::Type circt::sv::getHandleElementType(mlir::Type type) {
81 if (auto inout = dyn_cast_or_null<InOutType>(type))
82 return inout.getElementType();
83 if (auto net = dyn_cast_or_null<NetType>(type))
84 return net.getElementType();
85 if (auto var = dyn_cast_or_null<VarType>(type))
86 return var.getElementType();
87 return {};
88}
89
90/// Return a handle of the same kind (NetType or VarType) as `handleType`,
91/// wrapping `elementType` instead. Returns null if `handleType` isn't a
92/// NetType or VarType.
93/// Note: InOutType to be removed.
94mlir::Type circt::sv::getHandleOfElementType(mlir::Type handleType,
95 mlir::Type elementType) {
96 if (isa_and_present<InOutType>(handleType))
97 return InOutType::get(elementType);
98 if (isa_and_present<NetType>(handleType))
99 return NetType::get(elementType);
100 if (isa_and_present<VarType>(handleType))
101 return VarType::get(elementType);
102 return {};
103}
104
105//===----------------------------------------------------------------------===//
106// NetType type logic.
107//===----------------------------------------------------------------------===//
108
109/// Return the element type of a NetType or null if the operand isn't a Net
110/// type.
111mlir::Type circt::sv::getNetElementType(mlir::Type type) {
112 if (auto net = dyn_cast_or_null<NetType>(type))
113 return net.getElementType();
114 return {};
115}
116
117/// Return the innermost non-unpacked element type.
118static Type stripUnpackedDimensions(Type type) {
119 type = hw::getCanonicalType(type);
120 while (auto uarray = dyn_cast<hw::UnpackedArrayType>(type))
121 type = uarray.getElementType();
122 return type;
123}
124
125/// Return whether a type is valid as the element type of a NetType.
126bool circt::sv::isValidNetElementType(Type type) {
128}
129
130LogicalResult NetType::verify(function_ref<InFlightDiagnostic()> emitError,
131 Type elementType) {
132 if (isa_and_present<NetType, VarType>(elementType))
133 return emitError() << "sv.net element type may not be itself an sv.net or "
134 "sv.var handle";
135
136 Type packedElementType = stripUnpackedDimensions(elementType);
137 if (!isPackedType(packedElementType))
138 return emitError()
139 << "sv.net element type must have a packed base type, but got "
140 << packedElementType;
141
142 return success();
143}
144
145//===----------------------------------------------------------------------===//
146// VarType type logic.
147//===----------------------------------------------------------------------===//
148
149/// Return the element type of a VarType or null if the operand isn't a Var
150/// type.
151mlir::Type circt::sv::getVarElementType(mlir::Type type) {
152 if (auto var = dyn_cast_or_null<VarType>(type))
153 return var.getElementType();
154 return {};
155}
156
157static bool isValidVarElementTypeImpl(Type type) {
158 if (isPackedType(type) || isa<hw::StringType>(type))
159 return true;
160
161 if (auto uarray = dyn_cast<hw::UnpackedArrayType>(type))
162 return isValidVarElementTypeImpl(uarray.getElementType());
163
164 return false;
165}
166
167/// Return true if the type can be stored in a variable, including
168/// simulation-only and unpacked data types that are not valid net elements.
169bool circt::sv::isValidVarElementType(Type type) {
171}
172
173LogicalResult VarType::verify(function_ref<InFlightDiagnostic()> emitError,
174 Type elementType) {
175 if (isa_and_present<VarType, NetType>(elementType))
176 return emitError() << "sv.var element type may not be itself an sv.var or "
177 "sv.net handle";
179 return emitError() << "sv.var element type must be a valid value type, "
180 "but got "
181 << elementType;
182 return success();
183}
184
185//===----------------------------------------------------------------------===//
186// TableGen generated logic.
187//===----------------------------------------------------------------------===//
188
189// Provide the autogenerated implementation guts for the Op classes.
190#define GET_TYPEDEF_CLASSES
191#include "circt/Dialect/SV/SVTypes.cpp.inc"
192
193void SVDialect::registerTypes() {
194 addTypes<
195#define GET_TYPEDEF_LIST
196#include "circt/Dialect/SV/SVTypes.cpp.inc"
197 >();
198}
MlirType elementType
Definition CHIRRTL.cpp:29
return success()
static bool isValidVarElementTypeImpl(Type type)
Definition SVTypes.cpp:157
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:118
BaseTy type_dyn_cast(Type type)
Definition HWTypes.h:234
mlir::Type getCanonicalType(mlir::Type type)
Recursively remove HW type aliases from a type and its subelements.
Definition HWTypes.cpp:51
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:151
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 getHandleOfElementType(mlir::Type handleType, mlir::Type elementType)
Return a handle of the same kind (NetType or VarType) as handleType, wrapping elementType instead.
Definition SVTypes.cpp:94
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:111
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
mlir::Type getHandleElementType(mlir::Type type)
Return the element type of an SV handle type or null if the operand is not an SV lvalue (NetType or V...
Definition SVTypes.cpp:80
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.