1#include "loopback/LoopbackIP.h"
2#include "loopback/SerialCoordTranslator.h"
22 {
AppID(
"loopback_inst", 0),
AppID(
"loopback_tohw")}, lastLookup);
24 throw std::runtime_error(
"No loopback_tohw port found");
26 {
AppID(
"loopback_inst", 0),
AppID(
"loopback_fromhw")}, lastLookup);
28 throw std::runtime_error(
"No loopback_fromhw port found");
36 uint8_t sendVal = 0x5a;
39 std::unique_ptr<uint8_t> got = fromHw.
read();
40 if (!got || *got != sendVal)
41 throw std::runtime_error(
"Loopback byte mismatch");
43 std::cout <<
"loopback_i8 ok: 0x" << std::hex << (int)*got << std::dec
52 throw std::runtime_error(
"No structFunc port found");
59 esi_system::ArgStruct arg{};
61 arg.b(
static_cast<int8_t
>(-7));
63 esi_system::ResultStruct res = func.
call(arg).get();
65 int8_t expectedX =
static_cast<int8_t
>(arg.b() + 1);
66 if (res.x() != expectedX || res.y() != arg.b())
67 throw std::runtime_error(
"Struct func result mismatch");
69 std::cout <<
"struct_func ok: b=" << (int)arg.b() <<
" x=" << (int)res.x()
70 <<
" y=" << (int)res.y() <<
"\n";
78 throw std::runtime_error(
"No oddStructFunc port found");
85 esi_system::OddStruct arg{};
87 arg.b(
static_cast<int8_t
>(-17));
88 auto inner = arg.inner();
90 inner.q(
static_cast<int8_t
>(-7));
94 esi_system::OddStruct res = func.
call(arg).get();
96 uint16_t expectA =
static_cast<uint16_t
>(arg.a() + 1);
97 int8_t expectB =
static_cast<int8_t
>(arg.b() - 3);
98 uint8_t expectP =
static_cast<uint8_t
>(arg.inner().p() + 5);
99 int8_t expectQ =
static_cast<int8_t
>(arg.inner().q() + 2);
100 uint8_t expectR0 =
static_cast<uint8_t
>(arg.inner().r()[0] + 1);
101 uint8_t expectR1 =
static_cast<uint8_t
>(arg.inner().r()[1] + 2);
102 if (res.a() != expectA || res.b() != expectB || res.inner().p() != expectP ||
103 res.inner().q() != expectQ || res.inner().r()[0] != expectR0 ||
104 res.inner().r()[1] != expectR1)
105 throw std::runtime_error(
"Odd struct func result mismatch");
107 std::cout <<
"odd_struct_func ok: a=" << res.a() <<
" b=" << (int)res.b()
108 <<
" p=" << (int)res.inner().p() <<
" q=" << (int)res.inner().q()
109 <<
" r0=" << (int)res.inner().r()[0]
110 <<
" r1=" << (int)res.inner().r()[1] <<
"\n";
118 throw std::runtime_error(
"No arrayFunc port found");
122 throw std::runtime_error(
"arrayFunc not a FuncService::Function");
125 int8_t argArray[1] = {
static_cast<int8_t
>(-3)};
127 func->call(
MessageData(
reinterpret_cast<const uint8_t *
>(argArray),
131 const auto *res = resMsg.
as<esi_system::ResultArray>();
132 int8_t a = (*res)[0];
133 int8_t b = (*res)[1];
134 int8_t expect0 = argArray[0];
135 int8_t expect1 =
static_cast<int8_t
>(argArray[0] + 1);
137 bool ok = (a == expect0 && b == expect1) || (a == expect1 && b == expect0);
139 throw std::runtime_error(
"Array func result mismatch");
148 std::cout <<
"array_func ok: " << (int)low <<
" " << (
int)high <<
"\n";
156 throw std::runtime_error(
"No sint4Func port found");
166 int8_t posResult = func.
call(posArg).get();
167 if (posResult != posArg)
168 throw std::runtime_error(
"sint4 loopback positive mismatch: got " +
169 std::to_string(posResult));
173 int8_t negResult = func.
call(negArg).get();
174 if (negResult != negArg)
175 throw std::runtime_error(
"sint4 loopback negative mismatch: got " +
176 std::to_string(negResult));
178 std::cout <<
"sint4_loopback ok: pos=" << (int)posResult
179 <<
" neg=" << (
int)negResult <<
"\n";
188 _struct_x_translation_i32_y_translation_i32_coords__esi_list__hw_struct_x__i32__y__i32___serial_coord_args;
190 _struct_coords__esi_list__hw_struct_x__i32__y__i32___serial_coord_result;
194 size_t numCoords = 100;
195 uint32_t xTrans = 10, yTrans = 20;
198 std::mt19937 rng(0xDEADBEEF);
199 std::uniform_int_distribution<uint32_t> dist(0, 1000000);
200 std::vector<SerialCoordValue> coords;
201 coords.reserve(numCoords);
202 for (uint32_t i = 0; i < numCoords; ++i)
203 coords.emplace_back(dist(rng), dist(rng));
207 throw std::runtime_error(
"Serial coord translate test: no "
208 "'coord_translator_serial' child found");
210 esi_system::SerialCoordTranslator translator(childIt->second);
211 auto connected = translator.connect();
218 connected->translate_coords_serial(xTrans, yTrans, coords).get();
220 if (result.coords_count() != coords.size())
221 throw std::runtime_error(
"Serial coord translate result size mismatch");
224 uint32_t expX = coords[i].x() + xTrans;
225 uint32_t expY = coords[i].y() + yTrans;
226 if (got.x() != expX || got.y() != expY)
227 throw std::runtime_error(
"Serial coord translate result mismatch");
230 std::cout <<
"serial_coord_translate ok\n";
235 std::cout <<
"depth: 0x" << std::hex << esi_system::LoopbackIP::depth
237 std::cout <<
"depth_constant ok\n";
242 "loopback-typed-cpp",
243 "Loopback cosim test using generated ESI headers and typed ports.",
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.
BundlePort * resolvePort(const AppIDPath &path, AppIDPath &lastLookup) const
Attempt to resolve a path to a port.
const std::map< AppID, Instance * > & getChildren() const
Access the module's children by ID.
A concrete flat message backed by a single vector of bytes.
const T * as() const
Cast to a type.
std::future< ResultT > call(const ArgT &arg)
Strongly typed wrapper around a raw read channel.
std::unique_ptr< T > read()
Blocking typed read in polling mode.
void connect(const ChannelPort::ConnectOptions &opts={std::nullopt, false})
Connect in polling mode.
void connect(const ChannelPort::ConnectOptions &opts={std::nullopt, false})
void write(const T &data)
A function call which gets attached to a service port.
static int serialCoordTranslateTest(Accelerator *accel)
static int runSInt4Loopback(Accelerator *accel)
esi_system::_struct_coords__esi_list__hw_struct_x__i32__y__i32___serial_coord_result SerialCoordResult
static int runDepthConstant(Accelerator *)
static int runArrayFunc(Accelerator *accel)
static int runOddStructFunc(Accelerator *accel)
static int runStructFunc(Accelerator *accel)
static int runLoopbackI8(Accelerator *accel)
SerialCoordInput::value_type SerialCoordValue
#define ESI_PROBE_REGISTRY(name, description,...)
Convenience macro: defines main() with a probe registry.