1
0
Fork 0
mirror of https://git.rwth-aachen.de/acs/public/villas/node/ synced 2025-03-09 00:00:00 +01:00

fpga: make dma able to handle sequence numbers generated in the FPGA

Signed-off-by: Niklas Eiling <niklas.eiling@eonerc.rwth-aachen.de>
This commit is contained in:
Niklas Eiling 2024-07-04 10:29:08 +02:00 committed by Niklas Eiling
parent 64058be78f
commit 7128da24c3
2 changed files with 36 additions and 8 deletions

View file

@ -477,7 +477,7 @@ XAxiDma_Bd *Dma::readScatterGatherSetupBd(void *buf, size_t len) {
(uintptr_t)buf, (uintptr_t)bd, ret);
}
ret = XAxiDma_BdSetLength(curBd, readMsgSize, rxRing->MaxTransferLen);
ret = XAxiDma_BdSetLength(curBd, len, rxRing->MaxTransferLen);
if (ret != XST_SUCCESS) {
hwReadLock.unlock();
throw RuntimeError("Rx set length {} on BD {:x} failed {}", len,
@ -491,7 +491,7 @@ XAxiDma_Bd *Dma::readScatterGatherSetupBd(void *buf, size_t len) {
// TODO: Check if we really need this
XAxiDma_BdSetId(curBd, (uintptr_t)buf);
curBuf += readMsgSize;
curBuf += len;
curBd = (XAxiDma_Bd *)XAxiDma_BdRingNext(rxRing, curBd);
}
return bd;

View file

@ -183,12 +183,22 @@ const std::string &FpgaNode::getDetails() {
int FpgaNode::check() { return Node::check(); }
int FpgaNode::start() {
if (getOutputSignalsMaxCount() * sizeof(float) > blockRx->getSize()) {
if (getOutputSignalsMaxCount() * sizeof(float) > blockTx->getSize()) {
logger->error("Output signals exceed block size.");
throw villas ::RuntimeError("Output signals exceed block size.");
}
if (getInputSignalsMaxCount() * sizeof(float) > blockRx->getSize()) {
logger->error("Output signals exceed block size.");
throw villas ::RuntimeError("Output signals exceed block size.");
}
if (lowLatencyMode) {
dma->readScatterGatherPrepare(*blockRx, blockRx->getSize());
if (getInputSignalsMaxCount() != 0) {
dma->readScatterGatherPrepare(*blockRx,
getInputSignalsMaxCount() * sizeof(float));
} else {
logger->warn("No input signals defined. Not preparing read buffer - "
"reads will not work.");
}
if (getOutputSignalsMaxCount() != 0) {
dma->writeScatterGatherPrepare(*blockTx, getOutputSignalsMaxCount() *
sizeof(float));
@ -213,7 +223,7 @@ int FpgaNode::fastWrite(Sample *smps[], unsigned cnt) {
for (unsigned i = 0; i < smp->length; i++) {
if (smp->signals->getByIndex(i)->type == SignalType::FLOAT) {
mem[i] = smp->data[i].f;
mem[i] = static_cast<float>(smp->data[i].f);
} else {
mem[i] = static_cast<float>(smp->data[i].i);
}
@ -236,18 +246,36 @@ int FpgaNode::fastWrite(Sample *smps[], unsigned cnt) {
// what we have received. fastRead is thus capable of partial reads.
int FpgaNode::fastRead(Sample *smps[], unsigned cnt) {
Sample *smp = smps[0];
auto mem = MemoryAccessor<float>(*blockRx);
smp->flags = (int)SampleFlags::HAS_DATA;
smp->signals = in.signals;
size_t to_read = in.signals->size() * sizeof(uint32_t);
size_t read;
do {
dma->readScatterGatherFast();
auto read = dma->readScatterGatherPoll(true);
read = dma->readScatterGatherPoll(true);
if (read < to_read) {
logger->warn("Read only {} bytes, but {} were expected", read, to_read);
}
} while (read < to_read);
// when we read less than expected we don't know what we missed so the data is
// useless. Thus, we discard what we read and try again.
// We assume a lot without checking at this point. All for the latency!
smp->length = 0;
for (unsigned i = 0; i < MIN(read / sizeof(float), smp->capacity); i++) {
for (unsigned i = 0; i < MIN(read / sizeof(uint32_t), smp->capacity); i++) {
if (in.signals->getByIndex(i)->type == SignalType::INTEGER) {
auto mem = MemoryAccessor<uint32_t>(*blockRx);
smp->data[i].i = static_cast<int64_t>(mem[i]);
logger->info("Reading sample: {}, {}, {:#x}, i: {}", smp->data[i].i,
signalTypeToString(smp->signals->getByIndex(i)->type),
smp->data[i].i, i);
} else {
auto mem = MemoryAccessor<float>(*blockRx);
smp->data[i].f = static_cast<double>(mem[i]);
}
smp->length++;
}