Commit 9164efa3 authored by Daniel Krebs's avatar Daniel Krebs

ips/bram: add block RAM IP and use it with DMA test

parent 20af87d5
Pipeline #44257 failed with stages
in 1 minute and 34 seconds
/** Block-Raam related helper functions
* *
* @author Daniel Krebs <github@daniel-krebs.net>
* @copyright 2018, Daniel Krebs
* @license GNU General Public License (version 3)
*
* VILLASfpga
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*********************************************************************************/
/** @addtogroup fpga VILLASfpga
* @{
*/
#pragma once
#include "memory.hpp"
#include "fpga/ip.hpp"
namespace villas {
namespace fpga {
namespace ip {
class Bram : public IpCore
{
friend class BramFactory;
public:
bool init();
LinearAllocator&
getAllocator()
{ return *allocator; }
private:
static constexpr const char* memoryBlock = "Mem0";
std::list<MemoryBlockName> getMemoryBlocks() const
{ return { memoryBlock }; }
size_t size;
std::unique_ptr<LinearAllocator> allocator;
};
class BramFactory : public IpCoreFactory {
public:
BramFactory() :
IpCoreFactory(getName())
{}
bool configureJson(IpCore& ip, json_t *json_ip);
IpCore* create()
{ return new Bram; }
std::string
getName() const
{ return "Bram"; }
std::string
getDescription() const
{ return "Block RAM"; }
Vlnv getCompatibleVlnv() const
{ return {"xilinx.com:ip:axi_bram_ctrl:"}; }
};
} // namespace ip
} // namespace fpga
} // namespace villas
/** @} */
......@@ -10,6 +10,7 @@ set(SOURCES
ips/intc.cpp
ips/pcie.cpp
ips/dma.cpp
ips/bram.cpp
kernel/kernel.c
kernel/pci.c
......
#include "fpga/ips/bram.hpp"
namespace villas {
namespace fpga {
namespace ip {
static BramFactory factory;
bool
BramFactory::configureJson(IpCore& ip, json_t* json_ip)
{
auto& bram = reinterpret_cast<Bram&>(ip);
if(json_unpack(json_ip, "{ s: i }", "size", &bram.size) != 0) {
getLogger()->error("Cannot parse 'size'");
return false;
}
return true;
}
bool Bram::init()
{
allocator = std::make_unique<LinearAllocator>
(getAddressSpaceId(memoryBlock), this->size, 0);
return true;
}
} // namespace ip
} // namespace fpga
} // namespace villas
......@@ -3,6 +3,7 @@
#include <villas/log.hpp>
#include <villas/fpga/card.hpp>
#include <villas/fpga/ips/dma.hpp>
#include <villas/fpga/ips/bram.hpp>
#include <villas/utils.h>
......@@ -36,13 +37,18 @@ Test(fpga, dma, .description = "DMA")
continue;
}
// find a block RAM IP to write to
auto bramIp = state.cards.front()->lookupIp(villas::fpga::Vlnv("xilinx.com:ip:axi_bram_ctrl:"));
auto bram = reinterpret_cast<villas::fpga::ip::Bram*>(bramIp);
cr_assert_not_null(bram, "Couldn't find BRAM");
// 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::getAllocator().allocate<char>(len);
auto dst = villas::HostRam::getAllocator().allocate<char>(len);
auto dst = bram->getAllocator().allocate<char>(len);
/* Get new random data */
const size_t lenRandom = read_random(&src, len);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment