esiaccel 0.1.5.dev205__cp39-cp39-win_amd64.whl → 0.1.5.dev533__cp39-cp39-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.
- 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 +12 -3
- esiaccel/abseil_dll.dll +0 -0
- esiaccel/accelerator.py +37 -5
- esiaccel/cares.dll +0 -0
- esiaccel/codegen.py +3 -3
- esiaccel/cosim/Cosim_Endpoint.sv +0 -18
- esiaccel/cosim/driver.cpp +6 -6
- esiaccel/cosim/driver.sv +14 -0
- esiaccel/cosim/questa.py +67 -4
- esiaccel/cosim/simulator.py +185 -38
- esiaccel/cosim/verilator.py +36 -5
- esiaccel/esiCppAccel.cp312-win_amd64.pyd +0 -0
- esiaccel/esiquery.exe +0 -0
- esiaccel/include/esi/Accelerator.h +3 -16
- esiaccel/include/esi/CLI.h +5 -5
- esiaccel/include/esi/Common.h +11 -1
- esiaccel/include/esi/Context.h +17 -9
- esiaccel/include/esi/Design.h +9 -4
- esiaccel/include/esi/Manifest.h +0 -2
- esiaccel/include/esi/Ports.h +72 -15
- esiaccel/include/esi/Services.h +50 -18
- esiaccel/include/esi/Types.h +108 -31
- esiaccel/include/esi/Values.h +313 -0
- 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 +6 -4
- esiaccel/zlib1.dll +0 -0
- {esiaccel-0.1.5.dev205.dist-info → esiaccel-0.1.5.dev533.dist-info}/METADATA +1 -1
- esiaccel-0.1.5.dev533.dist-info/RECORD +54 -0
- esiaccel/esiCppAccel.cp39-win_amd64.pyd +0 -0
- esiaccel-0.1.5.dev205.dist-info/RECORD +0 -46
- {esiaccel-0.1.5.dev205.dist-info → esiaccel-0.1.5.dev533.dist-info}/WHEEL +0 -0
- {esiaccel-0.1.5.dev205.dist-info → esiaccel-0.1.5.dev533.dist-info}/entry_points.txt +0 -0
- {esiaccel-0.1.5.dev205.dist-info → esiaccel-0.1.5.dev533.dist-info}/licenses/LICENSE +0 -0
- {esiaccel-0.1.5.dev205.dist-info → esiaccel-0.1.5.dev533.dist-info}/top_level.txt +0 -0
esiaccel/cosim/verilator.py
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import os
|
|
6
6
|
from pathlib import Path
|
|
7
|
-
from typing import List
|
|
7
|
+
from typing import List, Optional, Callable, Dict
|
|
8
8
|
|
|
9
9
|
from .simulator import CosimCollateralDir, Simulator, SourceFiles
|
|
10
10
|
|
|
@@ -14,9 +14,29 @@ class Verilator(Simulator):
|
|
|
14
14
|
|
|
15
15
|
DefaultDriver = CosimCollateralDir / "driver.cpp"
|
|
16
16
|
|
|
17
|
-
def __init__(
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
def __init__(
|
|
18
|
+
self,
|
|
19
|
+
sources: SourceFiles,
|
|
20
|
+
run_dir: Path,
|
|
21
|
+
debug: bool,
|
|
22
|
+
run_stdout_callback: Optional[Callable[[str], None]] = None,
|
|
23
|
+
run_stderr_callback: Optional[Callable[[str], None]] = None,
|
|
24
|
+
compile_stdout_callback: Optional[Callable[[str], None]] = None,
|
|
25
|
+
compile_stderr_callback: Optional[Callable[[str], None]] = None,
|
|
26
|
+
make_default_logs: bool = True,
|
|
27
|
+
macro_definitions: Optional[Dict[str, str]] = None,
|
|
28
|
+
):
|
|
29
|
+
super().__init__(
|
|
30
|
+
sources=sources,
|
|
31
|
+
run_dir=run_dir,
|
|
32
|
+
debug=debug,
|
|
33
|
+
run_stdout_callback=run_stdout_callback,
|
|
34
|
+
run_stderr_callback=run_stderr_callback,
|
|
35
|
+
compile_stdout_callback=compile_stdout_callback,
|
|
36
|
+
compile_stderr_callback=compile_stderr_callback,
|
|
37
|
+
make_default_logs=make_default_logs,
|
|
38
|
+
macro_definitions=macro_definitions,
|
|
39
|
+
)
|
|
20
40
|
self.verilator = "verilator"
|
|
21
41
|
if "VERILATOR_PATH" in os.environ:
|
|
22
42
|
self.verilator = os.environ["VERILATOR_PATH"]
|
|
@@ -25,6 +45,15 @@ class Verilator(Simulator):
|
|
|
25
45
|
cmd: List[str] = [
|
|
26
46
|
self.verilator,
|
|
27
47
|
"--cc",
|
|
48
|
+
]
|
|
49
|
+
|
|
50
|
+
if self.macro_definitions:
|
|
51
|
+
cmd += [
|
|
52
|
+
f"+define+{k}={v}" if v is not None else f"+define+{k}"
|
|
53
|
+
for k, v in self.macro_definitions.items()
|
|
54
|
+
]
|
|
55
|
+
|
|
56
|
+
cmd += [
|
|
28
57
|
"--top-module",
|
|
29
58
|
self.sources.top,
|
|
30
59
|
"-DSIMULATION",
|
|
@@ -36,6 +65,7 @@ class Verilator(Simulator):
|
|
|
36
65
|
"-j",
|
|
37
66
|
"0",
|
|
38
67
|
"--output-split",
|
|
68
|
+
"--autoflush",
|
|
39
69
|
"--assert",
|
|
40
70
|
str(Verilator.DefaultDriver),
|
|
41
71
|
]
|
|
@@ -44,7 +74,8 @@ class Verilator(Simulator):
|
|
|
44
74
|
]
|
|
45
75
|
if self.debug:
|
|
46
76
|
cmd += [
|
|
47
|
-
"--trace", "--trace-params", "--trace-structs",
|
|
77
|
+
"--trace-fst", "--trace-params", "--trace-structs",
|
|
78
|
+
"--trace-underscore"
|
|
48
79
|
]
|
|
49
80
|
cflags.append("-DTRACE")
|
|
50
81
|
if len(cflags) > 0:
|
|
Binary file
|
esiaccel/esiquery.exe
CHANGED
|
Binary file
|
|
@@ -65,8 +65,8 @@ public:
|
|
|
65
65
|
Accelerator(std::optional<ModuleInfo> info,
|
|
66
66
|
std::vector<std::unique_ptr<Instance>> children,
|
|
67
67
|
std::vector<services::Service *> services,
|
|
68
|
-
std::vector<std::unique_ptr<BundlePort>>
|
|
69
|
-
: HWModule(info, std::move(children), services, ports) {}
|
|
68
|
+
std::vector<std::unique_ptr<BundlePort>> &&ports)
|
|
69
|
+
: HWModule(info, std::move(children), services, std::move(ports)) {}
|
|
70
70
|
};
|
|
71
71
|
|
|
72
72
|
//===----------------------------------------------------------------------===//
|
|
@@ -86,13 +86,6 @@ public:
|
|
|
86
86
|
/// Disconnect from the accelerator cleanly.
|
|
87
87
|
virtual void disconnect();
|
|
88
88
|
|
|
89
|
-
// While building the design, keep around a std::map of active services
|
|
90
|
-
// indexed by the service name. When a new service is encountered during
|
|
91
|
-
// descent, add it to the table (perhaps overwriting one). Modifications to
|
|
92
|
-
// the table only apply to the current branch, so copy this and update it at
|
|
93
|
-
// each level of the tree.
|
|
94
|
-
using ServiceTable = std::map<std::string, services::Service *>;
|
|
95
|
-
|
|
96
89
|
/// Return a pointer to the accelerator 'service' thread (or threads). If the
|
|
97
90
|
/// thread(s) are not running, they will be started when this method is
|
|
98
91
|
/// called. `std::thread` is used. If users don't want the runtime to spin up
|
|
@@ -165,7 +158,7 @@ private:
|
|
|
165
158
|
|
|
166
159
|
/// Cache services via a unique_ptr so they get free'd automatically when
|
|
167
160
|
/// Accelerator objects get deconstructed.
|
|
168
|
-
using ServiceCacheKey = std::tuple<
|
|
161
|
+
using ServiceCacheKey = std::tuple<std::string, AppIDPath>;
|
|
169
162
|
std::map<ServiceCacheKey, std::unique_ptr<Service>> serviceCache;
|
|
170
163
|
|
|
171
164
|
std::unique_ptr<AcceleratorServiceThread> serviceThread;
|
|
@@ -176,12 +169,6 @@ private:
|
|
|
176
169
|
|
|
177
170
|
namespace registry {
|
|
178
171
|
|
|
179
|
-
// Connect to an ESI accelerator given a backend name and connection specifier.
|
|
180
|
-
// Alternatively, instantiate the backend directly (if you're using C++).
|
|
181
|
-
std::unique_ptr<AcceleratorConnection> connect(Context &ctxt,
|
|
182
|
-
const std::string &backend,
|
|
183
|
-
const std::string &connection);
|
|
184
|
-
|
|
185
172
|
namespace internal {
|
|
186
173
|
|
|
187
174
|
/// Backends can register themselves to be connected via a connection string.
|
esiaccel/include/esi/CLI.h
CHANGED
|
@@ -51,19 +51,19 @@ public:
|
|
|
51
51
|
ctxt = Context::withLogger<ConsoleLogger>(Logger::Level::Debug);
|
|
52
52
|
else if (verbose)
|
|
53
53
|
ctxt = Context::withLogger<ConsoleLogger>(Logger::Level::Info);
|
|
54
|
+
else
|
|
55
|
+
ctxt = Context::withLogger<ConsoleLogger>(Logger::Level::Warning);
|
|
54
56
|
return 0;
|
|
55
57
|
}
|
|
56
58
|
|
|
57
59
|
/// Connect to the accelerator using the specified backend and connection.
|
|
58
|
-
|
|
59
|
-
return ctxt.connect(backend, connStr);
|
|
60
|
-
}
|
|
60
|
+
AcceleratorConnection *connect() { return ctxt->connect(backend, connStr); }
|
|
61
61
|
|
|
62
62
|
/// Get the context.
|
|
63
|
-
Context &getContext() { return ctxt; }
|
|
63
|
+
Context &getContext() { return *ctxt; }
|
|
64
64
|
|
|
65
65
|
protected:
|
|
66
|
-
Context ctxt;
|
|
66
|
+
std::unique_ptr<Context> ctxt;
|
|
67
67
|
|
|
68
68
|
std::string backend;
|
|
69
69
|
std::string connStr;
|
esiaccel/include/esi/Common.h
CHANGED
|
@@ -43,6 +43,13 @@ struct AppID {
|
|
|
43
43
|
return name == other.name && idx == other.idx;
|
|
44
44
|
}
|
|
45
45
|
bool operator!=(const AppID &other) const { return !(*this == other); }
|
|
46
|
+
friend std::ostream &operator<<(std::ostream &os, const AppID &id);
|
|
47
|
+
|
|
48
|
+
std::string toString() const {
|
|
49
|
+
if (idx.has_value())
|
|
50
|
+
return name + "[" + std::to_string(idx.value()) + "]";
|
|
51
|
+
return name;
|
|
52
|
+
}
|
|
46
53
|
};
|
|
47
54
|
bool operator<(const AppID &a, const AppID &b);
|
|
48
55
|
|
|
@@ -53,6 +60,7 @@ public:
|
|
|
53
60
|
AppIDPath operator+(const AppIDPath &b) const;
|
|
54
61
|
AppIDPath parent() const;
|
|
55
62
|
std::string toStr() const;
|
|
63
|
+
friend std::ostream &operator<<(std::ostream &os, const AppIDPath &path);
|
|
56
64
|
};
|
|
57
65
|
bool operator<(const AppIDPath &a, const AppIDPath &b);
|
|
58
66
|
|
|
@@ -106,6 +114,8 @@ class MessageData {
|
|
|
106
114
|
public:
|
|
107
115
|
/// Adopts the data vector buffer.
|
|
108
116
|
MessageData() = default;
|
|
117
|
+
MessageData(std::span<const uint8_t> data)
|
|
118
|
+
: data(data.data(), data.data() + data.size()) {}
|
|
109
119
|
MessageData(std::vector<uint8_t> &data) : data(std::move(data)) {}
|
|
110
120
|
MessageData(std::vector<uint8_t> &&data) : data(std::move(data)) {}
|
|
111
121
|
MessageData(const uint8_t *data, size_t size) : data(data, data + size) {}
|
|
@@ -126,6 +136,7 @@ public:
|
|
|
126
136
|
|
|
127
137
|
/// Get the size of the data in bytes.
|
|
128
138
|
size_t getSize() const { return data.size(); }
|
|
139
|
+
size_t size() const { return getSize(); }
|
|
129
140
|
|
|
130
141
|
/// Returns true if this message contains no data.
|
|
131
142
|
bool empty() const { return data.empty(); }
|
|
@@ -158,7 +169,6 @@ private:
|
|
|
158
169
|
} // namespace esi
|
|
159
170
|
|
|
160
171
|
std::ostream &operator<<(std::ostream &, const esi::ModuleInfo &);
|
|
161
|
-
std::ostream &operator<<(std::ostream &, const esi::AppID &);
|
|
162
172
|
|
|
163
173
|
//===----------------------------------------------------------------------===//
|
|
164
174
|
// Functions which should be in the standard library.
|
esiaccel/include/esi/Context.h
CHANGED
|
@@ -20,23 +20,30 @@
|
|
|
20
20
|
#include "esi/Types.h"
|
|
21
21
|
|
|
22
22
|
#include <exception>
|
|
23
|
+
#include <map>
|
|
23
24
|
#include <memory>
|
|
24
|
-
#include <
|
|
25
|
+
#include <vector>
|
|
25
26
|
|
|
26
27
|
namespace esi {
|
|
27
28
|
class AcceleratorConnection;
|
|
28
29
|
|
|
29
30
|
/// AcceleratorConnections, Accelerators, and Manifests must all share a
|
|
30
|
-
/// context. It owns all the types, uniquifying them.
|
|
31
|
+
/// context. It owns all the types, uniquifying them. It also owns the
|
|
32
|
+
/// connections (which own the Accelerators). When it is destroyed, all
|
|
33
|
+
/// connections are disconnected and the objects are destroyed.
|
|
31
34
|
class Context {
|
|
32
35
|
public:
|
|
33
|
-
Context()
|
|
34
|
-
Context(std::unique_ptr<Logger> logger)
|
|
36
|
+
Context();
|
|
37
|
+
Context(std::unique_ptr<Logger> logger);
|
|
38
|
+
~Context();
|
|
39
|
+
|
|
40
|
+
/// Disconnect from all accelerators associated with this context.
|
|
41
|
+
void disconnectAll();
|
|
35
42
|
|
|
36
43
|
/// Create a context with a specific logger type.
|
|
37
44
|
template <typename T, typename... Args>
|
|
38
|
-
static Context withLogger(Args &&...args) {
|
|
39
|
-
return Context(std::make_unique<T>(args...));
|
|
45
|
+
static std::unique_ptr<Context> withLogger(Args &&...args) {
|
|
46
|
+
return std::make_unique<Context>(std::make_unique<T>(args...));
|
|
40
47
|
}
|
|
41
48
|
|
|
42
49
|
/// Resolve a type id to the type.
|
|
@@ -49,9 +56,9 @@ public:
|
|
|
49
56
|
/// Register a type with the context. Takes ownership of the pointer type.
|
|
50
57
|
void registerType(Type *type);
|
|
51
58
|
|
|
52
|
-
/// Connect to an accelerator backend.
|
|
53
|
-
|
|
54
|
-
|
|
59
|
+
/// Connect to an accelerator backend. Retains ownership internally and
|
|
60
|
+
/// returns a non-owning pointer.
|
|
61
|
+
AcceleratorConnection *connect(std::string backend, std::string connection);
|
|
55
62
|
|
|
56
63
|
/// Register a logger with the accelerator. Assumes ownership of the logger.
|
|
57
64
|
void setLogger(std::unique_ptr<Logger> logger) {
|
|
@@ -63,6 +70,7 @@ public:
|
|
|
63
70
|
|
|
64
71
|
private:
|
|
65
72
|
std::unique_ptr<Logger> logger;
|
|
73
|
+
std::vector<std::unique_ptr<AcceleratorConnection>> connections;
|
|
66
74
|
|
|
67
75
|
private:
|
|
68
76
|
using TypeCache = std::map<Type::ID, std::unique_ptr<Type>>;
|
esiaccel/include/esi/Design.h
CHANGED
|
@@ -45,11 +45,15 @@ class Service;
|
|
|
45
45
|
|
|
46
46
|
/// Represents either the top level or an instance of a hardware module.
|
|
47
47
|
class HWModule {
|
|
48
|
+
public:
|
|
49
|
+
HWModule(const HWModule &) = delete;
|
|
50
|
+
HWModule &operator=(const HWModule &) = delete;
|
|
51
|
+
|
|
48
52
|
protected:
|
|
49
53
|
HWModule(std::optional<ModuleInfo> info,
|
|
50
54
|
std::vector<std::unique_ptr<Instance>> children,
|
|
51
55
|
std::vector<services::Service *> services,
|
|
52
|
-
std::vector<std::unique_ptr<BundlePort>>
|
|
56
|
+
std::vector<std::unique_ptr<BundlePort>> &&ports);
|
|
53
57
|
|
|
54
58
|
public:
|
|
55
59
|
virtual ~HWModule() = default;
|
|
@@ -112,11 +116,12 @@ public:
|
|
|
112
116
|
Instance(AppID id, std::optional<ModuleInfo> info,
|
|
113
117
|
std::vector<std::unique_ptr<Instance>> children,
|
|
114
118
|
std::vector<services::Service *> services,
|
|
115
|
-
std::vector<std::unique_ptr<BundlePort>>
|
|
116
|
-
: HWModule(info, std::move(children), services, ports),
|
|
119
|
+
std::vector<std::unique_ptr<BundlePort>> &&ports)
|
|
120
|
+
: HWModule(info, std::move(children), services, std::move(ports)),
|
|
121
|
+
id(id) {}
|
|
117
122
|
|
|
118
123
|
/// Get the instance's ID, which it will always have.
|
|
119
|
-
|
|
124
|
+
AppID getID() const { return id; }
|
|
120
125
|
|
|
121
126
|
protected:
|
|
122
127
|
const AppID id;
|
esiaccel/include/esi/Manifest.h
CHANGED
|
@@ -65,8 +65,6 @@ private:
|
|
|
65
65
|
|
|
66
66
|
} // namespace esi
|
|
67
67
|
|
|
68
|
-
std::ostream &operator<<(std::ostream &os, const esi::AppID &id);
|
|
69
|
-
std::ostream &operator<<(std::ostream &, const esi::AppIDPath &);
|
|
70
68
|
std::ostream &operator<<(std::ostream &, const esi::ModuleInfo &);
|
|
71
69
|
|
|
72
70
|
#endif // ESI_MANIFEST_H
|
esiaccel/include/esi/Ports.h
CHANGED
|
@@ -35,13 +35,63 @@ using PortMap = std::map<std::string, ChannelPort &>;
|
|
|
35
35
|
/// but used by higher level APIs which add types.
|
|
36
36
|
class ChannelPort {
|
|
37
37
|
public:
|
|
38
|
-
ChannelPort(const Type *type)
|
|
38
|
+
ChannelPort(const Type *type);
|
|
39
39
|
virtual ~ChannelPort() {}
|
|
40
40
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
41
|
+
struct ConnectOptions {
|
|
42
|
+
/// The buffer size is optional and should be considered merely a hint.
|
|
43
|
+
/// Individual implementations use it however they like. The unit is number
|
|
44
|
+
/// of messages of the port type.
|
|
45
|
+
std::optional<unsigned> bufferSize = std::nullopt;
|
|
46
|
+
|
|
47
|
+
/// If the type of this port is a window, translate the incoming/outgoing
|
|
48
|
+
/// data into its underlying ('into') type. For 'into' types without lists,
|
|
49
|
+
/// just re-arranges the data fields from the lowered type to the 'into'
|
|
50
|
+
/// type.
|
|
51
|
+
///
|
|
52
|
+
/// If this option is false, no translation is done and the data is
|
|
53
|
+
/// passed through as-is. Same is true for non-windowed types.
|
|
54
|
+
///
|
|
55
|
+
/// For messages with lists, only two types are supported:
|
|
56
|
+
/// 1) Parallel encoding includes any 'header' data with each frame. Said
|
|
57
|
+
/// header data is the same across all frames, so this encoding is
|
|
58
|
+
/// inefficient but is commonly used for on-chip streaming interfaces.
|
|
59
|
+
/// Each frame contains a 'last' field to indicate the end of the list.
|
|
60
|
+
/// In cases where 'numItems' is greater than 1, a field named
|
|
61
|
+
/// '<listField>_size' indicates the number of valid items in that
|
|
62
|
+
/// frame.
|
|
63
|
+
/// 2) Serial (bulk transfer) encoding, where a 'header' frame precedes
|
|
64
|
+
/// the list data frame. Said header frame contains a 'count' field
|
|
65
|
+
/// indicating the number of items in the list. Importantly, the
|
|
66
|
+
/// header frame is always re-transmitted after the specified number of
|
|
67
|
+
/// list items have been sent. If the 'count' field is zero, the end of
|
|
68
|
+
/// the list has been reached. If it is non-zero, the message has not
|
|
69
|
+
/// been completely transmitted and reading should continue until a
|
|
70
|
+
/// 'count' of zero is received.
|
|
71
|
+
///
|
|
72
|
+
/// In both cases, the returned MessageData contains the complete header
|
|
73
|
+
/// followed by the list data. In other words, header data is not duplicated
|
|
74
|
+
/// in the returned message.
|
|
75
|
+
///
|
|
76
|
+
/// Important note: for consistency, preserves SystemVerilog struct field
|
|
77
|
+
/// ordering! So it's the opposite of C struct ordering.
|
|
78
|
+
///
|
|
79
|
+
/// Implementation status:
|
|
80
|
+
/// - Lists are not yet supported.
|
|
81
|
+
/// - Write ports are not yet supported.
|
|
82
|
+
/// - Fields must be byte-aligned.
|
|
83
|
+
///
|
|
84
|
+
/// See the CIRCT documentation (or td files) for more details on windowed
|
|
85
|
+
/// messages.
|
|
86
|
+
bool translateMessage = true;
|
|
87
|
+
|
|
88
|
+
ConnectOptions(std::optional<unsigned> bufferSize = std::nullopt,
|
|
89
|
+
bool translateMessage = true)
|
|
90
|
+
: bufferSize(bufferSize), translateMessage(translateMessage) {}
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
/// Set up a connection to the accelerator.
|
|
94
|
+
virtual void connect(const ConnectOptions &options = ConnectOptions()) = 0;
|
|
45
95
|
virtual void disconnect() = 0;
|
|
46
96
|
virtual bool isConnected() const = 0;
|
|
47
97
|
|
|
@@ -63,6 +113,7 @@ public:
|
|
|
63
113
|
|
|
64
114
|
protected:
|
|
65
115
|
const Type *type;
|
|
116
|
+
const WindowType *translationType;
|
|
66
117
|
|
|
67
118
|
/// Method called by poll() to actually poll the channel if the channel is
|
|
68
119
|
/// connected.
|
|
@@ -70,7 +121,7 @@ protected:
|
|
|
70
121
|
|
|
71
122
|
/// Called by all connect methods to let backends initiate the underlying
|
|
72
123
|
/// connections.
|
|
73
|
-
virtual void connectImpl(
|
|
124
|
+
virtual void connectImpl(const ConnectOptions &options) {}
|
|
74
125
|
};
|
|
75
126
|
|
|
76
127
|
/// A ChannelPort which sends data to the accelerator.
|
|
@@ -78,9 +129,8 @@ class WriteChannelPort : public ChannelPort {
|
|
|
78
129
|
public:
|
|
79
130
|
using ChannelPort::ChannelPort;
|
|
80
131
|
|
|
81
|
-
virtual void
|
|
82
|
-
|
|
83
|
-
connectImpl(bufferSize);
|
|
132
|
+
virtual void connect(const ConnectOptions &options = {}) override {
|
|
133
|
+
connectImpl(options);
|
|
84
134
|
connected = true;
|
|
85
135
|
}
|
|
86
136
|
virtual void disconnect() override { connected = false; }
|
|
@@ -105,7 +155,7 @@ public:
|
|
|
105
155
|
UnknownWriteChannelPort(const Type *type, std::string errmsg)
|
|
106
156
|
: WriteChannelPort(type), errmsg(errmsg) {}
|
|
107
157
|
|
|
108
|
-
void connect(
|
|
158
|
+
void connect(const ConnectOptions &options = {}) override {
|
|
109
159
|
throw std::runtime_error(errmsg);
|
|
110
160
|
}
|
|
111
161
|
void write(const MessageData &) override { throw std::runtime_error(errmsg); }
|
|
@@ -143,7 +193,7 @@ public:
|
|
|
143
193
|
//===--------------------------------------------------------------------===//
|
|
144
194
|
|
|
145
195
|
virtual void connect(std::function<bool(MessageData)> callback,
|
|
146
|
-
|
|
196
|
+
const ConnectOptions &options = {});
|
|
147
197
|
|
|
148
198
|
//===--------------------------------------------------------------------===//
|
|
149
199
|
// Polling mode methods: To use futures or blocking reads, connect without any
|
|
@@ -154,8 +204,7 @@ public:
|
|
|
154
204
|
static constexpr uint64_t DefaultMaxDataQueueMsgs = 32;
|
|
155
205
|
|
|
156
206
|
/// Connect to the channel in polling mode.
|
|
157
|
-
virtual void
|
|
158
|
-
connect(std::optional<unsigned> bufferSize = std::nullopt) override;
|
|
207
|
+
virtual void connect(const ConnectOptions &options = {}) override;
|
|
159
208
|
|
|
160
209
|
/// Asynchronous read.
|
|
161
210
|
virtual std::future<MessageData> readAsync();
|
|
@@ -184,6 +233,14 @@ protected:
|
|
|
184
233
|
/// Backends call this callback when new data is available.
|
|
185
234
|
std::function<bool(MessageData)> callback;
|
|
186
235
|
|
|
236
|
+
/// Window translation support.
|
|
237
|
+
std::vector<uint8_t> translationBuffer;
|
|
238
|
+
/// Index of the next expected frame (for multi-frame windows).
|
|
239
|
+
size_t nextFrameIndex = 0;
|
|
240
|
+
/// Translate incoming data if the port type is a window type. Returns true if
|
|
241
|
+
/// the message has been completely received.
|
|
242
|
+
bool translateIncoming(MessageData &data);
|
|
243
|
+
|
|
187
244
|
//===--------------------------------------------------------------------===//
|
|
188
245
|
// Polling mode members.
|
|
189
246
|
//===--------------------------------------------------------------------===//
|
|
@@ -206,10 +263,10 @@ public:
|
|
|
206
263
|
: ReadChannelPort(type), errmsg(errmsg) {}
|
|
207
264
|
|
|
208
265
|
void connect(std::function<bool(MessageData)> callback,
|
|
209
|
-
|
|
266
|
+
const ConnectOptions &options = ConnectOptions()) override {
|
|
210
267
|
throw std::runtime_error(errmsg);
|
|
211
268
|
}
|
|
212
|
-
void connect(
|
|
269
|
+
void connect(const ConnectOptions &options = ConnectOptions()) override {
|
|
213
270
|
throw std::runtime_error(errmsg);
|
|
214
271
|
}
|
|
215
272
|
std::future<MessageData> readAsync() override {
|
esiaccel/include/esi/Services.h
CHANGED
|
@@ -25,10 +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;
|
|
31
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
|
+
|
|
32
43
|
namespace services {
|
|
33
44
|
|
|
34
45
|
/// Add a custom interface to a service client at a particular point in the
|
|
@@ -38,7 +49,9 @@ public:
|
|
|
38
49
|
using BundlePort::BundlePort;
|
|
39
50
|
virtual ~ServicePort() = default;
|
|
40
51
|
// Get a description of the service port.
|
|
41
|
-
virtual std::optional<std::string> toString() const {
|
|
52
|
+
virtual std::optional<std::string> toString(bool oneLine = false) const {
|
|
53
|
+
return std::nullopt;
|
|
54
|
+
}
|
|
42
55
|
};
|
|
43
56
|
|
|
44
57
|
/// Parent class of all APIs modeled as 'services'. May or may not map to a
|
|
@@ -170,7 +183,8 @@ public:
|
|
|
170
183
|
/// Write a 64-bit value to this region, not the global address space.
|
|
171
184
|
virtual void write(uint32_t addr, uint64_t data);
|
|
172
185
|
|
|
173
|
-
virtual std::optional<std::string>
|
|
186
|
+
virtual std::optional<std::string>
|
|
187
|
+
toString(bool oneLine = false) const override {
|
|
174
188
|
return "MMIO region " + toHex(desc.base) + " - " +
|
|
175
189
|
toHex(desc.base + desc.size);
|
|
176
190
|
}
|
|
@@ -282,10 +296,12 @@ public:
|
|
|
282
296
|
->getInner();
|
|
283
297
|
}
|
|
284
298
|
|
|
285
|
-
virtual std::optional<std::string>
|
|
299
|
+
virtual std::optional<std::string>
|
|
300
|
+
toString(bool oneLine = false) const override {
|
|
286
301
|
const esi::Type *argType = getArgType();
|
|
287
302
|
const esi::Type *resultType = getResultType();
|
|
288
|
-
return "function " + resultType->
|
|
303
|
+
return "function " + resultType->toString(oneLine) + "(" +
|
|
304
|
+
argType->toString(oneLine) + ")";
|
|
289
305
|
}
|
|
290
306
|
|
|
291
307
|
private:
|
|
@@ -338,10 +354,12 @@ public:
|
|
|
338
354
|
->getInner();
|
|
339
355
|
}
|
|
340
356
|
|
|
341
|
-
virtual std::optional<std::string>
|
|
357
|
+
virtual std::optional<std::string>
|
|
358
|
+
toString(bool oneLine = false) const override {
|
|
342
359
|
const esi::Type *argType = getArgType();
|
|
343
360
|
const esi::Type *resultType = getResultType();
|
|
344
|
-
return "callback " + resultType->
|
|
361
|
+
return "callback " + resultType->toString(oneLine) + "(" +
|
|
362
|
+
argType->toString(oneLine) + ")";
|
|
345
363
|
}
|
|
346
364
|
|
|
347
365
|
private:
|
|
@@ -365,37 +383,51 @@ public:
|
|
|
365
383
|
virtual std::string getServiceSymbol() const override;
|
|
366
384
|
virtual BundlePort *getPort(AppIDPath id,
|
|
367
385
|
const BundleType *type) const override;
|
|
386
|
+
virtual Service *getChildService(Service::Type service, AppIDPath id = {},
|
|
387
|
+
std::string implName = {},
|
|
388
|
+
ServiceImplDetails details = {},
|
|
389
|
+
HWClientDetails clients = {}) override;
|
|
390
|
+
MMIO::MMIORegion *getMMIORegion() const;
|
|
368
391
|
|
|
369
392
|
/// A telemetry port which gets attached to a service port.
|
|
370
|
-
class
|
|
393
|
+
class Metric : public ServicePort {
|
|
371
394
|
friend class TelemetryService;
|
|
372
|
-
|
|
395
|
+
Metric(AppID id, const BundleType *type, PortMap channels,
|
|
396
|
+
const TelemetryService *telemetryService,
|
|
397
|
+
std::optional<uint64_t> offset);
|
|
373
398
|
|
|
374
399
|
public:
|
|
375
|
-
static Telemetry *get(AppID id, BundleType *type, WriteChannelPort &get,
|
|
376
|
-
ReadChannelPort &data);
|
|
377
|
-
|
|
378
400
|
void connect();
|
|
379
401
|
std::future<MessageData> read();
|
|
402
|
+
uint64_t readInt();
|
|
380
403
|
|
|
381
|
-
virtual std::optional<std::string>
|
|
404
|
+
virtual std::optional<std::string>
|
|
405
|
+
toString(bool oneLine = false) const override {
|
|
382
406
|
const esi::Type *dataType =
|
|
383
407
|
dynamic_cast<const ChannelType *>(type->findChannel("data").first)
|
|
384
408
|
->getInner();
|
|
385
|
-
return "telemetry " + dataType->
|
|
409
|
+
return "telemetry " + dataType->toString(oneLine);
|
|
386
410
|
}
|
|
387
411
|
|
|
388
412
|
private:
|
|
389
|
-
|
|
390
|
-
|
|
413
|
+
const TelemetryService *telemetryService;
|
|
414
|
+
MMIO::MMIORegion *mmio;
|
|
415
|
+
std::optional<uint64_t> offset;
|
|
391
416
|
};
|
|
392
417
|
|
|
393
|
-
|
|
394
|
-
|
|
418
|
+
std::map<AppIDPath, Metric *> getTelemetryPorts() {
|
|
419
|
+
std::map<AppIDPath, Metric *> ports;
|
|
420
|
+
getTelemetryPorts(ports);
|
|
421
|
+
return ports;
|
|
395
422
|
}
|
|
423
|
+
void getTelemetryPorts(std::map<AppIDPath, Metric *> &ports);
|
|
396
424
|
|
|
397
425
|
private:
|
|
398
|
-
|
|
426
|
+
AppIDPath id;
|
|
427
|
+
mutable MMIO::MMIORegion *mmio;
|
|
428
|
+
std::map<AppIDPath, uint64_t> portAddressAssignments;
|
|
429
|
+
mutable std::map<AppIDPath, Metric *> telemetryPorts;
|
|
430
|
+
std::list<TelemetryService *> children;
|
|
399
431
|
};
|
|
400
432
|
|
|
401
433
|
/// Registry of services which can be instantiated directly by the Accelerator
|