1
0
Fork 0
mirror of https://git.rwth-aachen.de/acs/public/villas/node/ synced 2025-03-16 00:00:02 +01:00
VILLASnode/fpga/lib/ips/rtds2gpu/rtds2gpu.cpp
Steffen Vogel f776cba693 relicense project to Apache 2.0
The project is now also REUSE compliant: https://reuse.software/
Previous copyright holders have provided their
acknowledgement to transition to the new license in the
following GitHub PR: https://github.com/VILLASframework/fpga/pull/66

Signed-off-by: Steffen Vogel <post@steffenvogel.de>
2023-01-07 17:20:15 +01:00

120 lines
4 KiB
C++

/** GPU2RTDS IP core
*
* Author: Daniel Krebs <github@daniel-krebs.net>
* SPDX-FileCopyrightText: Daniel Krebs
* SPDX-License-Identifier: Apache-2.0
*********************************************************************************/
#include <unistd.h>
#include <cstring>
#include <villas/log.hpp>
#include <villas/memory_manager.hpp>
#include <villas/fpga/ips/rtds2gpu.hpp>
using namespace villas::fpga::ip;
bool Rtds2Gpu::init()
{
Hls::init();
xInstance.IsReady = XIL_COMPONENT_IS_READY;
xInstance.Ctrl_BaseAddress = getBaseAddr(registerMemory);
status.value = 0;
started = false;
// maxFrameSize = getMaxFrameSize();
maxFrameSize = 16;
logger->info("Max. frame size supported: {}", maxFrameSize);
return true;
}
void Rtds2Gpu::dump(spdlog::level::level_enum logLevel)
{
const auto baseaddr = XRtds2gpu_Get_baseaddr(&xInstance);
const auto data_offset = XRtds2gpu_Get_data_offset(&xInstance);
const auto doorbell_offset = XRtds2gpu_Get_doorbell_offset(&xInstance);
const auto frame_size = XRtds2gpu_Get_frame_size(&xInstance);
logger->log(logLevel, "Rtds2Gpu registers (IP base {:#x}):", xInstance.Ctrl_BaseAddress);
logger->log(logLevel, " Base address (bytes): {:#x}", baseaddr);
logger->log(logLevel, " Doorbell offset (bytes): {:#x}", doorbell_offset);
logger->log(logLevel, " Data offset (bytes): {:#x}", data_offset);
logger->log(logLevel, " Frame size (words): {:#x}", frame_size);
logger->log(logLevel, " Status: {:#x}", status.value);
logger->log(logLevel, " Running: {}", (status.is_running ? "yes" : "no"));
logger->log(logLevel, " Frame too short: {}", (status.frame_too_short ? "yes" : "no"));
logger->log(logLevel, " Frame too long: {}", (status.frame_too_long ? "yes" : "no"));
logger->log(logLevel, " Frame size invalid: {}", (status.invalid_frame_size ? "yes" : "no"));
logger->log(logLevel, " Last count: {}", (int) status.last_count);
logger->log(logLevel, " Last seq. number: {}", (int) status.last_seq_nr);
logger->log(logLevel, " Max. frame size: {}", (int) status.max_frame_size);
}
bool Rtds2Gpu::startOnce(const MemoryBlock &mem, size_t frameSize, size_t dataOffset, size_t doorbellOffset)
{
auto &mm = MemoryManager::get();
if (frameSize > maxFrameSize) {
logger->error("Requested frame size of {} exceeds max. frame size of {}",
frameSize, maxFrameSize);
return false;
}
auto translationFromIp = mm.getTranslation(
getMasterAddrSpaceByInterface(axiInterface),
mem.getAddrSpaceId());
// Set address of memory block in HLS IP
XRtds2gpu_Set_baseaddr(&xInstance, translationFromIp.getLocalAddr(0));
XRtds2gpu_Set_doorbell_offset(&xInstance, doorbellOffset);
XRtds2gpu_Set_data_offset(&xInstance, dataOffset);
XRtds2gpu_Set_frame_size(&xInstance, frameSize);
// Prepare memory with all zeroes
auto translationFromProcess = mm.getTranslationFromProcess(mem.getAddrSpaceId());
auto memory = reinterpret_cast<void*>(translationFromProcess.getLocalAddr(0));
memset(memory, 0, mem.getSize());
// Start IP
return start();
}
bool Rtds2Gpu::updateStatus()
{
if (not XRtds2gpu_Get_status_vld(&xInstance))
return false;
status.value = XRtds2gpu_Get_status(&xInstance);
return true;
}
size_t Rtds2Gpu::getMaxFrameSize()
{
XRtds2gpu_Set_frame_size(&xInstance, 0);
start();
while (not isFinished());
updateStatus();
return status.max_frame_size;
}
void Rtds2Gpu::dumpDoorbell(uint32_t doorbellRegister) const
{
auto &doorbell = reinterpret_cast<reg_doorbell_t&>(doorbellRegister);
logger->info("Doorbell register: {:#08x}", doorbell.value);
logger->info(" Valid: {}", doorbell.is_valid ? "yes" : "no");
logger->info(" Count: {}", (int) doorbell.count);
logger->info(" Seq. number: {}", (int) doorbell.seq_nr);
}
static char n[] = "Rtds2Gpu";
static char d[] = "HLS RTDS2GPU IP";
static char v[] = "acs.eonerc.rwth-aachen.de:hls:rtds2gpu:";
static NodePlugin<Rtds2Gpu, n, d, v> f;