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
83 // Dump a textual representation of this type to the provided stream.
84 void dump(std::ostream &os);
85
86 // Return a textual representation of this type.
87 std::string toString();
88
89protected:
91};
92
93/// Bundles represent a collection of channels. Services exclusively expose
94/// bundles (sometimes of just one channel). As such, they are the type of
95/// accessible ports on an accelerator, from a host API perspective.
96/// TODO: Add a good description of direction?
97class BundleType : public Type {
98public:
99 enum Direction { To, From };
100
102 std::vector<std::tuple<std::string, Direction, const Type *>>;
103
105 : Type(id), channels(channels) {}
106
107 const ChannelVector &getChannels() const { return channels; }
108 std::ptrdiff_t getBitWidth() const override { return -1; };
109
110 std::pair<const Type *, Direction> findChannel(std::string name) const;
111
112protected:
114};
115
116/// Channels are the basic communication primitives. They are unidirectional and
117/// carry one values of one type.
118class ChannelType : public Type {
119public:
120 using Type::deserialize;
121 ChannelType(const ID &id, const Type *inner) : Type(id), inner(inner) {}
122 const Type *getInner() const { return inner; }
123 std::ptrdiff_t getBitWidth() const override { return inner->getBitWidth(); };
124
125 void ensureValid(const std::any &obj) const override;
126 MutableBitVector serialize(const std::any &obj) const override;
127 std::any deserialize(BitVector &data) const override;
128
129private:
130 const Type *inner;
131};
132
133/// The "void" type is a special type which can be used to represent no type.
134class VoidType : public Type {
135public:
136 using Type::deserialize;
137 VoidType(const ID &id) : Type(id) {}
138 // 'void' is 1 bit by convention.
139 std::ptrdiff_t getBitWidth() const override { return 1; };
140
141 void ensureValid(const std::any &obj) const override;
142 MutableBitVector serialize(const std::any &obj) const override;
143 std::any deserialize(BitVector &data) const override;
144};
145
146/// The "any" type is a special type which can be used to represent any type, as
147/// identified by the type id. Said type id is guaranteed to be present in the
148/// manifest. Importantly, the "any" type id over the wire may not be a string
149/// as it is in software.
150class AnyType : public Type {
151public:
152 AnyType(const ID &id) : Type(id) {}
153 std::ptrdiff_t getBitWidth() const override { return -1; };
154};
155
156/// Bit vectors include signed, unsigned, and signless integers.
157class BitVectorType : public Type {
158public:
159 BitVectorType(const ID &id, uint64_t width) : Type(id), width(width) {}
160
161 uint64_t getWidth() const { return width; }
162 std::ptrdiff_t getBitWidth() const override { return getWidth(); };
163
164private:
165 uint64_t width;
166};
167
168/// Bits are just an array of bits. They are not interpreted as a number but are
169/// identified in the manifest as "signless" ints.
170class BitsType : public BitVectorType {
171public:
173 using Type::deserialize;
174
175 void ensureValid(const std::any &obj) const override;
176 MutableBitVector serialize(const std::any &obj) const override;
177 std::any deserialize(BitVector &data) const override;
178};
179
180/// Integers are bit vectors which may be signed or unsigned and are interpreted
181/// as numbers.
183public:
185};
186
187/// Signed integer.
188class SIntType : public IntegerType {
189public:
190 using IntegerType::IntegerType;
191 using Type::deserialize;
192
193 void ensureValid(const std::any &obj) const override;
194 MutableBitVector serialize(const std::any &obj) const override;
195 std::any deserialize(BitVector &data) const override;
196};
197
198/// Unsigned integer.
199class UIntType : public IntegerType {
200public:
201 using IntegerType::IntegerType;
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/// Structs are an ordered collection of fields, each with a name and a type.
210class StructType : public Type {
211public:
212 using FieldVector = std::vector<std::pair<std::string, const Type *>>;
213 using Type::deserialize;
214
215 StructType(const ID &id, const FieldVector &fields, bool reverse = true)
217
218 const FieldVector &getFields() const { return fields; }
219 std::ptrdiff_t getBitWidth() const override {
220 std::ptrdiff_t size = 0;
221 for (auto [name, ty] : getFields()) {
222 std::ptrdiff_t fieldSize = ty->getBitWidth();
223 if (fieldSize < 0)
224 return -1;
225 size += fieldSize;
226 }
227 return size;
228 }
229
230 void ensureValid(const std::any &obj) const override;
231 MutableBitVector serialize(const std::any &obj) const override;
232 std::any deserialize(BitVector &data) const override;
233
234 // Returns whether this struct type should be reversed when
235 // serializing/deserializing.
236 // By default, a truthy value here makes StructType's compatible with system
237 // verilog, which has reversed struct field ordering, wrt. C/software struct
238 // ordering.
239 bool isReverse() const { return reverse; }
240
241private:
244};
245
246/// Arrays have a compile time specified (static) size and an element type.
247class ArrayType : public Type {
248public:
249 ArrayType(const ID &id, const Type *elementType, uint64_t size,
250 bool reverse = true)
252 using Type::deserialize;
253
254 const Type *getElementType() const { return elementType; }
255 uint64_t getSize() const { return size; }
256 bool isReverse() const { return reverse; }
257 std::ptrdiff_t getBitWidth() const override {
258 std::ptrdiff_t elementSize = elementType->getBitWidth();
259 if (elementSize < 0)
260 return -1;
261 return elementSize * size;
262 }
263
264 void ensureValid(const std::any &obj) const override;
265 MutableBitVector serialize(const std::any &obj) const override;
266 std::any deserialize(BitVector &data) const override;
267
268private:
270 uint64_t size;
271 // 'reverse' controls whether array elements are reversed during
272 // serialization/deserialization (to match SystemVerilog/Python ordering
273 // expectations).
275};
276
277} // namespace esi
278
279#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:150
std::ptrdiff_t getBitWidth() const override
Definition Types.h:153
AnyType(const ID &id)
Definition Types.h:152
Arrays have a compile time specified (static) size and an element type.
Definition Types.h:247
uint64_t size
Definition Types.h:270
MutableBitVector serialize(const std::any &obj) const override
Serialize an object to a MutableBitVector (LSB-first stream).
Definition Types.cpp:342
void ensureValid(const std::any &obj) const override
Ensure that a std::any object is valid for this type.
Definition Types.cpp:320
bool reverse
Definition Types.h:274
std::any deserialize(BitVector &data) const override
Deserialize from a BitVector stream (LSB-first).
Definition Types.cpp:361
const Type * elementType
Definition Types.h:269
const Type * getElementType() const
Definition Types.h:254
std::ptrdiff_t getBitWidth() const override
Definition Types.h:257
ArrayType(const ID &id, const Type *elementType, uint64_t size, bool reverse=true)
Definition Types.h:249
uint64_t getSize() const
Definition Types.h:255
bool isReverse() const
Definition Types.h:256
Bit vectors include signed, unsigned, and signless integers.
Definition Types.h:157
BitVectorType(const ID &id, uint64_t width)
Definition Types.h:159
uint64_t width
Definition Types.h:165
std::ptrdiff_t getBitWidth() const override
Definition Types.h:162
uint64_t getWidth() const
Definition Types.h:161
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:170
void ensureValid(const std::any &obj) const override
Ensure that a std::any object is valid for this type.
Definition Types.cpp:131
std::any deserialize(BitVector &data) const override
Deserialize from a BitVector stream (LSB-first).
Definition Types.cpp:151
MutableBitVector serialize(const std::any &obj) const override
Serialize an object to a MutableBitVector (LSB-first stream).
Definition Types.cpp:145
Bundles represent a collection of channels.
Definition Types.h:97
BundleType(const ID &id, const ChannelVector &channels)
Definition Types.h:104
std::ptrdiff_t getBitWidth() const override
Definition Types.h:108
const ChannelVector & getChannels() const
Definition Types.h:107
ChannelVector channels
Definition Types.h:113
std::vector< std::tuple< std::string, Direction, const Type * > > ChannelVector
Definition Types.h:102
std::pair< const Type *, Direction > findChannel(std::string name) const
Definition Types.cpp:78
Channels are the basic communication primitives.
Definition Types.h:118
void ensureValid(const std::any &obj) const override
Ensure that a std::any object is valid for this type.
Definition Types.cpp:86
MutableBitVector serialize(const std::any &obj) const override
Serialize an object to a MutableBitVector (LSB-first stream).
Definition Types.cpp:90
ChannelType(const ID &id, const Type *inner)
Definition Types.h:121
const Type * getInner() const
Definition Types.h:122
const Type * inner
Definition Types.h:130
std::any deserialize(BitVector &data) const override
Deserialize from a BitVector stream (LSB-first).
Definition Types.cpp:94
std::ptrdiff_t getBitWidth() const override
Definition Types.h:123
Integers are bit vectors which may be signed or unsigned and are interpreted as numbers.
Definition Types.h:182
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:188
std::any deserialize(BitVector &data) const override
Deserialize from a BitVector stream (LSB-first).
Definition Types.cpp:221
MutableBitVector serialize(const std::any &obj) const override
Serialize an object to a MutableBitVector (LSB-first stream).
Definition Types.cpp:213
void ensureValid(const std::any &obj) const override
Ensure that a std::any object is valid for this type.
Definition Types.cpp:203
Structs are an ordered collection of fields, each with a name and a type.
Definition Types.h:210
std::ptrdiff_t getBitWidth() const override
Definition Types.h:219
bool isReverse() const
Definition Types.h:239
void ensureValid(const std::any &obj) const override
Ensure that a std::any object is valid for this type.
Definition Types.cpp:256
std::vector< std::pair< std::string, const Type * > > FieldVector
Definition Types.h:212
FieldVector fields
Definition Types.h:242
MutableBitVector serialize(const std::any &obj) const override
Serialize an object to a MutableBitVector (LSB-first stream).
Definition Types.cpp:282
StructType(const ID &id, const FieldVector &fields, bool reverse=true)
Definition Types.h:215
const FieldVector & getFields() const
Definition Types.h:218
std::any deserialize(BitVector &data) const override
Deserialize from a BitVector stream (LSB-first).
Definition Types.cpp:303
Root class of the ESI type system.
Definition Types.h:34
ID id
Definition Types.h:90
virtual void ensureValid(const std::any &obj) const
Ensure that a std::any object is valid for this type.
Definition Types.h:68
void dump(std::ostream &os)
Definition Types.cpp: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
std::string toString()
Definition Types.cpp:71
Unsigned integer.
Definition Types.h:199
std::any deserialize(BitVector &data) const override
Deserialize from a BitVector stream (LSB-first).
Definition Types.cpp:247
MutableBitVector serialize(const std::any &obj) const override
Serialize an object to a MutableBitVector (LSB-first stream).
Definition Types.cpp:240
void ensureValid(const std::any &obj) const override
Ensure that a std::any object is valid for this type.
Definition Types.cpp:230
The "void" type is a special type which can be used to represent no type.
Definition Types.h:134
std::any deserialize(BitVector &data) const override
Deserialize from a BitVector stream (LSB-first).
Definition Types.cpp:112
VoidType(const ID &id)
Definition Types.h:137
void ensureValid(const std::any &obj) const override
Ensure that a std::any object is valid for this type.
Definition Types.cpp:98
std::ptrdiff_t getBitWidth() const override
Definition Types.h:139
MutableBitVector serialize(const std::any &obj) const override
Serialize an object to a MutableBitVector (LSB-first stream).
Definition Types.cpp:124
Definition esi.py:1