esiaccel 0.0.17.dev447__cp310-cp310-win_amd64.whl → 0.1.5.dev406__cp310-cp310-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of esiaccel might be problematic. Click here for more details.
- esiaccel/CosimBackend.dll +0 -0
- esiaccel/CosimBackend.lib +0 -0
- esiaccel/ESICppRuntime.dll +0 -0
- esiaccel/ESICppRuntime.lib +0 -0
- esiaccel/EsiCosimDpiServer.dll +0 -0
- esiaccel/EsiCosimDpiServer.lib +0 -0
- esiaccel/MtiPli.dll +0 -0
- esiaccel/MtiPli.lib +0 -0
- esiaccel/__init__.py +10 -1
- esiaccel/abseil_dll.dll +0 -0
- esiaccel/accelerator.py +7 -0
- esiaccel/cares.dll +0 -0
- esiaccel/cmake/esiaccelConfig.cmake +1 -1
- esiaccel/cosim/Cosim_DpiPkg.sv +85 -0
- esiaccel/cosim/Cosim_Endpoint.sv +218 -0
- esiaccel/cosim/Cosim_Manifest.sv +32 -0
- esiaccel/cosim/driver.cpp +131 -0
- esiaccel/cosim/driver.sv +74 -0
- esiaccel/cosim/questa.py +141 -0
- esiaccel/cosim/simulator.py +382 -0
- esiaccel/cosim/verilator.py +92 -0
- esiaccel/esi-cosim.py +104 -0
- esiaccel/esiCppAccel.cp310-win_amd64.pyd +0 -0
- esiaccel/esiquery.exe +0 -0
- esiaccel/include/esi/Accelerator.h +31 -15
- esiaccel/include/esi/CLI.h +77 -0
- esiaccel/include/esi/Common.h +32 -3
- esiaccel/include/esi/Context.h +1 -1
- esiaccel/include/esi/Design.h +11 -4
- esiaccel/include/esi/Engines.h +124 -0
- esiaccel/include/esi/Logging.h +57 -7
- esiaccel/include/esi/Manifest.h +0 -2
- esiaccel/include/esi/Ports.h +47 -6
- esiaccel/include/esi/Services.h +144 -41
- esiaccel/include/esi/Types.h +103 -5
- esiaccel/include/esi/Values.h +313 -0
- esiaccel/include/esi/backends/Cosim.h +85 -0
- esiaccel/include/esi/backends/RpcServer.h +55 -0
- esiaccel/include/esi/backends/Trace.h +5 -6
- esiaccel/libcrypto-3-x64.dll +0 -0
- esiaccel/libprotobuf.dll +0 -0
- esiaccel/libssl-3-x64.dll +0 -0
- esiaccel/re2.dll +0 -0
- esiaccel/types.py +132 -26
- esiaccel/utils.py +21 -3
- esiaccel/zlib1.dll +0 -0
- {esiaccel-0.0.17.dev447.dist-info → esiaccel-0.1.5.dev406.dist-info}/METADATA +3 -3
- esiaccel-0.1.5.dev406.dist-info/RECORD +54 -0
- {esiaccel-0.0.17.dev447.dist-info → esiaccel-0.1.5.dev406.dist-info}/WHEEL +1 -1
- esiaccel/bin/esiquery.exe +0 -0
- esiaccel-0.0.17.dev447.dist-info/RECORD +0 -28
- {esiaccel-0.0.17.dev447.dist-info → esiaccel-0.1.5.dev406.dist-info}/entry_points.txt +0 -0
- {esiaccel-0.0.17.dev447.dist-info → esiaccel-0.1.5.dev406.dist-info/licenses}/LICENSE +0 -0
- {esiaccel-0.0.17.dev447.dist-info → esiaccel-0.1.5.dev406.dist-info}/top_level.txt +0 -0
esiaccel/include/esi/Ports.h
CHANGED
|
@@ -25,6 +25,9 @@
|
|
|
25
25
|
|
|
26
26
|
namespace esi {
|
|
27
27
|
|
|
28
|
+
class ChannelPort;
|
|
29
|
+
using PortMap = std::map<std::string, ChannelPort &>;
|
|
30
|
+
|
|
28
31
|
/// Unidirectional channels are the basic communication primitive between the
|
|
29
32
|
/// host and accelerator. A 'ChannelPort' is the host side of a channel. It can
|
|
30
33
|
/// be either read or write but not both. At this level, channels are untyped --
|
|
@@ -96,6 +99,24 @@ private:
|
|
|
96
99
|
volatile bool connected = false;
|
|
97
100
|
};
|
|
98
101
|
|
|
102
|
+
/// Instantiated when a backend does not know how to create a write channel.
|
|
103
|
+
class UnknownWriteChannelPort : public WriteChannelPort {
|
|
104
|
+
public:
|
|
105
|
+
UnknownWriteChannelPort(const Type *type, std::string errmsg)
|
|
106
|
+
: WriteChannelPort(type), errmsg(errmsg) {}
|
|
107
|
+
|
|
108
|
+
void connect(std::optional<unsigned> bufferSize = std::nullopt) override {
|
|
109
|
+
throw std::runtime_error(errmsg);
|
|
110
|
+
}
|
|
111
|
+
void write(const MessageData &) override { throw std::runtime_error(errmsg); }
|
|
112
|
+
bool tryWrite(const MessageData &) override {
|
|
113
|
+
throw std::runtime_error(errmsg);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
protected:
|
|
117
|
+
std::string errmsg;
|
|
118
|
+
};
|
|
119
|
+
|
|
99
120
|
/// A ChannelPort which reads data from the accelerator. It has two modes:
|
|
100
121
|
/// Callback and Polling which cannot be used at the same time. The mode is set
|
|
101
122
|
/// at connect() time. To change the mode, disconnect() and then connect()
|
|
@@ -178,6 +199,27 @@ protected:
|
|
|
178
199
|
std::queue<std::promise<MessageData>> promiseQueue;
|
|
179
200
|
};
|
|
180
201
|
|
|
202
|
+
/// Instantiated when a backend does not know how to create a read channel.
|
|
203
|
+
class UnknownReadChannelPort : public ReadChannelPort {
|
|
204
|
+
public:
|
|
205
|
+
UnknownReadChannelPort(const Type *type, std::string errmsg)
|
|
206
|
+
: ReadChannelPort(type), errmsg(errmsg) {}
|
|
207
|
+
|
|
208
|
+
void connect(std::function<bool(MessageData)> callback,
|
|
209
|
+
std::optional<unsigned> bufferSize = std::nullopt) override {
|
|
210
|
+
throw std::runtime_error(errmsg);
|
|
211
|
+
}
|
|
212
|
+
void connect(std::optional<unsigned> bufferSize = std::nullopt) override {
|
|
213
|
+
throw std::runtime_error(errmsg);
|
|
214
|
+
}
|
|
215
|
+
std::future<MessageData> readAsync() override {
|
|
216
|
+
throw std::runtime_error(errmsg);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
protected:
|
|
220
|
+
std::string errmsg;
|
|
221
|
+
};
|
|
222
|
+
|
|
181
223
|
/// Services provide connections to 'bundles' -- collections of named,
|
|
182
224
|
/// unidirectional communication channels. This class provides access to those
|
|
183
225
|
/// ChannelPorts.
|
|
@@ -190,7 +232,7 @@ public:
|
|
|
190
232
|
}
|
|
191
233
|
|
|
192
234
|
/// Construct a port.
|
|
193
|
-
BundlePort(AppID id,
|
|
235
|
+
BundlePort(AppID id, const BundleType *type, PortMap channels);
|
|
194
236
|
virtual ~BundlePort() = default;
|
|
195
237
|
|
|
196
238
|
/// Get the ID of the port.
|
|
@@ -202,9 +244,7 @@ public:
|
|
|
202
244
|
/// ordinary users should not use. You have been warned.
|
|
203
245
|
WriteChannelPort &getRawWrite(const std::string &name) const;
|
|
204
246
|
ReadChannelPort &getRawRead(const std::string &name) const;
|
|
205
|
-
const
|
|
206
|
-
return channels;
|
|
207
|
-
}
|
|
247
|
+
const PortMap &getChannels() const { return channels; }
|
|
208
248
|
|
|
209
249
|
/// Cast this Bundle port to a subclass which is actually useful. Returns
|
|
210
250
|
/// nullptr if the cast fails.
|
|
@@ -224,9 +264,10 @@ public:
|
|
|
224
264
|
return result;
|
|
225
265
|
}
|
|
226
266
|
|
|
227
|
-
|
|
267
|
+
protected:
|
|
228
268
|
AppID id;
|
|
229
|
-
|
|
269
|
+
const BundleType *type;
|
|
270
|
+
PortMap channels;
|
|
230
271
|
};
|
|
231
272
|
|
|
232
273
|
} // namespace esi
|
esiaccel/include/esi/Services.h
CHANGED
|
@@ -25,9 +25,21 @@
|
|
|
25
25
|
#include "esi/Ports.h"
|
|
26
26
|
|
|
27
27
|
#include <cstdint>
|
|
28
|
+
#include <list>
|
|
28
29
|
|
|
29
30
|
namespace esi {
|
|
30
31
|
class AcceleratorConnection;
|
|
32
|
+
class Engine;
|
|
33
|
+
namespace services {
|
|
34
|
+
class Service;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// While building the design, keep around a std::map of active services indexed
|
|
38
|
+
// by the service name. When a new service is encountered during descent, add it
|
|
39
|
+
// to the table (perhaps overwriting one). Modifications to the table only apply
|
|
40
|
+
// to the current branch, so copy this and update it at each level of the tree.
|
|
41
|
+
using ServiceTable = std::map<std::string, services::Service *>;
|
|
42
|
+
|
|
31
43
|
namespace services {
|
|
32
44
|
|
|
33
45
|
/// Add a custom interface to a service client at a particular point in the
|
|
@@ -45,6 +57,7 @@ public:
|
|
|
45
57
|
class Service {
|
|
46
58
|
public:
|
|
47
59
|
using Type = const std::type_info &;
|
|
60
|
+
Service(AcceleratorConnection &conn) : conn(conn) {}
|
|
48
61
|
virtual ~Service() = default;
|
|
49
62
|
|
|
50
63
|
virtual std::string getServiceSymbol() const = 0;
|
|
@@ -56,19 +69,21 @@ public:
|
|
|
56
69
|
/// calling the `getService` method on `AcceleratorConnection` to get the
|
|
57
70
|
/// global service, implying that the child service does not need to use the
|
|
58
71
|
/// service it is replacing.
|
|
59
|
-
virtual Service *getChildService(
|
|
60
|
-
Service::Type service, AppIDPath id = {},
|
|
72
|
+
virtual Service *getChildService(Service::Type service, AppIDPath id = {},
|
|
61
73
|
std::string implName = {},
|
|
62
74
|
ServiceImplDetails details = {},
|
|
63
75
|
HWClientDetails clients = {});
|
|
64
76
|
|
|
65
77
|
/// Get specialized port for this service to attach to the given appid path.
|
|
66
78
|
/// Null returns mean nothing to attach.
|
|
67
|
-
virtual
|
|
68
|
-
const std::map<std::string, ChannelPort &> &,
|
|
69
|
-
AcceleratorConnection &) const {
|
|
79
|
+
virtual BundlePort *getPort(AppIDPath id, const BundleType *type) const {
|
|
70
80
|
return nullptr;
|
|
71
81
|
}
|
|
82
|
+
|
|
83
|
+
AcceleratorConnection &getConnection() const { return conn; }
|
|
84
|
+
|
|
85
|
+
protected:
|
|
86
|
+
AcceleratorConnection &conn;
|
|
72
87
|
};
|
|
73
88
|
|
|
74
89
|
/// A service for which there are no standard services registered. Requires
|
|
@@ -76,13 +91,16 @@ public:
|
|
|
76
91
|
/// the ones in StdServices.h.
|
|
77
92
|
class CustomService : public Service {
|
|
78
93
|
public:
|
|
79
|
-
CustomService(AppIDPath idPath,
|
|
94
|
+
CustomService(AppIDPath idPath, AcceleratorConnection &,
|
|
95
|
+
const ServiceImplDetails &details,
|
|
80
96
|
const HWClientDetails &clients);
|
|
81
97
|
virtual ~CustomService() = default;
|
|
82
98
|
|
|
83
99
|
virtual std::string getServiceSymbol() const override {
|
|
84
100
|
return serviceSymbol;
|
|
85
101
|
}
|
|
102
|
+
virtual BundlePort *getPort(AppIDPath id,
|
|
103
|
+
const BundleType *type) const override;
|
|
86
104
|
|
|
87
105
|
protected:
|
|
88
106
|
std::string serviceSymbol;
|
|
@@ -92,6 +110,7 @@ protected:
|
|
|
92
110
|
/// Information about the Accelerator system.
|
|
93
111
|
class SysInfo : public Service {
|
|
94
112
|
public:
|
|
113
|
+
using Service::Service;
|
|
95
114
|
virtual ~SysInfo() = default;
|
|
96
115
|
|
|
97
116
|
virtual std::string getServiceSymbol() const override;
|
|
@@ -116,9 +135,8 @@ public:
|
|
|
116
135
|
uint32_t size;
|
|
117
136
|
};
|
|
118
137
|
|
|
119
|
-
MMIO(
|
|
120
|
-
const
|
|
121
|
-
MMIO() = default;
|
|
138
|
+
MMIO(AcceleratorConnection &, const AppIDPath &idPath,
|
|
139
|
+
const HWClientDetails &clients);
|
|
122
140
|
virtual ~MMIO() = default;
|
|
123
141
|
|
|
124
142
|
/// Read a 64-bit value from the global MMIO space.
|
|
@@ -133,8 +151,7 @@ public:
|
|
|
133
151
|
|
|
134
152
|
/// If the service is a MMIO service, return a region of the MMIO space which
|
|
135
153
|
/// peers into ours.
|
|
136
|
-
virtual Service *getChildService(
|
|
137
|
-
Service::Type service, AppIDPath id = {},
|
|
154
|
+
virtual Service *getChildService(Service::Type service, AppIDPath id = {},
|
|
138
155
|
std::string implName = {},
|
|
139
156
|
ServiceImplDetails details = {},
|
|
140
157
|
HWClientDetails clients = {}) override;
|
|
@@ -142,9 +159,8 @@ public:
|
|
|
142
159
|
virtual std::string getServiceSymbol() const override;
|
|
143
160
|
|
|
144
161
|
/// Get a MMIO region port for a particular region descriptor.
|
|
145
|
-
virtual
|
|
146
|
-
|
|
147
|
-
AcceleratorConnection &) const override;
|
|
162
|
+
virtual BundlePort *getPort(AppIDPath id,
|
|
163
|
+
const BundleType *type) const override;
|
|
148
164
|
|
|
149
165
|
private:
|
|
150
166
|
/// MMIO base address table.
|
|
@@ -193,6 +209,9 @@ private:
|
|
|
193
209
|
|
|
194
210
|
class HostMem : public Service {
|
|
195
211
|
public:
|
|
212
|
+
static constexpr std::string_view StdName = "esi.service.std.hostmem";
|
|
213
|
+
|
|
214
|
+
using Service::Service;
|
|
196
215
|
virtual ~HostMem() = default;
|
|
197
216
|
virtual std::string getServiceSymbol() const override;
|
|
198
217
|
|
|
@@ -200,9 +219,19 @@ public:
|
|
|
200
219
|
/// deconstructed.
|
|
201
220
|
struct HostMemRegion {
|
|
202
221
|
virtual ~HostMemRegion() = default;
|
|
222
|
+
/// Get a pointer to the host memory.
|
|
203
223
|
virtual void *getPtr() const = 0;
|
|
224
|
+
/// Sometimes the pointer the device sees is different from the pointer the
|
|
225
|
+
/// host sees. Call this functon to get the device pointer.
|
|
226
|
+
virtual void *getDevicePtr() const { return getPtr(); }
|
|
204
227
|
operator void *() const { return getPtr(); }
|
|
205
228
|
virtual std::size_t getSize() const = 0;
|
|
229
|
+
/// Flush the memory region to ensure that the device sees the latest
|
|
230
|
+
/// contents. Because some platforms require it before DMA transactions, it
|
|
231
|
+
/// is recommended to call this before any DMA on all platforms. On
|
|
232
|
+
/// platforms which don't require it, it is a cheap no-op virtual method
|
|
233
|
+
/// call.
|
|
234
|
+
virtual void flush() {}
|
|
206
235
|
};
|
|
207
236
|
|
|
208
237
|
/// Options for allocating host memory.
|
|
@@ -234,39 +263,47 @@ public:
|
|
|
234
263
|
/// Service for calling functions.
|
|
235
264
|
class FuncService : public Service {
|
|
236
265
|
public:
|
|
237
|
-
FuncService(
|
|
238
|
-
const std::string &implName, ServiceImplDetails details,
|
|
266
|
+
FuncService(AppIDPath id, AcceleratorConnection &, ServiceImplDetails details,
|
|
239
267
|
HWClientDetails clients);
|
|
240
268
|
|
|
241
269
|
virtual std::string getServiceSymbol() const override;
|
|
242
|
-
virtual
|
|
243
|
-
|
|
244
|
-
AcceleratorConnection &) const override;
|
|
270
|
+
virtual BundlePort *getPort(AppIDPath id,
|
|
271
|
+
const BundleType *type) const override;
|
|
245
272
|
|
|
246
273
|
/// A function call which gets attached to a service port.
|
|
247
274
|
class Function : public ServicePort {
|
|
248
275
|
friend class FuncService;
|
|
249
|
-
|
|
276
|
+
using ServicePort::ServicePort;
|
|
250
277
|
|
|
251
278
|
public:
|
|
252
|
-
static Function *get(AppID id, WriteChannelPort &arg,
|
|
279
|
+
static Function *get(AppID id, BundleType *type, WriteChannelPort &arg,
|
|
253
280
|
ReadChannelPort &result);
|
|
254
281
|
|
|
255
282
|
void connect();
|
|
256
283
|
std::future<MessageData> call(const MessageData &arg);
|
|
257
284
|
|
|
285
|
+
const esi::Type *getArgType() const {
|
|
286
|
+
return dynamic_cast<const ChannelType *>(type->findChannel("arg").first)
|
|
287
|
+
->getInner();
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
const esi::Type *getResultType() const {
|
|
291
|
+
return dynamic_cast<const ChannelType *>(
|
|
292
|
+
type->findChannel("result").first)
|
|
293
|
+
->getInner();
|
|
294
|
+
}
|
|
295
|
+
|
|
258
296
|
virtual std::optional<std::string> toString() const override {
|
|
259
|
-
const esi::Type *argType =
|
|
260
|
-
|
|
261
|
-
const esi::Type *resultType =
|
|
262
|
-
dynamic_cast<const ChannelType *>(result.getType())->getInner();
|
|
297
|
+
const esi::Type *argType = getArgType();
|
|
298
|
+
const esi::Type *resultType = getResultType();
|
|
263
299
|
return "function " + resultType->getID() + "(" + argType->getID() + ")";
|
|
264
300
|
}
|
|
265
301
|
|
|
266
302
|
private:
|
|
267
303
|
std::mutex callMutex;
|
|
268
|
-
WriteChannelPort
|
|
269
|
-
ReadChannelPort
|
|
304
|
+
WriteChannelPort *arg;
|
|
305
|
+
ReadChannelPort *result;
|
|
306
|
+
bool connected = false;
|
|
270
307
|
};
|
|
271
308
|
|
|
272
309
|
private:
|
|
@@ -276,23 +313,23 @@ private:
|
|
|
276
313
|
/// Service for servicing function calls from the accelerator.
|
|
277
314
|
class CallService : public Service {
|
|
278
315
|
public:
|
|
279
|
-
CallService(AcceleratorConnection
|
|
280
|
-
ServiceImplDetails details
|
|
316
|
+
CallService(AcceleratorConnection &acc, AppIDPath id,
|
|
317
|
+
ServiceImplDetails details);
|
|
281
318
|
|
|
282
319
|
virtual std::string getServiceSymbol() const override;
|
|
283
|
-
virtual
|
|
284
|
-
|
|
285
|
-
AcceleratorConnection &) const override;
|
|
320
|
+
virtual BundlePort *getPort(AppIDPath id,
|
|
321
|
+
const BundleType *type) const override;
|
|
286
322
|
|
|
287
323
|
/// A function call which gets attached to a service port.
|
|
288
324
|
class Callback : public ServicePort {
|
|
289
325
|
friend class CallService;
|
|
290
|
-
Callback(AcceleratorConnection &acc, AppID id,
|
|
291
|
-
|
|
326
|
+
Callback(AcceleratorConnection &acc, AppID id, const BundleType *,
|
|
327
|
+
PortMap channels);
|
|
292
328
|
|
|
293
329
|
public:
|
|
294
330
|
static Callback *get(AcceleratorConnection &acc, AppID id,
|
|
295
|
-
WriteChannelPort &result,
|
|
331
|
+
const BundleType *type, WriteChannelPort &result,
|
|
332
|
+
ReadChannelPort &arg);
|
|
296
333
|
|
|
297
334
|
/// Connect a callback to code which will be executed when the accelerator
|
|
298
335
|
/// invokes the callback. The 'quick' flag indicates that the callback is
|
|
@@ -301,17 +338,26 @@ public:
|
|
|
301
338
|
void connect(std::function<MessageData(const MessageData &)> callback,
|
|
302
339
|
bool quick = false);
|
|
303
340
|
|
|
341
|
+
const esi::Type *getArgType() const {
|
|
342
|
+
return dynamic_cast<const ChannelType *>(type->findChannel("arg").first)
|
|
343
|
+
->getInner();
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
const esi::Type *getResultType() const {
|
|
347
|
+
return dynamic_cast<const ChannelType *>(
|
|
348
|
+
type->findChannel("result").first)
|
|
349
|
+
->getInner();
|
|
350
|
+
}
|
|
351
|
+
|
|
304
352
|
virtual std::optional<std::string> toString() const override {
|
|
305
|
-
const esi::Type *argType =
|
|
306
|
-
|
|
307
|
-
const esi::Type *resultType =
|
|
308
|
-
dynamic_cast<const ChannelType *>(result.getType())->getInner();
|
|
353
|
+
const esi::Type *argType = getArgType();
|
|
354
|
+
const esi::Type *resultType = getResultType();
|
|
309
355
|
return "callback " + resultType->getID() + "(" + argType->getID() + ")";
|
|
310
356
|
}
|
|
311
357
|
|
|
312
358
|
private:
|
|
313
|
-
ReadChannelPort
|
|
314
|
-
WriteChannelPort
|
|
359
|
+
ReadChannelPort *arg;
|
|
360
|
+
WriteChannelPort *result;
|
|
315
361
|
AcceleratorConnection &acc;
|
|
316
362
|
};
|
|
317
363
|
|
|
@@ -319,6 +365,63 @@ private:
|
|
|
319
365
|
std::string symbol;
|
|
320
366
|
};
|
|
321
367
|
|
|
368
|
+
/// Service for retrieving telemetry data from the accelerator.
|
|
369
|
+
class TelemetryService : public Service {
|
|
370
|
+
public:
|
|
371
|
+
static constexpr std::string_view StdName = "esi.service.std.telemetry";
|
|
372
|
+
|
|
373
|
+
TelemetryService(AppIDPath id, AcceleratorConnection &,
|
|
374
|
+
ServiceImplDetails details, HWClientDetails clients);
|
|
375
|
+
|
|
376
|
+
virtual std::string getServiceSymbol() const override;
|
|
377
|
+
virtual BundlePort *getPort(AppIDPath id,
|
|
378
|
+
const BundleType *type) const override;
|
|
379
|
+
virtual Service *getChildService(Service::Type service, AppIDPath id = {},
|
|
380
|
+
std::string implName = {},
|
|
381
|
+
ServiceImplDetails details = {},
|
|
382
|
+
HWClientDetails clients = {}) override;
|
|
383
|
+
MMIO::MMIORegion *getMMIORegion() const;
|
|
384
|
+
|
|
385
|
+
/// A telemetry port which gets attached to a service port.
|
|
386
|
+
class Metric : public ServicePort {
|
|
387
|
+
friend class TelemetryService;
|
|
388
|
+
Metric(AppID id, const BundleType *type, PortMap channels,
|
|
389
|
+
const TelemetryService *telemetryService,
|
|
390
|
+
std::optional<uint64_t> offset);
|
|
391
|
+
|
|
392
|
+
public:
|
|
393
|
+
void connect();
|
|
394
|
+
std::future<MessageData> read();
|
|
395
|
+
uint64_t readInt();
|
|
396
|
+
|
|
397
|
+
virtual std::optional<std::string> toString() const override {
|
|
398
|
+
const esi::Type *dataType =
|
|
399
|
+
dynamic_cast<const ChannelType *>(type->findChannel("data").first)
|
|
400
|
+
->getInner();
|
|
401
|
+
return "telemetry " + dataType->getID();
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
private:
|
|
405
|
+
const TelemetryService *telemetryService;
|
|
406
|
+
MMIO::MMIORegion *mmio;
|
|
407
|
+
std::optional<uint64_t> offset;
|
|
408
|
+
};
|
|
409
|
+
|
|
410
|
+
std::map<AppIDPath, Metric *> getTelemetryPorts() {
|
|
411
|
+
std::map<AppIDPath, Metric *> ports;
|
|
412
|
+
getTelemetryPorts(ports);
|
|
413
|
+
return ports;
|
|
414
|
+
}
|
|
415
|
+
void getTelemetryPorts(std::map<AppIDPath, Metric *> &ports);
|
|
416
|
+
|
|
417
|
+
private:
|
|
418
|
+
AppIDPath id;
|
|
419
|
+
mutable MMIO::MMIORegion *mmio;
|
|
420
|
+
std::map<AppIDPath, uint64_t> portAddressAssignments;
|
|
421
|
+
mutable std::map<AppIDPath, Metric *> telemetryPorts;
|
|
422
|
+
std::list<TelemetryService *> children;
|
|
423
|
+
};
|
|
424
|
+
|
|
322
425
|
/// Registry of services which can be instantiated directly by the Accelerator
|
|
323
426
|
/// class if the backend doesn't do anything special with a service.
|
|
324
427
|
class ServiceRegistry {
|
esiaccel/include/esi/Types.h
CHANGED
|
@@ -16,11 +16,18 @@
|
|
|
16
16
|
#ifndef ESI_TYPES_H
|
|
17
17
|
#define ESI_TYPES_H
|
|
18
18
|
|
|
19
|
-
#include <
|
|
19
|
+
#include <algorithm>
|
|
20
|
+
#include <any>
|
|
20
21
|
#include <cstdint>
|
|
22
|
+
#include <map>
|
|
23
|
+
#include <span>
|
|
24
|
+
#include <stdexcept>
|
|
21
25
|
#include <string>
|
|
22
26
|
#include <vector>
|
|
23
27
|
|
|
28
|
+
#include "esi/Common.h"
|
|
29
|
+
#include "esi/Values.h" // For BitVector / Int / UInt
|
|
30
|
+
|
|
24
31
|
namespace esi {
|
|
25
32
|
|
|
26
33
|
/// Root class of the ESI type system.
|
|
@@ -33,6 +40,46 @@ public:
|
|
|
33
40
|
ID getID() const { return id; }
|
|
34
41
|
virtual std::ptrdiff_t getBitWidth() const { return -1; }
|
|
35
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
|
+
|
|
36
83
|
protected:
|
|
37
84
|
ID id;
|
|
38
85
|
};
|
|
@@ -54,6 +101,8 @@ public:
|
|
|
54
101
|
const ChannelVector &getChannels() const { return channels; }
|
|
55
102
|
std::ptrdiff_t getBitWidth() const override { return -1; };
|
|
56
103
|
|
|
104
|
+
std::pair<const Type *, Direction> findChannel(std::string name) const;
|
|
105
|
+
|
|
57
106
|
protected:
|
|
58
107
|
ChannelVector channels;
|
|
59
108
|
};
|
|
@@ -62,10 +111,15 @@ protected:
|
|
|
62
111
|
/// carry one values of one type.
|
|
63
112
|
class ChannelType : public Type {
|
|
64
113
|
public:
|
|
114
|
+
using Type::deserialize;
|
|
65
115
|
ChannelType(const ID &id, const Type *inner) : Type(id), inner(inner) {}
|
|
66
116
|
const Type *getInner() const { return inner; }
|
|
67
117
|
std::ptrdiff_t getBitWidth() const override { return inner->getBitWidth(); };
|
|
68
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
|
+
|
|
69
123
|
private:
|
|
70
124
|
const Type *inner;
|
|
71
125
|
};
|
|
@@ -73,9 +127,14 @@ private:
|
|
|
73
127
|
/// The "void" type is a special type which can be used to represent no type.
|
|
74
128
|
class VoidType : public Type {
|
|
75
129
|
public:
|
|
130
|
+
using Type::deserialize;
|
|
76
131
|
VoidType(const ID &id) : Type(id) {}
|
|
77
132
|
// 'void' is 1 bit by convention.
|
|
78
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;
|
|
79
138
|
};
|
|
80
139
|
|
|
81
140
|
/// The "any" type is a special type which can be used to represent any type, as
|
|
@@ -105,6 +164,11 @@ private:
|
|
|
105
164
|
class BitsType : public BitVectorType {
|
|
106
165
|
public:
|
|
107
166
|
using BitVectorType::BitVectorType;
|
|
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;
|
|
108
172
|
};
|
|
109
173
|
|
|
110
174
|
/// Integers are bit vectors which may be signed or unsigned and are interpreted
|
|
@@ -118,21 +182,32 @@ public:
|
|
|
118
182
|
class SIntType : public IntegerType {
|
|
119
183
|
public:
|
|
120
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;
|
|
121
190
|
};
|
|
122
191
|
|
|
123
192
|
/// Unsigned integer.
|
|
124
193
|
class UIntType : public IntegerType {
|
|
125
194
|
public:
|
|
126
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;
|
|
127
201
|
};
|
|
128
202
|
|
|
129
203
|
/// Structs are an ordered collection of fields, each with a name and a type.
|
|
130
204
|
class StructType : public Type {
|
|
131
205
|
public:
|
|
132
206
|
using FieldVector = std::vector<std::pair<std::string, const Type *>>;
|
|
207
|
+
using Type::deserialize;
|
|
133
208
|
|
|
134
|
-
StructType(const ID &id, const FieldVector &fields)
|
|
135
|
-
: Type(id), fields(fields) {}
|
|
209
|
+
StructType(const ID &id, const FieldVector &fields, bool reverse = true)
|
|
210
|
+
: Type(id), fields(fields), reverse(reverse) {}
|
|
136
211
|
|
|
137
212
|
const FieldVector &getFields() const { return fields; }
|
|
138
213
|
std::ptrdiff_t getBitWidth() const override {
|
|
@@ -146,18 +221,33 @@ public:
|
|
|
146
221
|
return size;
|
|
147
222
|
}
|
|
148
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
|
+
|
|
149
235
|
private:
|
|
150
236
|
FieldVector fields;
|
|
237
|
+
bool reverse;
|
|
151
238
|
};
|
|
152
239
|
|
|
153
240
|
/// Arrays have a compile time specified (static) size and an element type.
|
|
154
241
|
class ArrayType : public Type {
|
|
155
242
|
public:
|
|
156
|
-
ArrayType(const ID &id, const Type *elementType, uint64_t size
|
|
157
|
-
|
|
243
|
+
ArrayType(const ID &id, const Type *elementType, uint64_t size,
|
|
244
|
+
bool reverse = true)
|
|
245
|
+
: Type(id), elementType(elementType), size(size), reverse(reverse) {}
|
|
246
|
+
using Type::deserialize;
|
|
158
247
|
|
|
159
248
|
const Type *getElementType() const { return elementType; }
|
|
160
249
|
uint64_t getSize() const { return size; }
|
|
250
|
+
bool isReverse() const { return reverse; }
|
|
161
251
|
std::ptrdiff_t getBitWidth() const override {
|
|
162
252
|
std::ptrdiff_t elementSize = elementType->getBitWidth();
|
|
163
253
|
if (elementSize < 0)
|
|
@@ -165,9 +255,17 @@ public:
|
|
|
165
255
|
return elementSize * size;
|
|
166
256
|
}
|
|
167
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
|
+
|
|
168
262
|
private:
|
|
169
263
|
const Type *elementType;
|
|
170
264
|
uint64_t size;
|
|
265
|
+
// 'reverse' controls whether array elements are reversed during
|
|
266
|
+
// serialization/deserialization (to match SystemVerilog/Python ordering
|
|
267
|
+
// expectations).
|
|
268
|
+
bool reverse;
|
|
171
269
|
};
|
|
172
270
|
|
|
173
271
|
} // namespace esi
|