diff --git a/fpga/tests/CMakeLists.txt b/fpga/tests/CMakeLists.txt index 843c1b6a6..2e4cfe041 100644 --- a/fpga/tests/CMakeLists.txt +++ b/fpga/tests/CMakeLists.txt @@ -2,7 +2,7 @@ set(SOURCES main.cpp fpga.cpp logging.cpp -# dma.c + dma.cpp fifo.cpp # hls.c # intc.c diff --git a/fpga/tests/dma.cpp b/fpga/tests/dma.cpp new file mode 100644 index 000000000..fd69cfc94 --- /dev/null +++ b/fpga/tests/dma.cpp @@ -0,0 +1,63 @@ +#include + +#include +#include +#include + +#include + +#include "global.hpp" + +#include + + +Test(fpga, dma, .description = "DMA") +{ + auto logger = loggerGetOrCreate("unittest:dma"); + + size_t count = 0; + for(auto& ip : state.cards.front()->ips) { + // skip non-dma IPs + if(*ip != villas::fpga::Vlnv("xilinx.com:ip:axi_dma:")) + continue; + + logger->info("Testing {}", *ip); + + auto dma = reinterpret_cast(*ip); + + if(not dma.connectLoopback()) { + continue; + } + + count++; + + if(not dma.loopbackPossible()) { + logger->info("Loopback test not possible for {}", *ip); + continue; + } + + // Simple DMA can only transfer up to 4 kb due to PCIe page size burst + // limitation + size_t len = 4 * (1 << 10); + + /* Allocate memory to use with DMA */ + auto src = villas::HostRam::allocate(len); + auto dst = villas::HostRam::allocate(len); + + /* Get new random data */ + const size_t lenRandom = read_random(&src, len); + cr_assert(len == lenRandom, "Failed to get random data"); + + /* Start transfer */ + cr_assert(dma.pingPong(src, dst, len), "DMA ping pong failed"); + + /* Compare data */ + cr_assert(memcmp(&src, &dst, len) == 0, "Data not equal"); + + logger->info(TXT_GREEN("Passed")); + } + + villas::MemoryManager::get().dump(); + + cr_assert(count > 0, "No Dma found"); +}