esiaccel 0.2.3.dev49__cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.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/__init__.py +31 -0
- esiaccel/accelerator.py +134 -0
- esiaccel/bin/esi-cosim.py +104 -0
- esiaccel/bin/esiquery +0 -0
- esiaccel/cmake/esiaccelConfig.cmake +49 -0
- esiaccel/codegen.py +197 -0
- esiaccel/cosim/Cosim_CycleCount.sv +84 -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 +383 -0
- esiaccel/cosim/verilator.py +92 -0
- esiaccel/esiCppAccel.cpython-314-x86_64-linux-gnu.so +0 -0
- esiaccel/esiCppAccel.pyi +337 -0
- esiaccel/include/esi/Accelerator.h +229 -0
- esiaccel/include/esi/CLI.h +77 -0
- esiaccel/include/esi/Common.h +182 -0
- esiaccel/include/esi/Context.h +82 -0
- esiaccel/include/esi/Design.h +132 -0
- esiaccel/include/esi/Engines.h +124 -0
- esiaccel/include/esi/Logging.h +231 -0
- esiaccel/include/esi/Manifest.h +70 -0
- esiaccel/include/esi/Ports.h +482 -0
- esiaccel/include/esi/Services.h +467 -0
- esiaccel/include/esi/Types.h +334 -0
- esiaccel/include/esi/Utils.h +102 -0
- esiaccel/include/esi/Values.h +313 -0
- esiaccel/include/esi/backends/Cosim.h +78 -0
- esiaccel/include/esi/backends/RpcClient.h +97 -0
- esiaccel/include/esi/backends/RpcServer.h +73 -0
- esiaccel/include/esi/backends/Trace.h +87 -0
- esiaccel/lib/libCosimBackend.so +0 -0
- esiaccel/lib/libCosimRpc.so +0 -0
- esiaccel/lib/libESICppRuntime.so +0 -0
- esiaccel/lib/libEsiCosimDpiServer.so +0 -0
- esiaccel/lib/libMtiPli.so +0 -0
- esiaccel/types.py +565 -0
- esiaccel/utils.py +54 -0
- esiaccel-0.2.3.dev49.dist-info/METADATA +254 -0
- esiaccel-0.2.3.dev49.dist-info/RECORD +47 -0
- esiaccel-0.2.3.dev49.dist-info/WHEEL +6 -0
- esiaccel-0.2.3.dev49.dist-info/entry_points.txt +4 -0
- esiaccel-0.2.3.dev49.dist-info/licenses/LICENSE +234 -0
- esiaccel-0.2.3.dev49.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
//===- values.h - ESI value 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
|
+
// ESI arbitrary width bitvector and integer types.
|
|
10
|
+
// These types are not meant to be highly optimized. Rather, its a simple
|
|
11
|
+
// implementation to support arbitrary bit widths for ESI runtime values.
|
|
12
|
+
//
|
|
13
|
+
//===----------------------------------------------------------------------===//
|
|
14
|
+
// DO NOT EDIT!
|
|
15
|
+
// This file is distributed as part of an ESI package. The source for this file
|
|
16
|
+
// should always be modified within CIRCT.
|
|
17
|
+
//
|
|
18
|
+
//===----------------------------------------------------------------------===//
|
|
19
|
+
|
|
20
|
+
// NOLINTNEXTLINE(llvm-header-guard)
|
|
21
|
+
#ifndef ESI_VALUES_H
|
|
22
|
+
#define ESI_VALUES_H
|
|
23
|
+
|
|
24
|
+
#include <cstdint>
|
|
25
|
+
#include <format>
|
|
26
|
+
#include <memory> // (may be removable later)
|
|
27
|
+
#include <optional>
|
|
28
|
+
#include <ostream>
|
|
29
|
+
#include <span>
|
|
30
|
+
#include <stdexcept>
|
|
31
|
+
#include <string>
|
|
32
|
+
#include <vector>
|
|
33
|
+
|
|
34
|
+
namespace esi {
|
|
35
|
+
|
|
36
|
+
class MutableBitVector;
|
|
37
|
+
|
|
38
|
+
/// A lightweight, non-owning bit vector view backed by a byte array span.
|
|
39
|
+
/// BitVector is immutable wrt. modifying the underlying bits, and provides
|
|
40
|
+
/// read-only access to bits. It supports bit-level access and returns new views
|
|
41
|
+
/// for operations.
|
|
42
|
+
class BitVector {
|
|
43
|
+
public:
|
|
44
|
+
using byte = uint8_t;
|
|
45
|
+
|
|
46
|
+
/// Construct from an existing span. Width defaults to the number of bits in
|
|
47
|
+
/// the span (size * 8). The BitVector does not take ownership.
|
|
48
|
+
BitVector(std::span<const byte> bytes,
|
|
49
|
+
std::optional<size_t> width = std::nullopt, uint8_t bitIndex = 0);
|
|
50
|
+
BitVector() = default;
|
|
51
|
+
BitVector(const BitVector &other);
|
|
52
|
+
BitVector &operator=(const BitVector &other);
|
|
53
|
+
|
|
54
|
+
size_t width() const { return bitWidth; }
|
|
55
|
+
size_t size() const { return width(); }
|
|
56
|
+
|
|
57
|
+
/// Return the i-th bit (0 = LSB) as boolean.
|
|
58
|
+
bool getBit(size_t i) const;
|
|
59
|
+
|
|
60
|
+
/// Return a handle to the underlying span. Throws if the current bit index
|
|
61
|
+
/// is not 0 (since a non-zero bit offset breaks raw byte alignment).
|
|
62
|
+
std::span<const byte> getSpan() const {
|
|
63
|
+
if (bitIndex != 0)
|
|
64
|
+
throw std::runtime_error("Cannot get data span with non-zero bit index");
|
|
65
|
+
return data;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/// Logical right shift that drops the least-significant n bits by advancing
|
|
69
|
+
/// the byte/bit index and reducing width. Returns a new immutable
|
|
70
|
+
/// view. Does not modify the underlying storage contents.
|
|
71
|
+
BitVector operator>>(size_t n) const;
|
|
72
|
+
BitVector &operator>>=(size_t n);
|
|
73
|
+
|
|
74
|
+
/// Create a new immutable view of a contiguous bit slice [offset,
|
|
75
|
+
/// offset+sliceWidth). The returned BitVector is a view (not an owning copy)
|
|
76
|
+
/// into the same underlying span. Throws if the requested slice exceeds the
|
|
77
|
+
/// current width.
|
|
78
|
+
BitVector slice(size_t offset, size_t sliceWidth) const;
|
|
79
|
+
|
|
80
|
+
/// Return a view of the N least-significant bits.
|
|
81
|
+
BitVector lsb(size_t n) const { return slice(0, n); }
|
|
82
|
+
|
|
83
|
+
/// Return a view of the N most-significant bits.
|
|
84
|
+
BitVector msb(size_t n) const {
|
|
85
|
+
if (n > bitWidth)
|
|
86
|
+
throw std::invalid_argument("msb width exceeds bit width");
|
|
87
|
+
return slice(bitWidth - n, n);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
std::string toString(unsigned base = 16) const;
|
|
91
|
+
|
|
92
|
+
bool operator==(const BitVector &rhs) const;
|
|
93
|
+
bool operator!=(const BitVector &rhs) const { return !(*this == rhs); }
|
|
94
|
+
|
|
95
|
+
/// Bitwise AND: creates a new MutableBitVector with the result.
|
|
96
|
+
friend MutableBitVector operator&(const BitVector &a, const BitVector &b);
|
|
97
|
+
|
|
98
|
+
/// Bitwise OR: creates a new MutableBitVector with the result.
|
|
99
|
+
friend MutableBitVector operator|(const BitVector &a, const BitVector &b);
|
|
100
|
+
|
|
101
|
+
/// Bitwise XOR: creates a new MutableBitVector with the result.
|
|
102
|
+
friend MutableBitVector operator^(const BitVector &a, const BitVector &b);
|
|
103
|
+
|
|
104
|
+
/// Forward iterator for iterating over bits from LSB (index 0) to MSB.
|
|
105
|
+
class bit_iterator {
|
|
106
|
+
public:
|
|
107
|
+
using difference_type = std::ptrdiff_t;
|
|
108
|
+
using value_type = bool;
|
|
109
|
+
using pointer = const bool *;
|
|
110
|
+
using reference = bool;
|
|
111
|
+
using iterator_category = std::forward_iterator_tag;
|
|
112
|
+
|
|
113
|
+
/// Default constructor.
|
|
114
|
+
bit_iterator() = default;
|
|
115
|
+
|
|
116
|
+
/// Construct an iterator at the given bit position.
|
|
117
|
+
bit_iterator(const BitVector *bv, size_t pos = 0)
|
|
118
|
+
: bitVector(bv), position(pos) {}
|
|
119
|
+
|
|
120
|
+
/// Dereference: returns the bit value at the current position.
|
|
121
|
+
bool operator*() const {
|
|
122
|
+
if (bitVector == nullptr || position >= bitVector->bitWidth)
|
|
123
|
+
throw std::out_of_range("bit_iterator dereference out of range");
|
|
124
|
+
return bitVector->getBit(position);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/// Pre-increment: move to next bit.
|
|
128
|
+
bit_iterator &operator++() {
|
|
129
|
+
++position;
|
|
130
|
+
return *this;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/// Post-increment: move to next bit.
|
|
134
|
+
bit_iterator operator++(int) {
|
|
135
|
+
bit_iterator tmp = *this;
|
|
136
|
+
++position;
|
|
137
|
+
return tmp;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/// Equality comparison.
|
|
141
|
+
bool operator==(const bit_iterator &other) const {
|
|
142
|
+
return bitVector == other.bitVector && position == other.position;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/// Inequality comparison.
|
|
146
|
+
bool operator!=(const bit_iterator &other) const {
|
|
147
|
+
return !(*this == other);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/// Less-than comparison (for ranges support).
|
|
151
|
+
bool operator<(const bit_iterator &other) const {
|
|
152
|
+
return bitVector == other.bitVector && position < other.position;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/// Sentinel-compatible equality (for ranges support).
|
|
156
|
+
bool operator==(std::default_sentinel_t) const {
|
|
157
|
+
return bitVector == nullptr || position >= bitVector->bitWidth;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/// Sentinel-compatible inequality.
|
|
161
|
+
bool operator!=(std::default_sentinel_t sent) const {
|
|
162
|
+
return !(*this == sent);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
private:
|
|
166
|
+
const BitVector *bitVector = nullptr;
|
|
167
|
+
size_t position = 0;
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
/// Return an iterator to the first bit (LSB).
|
|
171
|
+
bit_iterator begin() const { return bit_iterator(this, 0); }
|
|
172
|
+
|
|
173
|
+
/// Return an iterator past the last bit.
|
|
174
|
+
bit_iterator end() const { return bit_iterator(this, bitWidth); }
|
|
175
|
+
|
|
176
|
+
protected:
|
|
177
|
+
// Underlying storage view. const, to allow for non-owning immutable views.
|
|
178
|
+
std::span<const byte> data{};
|
|
179
|
+
size_t bitWidth = 0; // Number of valid bits.
|
|
180
|
+
uint8_t bitIndex = 0; // Starting bit offset in first byte.
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
/// A mutable bit vector that owns its underlying storage.
|
|
184
|
+
/// It supports in-place modifications and mutable operations.
|
|
185
|
+
class MutableBitVector : public BitVector {
|
|
186
|
+
public:
|
|
187
|
+
/// Owning, zero-initialized constructor of a given width.
|
|
188
|
+
explicit MutableBitVector(size_t width);
|
|
189
|
+
|
|
190
|
+
/// Owning constructor from an rvalue vector (must move in).
|
|
191
|
+
MutableBitVector(std::vector<byte> &&bytes,
|
|
192
|
+
std::optional<size_t> width = std::nullopt);
|
|
193
|
+
|
|
194
|
+
MutableBitVector() = default;
|
|
195
|
+
|
|
196
|
+
// Copy constructor: duplicate storage.
|
|
197
|
+
MutableBitVector(const MutableBitVector &other);
|
|
198
|
+
|
|
199
|
+
// Copy constructor from immutable BitVector: creates owning copy.
|
|
200
|
+
MutableBitVector(const BitVector &other);
|
|
201
|
+
|
|
202
|
+
// Move constructor: transfer ownership.
|
|
203
|
+
MutableBitVector(MutableBitVector &&other) noexcept;
|
|
204
|
+
|
|
205
|
+
// Move constructor from immutable BitVector: creates owning copy.
|
|
206
|
+
MutableBitVector(BitVector &&other);
|
|
207
|
+
|
|
208
|
+
MutableBitVector &operator=(const MutableBitVector &other);
|
|
209
|
+
|
|
210
|
+
MutableBitVector &operator=(MutableBitVector &&other) noexcept;
|
|
211
|
+
|
|
212
|
+
/// Set the i-th bit.
|
|
213
|
+
void setBit(size_t i, bool v);
|
|
214
|
+
|
|
215
|
+
/// Return a handle to the underlying span (always aligned since bitIndex=0).
|
|
216
|
+
std::span<const byte> getSpan() const { return data; }
|
|
217
|
+
|
|
218
|
+
/// Return and transfer ownership of the underlying storage.
|
|
219
|
+
std::vector<uint8_t> takeStorage() { return std::move(owner); }
|
|
220
|
+
|
|
221
|
+
/// In-place logical right shift that drops the least-significant n bits.
|
|
222
|
+
/// Reduces width and updates internal state. Does not modify underlying
|
|
223
|
+
/// storage.
|
|
224
|
+
MutableBitVector &operator>>=(size_t n);
|
|
225
|
+
|
|
226
|
+
/// In-place logical left shift shifts in n zero bits at LSB, shifting
|
|
227
|
+
/// existing bits upward.
|
|
228
|
+
MutableBitVector &operator<<=(size_t n);
|
|
229
|
+
|
|
230
|
+
/// In-place concatenate: appends bits from other to this.
|
|
231
|
+
MutableBitVector &operator<<=(const MutableBitVector &other);
|
|
232
|
+
|
|
233
|
+
MutableBitVector &operator|=(const MutableBitVector &other);
|
|
234
|
+
MutableBitVector &operator&=(const MutableBitVector &other);
|
|
235
|
+
MutableBitVector &operator^=(const MutableBitVector &other);
|
|
236
|
+
MutableBitVector operator~() const;
|
|
237
|
+
MutableBitVector operator|(const MutableBitVector &other) const;
|
|
238
|
+
MutableBitVector operator&(const MutableBitVector &other) const;
|
|
239
|
+
MutableBitVector operator^(const MutableBitVector &other) const;
|
|
240
|
+
|
|
241
|
+
private:
|
|
242
|
+
// Storage owned by this MutableBitVector.
|
|
243
|
+
std::vector<byte> owner;
|
|
244
|
+
};
|
|
245
|
+
|
|
246
|
+
std::ostream &operator<<(std::ostream &os, const BitVector &bv);
|
|
247
|
+
|
|
248
|
+
// Arbitrary width signed integer type built on MutableBitVector.
|
|
249
|
+
class Int : public MutableBitVector {
|
|
250
|
+
public:
|
|
251
|
+
using MutableBitVector::MutableBitVector;
|
|
252
|
+
Int() = default;
|
|
253
|
+
Int(int64_t v, unsigned width = 64);
|
|
254
|
+
operator int64_t() const { return toI64(); }
|
|
255
|
+
operator int32_t() const { return toInt<int32_t>(); }
|
|
256
|
+
operator int16_t() const { return toInt<int16_t>(); }
|
|
257
|
+
operator int8_t() const { return toInt<int8_t>(); }
|
|
258
|
+
|
|
259
|
+
private:
|
|
260
|
+
template <typename T>
|
|
261
|
+
T toInt() const {
|
|
262
|
+
static_assert(std::is_integral<T>::value && std::is_signed<T>::value,
|
|
263
|
+
"T must be a signed integral type");
|
|
264
|
+
int64_t v = toI64();
|
|
265
|
+
fits(v, sizeof(T) * 8);
|
|
266
|
+
return static_cast<T>(v);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// Convert the bitvector to a signed intN_t, throwing if the value doesn't
|
|
270
|
+
// fit.
|
|
271
|
+
int64_t toI64() const;
|
|
272
|
+
|
|
273
|
+
// Check if the given value fits in the specified bit width.
|
|
274
|
+
static void fits(int64_t v, unsigned n);
|
|
275
|
+
};
|
|
276
|
+
|
|
277
|
+
// Arbitrary width unsigned integer type built on MutableBitVector.
|
|
278
|
+
class UInt : public MutableBitVector {
|
|
279
|
+
public:
|
|
280
|
+
using MutableBitVector::MutableBitVector;
|
|
281
|
+
UInt() = default;
|
|
282
|
+
UInt(uint64_t v, unsigned width = 64);
|
|
283
|
+
operator uint64_t() const { return toUI64(); }
|
|
284
|
+
operator uint32_t() const { return toUInt<uint32_t>(); }
|
|
285
|
+
operator uint16_t() const { return toUInt<uint16_t>(); }
|
|
286
|
+
operator uint8_t() const { return toUInt<uint8_t>(); }
|
|
287
|
+
|
|
288
|
+
private:
|
|
289
|
+
uint64_t toUI64() const;
|
|
290
|
+
|
|
291
|
+
static void fits(uint64_t v, unsigned n);
|
|
292
|
+
|
|
293
|
+
template <typename T>
|
|
294
|
+
T toUInt() const {
|
|
295
|
+
static_assert(std::is_integral<T>::value && std::is_unsigned<T>::value,
|
|
296
|
+
"T must be an unsigned integral type");
|
|
297
|
+
uint64_t v = toUI64();
|
|
298
|
+
fits(v, sizeof(T) * 8);
|
|
299
|
+
return static_cast<T>(v);
|
|
300
|
+
}
|
|
301
|
+
};
|
|
302
|
+
|
|
303
|
+
} // namespace esi
|
|
304
|
+
|
|
305
|
+
// Enable BitVector and MutableBitVector to work with std::ranges algorithms
|
|
306
|
+
template <>
|
|
307
|
+
inline constexpr bool std::ranges::enable_borrowed_range<esi::BitVector> = true;
|
|
308
|
+
|
|
309
|
+
template <>
|
|
310
|
+
inline constexpr bool
|
|
311
|
+
std::ranges::enable_borrowed_range<esi::MutableBitVector> = true;
|
|
312
|
+
|
|
313
|
+
#endif // ESI_VALUES_H
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
//===- Cosim.h - ESI C++ cosimulation backend -------------------*- 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
|
+
// This is a specialization of the ESI C++ API (backend) for connection into a
|
|
10
|
+
// simulation of an ESI system. Currently uses gRPC, but that could change.
|
|
11
|
+
// Requires gRPC C++ library.
|
|
12
|
+
//
|
|
13
|
+
// DO NOT EDIT!
|
|
14
|
+
// This file is distributed as part of an ESI package. The source for this file
|
|
15
|
+
// should always be modified within CIRCT (lib/dialect/ESI/runtime/cpp).
|
|
16
|
+
//
|
|
17
|
+
//===----------------------------------------------------------------------===//
|
|
18
|
+
|
|
19
|
+
// NOLINTNEXTLINE(llvm-header-guard)
|
|
20
|
+
#ifndef ESI_BACKENDS_COSIM_H
|
|
21
|
+
#define ESI_BACKENDS_COSIM_H
|
|
22
|
+
|
|
23
|
+
#include "esi/Accelerator.h"
|
|
24
|
+
|
|
25
|
+
#include <memory>
|
|
26
|
+
#include <set>
|
|
27
|
+
|
|
28
|
+
namespace esi {
|
|
29
|
+
namespace backends {
|
|
30
|
+
namespace cosim {
|
|
31
|
+
|
|
32
|
+
class CosimEngine;
|
|
33
|
+
class RpcClient;
|
|
34
|
+
|
|
35
|
+
/// Connect to an ESI simulation.
|
|
36
|
+
class CosimAccelerator : public esi::AcceleratorConnection {
|
|
37
|
+
friend class CosimEngine;
|
|
38
|
+
|
|
39
|
+
public:
|
|
40
|
+
CosimAccelerator(Context &, std::string hostname, uint16_t port);
|
|
41
|
+
~CosimAccelerator();
|
|
42
|
+
|
|
43
|
+
static std::unique_ptr<AcceleratorConnection>
|
|
44
|
+
connect(Context &, std::string connectionString);
|
|
45
|
+
|
|
46
|
+
// Different ways to retrieve the manifest in Cosimulation.
|
|
47
|
+
enum ManifestMethod {
|
|
48
|
+
Cosim, // Use the backdoor cosim interface. Default.
|
|
49
|
+
MMIO, // Use MMIO emulation.
|
|
50
|
+
};
|
|
51
|
+
// Set the way this connection will retrieve the manifest.
|
|
52
|
+
void setManifestMethod(ManifestMethod method);
|
|
53
|
+
|
|
54
|
+
void createEngine(const std::string &engineTypeName, AppIDPath idPath,
|
|
55
|
+
const ServiceImplDetails &details,
|
|
56
|
+
const HWClientDetails &clients) override;
|
|
57
|
+
|
|
58
|
+
protected:
|
|
59
|
+
virtual Service *createService(Service::Type service, AppIDPath path,
|
|
60
|
+
std::string implName,
|
|
61
|
+
const ServiceImplDetails &details,
|
|
62
|
+
const HWClientDetails &clients) override;
|
|
63
|
+
|
|
64
|
+
private:
|
|
65
|
+
std::unique_ptr<RpcClient> rpcClient;
|
|
66
|
+
|
|
67
|
+
// We own all channels connected to rpcClient since their lifetime is tied to
|
|
68
|
+
// rpcClient.
|
|
69
|
+
std::set<std::unique_ptr<ChannelPort>> channels;
|
|
70
|
+
|
|
71
|
+
ManifestMethod manifestMethod = Cosim;
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
} // namespace cosim
|
|
75
|
+
} // namespace backends
|
|
76
|
+
} // namespace esi
|
|
77
|
+
|
|
78
|
+
#endif // ESI_BACKENDS_COSIM_H
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
//===- RpcClient.h - ESI Cosim RPC client -----------------------*- 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
|
+
// This file contains the gRPC client implementation for ESI cosimulation.
|
|
10
|
+
// It wraps all gRPC/protobuf dependencies so they don't leak into other
|
|
11
|
+
// headers.
|
|
12
|
+
//
|
|
13
|
+
// DO NOT EDIT!
|
|
14
|
+
// This file is distributed as part of an ESI package. The source for this file
|
|
15
|
+
// should always be modified within CIRCT (lib/dialect/ESI/runtime/cpp).
|
|
16
|
+
//
|
|
17
|
+
//===----------------------------------------------------------------------===//
|
|
18
|
+
|
|
19
|
+
// NOLINTNEXTLINE(llvm-header-guard)
|
|
20
|
+
#ifndef ESI_BACKENDS_RPCCLIENT_H
|
|
21
|
+
#define ESI_BACKENDS_RPCCLIENT_H
|
|
22
|
+
|
|
23
|
+
#include "esi/Common.h"
|
|
24
|
+
|
|
25
|
+
#include <functional>
|
|
26
|
+
#include <memory>
|
|
27
|
+
#include <string>
|
|
28
|
+
#include <vector>
|
|
29
|
+
|
|
30
|
+
namespace esi {
|
|
31
|
+
namespace backends {
|
|
32
|
+
namespace cosim {
|
|
33
|
+
|
|
34
|
+
/// A gRPC client for communicating with the cosimulation server.
|
|
35
|
+
/// This class wraps all gRPC/protobuf dependencies.
|
|
36
|
+
class RpcClient {
|
|
37
|
+
public:
|
|
38
|
+
RpcClient(const std::string &hostname, uint16_t port);
|
|
39
|
+
~RpcClient();
|
|
40
|
+
|
|
41
|
+
// Non-copyable.
|
|
42
|
+
RpcClient(const RpcClient &) = delete;
|
|
43
|
+
RpcClient &operator=(const RpcClient &) = delete;
|
|
44
|
+
|
|
45
|
+
/// Get the ESI version from the manifest.
|
|
46
|
+
uint32_t getEsiVersion() const;
|
|
47
|
+
|
|
48
|
+
/// Get the compressed manifest from the server.
|
|
49
|
+
std::vector<uint8_t> getCompressedManifest() const;
|
|
50
|
+
|
|
51
|
+
/// Channel direction as reported by the server.
|
|
52
|
+
enum class ChannelDirection { ToServer, ToClient };
|
|
53
|
+
|
|
54
|
+
/// Description of a channel from the server.
|
|
55
|
+
struct ChannelDesc {
|
|
56
|
+
std::string name;
|
|
57
|
+
std::string type;
|
|
58
|
+
ChannelDirection dir;
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
/// Get the channel description for a channel name.
|
|
62
|
+
/// Returns true if the channel was found.
|
|
63
|
+
bool getChannelDesc(const std::string &channelName, ChannelDesc &desc) const;
|
|
64
|
+
|
|
65
|
+
/// List all channels available on the server.
|
|
66
|
+
std::vector<ChannelDesc> listChannels() const;
|
|
67
|
+
|
|
68
|
+
/// Send a message to a server-bound channel.
|
|
69
|
+
void writeToServer(const std::string &channelName, const MessageData &data);
|
|
70
|
+
|
|
71
|
+
/// Callback type for receiving messages from a client-bound channel.
|
|
72
|
+
/// Return true if the message was consumed, false to retry.
|
|
73
|
+
using ReadCallback = std::function<bool(const MessageData &)>;
|
|
74
|
+
|
|
75
|
+
/// Abstract handle for a read channel connection.
|
|
76
|
+
/// Destructor disconnects from the channel.
|
|
77
|
+
class ReadChannelConnection {
|
|
78
|
+
public:
|
|
79
|
+
virtual ~ReadChannelConnection() = default;
|
|
80
|
+
virtual void disconnect() = 0;
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
/// Connect to a client-bound channel and receive messages via callback.
|
|
84
|
+
/// Returns a handle that disconnects when destroyed.
|
|
85
|
+
std::unique_ptr<ReadChannelConnection>
|
|
86
|
+
connectClientReceiver(const std::string &channelName, ReadCallback callback);
|
|
87
|
+
|
|
88
|
+
private:
|
|
89
|
+
class Impl;
|
|
90
|
+
std::unique_ptr<Impl> impl;
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
} // namespace cosim
|
|
94
|
+
} // namespace backends
|
|
95
|
+
} // namespace esi
|
|
96
|
+
|
|
97
|
+
#endif // ESI_BACKENDS_RPCCLIENT_H
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
//===- RpcServer.h - Run a cosim server -------------------------*- 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
|
+
// Setup and run a server accepting connections via the 'cosim' RPC protocol.
|
|
10
|
+
// Then, one can request ports to and from the clients.
|
|
11
|
+
//
|
|
12
|
+
// Abstract this out to support multi-party communication in the future.
|
|
13
|
+
//
|
|
14
|
+
//===----------------------------------------------------------------------===//
|
|
15
|
+
|
|
16
|
+
#ifndef ESI_COSIM_RPCSERVER_H
|
|
17
|
+
#define ESI_COSIM_RPCSERVER_H
|
|
18
|
+
|
|
19
|
+
#include "esi/Context.h"
|
|
20
|
+
#include "esi/Ports.h"
|
|
21
|
+
|
|
22
|
+
namespace esi {
|
|
23
|
+
namespace cosim {
|
|
24
|
+
|
|
25
|
+
/// TODO: make this a proper backend (as much as possible).
|
|
26
|
+
class RpcServer {
|
|
27
|
+
public:
|
|
28
|
+
RpcServer(Context &ctxt);
|
|
29
|
+
~RpcServer();
|
|
30
|
+
|
|
31
|
+
/// Get the context.
|
|
32
|
+
Context &getContext() { return ctxt; }
|
|
33
|
+
|
|
34
|
+
/// Set the manifest and version. There is a race condition here in that the
|
|
35
|
+
/// RPC server can be started and a connection from the client could happen
|
|
36
|
+
/// before the manifest is set. TODO: rework the DPI API to require that the
|
|
37
|
+
/// manifest gets set first.
|
|
38
|
+
void setManifest(int esiVersion,
|
|
39
|
+
const std::vector<uint8_t> &compressedManifest);
|
|
40
|
+
|
|
41
|
+
/// Register a read or write port which communicates over RPC.
|
|
42
|
+
ReadChannelPort ®isterReadPort(const std::string &name,
|
|
43
|
+
const std::string &type);
|
|
44
|
+
WriteChannelPort ®isterWritePort(const std::string &name,
|
|
45
|
+
const std::string &type);
|
|
46
|
+
|
|
47
|
+
// Stop the RPC server.
|
|
48
|
+
// If a millisecond timeout is provided, will forcefully stop the underlying
|
|
49
|
+
// RPC server once the timeout expires. If not, the RPC server will attempt to
|
|
50
|
+
// stop gracefully, implying that any outstanding RPC calls must be served
|
|
51
|
+
// before the server actually stops (see grpc::ServerInterface::Shutdown for
|
|
52
|
+
// more).
|
|
53
|
+
void stop(uint32_t timeoutMS = 0);
|
|
54
|
+
|
|
55
|
+
// Start the RPC server. If no port is provided, the RPC server will let the
|
|
56
|
+
// OS pick a port.
|
|
57
|
+
void run(int port = -1);
|
|
58
|
+
|
|
59
|
+
// Return which port the RPC server is executing on.
|
|
60
|
+
int getPort();
|
|
61
|
+
|
|
62
|
+
/// Hide the implementation details from this header file.
|
|
63
|
+
class Impl;
|
|
64
|
+
|
|
65
|
+
private:
|
|
66
|
+
Context &ctxt;
|
|
67
|
+
std::unique_ptr<Impl> impl;
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
} // namespace cosim
|
|
71
|
+
} // namespace esi
|
|
72
|
+
|
|
73
|
+
#endif // ESI_COSIM_RPCSERVER_H
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
//===- Trace.h - ESI trace backend ------------------------------*- 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
|
+
// This is a specialization of the ESI C++ API (backend) for trace-based
|
|
10
|
+
// Accelerator interactions. This means that it will have the capability to read
|
|
11
|
+
// trace files recorded from interactions with an actual connection. It also has
|
|
12
|
+
// a mode wherein it will write to a file (for sends) and produce random data
|
|
13
|
+
// (for receives). Both modes are intended for debugging without a simulation.
|
|
14
|
+
//
|
|
15
|
+
// DO NOT EDIT!
|
|
16
|
+
// This file is distributed as part of an ESI package. The source for this file
|
|
17
|
+
// should always be modified within CIRCT (lib/dialect/ESI/runtime/cpp/).
|
|
18
|
+
//
|
|
19
|
+
//===----------------------------------------------------------------------===//
|
|
20
|
+
|
|
21
|
+
// NOLINTNEXTLINE(llvm-header-guard)
|
|
22
|
+
#ifndef ESI_BACKENDS_COSIM_H
|
|
23
|
+
#define ESI_BACKENDS_COSIM_H
|
|
24
|
+
|
|
25
|
+
#include "esi/Accelerator.h"
|
|
26
|
+
|
|
27
|
+
#include <filesystem>
|
|
28
|
+
#include <memory>
|
|
29
|
+
|
|
30
|
+
namespace esi {
|
|
31
|
+
namespace backends {
|
|
32
|
+
namespace trace {
|
|
33
|
+
|
|
34
|
+
/// Connect to an ESI simulation.
|
|
35
|
+
class TraceAccelerator : public esi::AcceleratorConnection {
|
|
36
|
+
public:
|
|
37
|
+
enum Mode {
|
|
38
|
+
// Write data sent to the accelerator to the trace file. Produce random
|
|
39
|
+
// garbage data for reads from the accelerator.
|
|
40
|
+
Write,
|
|
41
|
+
|
|
42
|
+
// Sent data to the accelerator is compared against the trace file's record.
|
|
43
|
+
// Data read from the accelerator is read from the trace file.
|
|
44
|
+
// TODO: Full trace mode not yet supported.
|
|
45
|
+
// Read
|
|
46
|
+
|
|
47
|
+
// Discard all data sent to the accelerator. Disable trace file generation.
|
|
48
|
+
Discard,
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
/// Create a trace-based accelerator backend.
|
|
52
|
+
/// \param mode The mode of operation. See Mode.
|
|
53
|
+
/// \param manifestJson The path to the manifest JSON file.
|
|
54
|
+
/// \param traceFile The path to the trace file. For 'Write' mode, this file
|
|
55
|
+
/// is opened for writing. For 'Read' mode, this file is opened for reading.
|
|
56
|
+
TraceAccelerator(Context &, Mode mode, std::filesystem::path manifestJson,
|
|
57
|
+
std::filesystem::path traceFile);
|
|
58
|
+
~TraceAccelerator() override;
|
|
59
|
+
|
|
60
|
+
/// Parse the connection string and instantiate the accelerator. Format is:
|
|
61
|
+
/// "<mode>:<manifest path>[:<traceFile>]".
|
|
62
|
+
static std::unique_ptr<AcceleratorConnection>
|
|
63
|
+
connect(Context &, std::string connectionString);
|
|
64
|
+
|
|
65
|
+
/// Internal implementation.
|
|
66
|
+
struct Impl;
|
|
67
|
+
Impl &getImpl();
|
|
68
|
+
|
|
69
|
+
protected:
|
|
70
|
+
void createEngine(const std::string &engineTypeName, AppIDPath idPath,
|
|
71
|
+
const ServiceImplDetails &details,
|
|
72
|
+
const HWClientDetails &clients) override;
|
|
73
|
+
|
|
74
|
+
virtual Service *createService(Service::Type service, AppIDPath idPath,
|
|
75
|
+
std::string implName,
|
|
76
|
+
const ServiceImplDetails &details,
|
|
77
|
+
const HWClientDetails &clients) override;
|
|
78
|
+
|
|
79
|
+
private:
|
|
80
|
+
std::unique_ptr<Impl> impl;
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
} // namespace trace
|
|
84
|
+
} // namespace backends
|
|
85
|
+
} // namespace esi
|
|
86
|
+
|
|
87
|
+
#endif // ESI_BACKENDS_COSIM_H
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|