CIRCT 23.0.0git
Loading...
Searching...
No Matches
Types.h
Go to the documentation of this file.
1//===- Types.h - ESI type system -------------------------------*- C++ -*-===//
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// DO NOT EDIT!
10// This file is distributed as part of an ESI package. The source for this file
11// should always be modified within CIRCT.
12//
13//===----------------------------------------------------------------------===//
14
15// NOLINTNEXTLINE(llvm-header-guard)
16#ifndef ESI_TYPES_H
17#define ESI_TYPES_H
18
19#include <algorithm>
20#include <any>
21#include <cassert>
22#include <cstdint>
23#include <map>
24#include <span>
25#include <stdexcept>
26#include <string>
27#include <utility>
28#include <vector>
29
30#include "esi/Common.h"
31#include "esi/Values.h" // For BitVector / Int / UInt
32
33namespace esi {
34
35/// Root class of the ESI type system.
36class Type {
37public:
38 using ID = std::string;
39 Type(const ID &id) : id(id) {}
40 virtual ~Type() = default;
41
42 ID getID() const { return id; }
43 virtual std::ptrdiff_t getBitWidth() const { return -1; }
44
45 /// Serialize an object to a MutableBitVector (LSB-first stream). The object
46 /// should be passed via std::any. Implementations append fields in the order
47 /// they are iterated (the first serialized field occupies the
48 /// least-significant bits of the result).
49 virtual MutableBitVector serialize(const std::any &obj) const {
50 throw std::runtime_error("Serialization not implemented for type " + id);
51 }
52
53 /// Deserialize from a BitVector stream (LSB-first). Implementations consume
54 /// bits from 'data' in-place (via logical right shifts) and return the
55 /// reconstructed value. Remaining bits stay in 'data'.
56 virtual std::any deserialize(BitVector &data) const {
57 throw std::runtime_error("Deserialization not implemented for type " + id);
58 }
59
60 // Deserialize from a MessageData buffer. Maps the MessageData onto a
61 // MutableBitVector, and proceeds with regular MutableBitVector
62 // deserialization.
63 std::any deserialize(const MessageData &data) const {
64 auto bv = MutableBitVector(std::vector<uint8_t>(data.getData()));
65 return deserialize(bv);
66 }
67
68 /// Ensure that a std::any object is valid for this type. Throws
69 /// std::runtime_error if the object is not valid.
70 virtual void ensureValid(const std::any &obj) const {
71 throw std::runtime_error("Validation not implemented for type " + id);
72 }
73
74 // Check if a std::any object is valid for this type. Returns an optional
75 // error message if the object is not valid, else, std::nullopt.
76 std::optional<std::string> isValid(const std::any &obj) const {
77 try {
78 ensureValid(obj);
79 return std::nullopt;
80 } catch (const std::runtime_error &e) {
81 return e.what();
82 }
83 }
84
85 // Dump a textual representation of this type to the provided stream.
86 void dump(std::ostream &os, bool oneLine = false) const;
87
88 // Return a textual representation of this type.
89 std::string toString(bool oneLine = false) const;
90
91protected:
93};
94
95/// Bundles represent a collection of channels. Services exclusively expose
96/// bundles (sometimes of just one channel). As such, they are the type of
97/// accessible ports on an accelerator, from a host API perspective.
98/// TODO: Add a good description of direction?
99class BundleType : public Type {
100public:
101 enum Direction { To, From };
102
104 std::vector<std::tuple<std::string, Direction, const Type *>>;
105
107 : Type(id), channels(channels) {}
108
109 const ChannelVector &getChannels() const { return channels; }
110 std::ptrdiff_t getBitWidth() const override { return -1; };
111
112 std::pair<const Type *, Direction> findChannel(std::string name) const;
113
114protected:
116};
117
118/// Channels are the basic communication primitives. They are unidirectional and
119/// carry one values of one type.
120class ChannelType : public Type {
121public:
122 using Type::deserialize;
123 ChannelType(const ID &id, const Type *inner) : Type(id), inner(inner) {}
124 const Type *getInner() const { return inner; }
125 std::ptrdiff_t getBitWidth() const override { return inner->getBitWidth(); };
126
127 void ensureValid(const std::any &obj) const override;
128 MutableBitVector serialize(const std::any &obj) const override;
129 std::any deserialize(BitVector &data) const override;
130
131private:
132 const Type *inner;
133};
134
135/// The "void" type is a special type which can be used to represent no type.
136class VoidType : public Type {
137public:
138 using Type::deserialize;
139 VoidType(const ID &id) : Type(id) {}
140 // 'void' is 1 bit by convention.
141 std::ptrdiff_t getBitWidth() const override { return 1; };
142
143 void ensureValid(const std::any &obj) const override;
144 MutableBitVector serialize(const std::any &obj) const override;
145 std::any deserialize(BitVector &data) const override;
146};
147
148/// The "any" type is a special type which can be used to represent any type, as
149/// identified by the type id. Said type id is guaranteed to be present in the
150/// manifest. Importantly, the "any" type id over the wire may not be a string
151/// as it is in software.
152class AnyType : public Type {
153public:
154 AnyType(const ID &id) : Type(id) {}
155 std::ptrdiff_t getBitWidth() const override { return -1; };
156};
157
158/// Type aliases provide a named type which forwards to an inner type.
159class TypeAliasType : public Type {
160public:
161 using Type::deserialize;
162
163 TypeAliasType(const ID &id, std::string name, const Type *innerType)
164 : Type(id), name(std::move(name)), innerType(innerType) {
165 assert(innerType != nullptr &&
166 "TypeAliasType must have a non-null inner type");
167 }
168
169 const std::string &getName() const { return name; }
170 const Type *getInnerType() const { return innerType; }
171
172 std::ptrdiff_t getBitWidth() const override {
173 return innerType->getBitWidth();
174 };
175
176 void ensureValid(const std::any &obj) const override;
177 MutableBitVector serialize(const std::any &obj) const override;
178 std::any deserialize(BitVector &data) const override;
179
180private:
181 std::string name;
183};
184
185/// Bit vectors include signed, unsigned, and signless integers.
186class BitVectorType : public Type {
187public:
188 BitVectorType(const ID &id, uint64_t width) : Type(id), width(width) {}
189
190 uint64_t getWidth() const { return width; }
191 std::ptrdiff_t getBitWidth() const override { return getWidth(); };
192
193private:
194 uint64_t width;
195};
196
197/// Bits are just an array of bits. They are not interpreted as a number but are
198/// identified in the manifest as "signless" ints.
199class BitsType : public BitVectorType {
200public:
202 using Type::deserialize;
203
204 void ensureValid(const std::any &obj) const override;
205 MutableBitVector serialize(const std::any &obj) const override;
206 std::any deserialize(BitVector &data) const override;
207};
208
209/// Integers are bit vectors which may be signed or unsigned and are interpreted
210/// as numbers.
212public:
214};
215
216/// Signed integer.
217class SIntType : public IntegerType {
218public:
219 using IntegerType::IntegerType;
220 using Type::deserialize;
221
222 void ensureValid(const std::any &obj) const override;
223 MutableBitVector serialize(const std::any &obj) const override;
224 std::any deserialize(BitVector &data) const override;
225};
226
227/// Unsigned integer.
228class UIntType : public IntegerType {
229public:
230 using IntegerType::IntegerType;
231 using Type::deserialize;
232
233 void ensureValid(const std::any &obj) const override;
234 MutableBitVector serialize(const std::any &obj) const override;
235 std::any deserialize(BitVector &data) const override;
236};
237
238/// Structs are an ordered collection of fields, each with a name and a type.
239class StructType : public Type {
240public:
241 using FieldVector = std::vector<std::pair<std::string, const Type *>>;
242 using Type::deserialize;
243
244 StructType(const ID &id, const FieldVector &fields, bool reverse = true)
246
247 const FieldVector &getFields() const { return fields; }
248 std::ptrdiff_t getBitWidth() const override {
249 std::ptrdiff_t size = 0;
250 for (auto [name, ty] : getFields()) {
251 std::ptrdiff_t fieldSize = ty->getBitWidth();
252 if (fieldSize < 0)
253 return -1;
254 size += fieldSize;
255 }
256 return size;
257 }
258
259 void ensureValid(const std::any &obj) const override;
260 MutableBitVector serialize(const std::any &obj) const override;
261 std::any deserialize(BitVector &data) const override;
262
263 // Returns whether this struct type should be reversed when
264 // serializing/deserializing.
265 // By default, a truthy value here makes StructType's compatible with system
266 // verilog, which has reversed struct field ordering, wrt. C/software struct
267 // ordering.
268 bool isReverse() const { return reverse; }
269
270private:
273};
274
275/// Arrays have a compile time specified (static) size and an element type.
276class ArrayType : public Type {
277public:
278 ArrayType(const ID &id, const Type *elementType, uint64_t size,
279 bool reverse = true)
281 using Type::deserialize;
282
283 const Type *getElementType() const { return elementType; }
284 uint64_t getSize() const { return size; }
285 bool isReverse() const { return reverse; }
286 std::ptrdiff_t getBitWidth() const override {
287 std::ptrdiff_t elementSize = elementType->getBitWidth();
288 if (elementSize < 0)
289 return -1;
290 return elementSize * size;
291 }
292
293 void ensureValid(const std::any &obj) const override;
294 MutableBitVector serialize(const std::any &obj) const override;
295 std::any deserialize(BitVector &data) const override;
296
297private:
299 uint64_t size;
300 // 'reverse' controls whether array elements are reversed during
301 // serialization/deserialization (to match SystemVerilog/Python ordering
302 // expectations).
304};
305
306/// Windows represent a fixed-size sliding window over a stream of data.
307/// They define an "into" type (the data structure being windowed) and a
308/// "loweredType" (the hardware representation including control signals).
309class WindowType : public Type {
310public:
311 /// Field information describing a field within a frame.
312 struct Field {
313 std::string name;
314 uint64_t numItems = 0; // 0 means not specified (use all items)
315 uint64_t bulkCountWidth = 0; // 0 means parallel encoding, >0 means serial
316 };
317
318 /// Frame information describing which fields are included in a particular
319 /// frame.
320 struct Frame {
321 std::string name;
322 std::vector<Field> fields;
323 };
324
325 WindowType(const ID &id, const std::string &name, const Type *intoType,
326 const Type *loweredType, const std::vector<Frame> &frames)
328 frames(frames) {}
329
330 const std::string &getName() const { return name; }
331 const Type *getIntoType() const { return intoType; }
332 const Type *getLoweredType() const { return loweredType; }
333 const std::vector<Frame> &getFrames() const { return frames; }
334
335 std::ptrdiff_t getBitWidth() const override {
336 return loweredType->getBitWidth();
337 }
338
339private:
340 std::string name;
343 std::vector<Frame> frames;
344};
345
346/// Lists represent variable-length sequences of elements of a single type.
347/// Unlike arrays which have a fixed size, lists can have any length.
348class ListType : public Type {
349public:
350 ListType(const ID &id, const Type *elementType)
352
353 const Type *getElementType() const { return elementType; }
354
355 std::ptrdiff_t getBitWidth() const override { return -1; }
356
357private:
359};
360
361} // namespace esi
362
363#endif // ESI_TYPES_H
assert(baseType &&"element must be base type")
The "any" type is a special type which can be used to represent any type, as identified by the type i...
Definition Types.h:152
std::ptrdiff_t getBitWidth() const override
Definition Types.h:155
AnyType(const ID &id)
Definition Types.h:154
Arrays have a compile time specified (static) size and an element type.
Definition Types.h:276
std::ptrdiff_t getBitWidth() const override
Definition Types.h:286
uint64_t size
Definition Types.h:299
MutableBitVector serialize(const std::any &obj) const override
Serialize an object to a MutableBitVector (LSB-first stream).
Definition Types.cpp:403
void ensureValid(const std::any &obj) const override
Ensure that a std::any object is valid for this type.
Definition Types.cpp:380
bool reverse
Definition Types.h:303
std::any deserialize(BitVector &data) const override
Deserialize from a BitVector stream (LSB-first).
Definition Types.cpp:422
const Type * elementType
Definition Types.h:298
const Type * getElementType() const
Definition Types.h:283
ArrayType(const ID &id, const Type *elementType, uint64_t size, bool reverse=true)
Definition Types.h:278
uint64_t getSize() const
Definition Types.h:284
bool isReverse() const
Definition Types.h:285
Bit vectors include signed, unsigned, and signless integers.
Definition Types.h:186
BitVectorType(const ID &id, uint64_t width)
Definition Types.h:188
uint64_t width
Definition Types.h:194
std::ptrdiff_t getBitWidth() const override
Definition Types.h:191
uint64_t getWidth() const
Definition Types.h:190
A lightweight, non-owning bit vector view backed by a byte array span.
Definition Values.h:42
Bits are just an array of bits.
Definition Types.h:199
void ensureValid(const std::any &obj) const override
Ensure that a std::any object is valid for this type.
Definition Types.cpp:178
std::any deserialize(BitVector &data) const override
Deserialize from a BitVector stream (LSB-first).
Definition Types.cpp:199
MutableBitVector serialize(const std::any &obj) const override
Serialize an object to a MutableBitVector (LSB-first stream).
Definition Types.cpp:193
Bundles represent a collection of channels.
Definition Types.h:99
BundleType(const ID &id, const ChannelVector &channels)
Definition Types.h:106
std::ptrdiff_t getBitWidth() const override
Definition Types.h:110
const ChannelVector & getChannels() const
Definition Types.h:109
ChannelVector channels
Definition Types.h:115
std::vector< std::tuple< std::string, Direction, const Type * > > ChannelVector
Definition Types.h:104
std::pair< const Type *, Direction > findChannel(std::string name) const
Definition Types.cpp:110
Channels are the basic communication primitives.
Definition Types.h:120
void ensureValid(const std::any &obj) const override
Ensure that a std::any object is valid for this type.
Definition Types.cpp:118
MutableBitVector serialize(const std::any &obj) const override
Serialize an object to a MutableBitVector (LSB-first stream).
Definition Types.cpp:122
std::ptrdiff_t getBitWidth() const override
Definition Types.h:125
ChannelType(const ID &id, const Type *inner)
Definition Types.h:123
const Type * getInner() const
Definition Types.h:124
const Type * inner
Definition Types.h:132
std::any deserialize(BitVector &data) const override
Deserialize from a BitVector stream (LSB-first).
Definition Types.cpp:126
Integers are bit vectors which may be signed or unsigned and are interpreted as numbers.
Definition Types.h:211
Lists represent variable-length sequences of elements of a single type.
Definition Types.h:348
ListType(const ID &id, const Type *elementType)
Definition Types.h:350
std::ptrdiff_t getBitWidth() const override
Definition Types.h:355
const Type * elementType
Definition Types.h:358
const Type * getElementType() const
Definition Types.h:353
A logical chunk of data representing serialized data.
Definition Common.h:113
A mutable bit vector that owns its underlying storage.
Definition Values.h:185
Signed integer.
Definition Types.h:217
std::any deserialize(BitVector &data) const override
Deserialize from a BitVector stream (LSB-first).
Definition Types.cpp:272
MutableBitVector serialize(const std::any &obj) const override
Serialize an object to a MutableBitVector (LSB-first stream).
Definition Types.cpp:261
void ensureValid(const std::any &obj) const override
Ensure that a std::any object is valid for this type.
Definition Types.cpp:251
Structs are an ordered collection of fields, each with a name and a type.
Definition Types.h:239
bool isReverse() const
Definition Types.h:268
void ensureValid(const std::any &obj) const override
Ensure that a std::any object is valid for this type.
Definition Types.cpp:314
std::vector< std::pair< std::string, const Type * > > FieldVector
Definition Types.h:241
FieldVector fields
Definition Types.h:271
std::ptrdiff_t getBitWidth() const override
Definition Types.h:248
MutableBitVector serialize(const std::any &obj) const override
Serialize an object to a MutableBitVector (LSB-first stream).
Definition Types.cpp:342
StructType(const ID &id, const FieldVector &fields, bool reverse=true)
Definition Types.h:244
const FieldVector & getFields() const
Definition Types.h:247
std::any deserialize(BitVector &data) const override
Deserialize from a BitVector stream (LSB-first).
Definition Types.cpp:363
Type aliases provide a named type which forwards to an inner type.
Definition Types.h:159
std::ptrdiff_t getBitWidth() const override
Definition Types.h:172
const Type * innerType
Definition Types.h:182
void ensureValid(const std::any &obj) const override
Ensure that a std::any object is valid for this type.
Definition Types.cpp:166
TypeAliasType(const ID &id, std::string name, const Type *innerType)
Definition Types.h:163
std::string name
Definition Types.h:181
const Type * getInnerType() const
Definition Types.h:170
std::any deserialize(BitVector &data) const override
Deserialize from a BitVector stream (LSB-first).
Definition Types.cpp:174
MutableBitVector serialize(const std::any &obj) const override
Serialize an object to a MutableBitVector (LSB-first stream).
Definition Types.cpp:170
const std::string & getName() const
Definition Types.h:169
Root class of the ESI type system.
Definition Types.h:36
ID id
Definition Types.h:92
virtual void ensureValid(const std::any &obj) const
Ensure that a std::any object is valid for this type.
Definition Types.h:70
virtual ~Type()=default
std::string toString(bool oneLine=false) const
Definition Types.cpp:103
Type(const ID &id)
Definition Types.h:39
virtual std::ptrdiff_t getBitWidth() const
Definition Types.h:43
std::any deserialize(const MessageData &data) const
Definition Types.h:63
std::string ID
Definition Types.h:38
virtual std::any deserialize(BitVector &data) const
Deserialize from a BitVector stream (LSB-first).
Definition Types.h:56
ID getID() const
Definition Types.h:42
std::optional< std::string > isValid(const std::any &obj) const
Definition Types.h:76
virtual MutableBitVector serialize(const std::any &obj) const
Serialize an object to a MutableBitVector (LSB-first stream).
Definition Types.h:49
void dump(std::ostream &os, bool oneLine=false) const
Definition Types.cpp:98
Unsigned integer.
Definition Types.h:228
std::any deserialize(BitVector &data) const override
Deserialize from a BitVector stream (LSB-first).
Definition Types.cpp:303
MutableBitVector serialize(const std::any &obj) const override
Serialize an object to a MutableBitVector (LSB-first stream).
Definition Types.cpp:293
void ensureValid(const std::any &obj) const override
Ensure that a std::any object is valid for this type.
Definition Types.cpp:283
The "void" type is a special type which can be used to represent no type.
Definition Types.h:136
std::any deserialize(BitVector &data) const override
Deserialize from a BitVector stream (LSB-first).
Definition Types.cpp:146
VoidType(const ID &id)
Definition Types.h:139
void ensureValid(const std::any &obj) const override
Ensure that a std::any object is valid for this type.
Definition Types.cpp:130
std::ptrdiff_t getBitWidth() const override
Definition Types.h:141
MutableBitVector serialize(const std::any &obj) const override
Serialize an object to a MutableBitVector (LSB-first stream).
Definition Types.cpp:159
Windows represent a fixed-size sliding window over a stream of data.
Definition Types.h:309
std::ptrdiff_t getBitWidth() const override
Definition Types.h:335
std::vector< Frame > frames
Definition Types.h:343
const std::vector< Frame > & getFrames() const
Definition Types.h:333
const Type * intoType
Definition Types.h:341
std::string name
Definition Types.h:340
const Type * getLoweredType() const
Definition Types.h:332
const std::string & getName() const
Definition Types.h:330
const Type * loweredType
Definition Types.h:342
const Type * getIntoType() const
Definition Types.h:331
WindowType(const ID &id, const std::string &name, const Type *intoType, const Type *loweredType, const std::vector< Frame > &frames)
Definition Types.h:325
Definition esi.py:1
Field information describing a field within a frame.
Definition Types.h:312
uint64_t bulkCountWidth
Definition Types.h:315
std::string name
Definition Types.h:313
Frame information describing which fields are included in a particular frame.
Definition Types.h:320
std::vector< Field > fields
Definition Types.h:322
std::string name
Definition Types.h:321