rtds2gpu.cpp 3.9 KB
Newer Older
Daniel Krebs's avatar
Daniel Krebs committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <unistd.h>
#include <cstring>

#include <villas/memory_manager.hpp>
#include <villas/fpga/ips/rtds2gpu.hpp>

#include "log.hpp"

namespace villas {
namespace fpga {
namespace ip {

static Rtds2GpuFactory factory;

bool Rtds2Gpu::init()
{
17
18
	Hls::init();

Daniel Krebs's avatar
Daniel Krebs committed
19
20
21
	xInstance.IsReady = XIL_COMPONENT_IS_READY;
	xInstance.Ctrl_BaseAddress = getBaseAddr(registerMemory);

Daniel Krebs's avatar
Daniel Krebs committed
22
23
24
	status.value = 0;
	started = false;

Daniel Krebs's avatar
Daniel Krebs committed
25
//	maxFrameSize = getMaxFrameSize();
26
	maxFrameSize = 64;
Daniel Krebs's avatar
Daniel Krebs committed
27
28
29
30
31
	logger->info("Max. frame size supported: {}", maxFrameSize);

	return true;
}

Daniel Krebs's avatar
Daniel Krebs committed
32
33


34
bool Rtds2Gpu::dumpLog(spdlog::level::level_enum logLevel)
Daniel Krebs's avatar
Daniel Krebs committed
35
36
37
38
39
{
	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);
Daniel Krebs's avatar
Daniel Krebs committed
40

41
42
	if(not updateStatus()) {
		logger->warn("Couldn't read status register (not ready), values may be wrong");
43
		return false;
44
45
	}

Daniel Krebs's avatar
Daniel Krebs committed
46
47
48
49
	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);
50
	logger->log(logLevel, "  Frame size (words):       {}", frame_size);
Daniel Krebs's avatar
Daniel Krebs committed
51
52
53
54
55
	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"));
56
	logger->log(logLevel, "    Last count:         {}", getStatusLastCount(status));
Daniel Krebs's avatar
Daniel Krebs committed
57
	logger->log(logLevel, "    Last seq. number:   {}", status.last_seq_nr);
58
	logger->log(logLevel, "    Max. frame size:    {}", getStatusMaxFrameSize(status));
59
60

	return true;
Daniel Krebs's avatar
Daniel Krebs committed
61
62
}

Daniel Krebs's avatar
Daniel Krebs committed
63
bool Rtds2Gpu::startOnce(const MemoryBlock& mem, size_t frameSize, size_t dataOffset, size_t doorbellOffset)
Daniel Krebs's avatar
Daniel Krebs committed
64
65
66
{
	auto& mm = MemoryManager::get();

Daniel Krebs's avatar
Daniel Krebs committed
67
68
69
70
71
72
	if(frameSize > maxFrameSize) {
		logger->error("Requested frame size of {} exceeds max. frame size of {}",
		              frameSize, maxFrameSize);
		return false;
	}

Daniel Krebs's avatar
Daniel Krebs committed
73
74
75
76
77
78
79
	auto translationFromIp = mm.getTranslation(
	                               getMasterAddrSpaceByInterface(axiInterface),
	                               mem.getAddrSpaceId());

	// set address of memory block in HLS IP
	XRtds2gpu_Set_baseaddr(&xInstance, translationFromIp.getLocalAddr(0));

Daniel Krebs's avatar
Daniel Krebs committed
80
81
	XRtds2gpu_Set_doorbell_offset(&xInstance, doorbellOffset);
	XRtds2gpu_Set_data_offset(&xInstance, dataOffset);
Daniel Krebs's avatar
Daniel Krebs committed
82
83
84
85
86
87
88
89
	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
Daniel Krebs's avatar
Daniel Krebs committed
90
91
92
93
94
95
96
97
98
99
100
101
102
103
	return start();
}





bool
Rtds2Gpu::updateStatus()
{
	if(not XRtds2gpu_Get_status_vld(&xInstance))
		return false;

	status.value = XRtds2gpu_Get_status(&xInstance);
Daniel Krebs's avatar
Daniel Krebs committed
104
105
106
107

	return true;
}

Daniel Krebs's avatar
Daniel Krebs committed
108
109
size_t
Rtds2Gpu::getMaxFrameSize()
Daniel Krebs's avatar
Daniel Krebs committed
110
{
Daniel Krebs's avatar
Daniel Krebs committed
111
112
113
114
	XRtds2gpu_Set_frame_size(&xInstance, 0);

	start();
	while(not isFinished());
115
	updateStatus();
Daniel Krebs's avatar
Daniel Krebs committed
116

117
	return getStatusMaxFrameSize(status);
Daniel Krebs's avatar
Daniel Krebs committed
118
119
120
121
122
123
124
125
126
}

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"));
127
	logger->info("  Count:       {}", getDoorbellCount(doorbell));
Daniel Krebs's avatar
Daniel Krebs committed
128
	logger->info("  Seq. number: {}", doorbell.seq_nr);
Daniel Krebs's avatar
Daniel Krebs committed
129
130
131
132
133
134
135
136
137
138
}

Rtds2GpuFactory::Rtds2GpuFactory() :
    IpNodeFactory(getName())
{
}

} // namespace ip
} // namespace fpga
} // namespace villas