CIRCT 22.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 <cstdint>
22#include <map>
23#include <span>
24#include <stdexcept>
25#include <string>
26#include <vector>
27
28#include "esi/Common.h"
29#include "esi/Values.h" // For BitVector / Int / UInt
30
31namespace esi {
32
33/// Root class of the ESI type system.
34class Type {
35public:
36 using ID = std::string;
37 Type(const ID &id) : id(id) {}
38 virtual ~Type() = default;
39
40 ID getID() const { return id; }
41 virtual std::ptrdiff_t getBitWidth() const { return -1; }
42
43 /// Serialize an object to a MutableBitVector (LSB-first stream). The object
44 /// should be passed via std::any. Implementations append fields in the order
45 /// they are iterated (the first serialized field occupies the
46 /// least-significant bits of the result).
47 virtual MutableBitVector serialize(const std::any &obj) const {
48 throw std::runtime_error("Serialization not implemented for type " + id);
49 }
50
51 /// Deserialize from a BitVector stream (LSB-first). Implementations consume
52 /// bits from 'data' in-place (via logical right shifts) and return the
53 /// reconstructed value. Remaining bits stay in 'data'.
54 virtual std::any deserialize(BitVector &data) const {
55 throw std::runtime_error("Deserialization not implemented for type " + id);
56 }
57
58 // Deserialize from a MessageData buffer. Maps the MessageData onto a
59 // MutableBitVector, and proceeds with regular MutableBitVector
60 // deserialization.
61 std::any deserialize(const MessageData &data) const {
62 auto bv = MutableBitVector(std::vector<uint8_t>(data.getData()));
63 return deserialize(bv);
64 }
65
66 /// Ensure that a std::any object is valid for this type. Throws
67 /// std::runtime_error if the object is not valid.
68 virtual void ensureValid(const std::any &obj) const {
69 throw std::runtime_error("Validation not implemented for type " + id);
70 }
71
72 // Check if a std::any object is valid for this type. Returns an optional
73 // error message if the object is not valid, else, std::nullopt.
74 std::optional<std::string> isValid(const std::any &obj) const {
75 try {
76 ensureValid(obj);
77 return std::nullopt;
78 } catch (const std::runtime_error &e) {
79 return e.what();
80 }
81 }
82
83protected:
85};
86
87/// Bundles represent a collection of channels. Services exclusively expose
88/// bundles (sometimes of just one channel). As such, they are the type of
89/// accessible ports on an accelerator, from a host API perspective.
90/// TODO: Add a good description of direction?
91class BundleType : public Type {
92public:
93 enum Direction { To, From };
94
96 std::vector<std::tuple<std::string, Direction, const Type *>>;
97
99 : Type(id), channels(channels) {}
100
101 const ChannelVector &getChannels() const { return channels; }
102 std::ptrdiff_t getBitWidth() const override { return -1; };
103
104 std::pair<const Type *, Direction> findChannel(std::string name) const;
105
106protected:
108};
109
110/// Channels are the basic communication primitives. They are unidirectional and
111/// carry one values of one type.
112class ChannelType : public Type {
113public:
114 using Type::deserialize;
115 ChannelType(const ID &id, const Type *inner) : Type(id), inner(inner) {}
116 const Type *getInner() const { return inner; }
117 std::ptrdiff_t getBitWidth() const override { return inner->getBitWidth(); };
118
119 void ensureValid(const std::any &obj) const override;
120 MutableBitVector serialize(const std::any &obj) const override;
121 std::any deserialize(BitVector &data) const override;
122
123private:
124 const Type *inner;
125};
126
127/// The "void" type is a special type which can be used to represent no type.
128class VoidType : public Type {
129public:
130 using Type::deserialize;
131 VoidType(const ID &id) : Type(id) {}
132 // 'void' is 1 bit by convention.
133 std::ptrdiff_t getBitWidth() const override { return 1; };
134
135 void ensureValid(const std::any &obj) const override;
136 MutableBitVector serialize(const std::any &obj) const override;
137 std::any deserialize(BitVector &data) const override;
138};
139
140/// The "any" type is a special type which can be used to represent any type, as
141/// identified by the type id. Said type id is guaranteed to be present in the
142/// manifest. Importantly, the "any" type id over the wire may not be a string
143/// as it is in software.
144class AnyType : public Type {
145public:
146 AnyType(const ID &id) : Type(id) {}
147 std::ptrdiff_t getBitWidth() const override { return -1; };
148};
149
150/// Bit vectors include signed, unsigned, and signless integers.
151class BitVectorType : public Type {
152public:
153 BitVectorType(const ID &id, uint64_t width) : Type(id), width(width) {}
154
155 uint64_t getWidth() const { return width; }
156 std::ptrdiff_t getBitWidth() const override { return getWidth(); };
157
158private:
159 uint64_t width;
160};
161
162/// Bits are just an array of bits. They are not interpreted as a number but are
163/// identified in the manifest as "signless" ints.
164class BitsType : public BitVectorType {
165public:
167 using Type::deserialize;
168
169 void ensureValid(const std::any &obj) const override;
170 MutableBitVector serialize(const std::any &obj) const override;
171 std::any deserialize(BitVector &data) const override;
172};
173
174/// Integers are bit vectors which may be signed or unsigned and are interpreted
175/// as numbers.
177public:
179};
180
181/// Signed integer.
182class SIntType : public IntegerType {
183public:
184 using IntegerType::IntegerType;
185 using Type::deserialize;
186
187 void ensureValid(const std::any &obj) const override;
188 MutableBitVector serialize(const std::any &obj) const override;
189 std::any deserialize(BitVector &data) const override;
190};
191
192/// Unsigned integer.
193class UIntType : public IntegerType {
194public:
195 using IntegerType::IntegerType;
196 using Type::deserialize;
197
198 void ensureValid(const std::any &obj) const override;
199 MutableBitVector serialize(const std::any &obj) const override;
200 std::any deserialize(BitVector &data) const override;
201};
202
203/// Structs are an ordered collection of fields, each with a name and a type.
204class StructType : public Type {
205public:
206 using FieldVector = std::vector<std::pair<std::string, const Type *>>;
207 using Type::deserialize;
208
209 StructType(const ID &id, const FieldVector &fields, bool reverse = true)
211
212 const FieldVector &getFields() const { return fields; }
213 std::ptrdiff_t getBitWidth() const override {
214 std::ptrdiff_t size = 0;
215 for (auto [name, ty] : getFields()) {
216 std::ptrdiff_t fieldSize = ty->getBitWidth();
217 if (fieldSize < 0)
218 return -1;
219 size += fieldSize;
220 }
221 return size;
222 }
223
224 void ensureValid(const std::any &obj) const override;
225 MutableBitVector serialize(const std::any &obj) const override;
226 std::any deserialize(BitVector &data) const override;
227
228 // Returns whether this struct type should be reversed when
229 // serializing/deserializing.
230 // By default, a truthy value here makes StructType's compatible with system
231 // verilog, which has reversed struct field ordering, wrt. C/software struct
232 // ordering.
233 bool isReverse() const { return reverse; }
234
235private:
238};
239
240/// Arrays have a compile time specified (static) size and an element type.
241class ArrayType : public Type {
242public:
243 ArrayType(const ID &id, const Type *elementType, uint64_t size,
244 bool reverse = true)
246 using Type::deserialize;
247
248 const Type *getElementType() const { return elementType; }
249 uint64_t getSize() const { return size; }
250 bool isReverse() const { return reverse; }
251 std::ptrdiff_t getBitWidth() const override {
252 std::ptrdiff_t elementSize = elementType->getBitWidth();
253 if (elementSize < 0)
254 return -1;
255 return elementSize * size;
256 }
257
258 void ensureValid(const std::any &obj) const override;
259 MutableBitVector serialize(const std::any &obj) const override;
260 std::any deserialize(BitVector &data) const override;
261
262private:
264 uint64_t size;
265 // 'reverse' controls whether array elements are reversed during
266 // serialization/deserialization (to match SystemVerilog/Python ordering
267 // expectations).
269};
270
271} // namespace esi
272
273#endif // ESI_TYPES_H
The "any" type is a special type which can be used to represent any type, as identified by the type i...
Definition Types.h:144
std::ptrdiff_t getBitWidth() const override
Definition Types.h:147
AnyType(const ID &id)
Definition Types.h:146
Arrays have a compile time specified (static) size and an element type.
Definition Types.h:241
uint64_t size
Definition Types.h:264
MutableBitVector serialize(const std::any &obj) const override
Serialize an object to a MutableBitVector (LSB-first stream).
Definition Types.cpp:289
void ensureValid(const std::any &obj) const override
Ensure that a std::any object is valid for this type.
Definition Types.cpp:267
bool reverse
Definition Types.h:268
std::any deserialize(BitVector &data) const override
Deserialize from a BitVector stream (LSB-first).
Definition Types.cpp:308
const Type * elementType
Definition Types.h:263
const Type * getElementType() const
Definition Types.h:248
std::ptrdiff_t getBitWidth() const override
Definition Types.h:251
ArrayType(const ID &id, const Type *elementType, uint64_t size, bool reverse=true)
Definition Types.h:243
uint64_t getSize() const
Definition Types.h:249
bool isReverse() const
Definition Types.h:250
Bit vectors include signed, unsigned, and signless integers.
Definition Types.h:151
BitVectorType(const ID &id, uint64_t width)
Definition Types.h:153
uint64_t width
Definition Types.h:159
std::ptrdiff_t getBitWidth() const override
Definition Types.h:156
uint64_t getWidth() const
Definition Types.h:155
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:164
void ensureValid(const std::any &obj) const override
Ensure that a std::any object is valid for this type.
Definition Types.cpp:78
std::any deserialize(BitVector &data) const override
Deserialize from a BitVector stream (LSB-first).
Definition Types.cpp:98
MutableBitVector serialize(const std::any &obj) const override
Serialize an object to a MutableBitVector (LSB-first stream).
Definition Types.cpp:92
Bundles represent a collection of channels.
Definition Types.h:91
BundleType(const ID &id, const ChannelVector &channels)
Definition Types.h:98
std::ptrdiff_t getBitWidth() const override
Definition Types.h:102
const ChannelVector & getChannels() const
Definition Types.h:101
ChannelVector channels
Definition Types.h:107
std::vector< std::tuple< std::string, Direction, const Type * > > ChannelVector
Definition Types.h:96
std::pair< const Type *, Direction > findChannel(std::string name) const
Definition Types.cpp:25
Channels are the basic communication primitives.
Definition Types.h:112
void ensureValid(const std::any &obj) const override
Ensure that a std::any object is valid for this type.
Definition Types.cpp:33
MutableBitVector serialize(const std::any &obj) const override
Serialize an object to a MutableBitVector (LSB-first stream).
Definition Types.cpp:37
ChannelType(const ID &id, const Type *inner)
Definition Types.h:115
const Type * getInner() const
Definition Types.h:116
const Type * inner
Definition Types.h:124
std::any deserialize(BitVector &data) const override
Deserialize from a BitVector stream (LSB-first).
Definition Types.cpp:41
std::ptrdiff_t getBitWidth() const override
Definition Types.h:117
Integers are bit vectors which may be signed or unsigned and are interpreted as numbers.
Definition Types.h:176
A logical chunk of data representing serialized data.
Definition Common.h:107
A mutable bit vector that owns its underlying storage.
Definition Values.h:185
Signed integer.
Definition Types.h:182
std::any deserialize(BitVector &data) const override
Deserialize from a BitVector stream (LSB-first).
Definition Types.cpp:168
MutableBitVector serialize(const std::any &obj) const override
Serialize an object to a MutableBitVector (LSB-first stream).
Definition Types.cpp:160
void ensureValid(const std::any &obj) const override
Ensure that a std::any object is valid for this type.
Definition Types.cpp:150
Structs are an ordered collection of fields, each with a name and a type.
Definition Types.h:204
std::ptrdiff_t getBitWidth() const override
Definition Types.h:213
bool isReverse() const
Definition Types.h:233
void ensureValid(const std::any &obj) const override
Ensure that a std::any object is valid for this type.
Definition Types.cpp:203
std::vector< std::pair< std::string, const Type * > > FieldVector
Definition Types.h:206
FieldVector fields
Definition Types.h:236
MutableBitVector serialize(const std::any &obj) const override
Serialize an object to a MutableBitVector (LSB-first stream).
Definition Types.cpp:229
StructType(const ID &id, const FieldVector &fields, bool reverse=true)
Definition Types.h:209
const FieldVector & getFields() const
Definition Types.h:212
std::any deserialize(BitVector &data) const override
Deserialize from a BitVector stream (LSB-first).
Definition Types.cpp:250
Root class of the ESI type system.
Definition Types.h:34
ID id
Definition Types.h:84
virtual void ensureValid(const std::any &obj) const
Ensure that a std::any object is valid for this type.
Definition Types.h:68
virtual ~Type()=default
Type(const ID &id)
Definition Types.h:37
virtual std::ptrdiff_t getBitWidth() const
Definition Types.h:41
std::any deserialize(const MessageData &data) const
Definition Types.h:61
std::string ID
Definition Types.h:36
virtual std::any deserialize(BitVector &data) const
Deserialize from a BitVector stream (LSB-first).
Definition Types.h:54
ID getID() const
Definition Types.h:40
std::optional< std::string > isValid(const std::any &obj) const
Definition Types.h:74
virtual MutableBitVector serialize(const std::any &obj) const
Serialize an object to a MutableBitVector (LSB-first stream).
Definition Types.h:47
Unsigned integer.
Definition Types.h:193
std::any deserialize(BitVector &data) const override
Deserialize from a BitVector stream (LSB-first).
Definition Types.cpp:194
MutableBitVector serialize(const std::any &obj) const override
Serialize an object to a MutableBitVector (LSB-first stream).
Definition Types.cpp:187
void ensureValid(const std::any &obj) const override
Ensure that a std::any object is valid for this type.
Definition Types.cpp:177
The "void" type is a special type which can be used to represent no type.
Definition Types.h:128
std::any deserialize(BitVector &data) const override
Deserialize from a BitVector stream (LSB-first).
Definition Types.cpp:59
VoidType(const ID &id)
Definition Types.h:131
void ensureValid(const std::any &obj) const override
Ensure that a std::any object is valid for this type.
Definition Types.cpp:45
std::ptrdiff_t getBitWidth() const override
Definition Types.h:133
MutableBitVector serialize(const std::any &obj) const override
Serialize an object to a MutableBitVector (LSB-first stream).
Definition Types.cpp:71
Definition esi.py:1