CIRCT 20.0.0git
Loading...
Searching...
No Matches
Types.cpp
Go to the documentation of this file.
1//===- Types.cpp - Slang type conversion ----------------------------------===//
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
10#include "slang/syntax/AllSyntax.h"
11
12using namespace circt;
13using namespace ImportVerilog;
14using moore::Domain;
15
16namespace {
17struct TypeVisitor {
18 Context &context;
19 Location loc;
20 TypeVisitor(Context &context, Location loc) : context(context), loc(loc) {}
21
22 // Handle simple bit vector types such as `bit`, `int`, or `bit [41:0]`.
23 Type getSimpleBitVectorType(const slang::ast::IntegralType &type) {
24 return moore::IntType::get(context.getContext(), type.bitWidth,
25 type.isFourState ? Domain::FourValued
26 : Domain::TwoValued);
27 }
28
29 // NOLINTBEGIN(misc-no-recursion)
30 Type visit(const slang::ast::VoidType &type) {
31 return moore::VoidType::get(context.getContext());
32 }
33
34 Type visit(const slang::ast::ScalarType &type) {
35 return getSimpleBitVectorType(type);
36 }
37
38 Type visit(const slang::ast::FloatingType &type) {
39 return moore::RealType::get(context.getContext());
40 }
41
42 Type visit(const slang::ast::PredefinedIntegerType &type) {
43 return getSimpleBitVectorType(type);
44 }
45
46 Type visit(const slang::ast::PackedArrayType &type) {
47 // Handle simple bit vector types of the form `bit [41:0]`.
48 if (type.elementType.as_if<slang::ast::ScalarType>())
49 return getSimpleBitVectorType(type);
50
51 // Handle all other packed arrays.
52 auto innerType = type.elementType.visit(*this);
53 if (!innerType)
54 return {};
55 // The Slang frontend guarantees the inner type to be packed.
56 return moore::ArrayType::get(type.range.width(),
57 cast<moore::PackedType>(innerType));
58 }
59
60 Type visit(const slang::ast::QueueType &type) {
61 auto innerType = type.elementType.visit(*this);
62 if (!innerType)
63 return {};
64 return moore::QueueType::get(cast<moore::UnpackedType>(innerType),
65 type.maxBound);
66 }
67
68 Type visit(const slang::ast::AssociativeArrayType &type) {
69 auto innerType = type.elementType.visit(*this);
70 if (!innerType)
71 return {};
72 auto indexType = type.indexType->visit(*this);
73 if (!indexType)
74 return {};
75 return moore::AssocArrayType::get(cast<moore::UnpackedType>(innerType),
76 cast<moore::UnpackedType>(indexType));
77 }
78
79 Type visit(const slang::ast::FixedSizeUnpackedArrayType &type) {
80 auto innerType = type.elementType.visit(*this);
81 if (!innerType)
82 return {};
83 return moore::UnpackedArrayType::get(type.range.width(),
84 cast<moore::UnpackedType>(innerType));
85 }
86
87 Type visit(const slang::ast::DynamicArrayType &type) {
88 auto innerType = type.elementType.visit(*this);
89 if (!innerType)
90 return {};
91 return moore::OpenUnpackedArrayType::get(
92 cast<moore::UnpackedType>(innerType));
93 }
94
95 // Handle type defs.
96 Type visit(const slang::ast::TypeAliasType &type) {
97 // Simply return the underlying type.
98 return type.targetType.getType().visit(*this);
99 }
100
101 // Handle enums.
102 Type visit(const slang::ast::EnumType &type) {
103 // Simply return the underlying type.
104 return type.baseType.visit(*this);
105 }
106
107 // Collect the members in a struct or union.
108 LogicalResult
109 collectMembers(const slang::ast::Scope &structType,
110 SmallVectorImpl<moore::StructLikeMember> &members) {
111 for (auto &field : structType.membersOfType<slang::ast::FieldSymbol>()) {
112 auto name = StringAttr::get(context.getContext(), field.name);
113 auto innerType = context.convertType(*field.getDeclaredType());
114 if (!innerType)
115 return failure();
116 members.push_back({name, cast<moore::UnpackedType>(innerType)});
117 }
118 return success();
119 }
120
121 // Handle packed and unpacked structs.
122 Type visit(const slang::ast::PackedStructType &type) {
123 SmallVector<moore::StructLikeMember> members;
124 if (failed(collectMembers(type, members)))
125 return {};
126 return moore::StructType::get(context.getContext(), members);
127 }
128
129 Type visit(const slang::ast::UnpackedStructType &type) {
130 SmallVector<moore::StructLikeMember> members;
131 if (failed(collectMembers(type, members)))
132 return {};
133 return moore::UnpackedStructType::get(context.getContext(), members);
134 }
135
136 Type visit(const slang::ast::PackedUnionType &type) {
137 SmallVector<moore::StructLikeMember> members;
138 if (failed(collectMembers(type, members)))
139 return {};
140 return moore::UnionType::get(context.getContext(), members);
141 }
142
143 Type visit(const slang::ast::UnpackedUnionType &type) {
144 SmallVector<moore::StructLikeMember> members;
145 if (failed(collectMembers(type, members)))
146 return {};
147 return moore::UnpackedUnionType::get(context.getContext(), members);
148 }
149
150 Type visit(const slang::ast::StringType &type) {
151 return moore::StringType::get(context.getContext());
152 }
153
154 /// Emit an error for all other types.
155 template <typename T>
156 Type visit(T &&node) {
157 auto d = mlir::emitError(loc, "unsupported type: ")
158 << slang::ast::toString(node.kind);
159 d.attachNote() << node.template as<slang::ast::Type>().toString();
160 return {};
161 }
162 // NOLINTEND(misc-no-recursion)
163};
164} // namespace
165
166// NOLINTBEGIN(misc-no-recursion)
167Type Context::convertType(const slang::ast::Type &type, LocationAttr loc) {
168 if (!loc)
169 loc = convertLocation(type.location);
170 return type.visit(TypeVisitor(*this, loc));
171}
172
173Type Context::convertType(const slang::ast::DeclaredType &type) {
174 LocationAttr loc;
175 if (auto *ts = type.getTypeSyntax())
176 loc = convertLocation(ts->sourceRange().start());
177 return convertType(type.getType(), loc);
178}
179// NOLINTEND(misc-no-recursion)
mlir::Type innerType(mlir::Type type)
Definition ESITypes.cpp:227
Domain
The number of values each bit of a type can assume.
Definition MooreTypes.h:47
@ TwoValued
Two-valued types such as bit or int.
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
A helper class to facilitate the conversion from a Slang AST to MLIR operations.
Type convertType(const slang::ast::Type &type, LocationAttr loc={})
Convert a slang type into an MLIR type.
Definition Types.cpp:167
MLIRContext * getContext()
Return the MLIR context.
Location convertLocation(slang::SourceLocation loc)
Convert a slang SourceLocation into an MLIR Location.