esiaccel 0.0.17.dev735__cp312-cp312-win_amd64.whl → 0.1.0__cp312-cp312-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/bin/esi-cosim.py +405 -0
- esiaccel/bin/esiquery.exe +0 -0
- esiaccel/cmake/esiaccelConfig.cmake +1 -1
- esiaccel/cosim/Cosim_DpiPkg.sv +85 -0
- esiaccel/cosim/Cosim_Endpoint.sv +189 -0
- esiaccel/cosim/Cosim_Manifest.sv +32 -0
- esiaccel/cosim/driver.cpp +131 -0
- esiaccel/cosim/driver.sv +60 -0
- esiaccel/esiCppAccel.cp312-win_amd64.pyd +0 -0
- esiaccel/include/esi/CLI.h +9 -3
- esiaccel/include/esi/Engines.h +124 -0
- esiaccel/include/esi/Logging.h +43 -7
- esiaccel/include/esi/Services.h +44 -0
- esiaccel/include/esi/backends/Cosim.h +85 -0
- esiaccel/include/esi/backends/RpcServer.h +55 -0
- esiaccel/lib/EsiCosimDpiServer.dll +0 -0
- esiaccel/lib/EsiCosimDpiServer.lib +0 -0
- esiaccel/lib/MtiPli.dll +0 -0
- esiaccel/lib/MtiPli.lib +0 -0
- esiaccel/types.py +55 -0
- esiaccel/zlib1.dll +0 -0
- {esiaccel-0.0.17.dev735.dist-info → esiaccel-0.1.0.dist-info}/METADATA +3 -3
- esiaccel-0.1.0.dist-info/RECORD +44 -0
- {esiaccel-0.0.17.dev735.dist-info → esiaccel-0.1.0.dist-info}/WHEEL +1 -1
- esiaccel-0.0.17.dev735.dist-info/RECORD +0 -29
- {esiaccel-0.0.17.dev735.dist-info → esiaccel-0.1.0.dist-info}/entry_points.txt +0 -0
- {esiaccel-0.0.17.dev735.dist-info → esiaccel-0.1.0.dist-info/licenses}/LICENSE +0 -0
- {esiaccel-0.0.17.dev735.dist-info → esiaccel-0.1.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
//===- Cosim_Manifest.sv - ESI manifest module -------------*- verilog -*-===//
|
|
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
|
+
// A cosimulated design needs to instantiate this ONCE with the zlib-compressed
|
|
10
|
+
// JSON manifest as the parameter.
|
|
11
|
+
//
|
|
12
|
+
//===----------------------------------------------------------------------===//
|
|
13
|
+
|
|
14
|
+
import Cosim_DpiPkg::*;
|
|
15
|
+
|
|
16
|
+
module Cosim_Manifest
|
|
17
|
+
#(
|
|
18
|
+
parameter int COMPRESSED_MANIFEST_SIZE = 0,
|
|
19
|
+
parameter int unsigned ESI_VERSION = 0
|
|
20
|
+
)(
|
|
21
|
+
input logic [COMPRESSED_MANIFEST_SIZE-1:0][7:0] compressed_manifest
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
byte unsigned compressed_manifest_bytes[COMPRESSED_MANIFEST_SIZE-1:0];
|
|
25
|
+
always_comb
|
|
26
|
+
for (int i=0; i<COMPRESSED_MANIFEST_SIZE; i++)
|
|
27
|
+
compressed_manifest_bytes[i] = compressed_manifest[i];
|
|
28
|
+
|
|
29
|
+
always@(compressed_manifest)
|
|
30
|
+
cosim_set_manifest(ESI_VERSION, compressed_manifest_bytes);
|
|
31
|
+
|
|
32
|
+
endmodule
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
//===- driver.cpp - ESI Verilator software driver -------------------------===//
|
|
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
|
+
// A fairly standard, boilerplate Verilator C++ simulation driver. Assumes the
|
|
10
|
+
// top level exposes just two signals: 'clk' and 'rst'.
|
|
11
|
+
//
|
|
12
|
+
//===----------------------------------------------------------------------===//
|
|
13
|
+
|
|
14
|
+
#ifndef TOP_MODULE
|
|
15
|
+
#define TOP_MODULE ESI_Cosim_Top
|
|
16
|
+
#endif // TOP_MODULE
|
|
17
|
+
|
|
18
|
+
// Macro black magic to get the header file name and class name from the
|
|
19
|
+
// TOP_MODULE macro. Need to disable formatting for this section, as
|
|
20
|
+
// clang-format messes it up by inserting spaces.
|
|
21
|
+
|
|
22
|
+
// clang-format off
|
|
23
|
+
#define STRINGIFY_MACRO(x) STR(x)
|
|
24
|
+
#define STR(x) #x
|
|
25
|
+
#define EXPAND(x)x
|
|
26
|
+
#define CONCAT3(n1, n2, n3) STRINGIFY_MACRO(EXPAND(n1)EXPAND(n2)EXPAND(n3))
|
|
27
|
+
#define TOKENPASTE(x, y) x ## y
|
|
28
|
+
#define CLASSNAME(x, y) TOKENPASTE(x, y)
|
|
29
|
+
|
|
30
|
+
#include CONCAT3(V,TOP_MODULE,.h)
|
|
31
|
+
// clang-format on
|
|
32
|
+
|
|
33
|
+
#include "verilated_vcd_c.h"
|
|
34
|
+
|
|
35
|
+
#include "signal.h"
|
|
36
|
+
#include <iostream>
|
|
37
|
+
#include <thread>
|
|
38
|
+
|
|
39
|
+
vluint64_t timeStamp;
|
|
40
|
+
|
|
41
|
+
// Stop the simulation gracefully on ctrl-c.
|
|
42
|
+
volatile bool stopSimulation = false;
|
|
43
|
+
void handle_sigint(int) { stopSimulation = true; }
|
|
44
|
+
|
|
45
|
+
// Called by $time in Verilog.
|
|
46
|
+
double sc_time_stamp() { return timeStamp; }
|
|
47
|
+
|
|
48
|
+
int main(int argc, char **argv) {
|
|
49
|
+
// Register graceful exit handler.
|
|
50
|
+
signal(SIGINT, handle_sigint);
|
|
51
|
+
|
|
52
|
+
Verilated::commandArgs(argc, argv);
|
|
53
|
+
|
|
54
|
+
// Construct the simulated module's C++ model.
|
|
55
|
+
auto &dut = *new CLASSNAME(V, TOP_MODULE)();
|
|
56
|
+
char *waveformFile = getenv("SAVE_WAVE");
|
|
57
|
+
|
|
58
|
+
char *periodStr = getenv("DEBUG_PERIOD");
|
|
59
|
+
unsigned debugPeriod = 0;
|
|
60
|
+
if (periodStr) {
|
|
61
|
+
debugPeriod = std::stoi(periodStr);
|
|
62
|
+
std::cout << "[driver] Setting debug period to " << debugPeriod
|
|
63
|
+
<< std::endl;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
#ifdef TRACE
|
|
67
|
+
VerilatedVcdC *tfp = nullptr;
|
|
68
|
+
#endif
|
|
69
|
+
|
|
70
|
+
if (waveformFile) {
|
|
71
|
+
#ifdef TRACE
|
|
72
|
+
tfp = new VerilatedVcdC();
|
|
73
|
+
Verilated::traceEverOn(true);
|
|
74
|
+
dut.trace(tfp, 99); // Trace 99 levels of hierarchy
|
|
75
|
+
tfp->open(waveformFile);
|
|
76
|
+
std::cout << "[driver] Writing trace to " << waveformFile << std::endl;
|
|
77
|
+
#else
|
|
78
|
+
std::cout
|
|
79
|
+
<< "[driver] Warning: waveform file specified, but not a debug build"
|
|
80
|
+
<< std::endl;
|
|
81
|
+
#endif
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
std::cout << "[driver] Starting simulation" << std::endl;
|
|
85
|
+
|
|
86
|
+
// TODO: Add max speed (cycles per second) option for small, interactive
|
|
87
|
+
// simulations to reduce waveform for debugging. Should this be a command line
|
|
88
|
+
// option or configurable over the cosim interface?
|
|
89
|
+
|
|
90
|
+
// Reset.
|
|
91
|
+
dut.rst = 1;
|
|
92
|
+
dut.clk = 0;
|
|
93
|
+
|
|
94
|
+
// TODO: Support ESI reset handshake in the future.
|
|
95
|
+
// Run for a few cycles with reset held.
|
|
96
|
+
for (timeStamp = 0; timeStamp < 8 && !Verilated::gotFinish(); timeStamp++) {
|
|
97
|
+
dut.eval();
|
|
98
|
+
dut.clk = !dut.clk;
|
|
99
|
+
#ifdef TRACE
|
|
100
|
+
if (tfp)
|
|
101
|
+
tfp->dump(timeStamp);
|
|
102
|
+
#endif
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Take simulation out of reset.
|
|
106
|
+
dut.rst = 0;
|
|
107
|
+
|
|
108
|
+
// Run for the specified number of cycles out of reset.
|
|
109
|
+
for (; !Verilated::gotFinish() && !stopSimulation; timeStamp++) {
|
|
110
|
+
dut.eval();
|
|
111
|
+
dut.clk = !dut.clk;
|
|
112
|
+
|
|
113
|
+
#ifdef TRACE
|
|
114
|
+
if (tfp)
|
|
115
|
+
tfp->dump(timeStamp);
|
|
116
|
+
#endif
|
|
117
|
+
if (debugPeriod)
|
|
118
|
+
std::this_thread::sleep_for(std::chrono::milliseconds(debugPeriod));
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Tell the simulator that we're going to exit. This flushes the output(s) and
|
|
122
|
+
// frees whatever memory may have been allocated.
|
|
123
|
+
dut.final();
|
|
124
|
+
#ifdef TRACE
|
|
125
|
+
if (tfp)
|
|
126
|
+
tfp->close();
|
|
127
|
+
#endif
|
|
128
|
+
|
|
129
|
+
std::cout << "[driver] Ending simulation at tick #" << timeStamp << std::endl;
|
|
130
|
+
return 0;
|
|
131
|
+
}
|
esiaccel/cosim/driver.sv
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
//===- driver.sv - ESI cosim testbench driver -----------------------------===//
|
|
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
|
+
// Contains the top module driver for an ESI cosimulation. It simply provides a
|
|
10
|
+
// clock and reset signal. In the future, the reset signal will become a reset
|
|
11
|
+
// handshake.
|
|
12
|
+
//
|
|
13
|
+
//===----------------------------------------------------------------------===//
|
|
14
|
+
|
|
15
|
+
`timescale 1ns / 100ps
|
|
16
|
+
|
|
17
|
+
`ifndef TOP_MODULE
|
|
18
|
+
`define TOP_MODULE ESI_Cosim_Top
|
|
19
|
+
`endif
|
|
20
|
+
|
|
21
|
+
module driver();
|
|
22
|
+
|
|
23
|
+
logic clk = 0;
|
|
24
|
+
logic rst = 0;
|
|
25
|
+
|
|
26
|
+
`TOP_MODULE top (
|
|
27
|
+
.clk(clk),
|
|
28
|
+
.rst(rst)
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
always begin
|
|
32
|
+
// A clock period is #4.
|
|
33
|
+
clk = ~clk;
|
|
34
|
+
#2;
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
initial begin
|
|
38
|
+
int cycles;
|
|
39
|
+
|
|
40
|
+
$display("[driver] Starting simulation");
|
|
41
|
+
|
|
42
|
+
rst = 1;
|
|
43
|
+
// Hold in reset for 4 cycles.
|
|
44
|
+
@(posedge clk);
|
|
45
|
+
@(posedge clk);
|
|
46
|
+
@(posedge clk);
|
|
47
|
+
@(posedge clk);
|
|
48
|
+
rst = 0;
|
|
49
|
+
|
|
50
|
+
if ($value$plusargs ("cycles=%d", cycles)) begin
|
|
51
|
+
int i;
|
|
52
|
+
for (i = 0; i < cycles; i++) begin
|
|
53
|
+
@(posedge clk);
|
|
54
|
+
end
|
|
55
|
+
$display("[driver] Ending simulation at tick #%0d", $time);
|
|
56
|
+
$finish();
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
endmodule
|
|
Binary file
|
esiaccel/include/esi/CLI.h
CHANGED
|
@@ -35,6 +35,9 @@ public:
|
|
|
35
35
|
"Connection string to use for accelerator communication")
|
|
36
36
|
->required();
|
|
37
37
|
add_flag("--debug", debug, "Enable debug logging");
|
|
38
|
+
#ifdef ESI_RUNTIME_TRACE
|
|
39
|
+
add_flag("--trace", trace, "Enable trace logging");
|
|
40
|
+
#endif
|
|
38
41
|
add_flag("-v,--verbose", verbose, "Enable verbose (info) logging");
|
|
39
42
|
require_subcommand(0, 1);
|
|
40
43
|
}
|
|
@@ -42,7 +45,9 @@ public:
|
|
|
42
45
|
/// Run the parser.
|
|
43
46
|
int esiParse(int argc, const char **argv) {
|
|
44
47
|
CLI11_PARSE(*this, argc, argv);
|
|
45
|
-
if (
|
|
48
|
+
if (trace)
|
|
49
|
+
ctxt = Context::withLogger<ConsoleLogger>(Logger::Level::Trace);
|
|
50
|
+
else if (debug)
|
|
46
51
|
ctxt = Context::withLogger<ConsoleLogger>(Logger::Level::Debug);
|
|
47
52
|
else if (verbose)
|
|
48
53
|
ctxt = Context::withLogger<ConsoleLogger>(Logger::Level::Info);
|
|
@@ -62,8 +67,9 @@ protected:
|
|
|
62
67
|
|
|
63
68
|
std::string backend;
|
|
64
69
|
std::string connStr;
|
|
65
|
-
bool
|
|
66
|
-
bool
|
|
70
|
+
bool trace = false;
|
|
71
|
+
bool debug = false;
|
|
72
|
+
bool verbose = false;
|
|
67
73
|
};
|
|
68
74
|
|
|
69
75
|
} // namespace esi
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
//===- Engines.h - Implement port communication -----------------*- C++ -*-===//
|
|
2
|
+
//
|
|
3
|
+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
4
|
+
// See https://llvm.org/LICENSE.txt for license information.
|
|
5
|
+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
6
|
+
//
|
|
7
|
+
//===----------------------------------------------------------------------===//
|
|
8
|
+
//
|
|
9
|
+
// DO NOT EDIT!
|
|
10
|
+
// This file is distributed as part of an ESI package. The source for this file
|
|
11
|
+
// should always be modified within CIRCT.
|
|
12
|
+
//
|
|
13
|
+
//===----------------------------------------------------------------------===//
|
|
14
|
+
//
|
|
15
|
+
// Engines (as in DMA engine) implement the actual communication between the
|
|
16
|
+
// host and the accelerator. They are low level of the ESI runtime API and are
|
|
17
|
+
// not intended to be used directly by users.
|
|
18
|
+
//
|
|
19
|
+
// They are called "engines" rather than "DMA engines" since communication need
|
|
20
|
+
// not be implemented via DMA.
|
|
21
|
+
//
|
|
22
|
+
//===----------------------------------------------------------------------===//
|
|
23
|
+
|
|
24
|
+
// NOLINTNEXTLINE(llvm-header-guard)
|
|
25
|
+
#ifndef ESI_ENGINGES_H
|
|
26
|
+
#define ESI_ENGINGES_H
|
|
27
|
+
|
|
28
|
+
#include "esi/Common.h"
|
|
29
|
+
#include "esi/Ports.h"
|
|
30
|
+
#include "esi/Services.h"
|
|
31
|
+
#include "esi/Utils.h"
|
|
32
|
+
|
|
33
|
+
#include <cassert>
|
|
34
|
+
#include <future>
|
|
35
|
+
|
|
36
|
+
namespace esi {
|
|
37
|
+
class Accelerator;
|
|
38
|
+
|
|
39
|
+
/// Engines implement the actual channel communication between the host and the
|
|
40
|
+
/// accelerator. Engines can support multiple channels. They are low level of
|
|
41
|
+
/// the ESI runtime API and are not intended to be used directly by users.
|
|
42
|
+
class Engine {
|
|
43
|
+
public:
|
|
44
|
+
Engine(AcceleratorConnection &conn) : connected(false), conn(conn) {}
|
|
45
|
+
virtual ~Engine() = default;
|
|
46
|
+
/// Start the engine, if applicable.
|
|
47
|
+
virtual void connect() { connected = true; };
|
|
48
|
+
/// Stop the engine, if applicable.
|
|
49
|
+
virtual void disconnect() { connected = false; };
|
|
50
|
+
/// Get a port for a channel, from the cache if it exists or create it. An
|
|
51
|
+
/// engine may override this method if different behavior is desired.
|
|
52
|
+
virtual ChannelPort &requestPort(AppIDPath idPath,
|
|
53
|
+
const std::string &channelName,
|
|
54
|
+
BundleType::Direction dir, const Type *type);
|
|
55
|
+
|
|
56
|
+
protected:
|
|
57
|
+
/// Each engine needs to know how to create a ports. This method is called if
|
|
58
|
+
/// a port doesn't exist in the engine cache.
|
|
59
|
+
virtual std::unique_ptr<ChannelPort>
|
|
60
|
+
createPort(AppIDPath idPath, const std::string &channelName,
|
|
61
|
+
BundleType::Direction dir, const Type *type) = 0;
|
|
62
|
+
|
|
63
|
+
bool connected;
|
|
64
|
+
AcceleratorConnection &conn;
|
|
65
|
+
|
|
66
|
+
private:
|
|
67
|
+
std::map<std::pair<AppIDPath, std::string>, std::unique_ptr<ChannelPort>>
|
|
68
|
+
ownedPorts;
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
/// Since engines can support multiple channels BUT not necessarily all of the
|
|
72
|
+
/// channels in a bundle, a mapping from bundle channels to engines is needed.
|
|
73
|
+
class BundleEngineMap {
|
|
74
|
+
friend class AcceleratorConnection;
|
|
75
|
+
|
|
76
|
+
public:
|
|
77
|
+
/// Request ports for all the channels in a bundle. If the engine doesn't
|
|
78
|
+
/// exist for a particular channel, skip said channel.
|
|
79
|
+
PortMap requestPorts(const AppIDPath &idPath,
|
|
80
|
+
const BundleType *bundleType) const;
|
|
81
|
+
|
|
82
|
+
private:
|
|
83
|
+
/// Set a particlar engine for a particular channel. Should only be called by
|
|
84
|
+
/// AcceleratorConnection while registering engines.
|
|
85
|
+
void setEngine(const std::string &channelName, Engine *engine);
|
|
86
|
+
std::map<std::string, Engine *> bundleEngineMap;
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
namespace registry {
|
|
90
|
+
|
|
91
|
+
/// Create an engine by name. This is the primary way to create engines for
|
|
92
|
+
/// "normal" backends.
|
|
93
|
+
std::unique_ptr<Engine> createEngine(AcceleratorConnection &conn,
|
|
94
|
+
const std::string &dmaEngineName,
|
|
95
|
+
AppIDPath idPath,
|
|
96
|
+
const ServiceImplDetails &details,
|
|
97
|
+
const HWClientDetails &clients);
|
|
98
|
+
|
|
99
|
+
namespace internal {
|
|
100
|
+
|
|
101
|
+
/// Engines can register themselves for pluggable functionality.
|
|
102
|
+
using EngineCreate = std::function<std::unique_ptr<Engine>(
|
|
103
|
+
AcceleratorConnection &conn, AppIDPath idPath,
|
|
104
|
+
const ServiceImplDetails &details, const HWClientDetails &clients)>;
|
|
105
|
+
void registerEngine(const std::string &name, EngineCreate create);
|
|
106
|
+
|
|
107
|
+
/// Helper struct to register engines.
|
|
108
|
+
template <typename TEngine>
|
|
109
|
+
struct RegisterEngine {
|
|
110
|
+
RegisterEngine(const char *name) { registerEngine(name, &TEngine::create); }
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
#define CONCAT_(prefix, suffix) prefix##suffix
|
|
114
|
+
#define CONCAT(prefix, suffix) CONCAT_(prefix, suffix)
|
|
115
|
+
#define REGISTER_ENGINE(Name, TEngine) \
|
|
116
|
+
static ::esi::registry::internal::RegisterEngine<TEngine> CONCAT( \
|
|
117
|
+
__register_engine__, __LINE__)(Name)
|
|
118
|
+
|
|
119
|
+
} // namespace internal
|
|
120
|
+
} // namespace registry
|
|
121
|
+
|
|
122
|
+
} // namespace esi
|
|
123
|
+
|
|
124
|
+
#endif // ESI_PORTS_H
|
esiaccel/include/esi/Logging.h
CHANGED
|
@@ -35,15 +35,19 @@ namespace esi {
|
|
|
35
35
|
class Logger {
|
|
36
36
|
public:
|
|
37
37
|
enum class Level {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
38
|
+
Trace, // Trace is even more detailed than debug and requires a compiler
|
|
39
|
+
// flag to be enabled when the runtime is built. Allows clients to do
|
|
40
|
+
// things like log every single message or interaction.
|
|
41
|
+
Debug, // Information useful when trying to debug an application.
|
|
42
|
+
Info, // General information, like connecting to an accelerator.
|
|
41
43
|
Warning, // May indicate a problem.
|
|
42
44
|
Error, // Many errors will be followed by exceptions which may get caught.
|
|
43
45
|
};
|
|
44
|
-
Logger(bool debugEnabled
|
|
46
|
+
Logger(bool debugEnabled, bool traceEnabled)
|
|
47
|
+
: debugEnabled(debugEnabled), traceEnabled(traceEnabled) {}
|
|
45
48
|
virtual ~Logger() = default;
|
|
46
49
|
bool getDebugEnabled() { return debugEnabled; }
|
|
50
|
+
bool getTraceEnabled() { return traceEnabled; }
|
|
47
51
|
|
|
48
52
|
/// Report a log message.
|
|
49
53
|
/// Arguments:
|
|
@@ -95,6 +99,35 @@ public:
|
|
|
95
99
|
debugImpl(debugFunc);
|
|
96
100
|
}
|
|
97
101
|
|
|
102
|
+
/// Log a trace message. If tracing is not enabled, this is a no-op. Since it
|
|
103
|
+
/// is inlined, the compiler will hopefully optimize it away creating a
|
|
104
|
+
/// zero-overhead call. This means that clients are free to go crazy with
|
|
105
|
+
/// trace messages.
|
|
106
|
+
inline void trace(const std::string &subsystem, const std::string &msg,
|
|
107
|
+
const std::map<std::string, std::any> *details = nullptr) {
|
|
108
|
+
#ifdef ESI_RUNTIME_TRACE
|
|
109
|
+
if (traceEnabled)
|
|
110
|
+
log(Level::Trace, subsystem, msg, details);
|
|
111
|
+
#endif
|
|
112
|
+
}
|
|
113
|
+
/// Log a trace message using a callback. Same as above, users can go hog-wild
|
|
114
|
+
/// calling this.
|
|
115
|
+
inline void
|
|
116
|
+
trace(std::function<
|
|
117
|
+
void(std::string &subsystem, std::string &msg,
|
|
118
|
+
std::unique_ptr<std::map<std::string, std::any>> &details)>
|
|
119
|
+
traceFunc) {
|
|
120
|
+
#ifdef ESI_RUNTIME_TRACE
|
|
121
|
+
if (!traceEnabled)
|
|
122
|
+
return;
|
|
123
|
+
std::string subsystem;
|
|
124
|
+
std::string msg;
|
|
125
|
+
std::unique_ptr<std::map<std::string, std::any>> details = nullptr;
|
|
126
|
+
traceFunc(subsystem, msg, details);
|
|
127
|
+
log(Level::Trace, subsystem, msg, details.get());
|
|
128
|
+
#endif
|
|
129
|
+
}
|
|
130
|
+
|
|
98
131
|
protected:
|
|
99
132
|
/// Overrideable version of debug. Only gets called if debug is enabled.
|
|
100
133
|
virtual void debugImpl(const std::string &subsystem, const std::string &msg,
|
|
@@ -118,6 +151,9 @@ protected:
|
|
|
118
151
|
|
|
119
152
|
/// Enable or disable debug messages.
|
|
120
153
|
bool debugEnabled = false;
|
|
154
|
+
|
|
155
|
+
/// Enable or disable trace messages.
|
|
156
|
+
bool traceEnabled;
|
|
121
157
|
};
|
|
122
158
|
|
|
123
159
|
/// A thread-safe logger which calls functions implemented by subclasses. Only
|
|
@@ -147,8 +183,8 @@ public:
|
|
|
147
183
|
/// Create a stream logger that logs to the given output stream and error
|
|
148
184
|
/// output stream.
|
|
149
185
|
StreamLogger(Level minLevel, std::ostream &out, std::ostream &error)
|
|
150
|
-
: TSLogger(minLevel
|
|
151
|
-
errorStream(error) {}
|
|
186
|
+
: TSLogger(minLevel <= Level::Debug, minLevel <= Level::Trace),
|
|
187
|
+
minLevel(minLevel), outStream(out), errorStream(error) {}
|
|
152
188
|
/// Create a stream logger that logs to stdout, stderr.
|
|
153
189
|
StreamLogger(Level minLevel);
|
|
154
190
|
void logImpl(Level level, const std::string &subsystem,
|
|
@@ -182,7 +218,7 @@ private:
|
|
|
182
218
|
/// A logger that does nothing.
|
|
183
219
|
class NullLogger : public Logger {
|
|
184
220
|
public:
|
|
185
|
-
NullLogger() : Logger(false) {}
|
|
221
|
+
NullLogger() : Logger(false, false) {}
|
|
186
222
|
void log(Level, const std::string &, const std::string &,
|
|
187
223
|
const std::map<std::string, std::any> *) override {}
|
|
188
224
|
};
|
esiaccel/include/esi/Services.h
CHANGED
|
@@ -337,6 +337,50 @@ private:
|
|
|
337
337
|
std::string symbol;
|
|
338
338
|
};
|
|
339
339
|
|
|
340
|
+
/// Service for retrieving telemetry data from the accelerator.
|
|
341
|
+
class TelemetryService : public Service {
|
|
342
|
+
public:
|
|
343
|
+
static constexpr std::string_view StdName = "esi.service.std.telemetry";
|
|
344
|
+
|
|
345
|
+
TelemetryService(AppIDPath id, AcceleratorConnection &,
|
|
346
|
+
ServiceImplDetails details, HWClientDetails clients);
|
|
347
|
+
|
|
348
|
+
virtual std::string getServiceSymbol() const override;
|
|
349
|
+
virtual BundlePort *getPort(AppIDPath id,
|
|
350
|
+
const BundleType *type) const override;
|
|
351
|
+
|
|
352
|
+
/// A telemetry port which gets attached to a service port.
|
|
353
|
+
class Telemetry : public ServicePort {
|
|
354
|
+
friend class TelemetryService;
|
|
355
|
+
Telemetry(AppID id, const BundleType *type, PortMap channels);
|
|
356
|
+
|
|
357
|
+
public:
|
|
358
|
+
static Telemetry *get(AppID id, BundleType *type, WriteChannelPort &get,
|
|
359
|
+
ReadChannelPort &data);
|
|
360
|
+
|
|
361
|
+
void connect();
|
|
362
|
+
std::future<MessageData> read();
|
|
363
|
+
|
|
364
|
+
virtual std::optional<std::string> toString() const override {
|
|
365
|
+
const esi::Type *dataType =
|
|
366
|
+
dynamic_cast<const ChannelType *>(type->findChannel("data").first)
|
|
367
|
+
->getInner();
|
|
368
|
+
return "telemetry " + dataType->getID();
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
private:
|
|
372
|
+
WriteChannelPort *get_req;
|
|
373
|
+
ReadChannelPort *data;
|
|
374
|
+
};
|
|
375
|
+
|
|
376
|
+
const std::map<AppIDPath, Telemetry *> &getTelemetryPorts() {
|
|
377
|
+
return telemetryPorts;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
private:
|
|
381
|
+
mutable std::map<AppIDPath, Telemetry *> telemetryPorts;
|
|
382
|
+
};
|
|
383
|
+
|
|
340
384
|
/// Registry of services which can be instantiated directly by the Accelerator
|
|
341
385
|
/// class if the backend doesn't do anything special with a service.
|
|
342
386
|
class ServiceRegistry {
|
|
@@ -0,0 +1,85 @@
|
|
|
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 Cap'nProto RPC, but that could
|
|
11
|
+
// change. Requires Cap'nProto 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 cosim {
|
|
30
|
+
class ChannelDesc;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
namespace backends {
|
|
34
|
+
namespace cosim {
|
|
35
|
+
class CosimEngine;
|
|
36
|
+
|
|
37
|
+
/// Connect to an ESI simulation.
|
|
38
|
+
class CosimAccelerator : public esi::AcceleratorConnection {
|
|
39
|
+
friend class CosimEngine;
|
|
40
|
+
|
|
41
|
+
public:
|
|
42
|
+
CosimAccelerator(Context &, std::string hostname, uint16_t port);
|
|
43
|
+
~CosimAccelerator();
|
|
44
|
+
|
|
45
|
+
static std::unique_ptr<AcceleratorConnection>
|
|
46
|
+
connect(Context &, std::string connectionString);
|
|
47
|
+
|
|
48
|
+
// Different ways to retrieve the manifest in Cosimulation.
|
|
49
|
+
enum ManifestMethod {
|
|
50
|
+
Cosim, // Use the backdoor cosim interface. Default.
|
|
51
|
+
MMIO, // Use MMIO emulation.
|
|
52
|
+
};
|
|
53
|
+
// Set the way this connection will retrieve the manifest.
|
|
54
|
+
void setManifestMethod(ManifestMethod method);
|
|
55
|
+
|
|
56
|
+
// C++ doesn't have a mechanism to forward declare a nested class and we don't
|
|
57
|
+
// want to include the generated header here. So we have to wrap it in a
|
|
58
|
+
// forward-declared struct we write ourselves.
|
|
59
|
+
struct StubContainer;
|
|
60
|
+
|
|
61
|
+
void createEngine(const std::string &engineTypeName, AppIDPath idPath,
|
|
62
|
+
const ServiceImplDetails &details,
|
|
63
|
+
const HWClientDetails &clients) override;
|
|
64
|
+
|
|
65
|
+
protected:
|
|
66
|
+
virtual Service *createService(Service::Type service, AppIDPath path,
|
|
67
|
+
std::string implName,
|
|
68
|
+
const ServiceImplDetails &details,
|
|
69
|
+
const HWClientDetails &clients) override;
|
|
70
|
+
|
|
71
|
+
private:
|
|
72
|
+
StubContainer *rpcClient;
|
|
73
|
+
|
|
74
|
+
// We own all channels connected to rpcClient since their lifetime is tied to
|
|
75
|
+
// rpcClient.
|
|
76
|
+
std::set<std::unique_ptr<ChannelPort>> channels;
|
|
77
|
+
|
|
78
|
+
ManifestMethod manifestMethod = Cosim;
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
} // namespace cosim
|
|
82
|
+
} // namespace backends
|
|
83
|
+
} // namespace esi
|
|
84
|
+
|
|
85
|
+
#endif // ESI_BACKENDS_COSIM_H
|
|
@@ -0,0 +1,55 @@
|
|
|
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/Ports.h"
|
|
20
|
+
|
|
21
|
+
namespace esi {
|
|
22
|
+
namespace cosim {
|
|
23
|
+
|
|
24
|
+
/// TODO: make this a proper backend (as much as possible).
|
|
25
|
+
class RpcServer {
|
|
26
|
+
public:
|
|
27
|
+
~RpcServer();
|
|
28
|
+
|
|
29
|
+
/// Set the manifest and version. There is a race condition here in that the
|
|
30
|
+
/// RPC server can be started and a connection from the client could happen
|
|
31
|
+
/// before the manifest is set. TODO: rework the DPI API to require that the
|
|
32
|
+
/// manifest gets set first.
|
|
33
|
+
void setManifest(int esiVersion,
|
|
34
|
+
const std::vector<uint8_t> &compressedManifest);
|
|
35
|
+
|
|
36
|
+
/// Register a read or write port which communicates over RPC.
|
|
37
|
+
ReadChannelPort ®isterReadPort(const std::string &name,
|
|
38
|
+
const std::string &type);
|
|
39
|
+
WriteChannelPort ®isterWritePort(const std::string &name,
|
|
40
|
+
const std::string &type);
|
|
41
|
+
|
|
42
|
+
void stop();
|
|
43
|
+
void run(int port);
|
|
44
|
+
|
|
45
|
+
/// Hide the implementation details from this header file.
|
|
46
|
+
class Impl;
|
|
47
|
+
|
|
48
|
+
private:
|
|
49
|
+
Impl *impl = nullptr;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
} // namespace cosim
|
|
53
|
+
} // namespace esi
|
|
54
|
+
|
|
55
|
+
#endif // ESI_COSIM_RPCSERVER_H
|
|
Binary file
|
|
Binary file
|
esiaccel/lib/MtiPli.dll
ADDED
|
Binary file
|
esiaccel/lib/MtiPli.lib
ADDED
|
Binary file
|