esiaccel 0.0.10__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 +15 -1
- esiaccel/cares.dll +0 -0
- esiaccel/cmake/esiaccelConfig.cmake +1 -1
- esiaccel/codegen.py +197 -0
- 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 +33 -9
- esiaccel/include/esi/CLI.h +77 -0
- esiaccel/include/esi/Common.h +59 -10
- esiaccel/include/esi/Context.h +21 -1
- esiaccel/include/esi/Design.h +14 -3
- esiaccel/include/esi/Engines.h +124 -0
- esiaccel/include/esi/Logging.h +231 -0
- esiaccel/include/esi/Manifest.h +0 -2
- esiaccel/include/esi/Ports.h +54 -7
- esiaccel/include/esi/Services.h +225 -22
- esiaccel/include/esi/Types.h +103 -5
- esiaccel/include/esi/Utils.h +5 -0
- 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 +8 -5
- 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 +174 -33
- esiaccel/utils.py +27 -3
- esiaccel/zlib1.dll +0 -0
- {esiaccel-0.0.10.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.10.dist-info → esiaccel-0.1.5.dev406.dist-info}/WHEEL +1 -1
- {esiaccel-0.0.10.dist-info → esiaccel-0.1.5.dev406.dist-info}/entry_points.txt +1 -0
- esiaccel/bin/ESICppRuntime.dll +0 -0
- esiaccel/bin/esiquery.exe +0 -0
- esiaccel/bin/zlib1.dll +0 -0
- esiaccel-0.0.10.dist-info/RECORD +0 -28
- {esiaccel-0.0.10.dist-info → esiaccel-0.1.5.dev406.dist-info/licenses}/LICENSE +0 -0
- {esiaccel-0.0.10.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 --
|
|
@@ -83,13 +86,37 @@ public:
|
|
|
83
86
|
virtual void disconnect() override { connected = false; }
|
|
84
87
|
virtual bool isConnected() const override { return connected; }
|
|
85
88
|
|
|
86
|
-
/// A very basic write API. Will likely change for performance
|
|
89
|
+
/// A very basic blocking write API. Will likely change for performance
|
|
90
|
+
/// reasons.
|
|
87
91
|
virtual void write(const MessageData &) = 0;
|
|
88
92
|
|
|
93
|
+
/// A basic non-blocking write API. Returns true if the data was written.
|
|
94
|
+
/// It is invalid for backends to always return false (i.e. backends must
|
|
95
|
+
/// eventually ensure that writes may succeed).
|
|
96
|
+
virtual bool tryWrite(const MessageData &data) = 0;
|
|
97
|
+
|
|
89
98
|
private:
|
|
90
99
|
volatile bool connected = false;
|
|
91
100
|
};
|
|
92
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
|
+
|
|
93
120
|
/// A ChannelPort which reads data from the accelerator. It has two modes:
|
|
94
121
|
/// Callback and Polling which cannot be used at the same time. The mode is set
|
|
95
122
|
/// at connect() time. To change the mode, disconnect() and then connect()
|
|
@@ -172,6 +199,27 @@ protected:
|
|
|
172
199
|
std::queue<std::promise<MessageData>> promiseQueue;
|
|
173
200
|
};
|
|
174
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
|
+
|
|
175
223
|
/// Services provide connections to 'bundles' -- collections of named,
|
|
176
224
|
/// unidirectional communication channels. This class provides access to those
|
|
177
225
|
/// ChannelPorts.
|
|
@@ -184,7 +232,7 @@ public:
|
|
|
184
232
|
}
|
|
185
233
|
|
|
186
234
|
/// Construct a port.
|
|
187
|
-
BundlePort(AppID id,
|
|
235
|
+
BundlePort(AppID id, const BundleType *type, PortMap channels);
|
|
188
236
|
virtual ~BundlePort() = default;
|
|
189
237
|
|
|
190
238
|
/// Get the ID of the port.
|
|
@@ -196,9 +244,7 @@ public:
|
|
|
196
244
|
/// ordinary users should not use. You have been warned.
|
|
197
245
|
WriteChannelPort &getRawWrite(const std::string &name) const;
|
|
198
246
|
ReadChannelPort &getRawRead(const std::string &name) const;
|
|
199
|
-
const
|
|
200
|
-
return channels;
|
|
201
|
-
}
|
|
247
|
+
const PortMap &getChannels() const { return channels; }
|
|
202
248
|
|
|
203
249
|
/// Cast this Bundle port to a subclass which is actually useful. Returns
|
|
204
250
|
/// nullptr if the cast fails.
|
|
@@ -218,9 +264,10 @@ public:
|
|
|
218
264
|
return result;
|
|
219
265
|
}
|
|
220
266
|
|
|
221
|
-
|
|
267
|
+
protected:
|
|
222
268
|
AppID id;
|
|
223
|
-
|
|
269
|
+
const BundleType *type;
|
|
270
|
+
PortMap channels;
|
|
224
271
|
};
|
|
225
272
|
|
|
226
273
|
} // namespace esi
|
esiaccel/include/esi/Services.h
CHANGED
|
@@ -21,12 +21,25 @@
|
|
|
21
21
|
#define ESI_RUNTIME_SERVICES_H
|
|
22
22
|
|
|
23
23
|
#include "esi/Common.h"
|
|
24
|
+
#include "esi/Context.h"
|
|
24
25
|
#include "esi/Ports.h"
|
|
25
26
|
|
|
26
27
|
#include <cstdint>
|
|
28
|
+
#include <list>
|
|
27
29
|
|
|
28
30
|
namespace esi {
|
|
29
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
|
+
|
|
30
43
|
namespace services {
|
|
31
44
|
|
|
32
45
|
/// Add a custom interface to a service client at a particular point in the
|
|
@@ -35,6 +48,8 @@ class ServicePort : public BundlePort {
|
|
|
35
48
|
public:
|
|
36
49
|
using BundlePort::BundlePort;
|
|
37
50
|
virtual ~ServicePort() = default;
|
|
51
|
+
// Get a description of the service port.
|
|
52
|
+
virtual std::optional<std::string> toString() const { return std::nullopt; }
|
|
38
53
|
};
|
|
39
54
|
|
|
40
55
|
/// Parent class of all APIs modeled as 'services'. May or may not map to a
|
|
@@ -42,17 +57,33 @@ public:
|
|
|
42
57
|
class Service {
|
|
43
58
|
public:
|
|
44
59
|
using Type = const std::type_info &;
|
|
60
|
+
Service(AcceleratorConnection &conn) : conn(conn) {}
|
|
45
61
|
virtual ~Service() = default;
|
|
46
62
|
|
|
47
63
|
virtual std::string getServiceSymbol() const = 0;
|
|
48
64
|
|
|
65
|
+
/// Create a "child" service of this service. Does not have to be the same
|
|
66
|
+
/// service type, but typically is. Used when a service already exists in the
|
|
67
|
+
/// active services table, but a new one wants to replace it. Useful for cases
|
|
68
|
+
/// where the child service needs to use the parent service. Defaults to
|
|
69
|
+
/// calling the `getService` method on `AcceleratorConnection` to get the
|
|
70
|
+
/// global service, implying that the child service does not need to use the
|
|
71
|
+
/// service it is replacing.
|
|
72
|
+
virtual Service *getChildService(Service::Type service, AppIDPath id = {},
|
|
73
|
+
std::string implName = {},
|
|
74
|
+
ServiceImplDetails details = {},
|
|
75
|
+
HWClientDetails clients = {});
|
|
76
|
+
|
|
49
77
|
/// Get specialized port for this service to attach to the given appid path.
|
|
50
78
|
/// Null returns mean nothing to attach.
|
|
51
|
-
virtual
|
|
52
|
-
const std::map<std::string, ChannelPort &> &,
|
|
53
|
-
AcceleratorConnection &) const {
|
|
79
|
+
virtual BundlePort *getPort(AppIDPath id, const BundleType *type) const {
|
|
54
80
|
return nullptr;
|
|
55
81
|
}
|
|
82
|
+
|
|
83
|
+
AcceleratorConnection &getConnection() const { return conn; }
|
|
84
|
+
|
|
85
|
+
protected:
|
|
86
|
+
AcceleratorConnection &conn;
|
|
56
87
|
};
|
|
57
88
|
|
|
58
89
|
/// A service for which there are no standard services registered. Requires
|
|
@@ -60,13 +91,16 @@ public:
|
|
|
60
91
|
/// the ones in StdServices.h.
|
|
61
92
|
class CustomService : public Service {
|
|
62
93
|
public:
|
|
63
|
-
CustomService(AppIDPath idPath,
|
|
94
|
+
CustomService(AppIDPath idPath, AcceleratorConnection &,
|
|
95
|
+
const ServiceImplDetails &details,
|
|
64
96
|
const HWClientDetails &clients);
|
|
65
97
|
virtual ~CustomService() = default;
|
|
66
98
|
|
|
67
99
|
virtual std::string getServiceSymbol() const override {
|
|
68
100
|
return serviceSymbol;
|
|
69
101
|
}
|
|
102
|
+
virtual BundlePort *getPort(AppIDPath id,
|
|
103
|
+
const BundleType *type) const override;
|
|
70
104
|
|
|
71
105
|
protected:
|
|
72
106
|
std::string serviceSymbol;
|
|
@@ -76,6 +110,7 @@ protected:
|
|
|
76
110
|
/// Information about the Accelerator system.
|
|
77
111
|
class SysInfo : public Service {
|
|
78
112
|
public:
|
|
113
|
+
using Service::Service;
|
|
79
114
|
virtual ~SysInfo() = default;
|
|
80
115
|
|
|
81
116
|
virtual std::string getServiceSymbol() const override;
|
|
@@ -92,10 +127,69 @@ public:
|
|
|
92
127
|
|
|
93
128
|
class MMIO : public Service {
|
|
94
129
|
public:
|
|
130
|
+
static constexpr std::string_view StdName = "esi.service.std.mmio";
|
|
131
|
+
|
|
132
|
+
/// Describe a region (slice) of MMIO space.
|
|
133
|
+
struct RegionDescriptor {
|
|
134
|
+
uint32_t base;
|
|
135
|
+
uint32_t size;
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
MMIO(AcceleratorConnection &, const AppIDPath &idPath,
|
|
139
|
+
const HWClientDetails &clients);
|
|
95
140
|
virtual ~MMIO() = default;
|
|
141
|
+
|
|
142
|
+
/// Read a 64-bit value from the global MMIO space.
|
|
96
143
|
virtual uint64_t read(uint32_t addr) const = 0;
|
|
144
|
+
/// Write a 64-bit value to the global MMIO space.
|
|
97
145
|
virtual void write(uint32_t addr, uint64_t data) = 0;
|
|
146
|
+
/// Get the regions of MMIO space that this service manages. Otherwise known
|
|
147
|
+
/// as the base address table.
|
|
148
|
+
const std::map<AppIDPath, RegionDescriptor> &getRegions() const {
|
|
149
|
+
return regions;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/// If the service is a MMIO service, return a region of the MMIO space which
|
|
153
|
+
/// peers into ours.
|
|
154
|
+
virtual Service *getChildService(Service::Type service, AppIDPath id = {},
|
|
155
|
+
std::string implName = {},
|
|
156
|
+
ServiceImplDetails details = {},
|
|
157
|
+
HWClientDetails clients = {}) override;
|
|
158
|
+
|
|
98
159
|
virtual std::string getServiceSymbol() const override;
|
|
160
|
+
|
|
161
|
+
/// Get a MMIO region port for a particular region descriptor.
|
|
162
|
+
virtual BundlePort *getPort(AppIDPath id,
|
|
163
|
+
const BundleType *type) const override;
|
|
164
|
+
|
|
165
|
+
private:
|
|
166
|
+
/// MMIO base address table.
|
|
167
|
+
std::map<AppIDPath, RegionDescriptor> regions;
|
|
168
|
+
|
|
169
|
+
public:
|
|
170
|
+
/// A "slice" of some parent MMIO space.
|
|
171
|
+
class MMIORegion : public ServicePort {
|
|
172
|
+
friend class MMIO;
|
|
173
|
+
MMIORegion(AppID id, MMIO *parent, RegionDescriptor desc);
|
|
174
|
+
|
|
175
|
+
public:
|
|
176
|
+
/// Get the offset (and size) of the region in the parent (usually global)
|
|
177
|
+
/// MMIO address space.
|
|
178
|
+
virtual RegionDescriptor getDescriptor() const { return desc; };
|
|
179
|
+
/// Read a 64-bit value from this region, not the global address space.
|
|
180
|
+
virtual uint64_t read(uint32_t addr) const;
|
|
181
|
+
/// Write a 64-bit value to this region, not the global address space.
|
|
182
|
+
virtual void write(uint32_t addr, uint64_t data);
|
|
183
|
+
|
|
184
|
+
virtual std::optional<std::string> toString() const override {
|
|
185
|
+
return "MMIO region " + toHex(desc.base) + " - " +
|
|
186
|
+
toHex(desc.base + desc.size);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
private:
|
|
190
|
+
MMIO *parent;
|
|
191
|
+
RegionDescriptor desc;
|
|
192
|
+
};
|
|
99
193
|
};
|
|
100
194
|
|
|
101
195
|
/// Implement the SysInfo API for a standard MMIO protocol.
|
|
@@ -115,6 +209,9 @@ private:
|
|
|
115
209
|
|
|
116
210
|
class HostMem : public Service {
|
|
117
211
|
public:
|
|
212
|
+
static constexpr std::string_view StdName = "esi.service.std.hostmem";
|
|
213
|
+
|
|
214
|
+
using Service::Service;
|
|
118
215
|
virtual ~HostMem() = default;
|
|
119
216
|
virtual std::string getServiceSymbol() const override;
|
|
120
217
|
|
|
@@ -122,9 +219,19 @@ public:
|
|
|
122
219
|
/// deconstructed.
|
|
123
220
|
struct HostMemRegion {
|
|
124
221
|
virtual ~HostMemRegion() = default;
|
|
222
|
+
/// Get a pointer to the host memory.
|
|
125
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(); }
|
|
126
227
|
operator void *() const { return getPtr(); }
|
|
127
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() {}
|
|
128
235
|
};
|
|
129
236
|
|
|
130
237
|
/// Options for allocating host memory.
|
|
@@ -133,6 +240,9 @@ public:
|
|
|
133
240
|
bool useLargePages = false;
|
|
134
241
|
};
|
|
135
242
|
|
|
243
|
+
/// In cases where necessary, enable host memory services.
|
|
244
|
+
virtual void start() {}
|
|
245
|
+
|
|
136
246
|
/// Allocate a region of host memory in accelerator accessible address space.
|
|
137
247
|
virtual std::unique_ptr<HostMemRegion> allocate(std::size_t size,
|
|
138
248
|
Options opts) const = 0;
|
|
@@ -153,31 +263,47 @@ public:
|
|
|
153
263
|
/// Service for calling functions.
|
|
154
264
|
class FuncService : public Service {
|
|
155
265
|
public:
|
|
156
|
-
FuncService(
|
|
157
|
-
const std::string &implName, ServiceImplDetails details,
|
|
266
|
+
FuncService(AppIDPath id, AcceleratorConnection &, ServiceImplDetails details,
|
|
158
267
|
HWClientDetails clients);
|
|
159
268
|
|
|
160
269
|
virtual std::string getServiceSymbol() const override;
|
|
161
|
-
virtual
|
|
162
|
-
|
|
163
|
-
AcceleratorConnection &) const override;
|
|
270
|
+
virtual BundlePort *getPort(AppIDPath id,
|
|
271
|
+
const BundleType *type) const override;
|
|
164
272
|
|
|
165
273
|
/// A function call which gets attached to a service port.
|
|
166
274
|
class Function : public ServicePort {
|
|
167
275
|
friend class FuncService;
|
|
168
|
-
|
|
276
|
+
using ServicePort::ServicePort;
|
|
169
277
|
|
|
170
278
|
public:
|
|
171
|
-
static Function *get(AppID id, WriteChannelPort &arg,
|
|
279
|
+
static Function *get(AppID id, BundleType *type, WriteChannelPort &arg,
|
|
172
280
|
ReadChannelPort &result);
|
|
173
281
|
|
|
174
282
|
void connect();
|
|
175
283
|
std::future<MessageData> call(const MessageData &arg);
|
|
176
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
|
+
|
|
296
|
+
virtual std::optional<std::string> toString() const override {
|
|
297
|
+
const esi::Type *argType = getArgType();
|
|
298
|
+
const esi::Type *resultType = getResultType();
|
|
299
|
+
return "function " + resultType->getID() + "(" + argType->getID() + ")";
|
|
300
|
+
}
|
|
301
|
+
|
|
177
302
|
private:
|
|
178
303
|
std::mutex callMutex;
|
|
179
|
-
WriteChannelPort
|
|
180
|
-
ReadChannelPort
|
|
304
|
+
WriteChannelPort *arg;
|
|
305
|
+
ReadChannelPort *result;
|
|
306
|
+
bool connected = false;
|
|
181
307
|
};
|
|
182
308
|
|
|
183
309
|
private:
|
|
@@ -187,21 +313,24 @@ private:
|
|
|
187
313
|
/// Service for servicing function calls from the accelerator.
|
|
188
314
|
class CallService : public Service {
|
|
189
315
|
public:
|
|
190
|
-
CallService(AcceleratorConnection
|
|
191
|
-
ServiceImplDetails details
|
|
316
|
+
CallService(AcceleratorConnection &acc, AppIDPath id,
|
|
317
|
+
ServiceImplDetails details);
|
|
192
318
|
|
|
193
319
|
virtual std::string getServiceSymbol() const override;
|
|
194
|
-
virtual
|
|
195
|
-
|
|
196
|
-
AcceleratorConnection &) const override;
|
|
320
|
+
virtual BundlePort *getPort(AppIDPath id,
|
|
321
|
+
const BundleType *type) const override;
|
|
197
322
|
|
|
198
323
|
/// A function call which gets attached to a service port.
|
|
199
324
|
class Callback : public ServicePort {
|
|
200
325
|
friend class CallService;
|
|
201
|
-
Callback(AcceleratorConnection &acc, AppID id,
|
|
202
|
-
|
|
326
|
+
Callback(AcceleratorConnection &acc, AppID id, const BundleType *,
|
|
327
|
+
PortMap channels);
|
|
203
328
|
|
|
204
329
|
public:
|
|
330
|
+
static Callback *get(AcceleratorConnection &acc, AppID id,
|
|
331
|
+
const BundleType *type, WriteChannelPort &result,
|
|
332
|
+
ReadChannelPort &arg);
|
|
333
|
+
|
|
205
334
|
/// Connect a callback to code which will be executed when the accelerator
|
|
206
335
|
/// invokes the callback. The 'quick' flag indicates that the callback is
|
|
207
336
|
/// sufficiently fast that it could be called in the same thread as the
|
|
@@ -209,9 +338,26 @@ public:
|
|
|
209
338
|
void connect(std::function<MessageData(const MessageData &)> callback,
|
|
210
339
|
bool quick = false);
|
|
211
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
|
+
|
|
352
|
+
virtual std::optional<std::string> toString() const override {
|
|
353
|
+
const esi::Type *argType = getArgType();
|
|
354
|
+
const esi::Type *resultType = getResultType();
|
|
355
|
+
return "callback " + resultType->getID() + "(" + argType->getID() + ")";
|
|
356
|
+
}
|
|
357
|
+
|
|
212
358
|
private:
|
|
213
|
-
ReadChannelPort
|
|
214
|
-
WriteChannelPort
|
|
359
|
+
ReadChannelPort *arg;
|
|
360
|
+
WriteChannelPort *result;
|
|
215
361
|
AcceleratorConnection &acc;
|
|
216
362
|
};
|
|
217
363
|
|
|
@@ -219,6 +365,63 @@ private:
|
|
|
219
365
|
std::string symbol;
|
|
220
366
|
};
|
|
221
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
|
+
|
|
222
425
|
/// Registry of services which can be instantiated directly by the Accelerator
|
|
223
426
|
/// class if the backend doesn't do anything special with a service.
|
|
224
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
|