From cbad1ca9d1ff0de04924b938e96a911727b57a03 Mon Sep 17 00:00:00 2001 From: Niklas Eiling Date: Wed, 8 Feb 2023 10:31:52 +0100 Subject: [PATCH 01/12] ConnectString: also allow pipe as a connection target Signed-off-by: Niklas Eiling --- fpga/lib/utils.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fpga/lib/utils.cpp b/fpga/lib/utils.cpp index 470210aa2..c2a1425a1 100644 --- a/fpga/lib/utils.cpp +++ b/fpga/lib/utils.cpp @@ -63,7 +63,7 @@ void fpga::ConnectString::parseString(std::string& connectString) return; } - static const std::regex regex("([0-9]+)([<\\->]+)([0-9]+|stdin|stdout)"); + static const std::regex regex("([0-9]+)([<\\->]+)([0-9]+|stdin|stdout|pipe)"); std::smatch match; if (!std::regex_match(connectString, match, regex) || match.size() != 4) { @@ -92,7 +92,7 @@ void fpga::ConnectString::parseString(std::string& connectString) int fpga::ConnectString::portStringToInt(std::string &str) const { - if (str == "stdin" || str == "stdout") { + if (str == "stdin" || str == "stdout" || str == "pipe") { return -1; } else { const int port = std::stoi(str); From 6b58624e5752d331e2e8cfe6ba5a2301df66ea2e Mon Sep 17 00:00:00 2001 From: Niklas Eiling Date: Wed, 15 Mar 2023 16:02:53 +0100 Subject: [PATCH 02/12] fix villas-fpga-pipe Signed-off-by: Niklas Eiling --- fpga/.vscode/launch.json | 2 +- fpga/include/villas/fpga/ips/dma.hpp | 2 +- fpga/lib/utils.cpp | 2 ++ fpga/src/CMakeLists.txt | 7 +++++++ fpga/src/villas-fpga-ctrl.cpp | 2 +- fpga/src/villas-fpga-pipe.cpp | 18 +++++++++--------- 6 files changed, 21 insertions(+), 12 deletions(-) diff --git a/fpga/.vscode/launch.json b/fpga/.vscode/launch.json index 1bce5a80d..2e3dcbd26 100644 --- a/fpga/.vscode/launch.json +++ b/fpga/.vscode/launch.json @@ -10,7 +10,7 @@ "request": "launch", "program": "${workspaceFolder}/build/src/villas-fpga-ctrl", "args": [ - "-c", "${workspaceFolder}/etc/fpgas.json", "--connect", "\"2<->stdout\"" + "-c", "${workspaceFolder}/etc/fpgas.json", "--connect", "\"4<->stdout\"" ], "stopAtEntry": false, "cwd": "${workspaceFolder}", diff --git a/fpga/include/villas/fpga/ips/dma.hpp b/fpga/include/villas/fpga/ips/dma.hpp index 6e788e1d3..7f15ede92 100644 --- a/fpga/include/villas/fpga/ips/dma.hpp +++ b/fpga/include/villas/fpga/ips/dma.hpp @@ -129,7 +129,7 @@ private: int delay = 0; // Coalesce is the number of messages/BDs to wait for before issuing an interrupt uint32_t writeCoalesce = 1; - uint32_t readCoalesce = 16; + uint32_t readCoalesce = 1; // (maximum) size of a single message on the read channel in bytes. // The message buffer/BD should have enough room for this many bytes. diff --git a/fpga/lib/utils.cpp b/fpga/lib/utils.cpp index c2a1425a1..b8979afe8 100644 --- a/fpga/lib/utils.cpp +++ b/fpga/lib/utils.cpp @@ -84,9 +84,11 @@ void fpga::ConnectString::parseString(std::string& connectString) dstAsInt = portStringToInt(dstStr); if (srcAsInt == -1) { srcIsStdin = true; + dstIsStdout = bidirectional; } if (dstAsInt == -1) { dstIsStdout = true; + srcIsStdin = bidirectional; } } diff --git a/fpga/src/CMakeLists.txt b/fpga/src/CMakeLists.txt index 4a93677ef..c9b3ebee8 100644 --- a/fpga/src/CMakeLists.txt +++ b/fpga/src/CMakeLists.txt @@ -11,4 +11,11 @@ target_link_libraries(villas-fpga-ctrl PUBLIC villas-fpga ) +add_executable(villas-fpga-pipe villas-fpga-pipe.cpp) + +target_link_libraries(villas-fpga-pipe PUBLIC + villas-fpga +) + + add_executable(pcimem pcimem.c) diff --git a/fpga/src/villas-fpga-ctrl.cpp b/fpga/src/villas-fpga-ctrl.cpp index def5b2e9a..7c14b3429 100644 --- a/fpga/src/villas-fpga-ctrl.cpp +++ b/fpga/src/villas-fpga-ctrl.cpp @@ -51,7 +51,7 @@ void writeToDmaFromStdIn(std::shared_ptr dma) } size_t cur = 0, next = 1; - std::ios::sync_with_stdio(false); +er //std::ios::sync_with_stdio(false); std::string line; bool firstXfer = true; diff --git a/fpga/src/villas-fpga-pipe.cpp b/fpga/src/villas-fpga-pipe.cpp index b60e67fc4..081ddc0a8 100644 --- a/fpga/src/villas-fpga-pipe.cpp +++ b/fpga/src/villas-fpga-pipe.cpp @@ -89,8 +89,8 @@ int main(int argc, char* argv[]) dma->connectLoopback(); #endif auto &alloc = villas::HostRam::getAllocator(); - auto mem = alloc.allocate(0x100); - auto block = mem.getMemoryBlock(); + std::shared_ptr block = alloc.allocateBlock(0x100 * sizeof(int32_t)); + villas::MemoryAccessor mem = *block; dma->makeAccesibleFromVA(block); @@ -99,7 +99,7 @@ int main(int argc, char* argv[]) while (true) { // Setup read transfer - dma->read(block, block.getSize()); + dma->read(*block, block->getSize()); // Read values from stdin std::string line; @@ -115,16 +115,16 @@ int main(int argc, char* argv[]) } // Initiate write transfer - bool state = dma->write(block, i * sizeof(int32_t)); + bool state = dma->write(*block, i * sizeof(int32_t)); if (!state) logger->error("Failed to write to device"); - auto bytesWritten = dma->writeComplete(); - logger->info("Wrote {} bytes", bytesWritten); + auto writeComp = dma->writeComplete(); + logger->info("Wrote {} bytes", writeComp.bytes); - auto bytesRead = dma->readComplete(); - auto valuesRead = bytesRead / sizeof(int32_t); - logger->info("Read {} bytes", bytesRead); + auto readComp = dma->readComplete(); + auto valuesRead = readComp.bytes / sizeof(int32_t); + logger->info("Read {} bytes, {} bds, {} interrupts", readComp.bytes, readComp.bds, readComp.interrupts); for (size_t i = 0; i < valuesRead; i++) std::cerr << mem[i] << ";"; From 4ef114fad43cf09953bb429a0795fab926feccac Mon Sep 17 00:00:00 2001 From: Niklas Eiling Date: Mon, 20 Mar 2023 10:23:13 +0100 Subject: [PATCH 03/12] remove unnecessary characters in villas-fpga-ctrl Signed-off-by: Niklas Eiling --- fpga/src/villas-fpga-ctrl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fpga/src/villas-fpga-ctrl.cpp b/fpga/src/villas-fpga-ctrl.cpp index 7c14b3429..def5b2e9a 100644 --- a/fpga/src/villas-fpga-ctrl.cpp +++ b/fpga/src/villas-fpga-ctrl.cpp @@ -51,7 +51,7 @@ void writeToDmaFromStdIn(std::shared_ptr dma) } size_t cur = 0, next = 1; -er //std::ios::sync_with_stdio(false); + std::ios::sync_with_stdio(false); std::string line; bool firstXfer = true; From e6f34f83f44d4ad7b2ad9f32ae36038b8784ed45 Mon Sep 17 00:00:00 2001 From: Niklas Eiling Date: Mon, 20 Mar 2023 12:10:37 +0100 Subject: [PATCH 04/12] make villas-fpga-pipe use separat memory segments for reading and writing Signed-off-by: Niklas Eiling --- fpga/src/villas-fpga-pipe.cpp | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/fpga/src/villas-fpga-pipe.cpp b/fpga/src/villas-fpga-pipe.cpp index 081ddc0a8..2aba4abab 100644 --- a/fpga/src/villas-fpga-pipe.cpp +++ b/fpga/src/villas-fpga-pipe.cpp @@ -83,23 +83,27 @@ int main(int argc, char* argv[]) // Configure Crossbar switch #if 1 - aurora_channels[2]->connect(aurora_channels[2]->getDefaultMasterPort(), dma->getDefaultSlavePort()); + aurora_channels[3]->connect(aurora_channels[3]->getDefaultMasterPort(), dma->getDefaultSlavePort()); dma->connect(dma->getDefaultMasterPort(), aurora_channels[3]->getDefaultSlavePort()); #else dma->connectLoopback(); #endif auto &alloc = villas::HostRam::getAllocator(); - std::shared_ptr block = alloc.allocateBlock(0x100 * sizeof(int32_t)); - villas::MemoryAccessor mem = *block; - - dma->makeAccesibleFromVA(block); + const std::shared_ptr block[] = { + alloc.allocateBlock(0x200 * sizeof(uint32_t)), + alloc.allocateBlock(0x200 * sizeof(uint32_t)) + }; + villas::MemoryAccessor mem[] = {*block[0], *block[1]}; + for (auto b : block) { + dma->makeAccesibleFromVA(b); + } auto &mm = MemoryManager::get(); mm.getGraph().dump("graph.dot"); while (true) { // Setup read transfer - dma->read(*block, block->getSize()); + dma->read(*block[0], block[0]->getSize()); // Read values from stdin std::string line; @@ -111,11 +115,11 @@ int main(int argc, char* argv[]) if (value.empty()) continue; const int32_t number = std::stoi(value); - mem[i++] = number; + mem[1][i++] = number; } // Initiate write transfer - bool state = dma->write(*block, i * sizeof(int32_t)); + bool state = dma->write(*block[1], i * sizeof(int32_t)); if (!state) logger->error("Failed to write to device"); @@ -127,7 +131,7 @@ int main(int argc, char* argv[]) logger->info("Read {} bytes, {} bds, {} interrupts", readComp.bytes, readComp.bds, readComp.interrupts); for (size_t i = 0; i < valuesRead; i++) - std::cerr << mem[i] << ";"; + std::cerr << mem[0][i] << ";"; std::cerr << std::endl; } } catch (const RuntimeError &e) { From 7847658548b71017bdfac09cb42a3391113a1767 Mon Sep 17 00:00:00 2001 From: Niklas Eiling Date: Mon, 20 Mar 2023 15:35:38 +0100 Subject: [PATCH 05/12] fix output formatting not being able to print numbers larger than 9 Signed-off-by: Niklas Eiling --- fpga/include/villas/fpga/utils.hpp | 14 ++-- fpga/lib/ips/dma.cpp | 2 +- fpga/src/villas-fpga-ctrl.cpp | 101 +++++++++++++++++++---------- 3 files changed, 76 insertions(+), 41 deletions(-) diff --git a/fpga/include/villas/fpga/utils.hpp b/fpga/include/villas/fpga/utils.hpp index a6e4a3139..5e93465cf 100644 --- a/fpga/include/villas/fpga/utils.hpp +++ b/fpga/include/villas/fpga/utils.hpp @@ -86,14 +86,16 @@ public: virtual void format(float value) override { - if (std::snprintf(nextBufPos(), formatStringSize+1, formatString, value) > (int)formatStringSize) { - throw RuntimeError("Output buffer too small"); + size_t chars; + if ((chars = std::snprintf(nextBufPos(), formatStringSize+1, formatString, value)) > (int)formatStringSize) { + throw RuntimeError("Output buffer too small. Expected " + std::to_string(formatStringSize) + + " characters, got " + std::to_string(chars)); } } protected: - static constexpr char formatString[] = "%7f\n"; - static constexpr size_t formatStringSize = 9; + static constexpr char formatString[] = "%013.6f\n"; + static constexpr size_t formatStringSize = 14; }; class BufferedSampleFormatterLong : public BufferedSampleFormatter { @@ -111,8 +113,8 @@ public: } protected: - static constexpr char formatString[] = "%05zd: %7f\n"; - static constexpr size_t formatStringSize = 16; + static constexpr char formatString[] = "%05zd: %013.6f\n"; + static constexpr size_t formatStringSize = 22; size_t sampleCnt; }; diff --git a/fpga/lib/ips/dma.cpp b/fpga/lib/ips/dma.cpp index 378145f47..b2a6600ed 100644 --- a/fpga/lib/ips/dma.cpp +++ b/fpga/lib/ips/dma.cpp @@ -243,7 +243,7 @@ bool Dma::write(const MemoryBlock &mem, size_t len) if (buf == nullptr) throw RuntimeError("Buffer was null"); - logger->debug("Write to stream from address {:p}", buf); + logger->trace("Write to stream from address {:p}", buf); return hasScatterGather() ? writeScatterGather(buf, len) : writeSimple(buf, len); } diff --git a/fpga/src/villas-fpga-ctrl.cpp b/fpga/src/villas-fpga-ctrl.cpp index def5b2e9a..c88a7c32d 100644 --- a/fpga/src/villas-fpga-ctrl.cpp +++ b/fpga/src/villas-fpga-ctrl.cpp @@ -39,25 +39,15 @@ static auto logger = villas::logging.get("ctrl"); void writeToDmaFromStdIn(std::shared_ptr dma) { auto &alloc = villas::HostRam::getAllocator(); + const std::shared_ptr block = alloc.allocateBlock(0x200 * sizeof(float)); + villas::MemoryAccessor mem = *block; + dma->makeAccesibleFromVA(block); - const std::shared_ptr block[] = { - alloc.allocateBlock(0x200 * sizeof(uint32_t)), - alloc.allocateBlock(0x200 * sizeof(uint32_t)) - }; - villas::MemoryAccessor mem[] = {*block[0], *block[1]}; + logger->info("Please enter values to write to the device, separated by ';'"); - for (auto b : block) { - dma->makeAccesibleFromVA(b); - } - - size_t cur = 0, next = 1; - std::ios::sync_with_stdio(false); - std::string line; - bool firstXfer = true; - - while(true) { + while (true) { // Read values from stdin - + std::string line; std::getline(std::cin, line); auto values = villas::utils::tokenize(line, ";"); @@ -66,24 +56,63 @@ void writeToDmaFromStdIn(std::shared_ptr dma) if (value.empty()) continue; const float number = std::stof(value); - mem[cur][i++] = number; + mem[i++] = number; } // Initiate write transfer - bool state = dma->write(*block[cur], i * sizeof(float)); + bool state = dma->write(*block, i * sizeof(float)); if (!state) logger->error("Failed to write to device"); - if (!firstXfer) { - auto bytesWritten = dma->writeComplete(); - logger->debug("Wrote {} bytes", bytesWritten.bytes); - } else { - firstXfer = false; - } - - cur = next; - next = (next + 1) % (sizeof(mem) / sizeof(mem[0])); + auto writeComp = dma->writeComplete(); + logger->debug("Wrote {} bytes", writeComp.bytes); } + // auto &alloc = villas::HostRam::getAllocator(); + + // const std::shared_ptr block[] = { + // alloc.allocateBlock(0x200 * sizeof(uint32_t)), + // alloc.allocateBlock(0x200 * sizeof(uint32_t)) + // }; + // villas::MemoryAccessor mem[] = {*block[0], *block[1]}; + + // for (auto b : block) { + // dma->makeAccesibleFromVA(b); + // } + + // size_t cur = 0, next = 1; + // std::ios::sync_with_stdio(false); + // std::string line; + // bool firstXfer = true; + + // while(true) { + // // Read values from stdin + + // std::getline(std::cin, line); + // auto values = villas::utils::tokenize(line, ";"); + + // size_t i = 0; + // for (auto &value: values) { + // if (value.empty()) continue; + + // const float number = std::stof(value); + // mem[cur][i++] = number; + // } + + // // Initiate write transfer + // bool state = dma->write(*block[cur], i * sizeof(float)); + // if (!state) + // logger->error("Failed to write to device"); + + // if (!firstXfer) { + // auto bytesWritten = dma->writeComplete(); + // logger->debug("Wrote {} bytes", bytesWritten.bytes); + // } else { + // firstXfer = false; + // } + + // cur = next; + // next = (next + 1) % (sizeof(mem) / sizeof(mem[0])); + // } } void readFromDmaToStdOut(std::shared_ptr dma, @@ -117,15 +146,19 @@ void readFromDmaToStdOut(std::shared_ptr dma, logger->warn("Missed {} interrupts", c.interrupts - 1); } - logger->trace("bytes: {}, intrs: {}, bds: {}", + logger->debug("bytes: {}, intrs: {}, bds: {}", c.bytes, c.interrupts, c.bds); - - for (size_t i = 0; i*4 < c.bytes; i++) { - int32_t ival = mem[cur][i]; - float fval = *((float*)(&ival)); // cppcheck-suppress invalidPointerCast - formatter->format(fval); + try { + for (size_t i = 0; i*4 < c.bytes; i++) { + int32_t ival = mem[cur][i]; + float fval = *((float*)(&ival)); // cppcheck-suppress invalidPointerCast + formatter->format(fval); + printf("%#x\n", ival); + } + formatter->output(std::cout); + } catch (const std::exception &e) { + logger->warn("Failed to output data: {}", e.what()); } - formatter->output(std::cout); cur = next; next = (next + 1) % (sizeof(mem) / sizeof(mem[0])); From b05910f24ea4f84ab03db6a78bffb39266d4ea04 Mon Sep 17 00:00:00 2001 From: Niklas Eiling Date: Mon, 20 Mar 2023 17:12:47 +0100 Subject: [PATCH 06/12] add C bindings for external use of VILLASfpga Signed-off-by: Niklas Eiling --- fpga/include/villas/fpga/utils.hpp | 16 +- fpga/include/villas/fpga/villasfpga_dma.h | 31 ++++ fpga/lib/CMakeLists.txt | 1 + fpga/lib/utils.cpp | 12 ++ fpga/lib/villasfpga_dma.cpp | 195 ++++++++++++++++++++++ fpga/src/villas-fpga-ctrl.cpp | 1 - 6 files changed, 242 insertions(+), 14 deletions(-) create mode 100644 fpga/include/villas/fpga/villasfpga_dma.h create mode 100644 fpga/lib/villasfpga_dma.cpp diff --git a/fpga/include/villas/fpga/utils.hpp b/fpga/include/villas/fpga/utils.hpp index 5e93465cf..fd9e7fbcd 100644 --- a/fpga/include/villas/fpga/utils.hpp +++ b/fpga/include/villas/fpga/utils.hpp @@ -8,6 +8,7 @@ #include #include +#include namespace villas { namespace fpga { @@ -25,7 +26,7 @@ public: int portStringToInt(std::string &str) const; void configCrossBar(std::shared_ptr dma, - std::vector>& aurora_channels) const; + std::vector>& aurora_channels) const; bool isBidirectional() const { return bidirectional; }; bool isDmaLoopback() const { return dmaLoopback; }; @@ -119,18 +120,7 @@ protected: }; -std::unique_ptr getBufferedSampleFormatter( - const std::string &format, - size_t bufSizeInSamples) -{ - if (format == "long") { - return std::make_unique(bufSizeInSamples); - } else if (format == "short") { - return std::make_unique(bufSizeInSamples); - } else { - throw RuntimeError("Unknown output format '{}'", format); - } -} +std::unique_ptr getBufferedSampleFormatter(const std::string &format, size_t bufSizeInSamples); } /* namespace fpga */ } /* namespace villas */ diff --git a/fpga/include/villas/fpga/villasfpga_dma.h b/fpga/include/villas/fpga/villasfpga_dma.h new file mode 100644 index 000000000..353a7eb75 --- /dev/null +++ b/fpga/include/villas/fpga/villasfpga_dma.h @@ -0,0 +1,31 @@ +/** C bindings for VILLASfpga + * + * Author: Niklas Eiling + * SPDX-FileCopyrightText: 2023 Niklas Eiling + * SPDX-License-Identifier: Apache-2.0 + ******************************************************************************/ + +#pragma once + +extern "C" { + +#include + +typedef struct villasfpga_handle_t *villasfpga_handle; +typedef struct villasfpga_memory_t *villasfpga_memory; + +villasfpga_handle villasfpga_init(const char *configFile); + +void villasfpga_destroy(villasfpga_handle handle); + +int villasfpga_alloc(villasfpga_handle handle, villasfpga_memory *mem, size_t size); +int villasfpga_register(villasfpga_handle handle, villasfpga_memory *mem); +int villasfpga_free(villasfpga_memory mem); + +int villasfpga_read(villasfpga_handle handle, villasfpga_memory mem, size_t size); +int vilalsfpga_read_complete(villasfpga_handle handle, size_t *size); + +int villasfpga_write(villasfpga_handle handle, villasfpga_memory mem, size_t size); +int vilalsfpga_write_complete(villasfpga_handle handle, size_t *size); + +} // extern "C" diff --git a/fpga/lib/CMakeLists.txt b/fpga/lib/CMakeLists.txt index a89150c07..148d77867 100644 --- a/fpga/lib/CMakeLists.txt +++ b/fpga/lib/CMakeLists.txt @@ -12,6 +12,7 @@ set(SOURCES core.cpp node.cpp utils.cpp + villasfpga_dma.cpp ips/aurora_xilinx.cpp ips/aurora.cpp diff --git a/fpga/lib/utils.cpp b/fpga/lib/utils.cpp index b8979afe8..763a68739 100644 --- a/fpga/lib/utils.cpp +++ b/fpga/lib/utils.cpp @@ -215,3 +215,15 @@ fpga::setupFpgaCard(const std::string &configFile, const std::string &fpgaName) return card; } +std::unique_ptr fpga::getBufferedSampleFormatter( + const std::string &format, + size_t bufSizeInSamples) +{ + if (format == "long") { + return std::make_unique(bufSizeInSamples); + } else if (format == "short") { + return std::make_unique(bufSizeInSamples); + } else { + throw RuntimeError("Unknown output format '{}'", format); + } +} diff --git a/fpga/lib/villasfpga_dma.cpp b/fpga/lib/villasfpga_dma.cpp new file mode 100644 index 000000000..31699cf55 --- /dev/null +++ b/fpga/lib/villasfpga_dma.cpp @@ -0,0 +1,195 @@ +/** API for interacting with the FPGA DMA Controller. + * + * Author: Niklas Eiling + * SPDX-FileCopyrightText: 2023 Niklas Eiling + * SPDX-License-Identifier: Apache-2.0 + *********************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +using namespace villas; + +static std::shared_ptr pciDevices; +static auto logger = villas::logging.get("villasfpga_dma"); + +struct villasfpga_handle_t { + std::shared_ptr card; + std::shared_ptr dma; +}; +struct villasfpga_memory_t { + std::shared_ptr block; +}; + +villasfpga_handle villasfpga_init(const char *configFile) +{ + std::string fpgaName = "vc707"; + std::string connectStr = "3<->pipe"; + std::string outputFormat = "short"; + bool dumpGraph = false; + bool dumpAuroraChannels = true; + try { + // Logging setup + logging.setLevel(spdlog::level::debug); + fpga::setupColorHandling(); + + if (configFile == nullptr || configFile[0] == '\0') { + logger->error("No configuration file provided/ Please use -c/--config argument"); + return nullptr; + } + + auto handle = new villasfpga_handle_t; + handle->card = fpga::setupFpgaCard(configFile, fpgaName); + + std::vector> aurora_channels; + for (int i = 0; i < 4; i++) { + auto name = fmt::format("aurora_8b10b_ch{}", i); + auto id = fpga::ip::IpIdentifier("xilinx.com:ip:aurora_8b10b:", name); + auto aurora = std::dynamic_pointer_cast(handle->card->lookupIp(id)); + if (aurora == nullptr) { + logger->error("No Aurora interface found on FPGA"); + return nullptr; + } + + aurora_channels.push_back(aurora); + } + + handle->dma = std::dynamic_pointer_cast + (handle->card->lookupIp(fpga::Vlnv("xilinx.com:ip:axi_dma:"))); + if (handle->dma == nullptr) { + logger->error("No DMA found on FPGA "); + return nullptr; + } + + if (dumpGraph) { + auto &mm = MemoryManager::get(); + mm.getGraph().dump("graph.dot"); + } + + if (dumpAuroraChannels) { + for (auto aurora : aurora_channels) + aurora->dump(); + } + + // Configure Crossbar switch + const fpga::ConnectString parsedConnectString(connectStr); + parsedConnectString.configCrossBar(handle->dma, aurora_channels); + + return handle; + } catch (const RuntimeError &e) { + logger->error("Error: {}", e.what()); + return nullptr; + } catch (const std::exception &e) { + logger->error("Error: {}", e.what()); + return nullptr; + } catch (...) { + logger->error("Unknown error"); + return nullptr; + } +} + +void villasfpga_destroy(villasfpga_handle handle) +{ + delete handle; +} + +int villasfpga_alloc(villasfpga_handle handle, villasfpga_memory *mem, size_t size) +{ + try { + auto &alloc = villas::HostRam::getAllocator(); + *mem = new villasfpga_memory_t; + (*mem)->block = alloc.allocateBlock(size); + return villasfpga_register(handle, mem); + } catch (const RuntimeError &e) { + logger->error("Failed to allocate memory: {}", e.what()); + return -1; + } +} +int villasfpga_register(villasfpga_handle handle, villasfpga_memory *mem) +{ + try { + handle->dma->makeAccesibleFromVA((*mem)->block); + return 0; + } catch (const RuntimeError &e) { + logger->error("Failed to register memory: {}", e.what()); + return -1; + } +} +int villasfpga_free(villasfpga_memory mem) +{ + try { + delete mem; + return 0; + } catch (const RuntimeError &e) { + logger->error("Failed to free memory: {}", e.what()); + return -1; + } +} + +int villasfpga_read(villasfpga_handle handle, villasfpga_memory mem, size_t size) +{ + try { + if (!handle->dma->read(*mem->block, size)) { + logger->error("Failed to read from device"); + return -1; + } + return 0; + } catch (const RuntimeError &e) { + logger->error("Failed to read memory: {}", e.what()); + return -1; + } +} + +int vilalsfpga_read_complete(villasfpga_handle handle, size_t *size) +{ + try { + auto readComp = handle->dma->readComplete(); + logger->debug("Wrote {} bytes", readComp.bytes); + *size = readComp.bytes; + return 0; + } catch (const RuntimeError &e) { + logger->error("Failed to read memory: {}", e.what()); + return -1; + } +} + +int villasfpga_write(villasfpga_handle handle, villasfpga_memory mem, size_t size) +{ + try { + if (!handle->dma->write(*mem->block, size)) { + logger->error("Failed to write to device"); + return -1; + } + return 0; + } catch (const RuntimeError &e) { + logger->error("Failed to write memory: {}", e.what()); + return -1; + } +} + +int vilalsfpga_write_complete(villasfpga_handle handle, size_t *size) +{ + try { + auto writeComp = handle->dma->writeComplete(); + logger->debug("Wrote {} bytes", writeComp.bytes); + *size = writeComp.bytes; + return 0; + } catch (const RuntimeError &e) { + logger->error("Failed to write memory: {}", e.what()); + return -1; + } +} diff --git a/fpga/src/villas-fpga-ctrl.cpp b/fpga/src/villas-fpga-ctrl.cpp index c88a7c32d..e1a6ac066 100644 --- a/fpga/src/villas-fpga-ctrl.cpp +++ b/fpga/src/villas-fpga-ctrl.cpp @@ -21,7 +21,6 @@ #include #include #include -#include #include #include From c05ae4d2829a555c1e48c09af678ce37a64994f6 Mon Sep 17 00:00:00 2001 From: Niklas Eiling Date: Tue, 21 Mar 2023 10:47:45 +0100 Subject: [PATCH 07/12] add C bindings for DMA interactions and add a test/example Signed-off-by: Niklas Eiling --- fpga/include/villas/fpga/villasfpga_dma.h | 15 +++-- fpga/lib/villasfpga_dma.cpp | 4 +- fpga/tests/unit/CMakeLists.txt | 10 +++ fpga/tests/unit/villasfpga_dma.c | 82 +++++++++++++++++++++++ 4 files changed, 105 insertions(+), 6 deletions(-) create mode 100644 fpga/tests/unit/villasfpga_dma.c diff --git a/fpga/include/villas/fpga/villasfpga_dma.h b/fpga/include/villas/fpga/villasfpga_dma.h index 353a7eb75..f6491ddd8 100644 --- a/fpga/include/villas/fpga/villasfpga_dma.h +++ b/fpga/include/villas/fpga/villasfpga_dma.h @@ -5,9 +5,12 @@ * SPDX-License-Identifier: Apache-2.0 ******************************************************************************/ -#pragma once - +#ifndef _VILLASFPGA_DMA_H +#define _VILLASFPGA_DMA_H +#ifdef __cplusplus extern "C" { +#endif + #include @@ -23,9 +26,13 @@ int villasfpga_register(villasfpga_handle handle, villasfpga_memory *mem); int villasfpga_free(villasfpga_memory mem); int villasfpga_read(villasfpga_handle handle, villasfpga_memory mem, size_t size); -int vilalsfpga_read_complete(villasfpga_handle handle, size_t *size); +int villasfpga_read_complete(villasfpga_handle handle, size_t *size); int villasfpga_write(villasfpga_handle handle, villasfpga_memory mem, size_t size); -int vilalsfpga_write_complete(villasfpga_handle handle, size_t *size); +int villasfpga_write_complete(villasfpga_handle handle, size_t *size); +#ifdef __cplusplus } // extern "C" +#endif + +#endif /* _VILLASFPGA_DMA_H */ diff --git a/fpga/lib/villasfpga_dma.cpp b/fpga/lib/villasfpga_dma.cpp index 31699cf55..872813c59 100644 --- a/fpga/lib/villasfpga_dma.cpp +++ b/fpga/lib/villasfpga_dma.cpp @@ -154,7 +154,7 @@ int villasfpga_read(villasfpga_handle handle, villasfpga_memory mem, size_t size } } -int vilalsfpga_read_complete(villasfpga_handle handle, size_t *size) +int villasfpga_read_complete(villasfpga_handle handle, size_t *size) { try { auto readComp = handle->dma->readComplete(); @@ -181,7 +181,7 @@ int villasfpga_write(villasfpga_handle handle, villasfpga_memory mem, size_t siz } } -int vilalsfpga_write_complete(villasfpga_handle handle, size_t *size) +int villasfpga_write_complete(villasfpga_handle handle, size_t *size) { try { auto writeComp = handle->dma->writeComplete(); diff --git a/fpga/tests/unit/CMakeLists.txt b/fpga/tests/unit/CMakeLists.txt index a114eea99..454525714 100644 --- a/fpga/tests/unit/CMakeLists.txt +++ b/fpga/tests/unit/CMakeLists.txt @@ -36,3 +36,13 @@ target_link_libraries(unit-tests-fpga PUBLIC villas-fpga ${CRITERION_LIBRARIES} ) + +add_executable(villasfpga-dma villasfpga_dma.c) + +target_include_directories(villasfpga-dma PUBLIC + ../include +) + +target_link_libraries(villasfpga-dma PUBLIC + villas-fpga +) diff --git a/fpga/tests/unit/villasfpga_dma.c b/fpga/tests/unit/villasfpga_dma.c new file mode 100644 index 000000000..cfb70e3e7 --- /dev/null +++ b/fpga/tests/unit/villasfpga_dma.c @@ -0,0 +1,82 @@ +#include +#include +#include + +#include + +int main(int argc, char *argv[]) +{ + int ret; + villasfpga_handle vh; + villasfpga_memory mem1, mem2; + char line[1024]; + float f; + size_t size; + + if (argc != 2 && argv != NULL) { + fprintf(stderr, "Usage: %s \n", argv[0]); + } + + if ((vh = villasfpga_init(argv[1])) == NULL) { + fprintf(stderr, "Failed to initialize FPGA\n"); + ret = 1; + goto out; + } + + if (villasfpga_alloc(vh, &mem1, 0x200 * sizeof(uint32_t)) != 0) { + fprintf(stderr, "Failed to allocate DMA memory 1\n"); + ret = 1; + goto out; + } + + if (villasfpga_alloc(vh, &mem2, 0x200 * sizeof(uint32_t)) != 0) { + fprintf(stderr, "Failed to allocate DMA memory 2\n"); + ret = 1; + goto out; + } + + while (1) { + // Setup read transfer + if ((ret = villasfpga_read(vh, mem1, 0x200 * sizeof(uint32_t))) != 0) { + fprintf(stderr, "Failed to initiate read transfer\n"); + ret = 1; + goto out; + } + + printf("Enter a float:\n"); + if ((ret = sscanf(line, "%f")) != 1) { + fprintf(stderr, "Failed to parse input: sscanf returned %d\n", ret); + ret = 1; + goto out; + } + + ((float*)mem2)[0] = atof(line); + printf("Read %f\n", ((float*)mem2)[0]); + // Initiate write transfer + if ((ret = villasfpga_write(vh, mem2, sizeof(float))) != 0) { + fprintf(stderr, "Failed to initiate write transfer\n"); + ret = 1; + goto out; + } + + if ((ret = villasfpga_write_complete(vh, &size)) != 0) { + fprintf(stderr, "Failed to write complete\n"); + ret = 1; + goto out; + } + printf("Wrote %zu bytes", size); + + if ((ret = villasfpga_read_complete(vh, &size)) != 0) { + fprintf(stderr, "Failed to write complete\n"); + ret = 1; + goto out; + } + printf("Read %zu bytes", size); + + printf("Read %f\n", ((float*)mem1)[0]); + } + + ret = 0; + out: + return ret; +} From d9e60e22b1a406e8deaf8dab19445b6b76af85a6 Mon Sep 17 00:00:00 2001 From: Niklas Eiling Date: Tue, 21 Mar 2023 11:15:25 +0100 Subject: [PATCH 08/12] make it possible to specify a search path in PcieCard::make so we can use relative paths in config files Signed-off-by: Niklas Eiling --- fpga/include/villas/fpga/pcie_card.hpp | 7 +++++-- fpga/lib/pcie_card.cpp | 23 +++++++++++++++++------ fpga/lib/utils.cpp | 2 ++ 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/fpga/include/villas/fpga/pcie_card.hpp b/fpga/include/villas/fpga/pcie_card.hpp index e29ddee70..6e7153d56 100644 --- a/fpga/include/villas/fpga/pcie_card.hpp +++ b/fpga/include/villas/fpga/pcie_card.hpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -78,8 +79,10 @@ protected: class PCIeCardFactory : public plugin::Plugin { public: - static - std::list> make(json_t *json, std::shared_ptr pci, std::shared_ptr vc); + static std::list> make(json_t *json, + std::shared_ptr pci, + std::shared_ptr vc, + const std::filesystem::path& searchPath = std::filesystem::path()); static PCIeCard* make() diff --git a/fpga/lib/pcie_card.cpp b/fpga/lib/pcie_card.cpp index 31fb1ca8d..2df19dd0d 100644 --- a/fpga/lib/pcie_card.cpp +++ b/fpga/lib/pcie_card.cpp @@ -27,7 +27,10 @@ static PCIeCardFactory PCIeCardFactoryInstance; static const kernel::pci::Device defaultFilter((kernel::pci::Id(FPGA_PCI_VID_XILINX, FPGA_PCI_PID_VFPGA))); -std::list> PCIeCardFactory::make(json_t *json, std::shared_ptr pci, std::shared_ptr vc) +std::list> PCIeCardFactory::make(json_t *json, + std::shared_ptr pci, + std::shared_ptr vc, + const std::filesystem::path& searchPath) { std::list> cards; auto logger = getStaticLogger(); @@ -87,11 +90,19 @@ std::list> PCIeCardFactory::make(json_t *json, std::sh } // Load IPs from a separate json file - if (json_is_string(json_ips)) { - auto json_ips_fn = json_string_value(json_ips); - json_ips = json_load_file(json_ips_fn, 0, nullptr); - if (json_ips == nullptr) - throw ConfigError(json_ips, "node-config-fpga-ips", "Failed to load FPGA IP cores from {}", json_ips_fn); + if (json_is_string(json_ips) && !searchPath.empty()) { + std::filesystem::path json_ips_path = searchPath / json_string_value(json_ips); + json_ips = json_load_file(json_ips_path.c_str(), 0, nullptr); + if (json_ips == nullptr) { + logger->debug("FPGA IP cores config not found in {} looking elsewhere...", json_ips_path); + } + } + if (json_is_string(json_ips) && json_ips == nullptr) { + json_ips = json_load_file(json_string_value(json_ips), 0, nullptr); + if (json_ips == nullptr) { + logger->debug("FPGA IP cores config not found in {}", json_string_value(json_ips)); + throw ConfigError(json_ips, "node-config-fpga-ips", "Failed to find FPGA IP cores config"); + } } if (not json_is_object(json_ips)) diff --git a/fpga/lib/utils.cpp b/fpga/lib/utils.cpp index 763a68739..11e786797 100644 --- a/fpga/lib/utils.cpp +++ b/fpga/lib/utils.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -168,6 +169,7 @@ fpga::setupFpgaCard(const std::string &configFile, const std::string &fpgaName) pciDevices = std::make_shared(); auto vfioContainer = std::make_shared(); + auto configDir = std::filesystem::path(configFile).parent_path(); // Parse FPGA configuration FILE* f = fopen(configFile.c_str(), "r"); From d273162f719da1190399a14f97108d76a951fa62 Mon Sep 17 00:00:00 2001 From: Niklas Eiling Date: Tue, 21 Mar 2023 11:29:32 +0100 Subject: [PATCH 09/12] fix PCIeCardFactory looking for IP config file at the wrong location Signed-off-by: Niklas Eiling --- fpga/etc/fpgas.json | 2 +- fpga/lib/pcie_card.cpp | 18 ++++++++++-------- fpga/lib/utils.cpp | 2 +- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/fpga/etc/fpgas.json b/fpga/etc/fpgas.json index c5c471d49..0527e0dc0 100644 --- a/fpga/etc/fpgas.json +++ b/fpga/etc/fpgas.json @@ -4,7 +4,7 @@ "id": "10ee:7021", "slot": "0000:88:00.0", "do_reset": true, - "ips": "etc/vc707-xbar-pcie/vc707-xbar-pcie.json", + "ips": "vc707-xbar-pcie/vc707-xbar-pcie.json", "polling": false } } diff --git a/fpga/lib/pcie_card.cpp b/fpga/lib/pcie_card.cpp index 2df19dd0d..84cedbac1 100644 --- a/fpga/lib/pcie_card.cpp +++ b/fpga/lib/pcie_card.cpp @@ -90,17 +90,19 @@ std::list> PCIeCardFactory::make(json_t *json, } // Load IPs from a separate json file - if (json_is_string(json_ips) && !searchPath.empty()) { - std::filesystem::path json_ips_path = searchPath / json_string_value(json_ips); - json_ips = json_load_file(json_ips_path.c_str(), 0, nullptr); - if (json_ips == nullptr) { - logger->debug("FPGA IP cores config not found in {} looking elsewhere...", json_ips_path); - } + if (!json_is_string(json_ips)) { + logger->debug("FPGA IP cores config item is not a string."); + throw ConfigError(json_ips, "node-config-fpga-ips", "FPGA IP cores config item is not a string."); } - if (json_is_string(json_ips) && json_ips == nullptr) { + if (!searchPath.empty()) { + std::filesystem::path json_ips_path = searchPath / json_string_value(json_ips); + logger->debug("searching for FPGA IP cors config at {}", json_ips_path); + json_ips = json_load_file(json_ips_path.c_str(), 0, nullptr); + } + if (json_ips == nullptr) { json_ips = json_load_file(json_string_value(json_ips), 0, nullptr); + logger->debug("searching for FPGA IP cors config at {}", json_string_value(json_ips)); if (json_ips == nullptr) { - logger->debug("FPGA IP cores config not found in {}", json_string_value(json_ips)); throw ConfigError(json_ips, "node-config-fpga-ips", "Failed to find FPGA IP cores config"); } } diff --git a/fpga/lib/utils.cpp b/fpga/lib/utils.cpp index 11e786797..c8b45eb75 100644 --- a/fpga/lib/utils.cpp +++ b/fpga/lib/utils.cpp @@ -199,7 +199,7 @@ fpga::setupFpgaCard(const std::string &configFile, const std::string &fpgaName) } // Create all FPGA card instances using the corresponding plugin - auto cards = fpgaCardFactory->make(fpgas, pciDevices, vfioContainer); + auto cards = fpgaCardFactory->make(fpgas, pciDevices, vfioContainer, configDir); std::shared_ptr card; for (auto &fpgaCard : cards) { From 9d4cd5384dc7d9e245df62241268b739fa4e2236 Mon Sep 17 00:00:00 2001 From: Niklas Eiling Date: Tue, 21 Mar 2023 11:51:17 +0100 Subject: [PATCH 10/12] clean up debuggin output and fix scanf usage in villasfpga_dma.c Signed-off-by: Niklas Eiling --- fpga/.vscode/launch.json | 2 +- fpga/include/villas/fpga/villasfpga_dma.h | 1 + fpga/lib/villasfpga_dma.cpp | 8 +++++++- fpga/tests/unit/villasfpga_dma.c | 25 ++++++++++++++++------- 4 files changed, 27 insertions(+), 9 deletions(-) diff --git a/fpga/.vscode/launch.json b/fpga/.vscode/launch.json index 2e3dcbd26..1bce5a80d 100644 --- a/fpga/.vscode/launch.json +++ b/fpga/.vscode/launch.json @@ -10,7 +10,7 @@ "request": "launch", "program": "${workspaceFolder}/build/src/villas-fpga-ctrl", "args": [ - "-c", "${workspaceFolder}/etc/fpgas.json", "--connect", "\"4<->stdout\"" + "-c", "${workspaceFolder}/etc/fpgas.json", "--connect", "\"2<->stdout\"" ], "stopAtEntry": false, "cwd": "${workspaceFolder}", diff --git a/fpga/include/villas/fpga/villasfpga_dma.h b/fpga/include/villas/fpga/villasfpga_dma.h index f6491ddd8..dec2f5992 100644 --- a/fpga/include/villas/fpga/villasfpga_dma.h +++ b/fpga/include/villas/fpga/villasfpga_dma.h @@ -24,6 +24,7 @@ void villasfpga_destroy(villasfpga_handle handle); int villasfpga_alloc(villasfpga_handle handle, villasfpga_memory *mem, size_t size); int villasfpga_register(villasfpga_handle handle, villasfpga_memory *mem); int villasfpga_free(villasfpga_memory mem); +void* villasfpga_get_ptr(villasfpga_memory mem); int villasfpga_read(villasfpga_handle handle, villasfpga_memory mem, size_t size); int villasfpga_read_complete(villasfpga_handle handle, size_t *size); diff --git a/fpga/lib/villasfpga_dma.cpp b/fpga/lib/villasfpga_dma.cpp index 872813c59..a1e6324b6 100644 --- a/fpga/lib/villasfpga_dma.cpp +++ b/fpga/lib/villasfpga_dma.cpp @@ -158,7 +158,7 @@ int villasfpga_read_complete(villasfpga_handle handle, size_t *size) { try { auto readComp = handle->dma->readComplete(); - logger->debug("Wrote {} bytes", readComp.bytes); + logger->debug("Read {} bytes", readComp.bytes); *size = readComp.bytes; return 0; } catch (const RuntimeError &e) { @@ -193,3 +193,9 @@ int villasfpga_write_complete(villasfpga_handle handle, size_t *size) return -1; } } + +void* villasfpga_get_ptr(villasfpga_memory mem) +{ + return (void*)MemoryManager::get().getTranslationFromProcess(mem->block->getAddrSpaceId()).getLocalAddr(0); +} + diff --git a/fpga/tests/unit/villasfpga_dma.c b/fpga/tests/unit/villasfpga_dma.c index cfb70e3e7..427f1f0a6 100644 --- a/fpga/tests/unit/villasfpga_dma.c +++ b/fpga/tests/unit/villasfpga_dma.c @@ -9,6 +9,7 @@ int main(int argc, char *argv[]) int ret; villasfpga_handle vh; villasfpga_memory mem1, mem2; + void *mem1ptr, *mem2ptr; char line[1024]; float f; size_t size; @@ -35,6 +36,20 @@ int main(int argc, char *argv[]) goto out; } + if ((mem1ptr = villasfpga_get_ptr(mem1)) == NULL) { + fprintf(stderr, "Failed to get pointer to DMA memory 1\n"); + ret = 1; + goto out; + } + + if ((mem2ptr = villasfpga_get_ptr(mem2)) == NULL) { + fprintf(stderr, "Failed to get pointer to DMA memory 2\n"); + ret = 1; + goto out; + } + + printf("DMA memory 1: %p, DMA memory 2: %p\n", mem1ptr, mem2ptr); + while (1) { // Setup read transfer if ((ret = villasfpga_read(vh, mem1, 0x200 * sizeof(uint32_t))) != 0) { @@ -44,14 +59,12 @@ int main(int argc, char *argv[]) } printf("Enter a float:\n"); - if ((ret = sscanf(line, "%f")) != 1) { + if ((ret = scanf("%f", mem2ptr)) != 1) { fprintf(stderr, "Failed to parse input: sscanf returned %d\n", ret); ret = 1; goto out; } - - ((float*)mem2)[0] = atof(line); - printf("Read %f\n", ((float*)mem2)[0]); + printf("sending %f (%zu bytes)\n", ((float*)mem2ptr)[0], sizeof(float)); // Initiate write transfer if ((ret = villasfpga_write(vh, mem2, sizeof(float))) != 0) { fprintf(stderr, "Failed to initiate write transfer\n"); @@ -64,16 +77,14 @@ int main(int argc, char *argv[]) ret = 1; goto out; } - printf("Wrote %zu bytes", size); if ((ret = villasfpga_read_complete(vh, &size)) != 0) { fprintf(stderr, "Failed to write complete\n"); ret = 1; goto out; } - printf("Read %zu bytes", size); - printf("Read %f\n", ((float*)mem1)[0]); + printf("Read %f (%zu bytes)\n", ((float*)mem1ptr)[0], size); } ret = 0; From 1d9ccd6c0564db97222a6e20f26237de873a664a Mon Sep 17 00:00:00 2001 From: Niklas Eiling Date: Tue, 21 Mar 2023 11:59:22 +0100 Subject: [PATCH 11/12] add license note to villasfpga_dma.c Signed-off-by: Niklas Eiling --- fpga/tests/unit/villasfpga_dma.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/fpga/tests/unit/villasfpga_dma.c b/fpga/tests/unit/villasfpga_dma.c index 427f1f0a6..85d14ee18 100644 --- a/fpga/tests/unit/villasfpga_dma.c +++ b/fpga/tests/unit/villasfpga_dma.c @@ -1,3 +1,10 @@ +/** Testing the C bindings for the VILLASfpga DMA interface. + * + * Author: Niklas Eiling + * SPDX-FileCopyrightText: 2023 Niklas Eiling + * SPDX-License-Identifier: Apache-2.0 + *********************************************************************************/ + #include #include #include From d9993409e0aba73d34daaa64ac4078fb9aeabb3b Mon Sep 17 00:00:00 2001 From: Niklas Eiling Date: Tue, 21 Mar 2023 12:26:13 +0100 Subject: [PATCH 12/12] fix possible NULL dereferencing in villasfpga_dma.c Signed-off-by: Niklas Eiling --- fpga/include/villas/fpga/{villasfpga_dma.h => dma.h} | 0 fpga/lib/CMakeLists.txt | 2 +- fpga/lib/{villasfpga_dma.cpp => dma.cpp} | 2 +- fpga/tests/unit/CMakeLists.txt | 2 +- fpga/tests/unit/{villasfpga_dma.c => dma.c} | 9 ++++++--- 5 files changed, 9 insertions(+), 6 deletions(-) rename fpga/include/villas/fpga/{villasfpga_dma.h => dma.h} (100%) rename fpga/lib/{villasfpga_dma.cpp => dma.cpp} (99%) rename fpga/tests/unit/{villasfpga_dma.c => dma.c} (93%) diff --git a/fpga/include/villas/fpga/villasfpga_dma.h b/fpga/include/villas/fpga/dma.h similarity index 100% rename from fpga/include/villas/fpga/villasfpga_dma.h rename to fpga/include/villas/fpga/dma.h diff --git a/fpga/lib/CMakeLists.txt b/fpga/lib/CMakeLists.txt index 148d77867..f32da84a7 100644 --- a/fpga/lib/CMakeLists.txt +++ b/fpga/lib/CMakeLists.txt @@ -12,7 +12,7 @@ set(SOURCES core.cpp node.cpp utils.cpp - villasfpga_dma.cpp + dma.cpp ips/aurora_xilinx.cpp ips/aurora.cpp diff --git a/fpga/lib/villasfpga_dma.cpp b/fpga/lib/dma.cpp similarity index 99% rename from fpga/lib/villasfpga_dma.cpp rename to fpga/lib/dma.cpp index a1e6324b6..67014d67c 100644 --- a/fpga/lib/villasfpga_dma.cpp +++ b/fpga/lib/dma.cpp @@ -5,7 +5,7 @@ * SPDX-License-Identifier: Apache-2.0 *********************************************************************************/ -#include +#include #include #include diff --git a/fpga/tests/unit/CMakeLists.txt b/fpga/tests/unit/CMakeLists.txt index 454525714..6185b2e6d 100644 --- a/fpga/tests/unit/CMakeLists.txt +++ b/fpga/tests/unit/CMakeLists.txt @@ -37,7 +37,7 @@ target_link_libraries(unit-tests-fpga PUBLIC ${CRITERION_LIBRARIES} ) -add_executable(villasfpga-dma villasfpga_dma.c) +add_executable(villasfpga-dma dma.c) target_include_directories(villasfpga-dma PUBLIC ../include diff --git a/fpga/tests/unit/villasfpga_dma.c b/fpga/tests/unit/dma.c similarity index 93% rename from fpga/tests/unit/villasfpga_dma.c rename to fpga/tests/unit/dma.c index 85d14ee18..5aede35c8 100644 --- a/fpga/tests/unit/villasfpga_dma.c +++ b/fpga/tests/unit/dma.c @@ -9,7 +9,7 @@ #include #include -#include +#include int main(int argc, char *argv[]) { @@ -21,7 +21,10 @@ int main(int argc, char *argv[]) float f; size_t size; - if (argc != 2 && argv != NULL) { + if (argv == NULL) { + return 1; + } + if (argc != 2 || argv[1] == NULL) { fprintf(stderr, "Usage: %s \n", argv[0]); } @@ -66,7 +69,7 @@ int main(int argc, char *argv[]) } printf("Enter a float:\n"); - if ((ret = scanf("%f", mem2ptr)) != 1) { + if ((ret = scanf("%f", (float*)mem2ptr)) != 1) { fprintf(stderr, "Failed to parse input: sscanf returned %d\n", ret); ret = 1; goto out;