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