2018-05-23 20:04:10 +02:00
|
|
|
#include <unistd.h>
|
|
|
|
#include <cstring>
|
|
|
|
|
2018-08-21 14:25:20 +02:00
|
|
|
#include <villas/log.hpp>
|
2018-05-23 20:04:10 +02:00
|
|
|
#include <villas/memory_manager.hpp>
|
|
|
|
#include <villas/fpga/ips/rtds2gpu.hpp>
|
|
|
|
|
2020-06-14 22:11:15 +02:00
|
|
|
using namespace villas::fpga::ip;
|
2018-05-23 20:04:10 +02:00
|
|
|
static Rtds2GpuFactory factory;
|
|
|
|
|
|
|
|
bool Rtds2Gpu::init()
|
|
|
|
{
|
2018-05-30 13:58:26 +02:00
|
|
|
Hls::init();
|
|
|
|
|
2018-05-23 20:04:10 +02:00
|
|
|
xInstance.IsReady = XIL_COMPONENT_IS_READY;
|
|
|
|
xInstance.Ctrl_BaseAddress = getBaseAddr(registerMemory);
|
|
|
|
|
2018-05-29 12:28:09 +02:00
|
|
|
status.value = 0;
|
|
|
|
started = false;
|
|
|
|
|
2018-06-06 09:55:14 +02:00
|
|
|
// maxFrameSize = getMaxFrameSize();
|
|
|
|
maxFrameSize = 16;
|
2018-05-29 12:28:09 +02:00
|
|
|
logger->info("Max. frame size supported: {}", maxFrameSize);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Rtds2Gpu::dump(spdlog::level::level_enum logLevel)
|
2018-05-23 20:04:10 +02:00
|
|
|
{
|
|
|
|
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);
|
2018-05-29 12:28:09 +02:00
|
|
|
|
|
|
|
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"));
|
2022-03-04 03:33:47 -05:00
|
|
|
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);
|
2018-05-23 20:04:10 +02:00
|
|
|
}
|
|
|
|
|
2020-06-14 22:03:50 +02:00
|
|
|
bool Rtds2Gpu::startOnce(const MemoryBlock &mem, size_t frameSize, size_t dataOffset, size_t doorbellOffset)
|
2018-05-23 20:04:10 +02:00
|
|
|
{
|
2020-06-14 22:03:50 +02:00
|
|
|
auto &mm = MemoryManager::get();
|
2018-05-23 20:04:10 +02:00
|
|
|
|
2020-06-11 18:38:46 +02:00
|
|
|
if (frameSize > maxFrameSize) {
|
2018-05-29 12:28:09 +02:00
|
|
|
logger->error("Requested frame size of {} exceeds max. frame size of {}",
|
|
|
|
frameSize, maxFrameSize);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2018-05-23 20:04:10 +02:00
|
|
|
auto translationFromIp = mm.getTranslation(
|
|
|
|
getMasterAddrSpaceByInterface(axiInterface),
|
|
|
|
mem.getAddrSpaceId());
|
|
|
|
|
2022-08-30 12:01:47 -04:00
|
|
|
// Set address of memory block in HLS IP
|
2018-05-23 20:04:10 +02:00
|
|
|
XRtds2gpu_Set_baseaddr(&xInstance, translationFromIp.getLocalAddr(0));
|
|
|
|
|
2018-05-29 12:28:09 +02:00
|
|
|
XRtds2gpu_Set_doorbell_offset(&xInstance, doorbellOffset);
|
|
|
|
XRtds2gpu_Set_data_offset(&xInstance, dataOffset);
|
2018-05-23 20:04:10 +02:00
|
|
|
XRtds2gpu_Set_frame_size(&xInstance, frameSize);
|
|
|
|
|
2022-08-30 12:01:47 -04:00
|
|
|
// Prepare memory with all zeroes
|
2018-05-23 20:04:10 +02:00
|
|
|
auto translationFromProcess = mm.getTranslationFromProcess(mem.getAddrSpaceId());
|
|
|
|
auto memory = reinterpret_cast<void*>(translationFromProcess.getLocalAddr(0));
|
|
|
|
memset(memory, 0, mem.getSize());
|
|
|
|
|
2022-08-30 12:01:47 -04:00
|
|
|
// Start IP
|
2018-05-29 12:28:09 +02:00
|
|
|
return start();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
Rtds2Gpu::updateStatus()
|
|
|
|
{
|
2020-06-11 18:38:46 +02:00
|
|
|
if (not XRtds2gpu_Get_status_vld(&xInstance))
|
2018-05-29 12:28:09 +02:00
|
|
|
return false;
|
|
|
|
|
|
|
|
status.value = XRtds2gpu_Get_status(&xInstance);
|
2018-05-23 20:04:10 +02:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2018-05-29 12:28:09 +02:00
|
|
|
size_t
|
|
|
|
Rtds2Gpu::getMaxFrameSize()
|
2018-05-23 20:04:10 +02:00
|
|
|
{
|
2018-05-29 12:28:09 +02:00
|
|
|
XRtds2gpu_Set_frame_size(&xInstance, 0);
|
|
|
|
|
|
|
|
start();
|
2020-06-11 18:38:46 +02:00
|
|
|
while (not isFinished());
|
2018-05-30 13:58:26 +02:00
|
|
|
updateStatus();
|
2018-05-29 12:28:09 +02:00
|
|
|
|
|
|
|
return status.max_frame_size;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
Rtds2Gpu::dumpDoorbell(uint32_t doorbellRegister) const
|
|
|
|
{
|
2020-06-14 22:03:50 +02:00
|
|
|
auto &doorbell = reinterpret_cast<reg_doorbell_t&>(doorbellRegister);
|
2018-05-29 12:28:09 +02:00
|
|
|
|
|
|
|
logger->info("Doorbell register: {:#08x}", doorbell.value);
|
2022-03-04 03:33:47 -05:00
|
|
|
logger->info(" Valid: {}", doorbell.is_valid ? "yes" : "no");
|
|
|
|
logger->info(" Count: {}", (int) doorbell.count);
|
|
|
|
logger->info(" Seq. number: {}", (int) doorbell.seq_nr);
|
2018-05-23 20:04:10 +02:00
|
|
|
}
|
|
|
|
|