mirror of https://github.com/llvm/circt.git
[ESI][Runtime] MMIO service support (#6034)
Service C++ interface, Python wrapping, and cosim support for MMIO. Also adds the basic service framework.
This commit is contained in:
parent
d345d1ffbd
commit
28bd7f1521
|
@ -1,5 +0,0 @@
|
||||||
# REQUIRES: esi-runtime
|
|
||||||
# RUN: %PYTHON% %s
|
|
||||||
|
|
||||||
# Just test that we can load the python library.
|
|
||||||
import esiaccel
|
|
|
@ -0,0 +1,94 @@
|
||||||
|
// REQUIRES: esi-cosim, esi-runtime
|
||||||
|
// RUN: esi-cosim-runner.py --exec %s.py %s
|
||||||
|
|
||||||
|
// Test the low level cosim MMIO functionality. This test has 1024 64-bit
|
||||||
|
// registers as a memory. It is an error to write to register 0.
|
||||||
|
|
||||||
|
import Cosim_DpiPkg::*;
|
||||||
|
|
||||||
|
module top(
|
||||||
|
input logic clk,
|
||||||
|
input logic rst
|
||||||
|
);
|
||||||
|
|
||||||
|
// MMIO read: address channel.
|
||||||
|
logic arvalid;
|
||||||
|
logic arready;
|
||||||
|
logic [31:0] araddr;
|
||||||
|
|
||||||
|
// MMIO read: data response channel.
|
||||||
|
reg rvalid;
|
||||||
|
logic rready;
|
||||||
|
reg [31:0] rdata;
|
||||||
|
reg [1:0] rresp;
|
||||||
|
|
||||||
|
// MMIO write: address channel.
|
||||||
|
logic awvalid;
|
||||||
|
reg awready;
|
||||||
|
logic [31:0] awaddr;
|
||||||
|
|
||||||
|
// MMIO write: data channel.
|
||||||
|
logic wvalid;
|
||||||
|
reg wready;
|
||||||
|
logic [31:0] wdata;
|
||||||
|
|
||||||
|
// MMIO write: write response channel.
|
||||||
|
reg bvalid;
|
||||||
|
logic bready;
|
||||||
|
reg [1:0] bresp;
|
||||||
|
|
||||||
|
Cosim_MMIO mmio (
|
||||||
|
.clk(clk),
|
||||||
|
.rst(rst),
|
||||||
|
.arvalid(arvalid),
|
||||||
|
.arready(arready),
|
||||||
|
.araddr(araddr),
|
||||||
|
.rvalid(rvalid),
|
||||||
|
.rready(rready),
|
||||||
|
.rdata(rdata),
|
||||||
|
.rresp(rresp),
|
||||||
|
.awvalid(awvalid),
|
||||||
|
.awready(awready),
|
||||||
|
.awaddr(awaddr),
|
||||||
|
.wvalid(wvalid),
|
||||||
|
.wready(wready),
|
||||||
|
.wdata(wdata),
|
||||||
|
.bvalid(bvalid),
|
||||||
|
.bready(bready),
|
||||||
|
.bresp(bresp)
|
||||||
|
);
|
||||||
|
|
||||||
|
reg [31:0] regs [1023:0];
|
||||||
|
|
||||||
|
assign arready = 1;
|
||||||
|
assign rdata = regs[araddr >> 3];
|
||||||
|
assign rresp = araddr == 0 ? 3 : 0;
|
||||||
|
always@(posedge clk) begin
|
||||||
|
if (rst) begin
|
||||||
|
rvalid <= 0;
|
||||||
|
end else begin
|
||||||
|
if (arvalid)
|
||||||
|
rvalid <= 1;
|
||||||
|
if (rready && rvalid)
|
||||||
|
rvalid <= 0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
wire write = awvalid && wvalid && !bvalid;
|
||||||
|
assign awready = write;
|
||||||
|
assign wready = write;
|
||||||
|
always@(posedge clk) begin
|
||||||
|
if (rst) begin
|
||||||
|
bvalid <= 0;
|
||||||
|
end else begin
|
||||||
|
if (bvalid && bready)
|
||||||
|
bvalid <= 0;
|
||||||
|
if (write) begin
|
||||||
|
bvalid <= 1;
|
||||||
|
bresp <= awaddr == 0 ? 3 : 0;
|
||||||
|
regs[awaddr >> 3] <= wdata;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
|
@ -0,0 +1,32 @@
|
||||||
|
import esiaccel
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
conn = f"{sys.argv[1]}:{sys.argv[2]}"
|
||||||
|
|
||||||
|
acc = esiaccel.Accelerator.connect("cosim", conn)
|
||||||
|
mmio = acc.get_service_mmio()
|
||||||
|
|
||||||
|
r = mmio.read(40)
|
||||||
|
print(f"data resp: 0x{r:x}")
|
||||||
|
|
||||||
|
try:
|
||||||
|
mmio.read(0)
|
||||||
|
assert False, "above should have thrown exception"
|
||||||
|
except Exception:
|
||||||
|
print("caught expected exception")
|
||||||
|
|
||||||
|
mmio.write(32, 86)
|
||||||
|
r = mmio.read(32)
|
||||||
|
print(f"data resp: 0x{r:x}")
|
||||||
|
assert r == 86
|
||||||
|
|
||||||
|
try:
|
||||||
|
mmio.write(0, 44)
|
||||||
|
assert False, "above should have thrown exception"
|
||||||
|
except Exception:
|
||||||
|
print("caught expected exception")
|
||||||
|
|
||||||
|
# Crashes with "magic num not found", which is expected since this isn't
|
||||||
|
# supported yet.
|
||||||
|
# acc.sysinfo().esi_version()
|
|
@ -0,0 +1,2 @@
|
||||||
|
# Don't treat the Python files in this directory as tests.
|
||||||
|
config.suffixes.remove('.py')
|
|
@ -84,10 +84,12 @@ set(ESI_RUNTIME_SRCS
|
||||||
|
|
||||||
runtime/CMakeLists.txt
|
runtime/CMakeLists.txt
|
||||||
runtime/cpp/include/esi/Accelerator.h
|
runtime/cpp/include/esi/Accelerator.h
|
||||||
|
runtime/cpp/include/esi/StdServices.h
|
||||||
runtime/cpp/include/esi/backends/Cosim.h
|
runtime/cpp/include/esi/backends/Cosim.h
|
||||||
runtime/cpp/include/esi/backends/capnp.h
|
runtime/cpp/include/esi/backends/capnp.h
|
||||||
runtime/cpp/include/esi/esi.h
|
runtime/cpp/include/esi/esi.h
|
||||||
runtime/cpp/lib/Accelerator.cpp
|
runtime/cpp/lib/Accelerator.cpp
|
||||||
|
runtime/cpp/lib/StdServices.cpp
|
||||||
runtime/cpp/lib/backends/Cosim.cpp
|
runtime/cpp/lib/backends/Cosim.cpp
|
||||||
runtime/cpp/tools/esiquery.cpp
|
runtime/cpp/tools/esiquery.cpp
|
||||||
runtime/python/esi/esiaccel.cpp
|
runtime/python/esi/esiaccel.cpp
|
||||||
|
|
|
@ -33,6 +33,7 @@ include_directories(cpp/include)
|
||||||
|
|
||||||
set(ESIRuntimeSources
|
set(ESIRuntimeSources
|
||||||
cpp/lib/Accelerator.cpp
|
cpp/lib/Accelerator.cpp
|
||||||
|
cpp/lib/StdServices.cpp
|
||||||
)
|
)
|
||||||
set(ESIRuntimeLinkLibraries)
|
set(ESIRuntimeLinkLibraries)
|
||||||
|
|
||||||
|
|
|
@ -23,30 +23,56 @@
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <typeinfo>
|
||||||
|
|
||||||
namespace esi {
|
namespace esi {
|
||||||
class SysInfo;
|
|
||||||
|
constexpr uint32_t MagicNumOffset = 16;
|
||||||
|
constexpr uint32_t MagicNumberLo = 0xE5100E51;
|
||||||
|
constexpr uint32_t MagicNumberHi = 0x207D98E5;
|
||||||
|
constexpr uint32_t VersionNumberOffset = MagicNumOffset + 8;
|
||||||
|
constexpr uint32_t ExpectedVersionNumber = 0;
|
||||||
|
|
||||||
|
namespace services {
|
||||||
|
/// Parent class of all APIs modeled as 'services'. May or may not map to a
|
||||||
|
/// hardware side 'service'.
|
||||||
|
class Service {
|
||||||
|
public:
|
||||||
|
using Type = const std::type_info &;
|
||||||
|
virtual ~Service() = default;
|
||||||
|
};
|
||||||
|
} // namespace services
|
||||||
|
|
||||||
/// An ESI accelerator system.
|
/// An ESI accelerator system.
|
||||||
class Accelerator {
|
class Accelerator {
|
||||||
public:
|
public:
|
||||||
virtual ~Accelerator() = default;
|
virtual ~Accelerator() = default;
|
||||||
|
|
||||||
virtual const SysInfo &sysInfo() = 0;
|
/// Get a typed reference to a particular service type. Caller does *not* take
|
||||||
};
|
/// ownership of the returned pointer -- the Accelerator object owns it.
|
||||||
|
/// Pointer lifetime ends with the Accelerator lifetime.
|
||||||
|
template <typename ServiceClass>
|
||||||
|
ServiceClass *getService() {
|
||||||
|
return dynamic_cast<ServiceClass *>(getServiceImpl(typeid(ServiceClass)));
|
||||||
|
}
|
||||||
|
|
||||||
/// Information about the Accelerator system.
|
protected:
|
||||||
class SysInfo {
|
using Service = services::Service;
|
||||||
public:
|
/// Called by `getServiceImpl` exclusively. It wraps the pointer returned by
|
||||||
virtual ~SysInfo() = default;
|
/// this in a unique_ptr and caches it. Separate this from the
|
||||||
|
/// wrapping/caching since wrapping/caching is an implementation detail.
|
||||||
|
virtual Service *createService(Service::Type service) = 0;
|
||||||
|
/// Calls `createService` and caches the result. Subclasses can override if
|
||||||
|
/// they want to use their own caching mechanism.
|
||||||
|
virtual Service *getServiceImpl(Service::Type service);
|
||||||
|
|
||||||
/// Get the ESI version number to check version compatibility.
|
private:
|
||||||
virtual uint32_t esiVersion() const = 0;
|
/// Cache services via a unique_ptr so they get free'd automatically when
|
||||||
|
/// Accelerator objects get deconstructed.
|
||||||
/// Return the JSON-formatted system manifest.
|
std::map<const std::type_info *, std::unique_ptr<Service>> serviceCache;
|
||||||
virtual std::string rawJsonManifest() const = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace registry {
|
namespace registry {
|
||||||
|
|
|
@ -0,0 +1,67 @@
|
||||||
|
//===- StdServices.h - ESI standard services C++ API ------------*- C++ -*-===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// The APIs in this backend are all optionally implemented. The lower level
|
||||||
|
// ones, however, are strongly recommended. 'Services' here refers to ESI
|
||||||
|
// services. These are standard APIs into the standard ESI services.
|
||||||
|
//
|
||||||
|
// DO NOT EDIT!
|
||||||
|
// This file is distributed as part of an ESI package. The source for this file
|
||||||
|
// should always be modified within CIRCT.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
// NOLINTNEXTLINE(llvm-header-guard)
|
||||||
|
#ifndef ESI_RUNTIME_STDSERVICES_H
|
||||||
|
#define ESI_RUNTIME_STDSERVICES_H
|
||||||
|
|
||||||
|
#include "esi/Accelerator.h"
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
namespace esi {
|
||||||
|
namespace services {
|
||||||
|
|
||||||
|
/// Information about the Accelerator system.
|
||||||
|
class SysInfo : public Service {
|
||||||
|
public:
|
||||||
|
virtual ~SysInfo() = default;
|
||||||
|
|
||||||
|
/// Get the ESI version number to check version compatibility.
|
||||||
|
virtual uint32_t esiVersion() const = 0;
|
||||||
|
|
||||||
|
/// Return the JSON-formatted system manifest.
|
||||||
|
virtual std::string rawJsonManifest() const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MMIO : public Service {
|
||||||
|
public:
|
||||||
|
virtual ~MMIO() = default;
|
||||||
|
virtual uint64_t read(uint32_t addr) const = 0;
|
||||||
|
virtual void write(uint32_t addr, uint64_t data) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Implement the SysInfo API for a standard MMIO protocol.
|
||||||
|
class MMIOSysInfo final : public SysInfo {
|
||||||
|
public:
|
||||||
|
MMIOSysInfo(const MMIO *);
|
||||||
|
|
||||||
|
/// Get the ESI version number to check version compatibility.
|
||||||
|
uint32_t esiVersion() const override;
|
||||||
|
|
||||||
|
/// Return the JSON-formatted system manifest.
|
||||||
|
std::string rawJsonManifest() const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
const MMIO *mmio;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace services
|
||||||
|
} // namespace esi
|
||||||
|
|
||||||
|
#endif // ESI_RUNTIME_STDSERVICES_H
|
|
@ -22,22 +22,24 @@
|
||||||
|
|
||||||
#include "esi/Accelerator.h"
|
#include "esi/Accelerator.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
namespace esi {
|
namespace esi {
|
||||||
namespace backends {
|
namespace backends {
|
||||||
namespace cosim {
|
namespace cosim {
|
||||||
class CosimSysInfo;
|
|
||||||
|
|
||||||
/// Connect to an ESI simulation.
|
/// Connect to an ESI simulation.
|
||||||
class CosimAccelerator : public esi::Accelerator {
|
class CosimAccelerator : public esi::Accelerator {
|
||||||
public:
|
public:
|
||||||
CosimAccelerator(std::string hostname, uint16_t port);
|
CosimAccelerator(std::string hostname, uint16_t port);
|
||||||
~CosimAccelerator();
|
|
||||||
static std::unique_ptr<Accelerator> connect(std::string connectionString);
|
static std::unique_ptr<Accelerator> connect(std::string connectionString);
|
||||||
|
|
||||||
const SysInfo &sysInfo() override;
|
protected:
|
||||||
|
virtual Service *createService(Service::Type service) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CosimSysInfo *info;
|
struct Impl;
|
||||||
|
std::unique_ptr<Impl> impl;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace cosim
|
} // namespace cosim
|
||||||
|
|
|
@ -19,6 +19,12 @@
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
namespace esi {
|
namespace esi {
|
||||||
|
services::Service *Accelerator::getServiceImpl(Service::Type svcType) {
|
||||||
|
std::unique_ptr<Service> &cacheEntry = serviceCache[&svcType];
|
||||||
|
if (cacheEntry == nullptr)
|
||||||
|
cacheEntry = std::unique_ptr<Service>(createService(svcType));
|
||||||
|
return cacheEntry.get();
|
||||||
|
}
|
||||||
namespace registry {
|
namespace registry {
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
//===- StdServices.cpp - implementations of std services ------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// DO NOT EDIT!
|
||||||
|
// This file is distributed as part of an ESI package. The source for this file
|
||||||
|
// should always be modified within CIRCT
|
||||||
|
// (lib/dialect/ESI/runtime/cpp/lib/backends/Cosim.cpp).
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#include "esi/StdServices.h"
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
using namespace esi;
|
||||||
|
using namespace esi::services;
|
||||||
|
|
||||||
|
MMIOSysInfo::MMIOSysInfo(const MMIO *mmio) : mmio(mmio) {}
|
||||||
|
|
||||||
|
uint32_t MMIOSysInfo::esiVersion() const {
|
||||||
|
uint32_t hi = mmio->read(MagicNumOffset);
|
||||||
|
uint32_t lo = mmio->read(MagicNumOffset + 4);
|
||||||
|
if (hi != MagicNumberHi || lo != MagicNumberLo)
|
||||||
|
throw std::runtime_error("ESI magic number not found");
|
||||||
|
return mmio->read(VersionNumberOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string MMIOSysInfo::rawJsonManifest() const { return ""; }
|
|
@ -14,6 +14,7 @@
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#include "esi/backends/Cosim.h"
|
#include "esi/backends/Cosim.h"
|
||||||
|
#include "esi/StdServices.h"
|
||||||
|
|
||||||
#include "CosimDpi.capnp.h"
|
#include "CosimDpi.capnp.h"
|
||||||
#include <capnp/ez-rpc.h>
|
#include <capnp/ez-rpc.h>
|
||||||
|
@ -22,30 +23,9 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
using namespace esi;
|
using namespace esi;
|
||||||
|
using namespace esi::services;
|
||||||
using namespace esi::backends::cosim;
|
using namespace esi::backends::cosim;
|
||||||
|
|
||||||
namespace esi::backends::cosim {
|
|
||||||
|
|
||||||
/// Implement the SysInfo API for cosimulation.
|
|
||||||
class CosimSysInfo final : public esi::SysInfo {
|
|
||||||
private:
|
|
||||||
friend class CosimAccelerator;
|
|
||||||
CosimSysInfo() = default;
|
|
||||||
|
|
||||||
public:
|
|
||||||
/// Get the ESI version number to check version compatibility.
|
|
||||||
uint32_t esiVersion() const override;
|
|
||||||
|
|
||||||
/// Return the JSON-formatted system manifest.
|
|
||||||
std::string rawJsonManifest() const override;
|
|
||||||
};
|
|
||||||
} // namespace esi::backends::cosim
|
|
||||||
|
|
||||||
// For now, just return dummy values since these are not yet supported by the
|
|
||||||
// hardware.
|
|
||||||
uint32_t CosimSysInfo::esiVersion() const { return -1; }
|
|
||||||
std::string CosimSysInfo::rawJsonManifest() const { return ""; }
|
|
||||||
|
|
||||||
/// Parse the connection string and instantiate the accelerator. Support the
|
/// Parse the connection string and instantiate the accelerator. Support the
|
||||||
/// traditional 'host:port' syntax and a path to 'cosim.cfg' which is output by
|
/// traditional 'host:port' syntax and a path to 'cosim.cfg' which is output by
|
||||||
/// the cosimulation when it starts (which is useful when it chooses its own
|
/// the cosimulation when it starts (which is useful when it chooses its own
|
||||||
|
@ -80,21 +60,57 @@ CosimAccelerator::connect(std::string connectionString) {
|
||||||
return std::make_unique<CosimAccelerator>(host, port);
|
return std::make_unique<CosimAccelerator>(host, port);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct esi::backends::cosim::CosimAccelerator::Impl {
|
||||||
|
capnp::EzRpcClient rpcClient;
|
||||||
|
kj::WaitScope &waitScope;
|
||||||
|
CosimDpiServer::Client cosim;
|
||||||
|
EsiLowLevel::Client lowLevel;
|
||||||
|
|
||||||
|
Impl(std::string hostname, uint16_t port)
|
||||||
|
: rpcClient(hostname, port), waitScope(rpcClient.getWaitScope()),
|
||||||
|
cosim(rpcClient.getMain<CosimDpiServer>()), lowLevel(nullptr) {
|
||||||
|
auto llReq = cosim.openLowLevelRequest();
|
||||||
|
auto llPromise = llReq.send();
|
||||||
|
lowLevel = llPromise.wait(waitScope).getLowLevel();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/// Construct and connect to a cosim server.
|
/// Construct and connect to a cosim server.
|
||||||
// TODO: Implement this.
|
// TODO: Implement this.
|
||||||
CosimAccelerator::CosimAccelerator(std::string hostname, uint16_t port)
|
CosimAccelerator::CosimAccelerator(std::string hostname, uint16_t port) {
|
||||||
: info(nullptr) {
|
impl = std::make_unique<Impl>(hostname, port);
|
||||||
std::cout << hostname << ":" << port << std::endl;
|
|
||||||
}
|
|
||||||
CosimAccelerator::~CosimAccelerator() {
|
|
||||||
if (info)
|
|
||||||
delete info;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const SysInfo &CosimAccelerator::sysInfo() {
|
namespace {
|
||||||
if (info == nullptr)
|
class CosimMMIO : public MMIO {
|
||||||
info = new CosimSysInfo();
|
public:
|
||||||
return *info;
|
CosimMMIO(EsiLowLevel::Client &llClient, kj::WaitScope &waitScope)
|
||||||
|
: llClient(llClient), waitScope(waitScope) {}
|
||||||
|
|
||||||
|
uint64_t read(uint32_t addr) const override {
|
||||||
|
auto req = llClient.readMMIORequest();
|
||||||
|
req.setAddress(addr);
|
||||||
|
return req.send().wait(waitScope).getData();
|
||||||
|
}
|
||||||
|
void write(uint32_t addr, uint64_t data) override {
|
||||||
|
auto req = llClient.writeMMIORequest();
|
||||||
|
req.setAddress(addr);
|
||||||
|
req.setData(data);
|
||||||
|
req.send().wait(waitScope);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
EsiLowLevel::Client &llClient;
|
||||||
|
kj::WaitScope &waitScope;
|
||||||
|
};
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
Service *CosimAccelerator::createService(Service::Type svcType) {
|
||||||
|
if (svcType == typeid(MMIO))
|
||||||
|
return new CosimMMIO(impl->lowLevel, impl->waitScope);
|
||||||
|
else if (svcType == typeid(SysInfo))
|
||||||
|
return new MMIOSysInfo(getService<MMIO>());
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
REGISTER_ACCELERATOR("cosim", backends::cosim::CosimAccelerator);
|
REGISTER_ACCELERATOR("cosim", backends::cosim::CosimAccelerator);
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#include "esi/Accelerator.h"
|
#include "esi/Accelerator.h"
|
||||||
|
#include "esi/StdServices.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
|
@ -11,21 +11,30 @@
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#include "esi/Accelerator.h"
|
#include "esi/Accelerator.h"
|
||||||
|
#include "esi/StdServices.h"
|
||||||
|
|
||||||
// pybind11 includes
|
// pybind11 includes
|
||||||
#include "pybind11/pybind11.h"
|
#include "pybind11/pybind11.h"
|
||||||
namespace py = pybind11;
|
namespace py = pybind11;
|
||||||
|
|
||||||
using namespace esi;
|
using namespace esi;
|
||||||
|
using namespace esi::services;
|
||||||
|
|
||||||
// NOLINTNEXTLINE(readability-identifier-naming)
|
// NOLINTNEXTLINE(readability-identifier-naming)
|
||||||
PYBIND11_MODULE(esiaccel, m) {
|
PYBIND11_MODULE(esiaccel, m) {
|
||||||
py::class_<Accelerator>(m, "Accelerator")
|
py::class_<Accelerator>(m, "Accelerator")
|
||||||
.def_static("connect", ®istry::connect,
|
.def_static("connect", ®istry::connect,
|
||||||
py::return_value_policy::take_ownership)
|
py::return_value_policy::take_ownership)
|
||||||
.def("sysinfo", &Accelerator::sysInfo,
|
.def("sysinfo", &Accelerator::getService<SysInfo>,
|
||||||
|
py::return_value_policy::reference_internal)
|
||||||
|
.def("get_service_mmio", &Accelerator::getService<services::MMIO>,
|
||||||
py::return_value_policy::reference_internal);
|
py::return_value_policy::reference_internal);
|
||||||
|
|
||||||
py::class_<SysInfo>(m, "SysInfo")
|
py::class_<SysInfo>(m, "SysInfo")
|
||||||
.def("esi_version", &SysInfo::esiVersion)
|
.def("esi_version", &SysInfo::esiVersion)
|
||||||
.def("raw_json_manifest", &SysInfo::rawJsonManifest);
|
.def("raw_json_manifest", &SysInfo::rawJsonManifest);
|
||||||
|
|
||||||
|
py::class_<services::MMIO>(m, "MMIO")
|
||||||
|
.def("read", &services::MMIO::read)
|
||||||
|
.def("write", &services::MMIO::write);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue