1#include "loopback/LoopbackIP.h"
17 {
AppID(
"loopback_inst", 0),
AppID(
"loopback_tohw")}, lastLookup);
19 throw std::runtime_error(
"No loopback_tohw port found");
21 {
AppID(
"loopback_inst", 0),
AppID(
"loopback_fromhw")}, lastLookup);
23 throw std::runtime_error(
"No loopback_fromhw port found");
30 uint8_t sendVal = 0x5a;
35 if (recvMsg.
getSize() !=
sizeof(uint8_t))
36 throw std::runtime_error(
"Unexpected loopback recv size");
37 uint8_t got = *recvMsg.
as<uint8_t>();
39 throw std::runtime_error(
"Loopback byte mismatch");
41 std::cout <<
"loopback i8 ok: 0x" << std::hex << (int)got << std::dec <<
"\n";
48 throw std::runtime_error(
"No structFunc port found");
52 throw std::runtime_error(
"structFunc not a FuncService::Function");
55 esi_system::ArgStruct arg{};
57 arg.b =
static_cast<int8_t
>(-7);
60 const auto *res = resMsg.
as<esi_system::ResultStruct>();
62 int8_t expectedX =
static_cast<int8_t
>(arg.b + 1);
63 if (res->x != expectedX || res->y != arg.b)
64 throw std::runtime_error(
"Struct func result mismatch");
66 std::cout <<
"struct func ok: b=" << (int)arg.b <<
" x=" << (
int)res->x
67 <<
" y=" << (int)res->y <<
"\n";
74 throw std::runtime_error(
"No oddStructFunc port found");
78 throw std::runtime_error(
"oddStructFunc not a FuncService::Function");
81 esi_system::OddStruct arg{};
83 arg.b =
static_cast<int8_t
>(-17);
85 arg.inner.q =
static_cast<int8_t
>(-7);
90 const auto *res = resMsg.
as<esi_system::OddStruct>();
92 uint16_t expectA =
static_cast<uint16_t
>(arg.a + 1);
93 int8_t expectB =
static_cast<int8_t
>(arg.b - 3);
94 uint8_t expectP =
static_cast<uint8_t
>(arg.inner.p + 5);
95 int8_t expectQ =
static_cast<int8_t
>(arg.inner.q + 2);
96 uint8_t expectR0 =
static_cast<uint8_t
>(arg.inner.r[0] + 1);
97 uint8_t expectR1 =
static_cast<uint8_t
>(arg.inner.r[1] + 2);
98 if (res->a != expectA || res->b != expectB || res->inner.p != expectP ||
99 res->inner.q != expectQ || res->inner.r[0] != expectR0 ||
100 res->inner.r[1] != expectR1)
101 throw std::runtime_error(
"Odd struct func result mismatch");
103 std::cout <<
"odd struct func ok: a=" << res->a <<
" b=" << (int)res->b
104 <<
" p=" << (
int)res->inner.p <<
" q=" << (int)res->inner.q
105 <<
" r0=" << (
int)res->inner.r[0] <<
" r1=" << (int)res->inner.r[1]
113 throw std::runtime_error(
"No arrayFunc port found");
117 throw std::runtime_error(
"arrayFunc not a FuncService::Function");
120 int8_t argArray[1] = {
static_cast<int8_t
>(-3)};
122 func->call(
MessageData(
reinterpret_cast<const uint8_t *
>(argArray),
126 const auto *res = resMsg.
as<esi_system::ResultArray>();
127 int8_t a = (*res)[0];
128 int8_t b = (*res)[1];
129 int8_t expect0 = argArray[0];
130 int8_t expect1 =
static_cast<int8_t
>(argArray[0] + 1);
132 bool ok = (a == expect0 && b == expect1) || (a == expect1 && b == expect0);
134 throw std::runtime_error(
"Array func result mismatch");
143 std::cout <<
"array func ok: " << (int)low <<
" " << (
int)high <<
"\n";
146int main(
int argc,
const char *argv[]) {
148 cli.description(
"Loopback cosim test using generated ESI headers.");
149 if (
int rc = cli.
esiParse(argc, argv))
151 if (!cli.get_help_ptr()->empty())
158 Manifest manifest(ctxt, info.getJsonManifest());
159 Accelerator *accel = manifest.buildAccelerator(*conn);
160 conn->getServiceThread()->addPoll(*accel);
162 std::cout <<
"depth: 0x" << std::hex << esi_system::LoopbackIP::depth
171 }
catch (std::exception &e) {
Abstract class representing a connection to an accelerator.
Top level accelerator class.
Services provide connections to 'bundles' – collections of named, unidirectional communication channe...
T * getAs() const
Cast this Bundle port to a subclass which is actually useful.
ReadChannelPort & getRawRead(const std::string &name) const
WriteChannelPort & getRawWrite(const std::string &name) const
Get access to the raw byte streams of a channel.
Common options and code for ESI runtime tools.
Context & getContext()
Get the context.
AcceleratorConnection * connect()
Connect to the accelerator using the specified backend and connection.
int esiParse(int argc, const char **argv)
Run the parser.
AcceleratorConnections, Accelerators, and Manifests must all share a context.
BundlePort * resolvePort(const AppIDPath &path, AppIDPath &lastLookup) const
Attempt to resolve a path to a port.
virtual void error(const std::string &subsystem, const std::string &msg, const std::map< std::string, std::any > *details=nullptr)
Report an error.
Class to parse a manifest.
A logical chunk of data representing serialized data.
const T * as() const
Cast to a type.
size_t getSize() const
Get the size of the data in bytes.
static MessageData from(T &t)
Cast from a type to its raw bytes.
A ChannelPort which reads data from the accelerator.
virtual void connect(std::function< bool(MessageData)> callback, const ConnectOptions &options={})
virtual void read(MessageData &outData)
Specify a buffer to read into.
A ChannelPort which sends data to the accelerator.
void write(const MessageData &data)
A very basic blocking write API.
virtual void connect(const ConnectOptions &options={}) override
Set up a connection to the accelerator.
A function call which gets attached to a service port.
Information about the Accelerator system.
static void runOddStructFunc(Accelerator *accel)
int main(int argc, const char *argv[])
static void runLoopbackI8(Accelerator *accel)
static void runStructFunc(Accelerator *accel)
static void runArrayFunc(Accelerator *accel)