mirror of
https://git.rwth-aachen.de/acs/public/villas/node/
synced 2025-03-09 00:00:00 +01:00
cleanup of comments
This commit is contained in:
parent
5c68a22ffe
commit
fb824a82f9
51 changed files with 377 additions and 394 deletions
|
@ -10,7 +10,7 @@ insert_final_newline = true
|
|||
|
||||
# Matches multiple files with brace expansion notation
|
||||
# Set default charset
|
||||
[{etc,include,lib,plugins,src,tests,tools}/**.{c,h}]
|
||||
[**.{c,h,cpp,hpp}]
|
||||
charset = utf-8
|
||||
indent_style = tab
|
||||
indent_size = 8
|
||||
|
|
|
@ -51,7 +51,7 @@ public:
|
|||
|
||||
bool makeAccessibleToPCIeAndVA(const MemoryBlock &mem);
|
||||
|
||||
/// Make some memory block accssible for this GPU
|
||||
// Make some memory block accssible for this GPU
|
||||
bool makeAccessibleFromPCIeOrHostRam(const MemoryBlock &mem);
|
||||
|
||||
void memcpySync(const MemoryBlock &src, const MemoryBlock &dst, size_t size);
|
||||
|
@ -69,7 +69,7 @@ private:
|
|||
class impl;
|
||||
std::unique_ptr<impl> pImpl;
|
||||
|
||||
// master, will be used to derived slave addr spaces for allocation
|
||||
// Master, will be used to derived slave addr spaces for allocation
|
||||
MemoryManager::AddressSpaceId masterPciEAddrSpaceId;
|
||||
|
||||
MemoryManager::AddressSpaceId slaveMemoryAddrSpaceId;
|
||||
|
|
|
@ -74,7 +74,7 @@ GpuFactory::GpuFactory() :
|
|||
logger = villas::logging.get("gpu:factory");
|
||||
}
|
||||
|
||||
// required to be defined here for PIMPL to compile
|
||||
// Required to be defined here for PIMPL to compile
|
||||
Gpu::~Gpu()
|
||||
{
|
||||
auto &mm = MemoryManager::get();
|
||||
|
@ -82,7 +82,7 @@ Gpu::~Gpu()
|
|||
}
|
||||
|
||||
|
||||
// we use PIMPL in order to hide gdrcopy types from the public header
|
||||
// We use PIMPL in order to hide gdrcopy types from the public header
|
||||
class Gpu::impl {
|
||||
public:
|
||||
gdr_t gdr;
|
||||
|
@ -93,7 +93,7 @@ std::string Gpu::getName() const
|
|||
{
|
||||
cudaDeviceProp deviceProp;
|
||||
if (cudaGetDeviceProperties(&deviceProp, gpuId) != cudaSuccess) {
|
||||
// logger not yet availabe
|
||||
// Logger not yet availabe
|
||||
villas::logging.get("gpu")->error("Cannot retrieve properties for GPU {}", gpuId);
|
||||
throw std::exception();
|
||||
}
|
||||
|
@ -116,13 +116,13 @@ bool Gpu::registerIoMemory(const MemoryBlock &mem)
|
|||
auto translation = mm.getTranslation(masterPciEAddrSpaceId,
|
||||
mem.getAddrSpaceId());
|
||||
if (translation.getSize() >= mem.getSize())
|
||||
// there is already a sufficient path
|
||||
// There is already a sufficient path
|
||||
logger->debug("Already mapped through another mapping");
|
||||
return true;
|
||||
else
|
||||
else
|
||||
logger->warn("There's already a mapping, but too small");
|
||||
} catch (const std::out_of_range&) {
|
||||
// not yet reachable, that's okay, proceed
|
||||
// Not yet reachable, that's okay, proceed
|
||||
}
|
||||
|
||||
|
||||
|
@ -131,7 +131,7 @@ bool Gpu::registerIoMemory(const MemoryBlock &mem)
|
|||
MemoryManager::AddressSpaceId mappedBaseAddrSpaceId;
|
||||
try {
|
||||
auto path = mm.findPath(mm.getProcessAddressSpace(), mem.getAddrSpaceId());
|
||||
// first node in path is the mapped memory space whose virtual address
|
||||
// First node in path is the mapped memory space whose virtual address
|
||||
// we need to hand to CUDA
|
||||
mappedBaseAddrSpaceId = path.front();
|
||||
} catch (const std::out_of_range&) {
|
||||
|
@ -139,7 +139,7 @@ bool Gpu::registerIoMemory(const MemoryBlock &mem)
|
|||
return false;
|
||||
}
|
||||
|
||||
// determine the base address of the mapped memory region needed by CUDA
|
||||
// Determine the base address of the mapped memory region needed by CUDA
|
||||
const auto translationProcess = mm.getTranslationFromProcess(mappedBaseAddrSpaceId);
|
||||
const uintptr_t baseAddrForProcess = translationProcess.getLocalAddr(0);
|
||||
|
||||
|
@ -224,10 +224,9 @@ bool Gpu::makeAccessibleToPCIeAndVA(const MemoryBlock &mem)
|
|||
|
||||
try {
|
||||
auto path = mm.findPath(masterPciEAddrSpaceId, mem.getAddrSpaceId());
|
||||
// if first hop is the PCIe bus, we know that memory is off-GPU
|
||||
if (path.front() == mm.getPciAddressSpace()) {
|
||||
// If first hop is the PCIe bus, we know that memory is off-GPU
|
||||
if (path.front() == mm.getPciAddressSpace())
|
||||
throw std::out_of_range("Memory block is outside of this GPU");
|
||||
}
|
||||
|
||||
} catch (const std::out_of_range&) {
|
||||
logger->error("Trying to map non-GPU memory block");
|
||||
|
@ -235,14 +234,15 @@ bool Gpu::makeAccessibleToPCIeAndVA(const MemoryBlock &mem)
|
|||
}
|
||||
|
||||
logger->debug("retrieve complete device pointer from point of view of GPU");
|
||||
// retrieve complete device pointer from point of view of GPU
|
||||
|
||||
// Retrieve complete device pointer from point of view of GPU
|
||||
auto translation = mm.getTranslation(masterPciEAddrSpaceId,
|
||||
mem.getAddrSpaceId());
|
||||
CUdeviceptr devptr = translation.getLocalAddr(0);
|
||||
|
||||
int ret;
|
||||
|
||||
// required to set this flag before mapping
|
||||
// Required to set this flag before mapping
|
||||
unsigned int enable = 1;
|
||||
ret = cuPointerSetAttribute(&enable, CU_POINTER_ATTRIBUTE_SYNC_MEMOPS, devptr);
|
||||
if (ret != CUDA_SUCCESS) {
|
||||
|
@ -285,24 +285,23 @@ bool Gpu::makeAccessibleToPCIeAndVA(const MemoryBlock &mem)
|
|||
logger->debug("offset: {:#x}", offset);
|
||||
logger->debug("user pointer: {:#x}", userPtr);
|
||||
|
||||
// mapping to acceses memory block from process
|
||||
// Mapping to acceses memory block from process
|
||||
mm.createMapping(userPtr, 0, info.mapped_size, "GDRcopy",
|
||||
mm.getProcessAddressSpace(), mem.getAddrSpaceId());
|
||||
|
||||
// retrieve bus address
|
||||
// Retrieve bus address
|
||||
uint64_t addr[8];
|
||||
ret = gdr_map_dma(pImpl->gdr, mh, 3, 0, 0, addr, 8);
|
||||
|
||||
for (int i = 0; i < ret; i++) {
|
||||
for (int i = 0; i < ret; i++)
|
||||
logger->debug("DMA addr[{}]: {:#x}", i, addr[i]);
|
||||
}
|
||||
|
||||
if (ret != 1) {
|
||||
logger->error("Only one DMA address per block supported at the moment");
|
||||
return false;
|
||||
}
|
||||
|
||||
// mapping to access memory block from peer devices via PCIe
|
||||
// Mapping to access memory block from peer devices via PCIe
|
||||
mm.createMapping(addr[0], 0, mem.getSize(), "GDRcopyDMA",
|
||||
mm.getPciAddressSpace(), mem.getAddrSpaceId());
|
||||
|
||||
|
@ -324,7 +323,7 @@ Gpu::makeAccessibleFromPCIeOrHostRam(const MemoryBlock &mem)
|
|||
auto path = mm.findPath(mm.getPciAddressSpace(), mem.getAddrSpaceId());
|
||||
isIoMemory = true;
|
||||
} catch (const std::out_of_range&) {
|
||||
// not reachable via PCI -> not IO memory
|
||||
// Not reachable via PCI -> not IO memory
|
||||
}
|
||||
|
||||
if (isIoMemory) {
|
||||
|
@ -390,7 +389,7 @@ GpuAllocator::allocateBlock(size_t size)
|
|||
void* addr;
|
||||
auto &mm = MemoryManager::get();
|
||||
|
||||
// search for an existing chunk that has enough free memory
|
||||
// Search for an existing chunk that has enough free memory
|
||||
auto chunk = std::find_if(chunks.begin(), chunks.end(), [&](const auto &chunk) {
|
||||
return chunk->getAvailableMemory() >= size;
|
||||
});
|
||||
|
@ -402,9 +401,9 @@ GpuAllocator::allocateBlock(size_t size)
|
|||
return (*chunk)->allocateBlock(size);
|
||||
}
|
||||
else {
|
||||
// allocate a new chunk
|
||||
// Allocate a new chunk
|
||||
|
||||
// rounded-up multiple of GPU page size
|
||||
// Rounded-up multiple of GPU page size
|
||||
const size_t chunkSize = size - (size & (GpuPageSize - 1)) + GpuPageSize;
|
||||
logger->debug("Allocate new chunk of {:#x} bytes", chunkSize);
|
||||
|
||||
|
@ -413,7 +412,7 @@ GpuAllocator::allocateBlock(size_t size)
|
|||
throw std::bad_alloc();
|
||||
}
|
||||
|
||||
// assemble name for this block
|
||||
// Assemble name for this block
|
||||
std::stringstream name;
|
||||
name << std::showbase << std::hex << reinterpret_cast<uintptr_t>(addr);
|
||||
|
||||
|
@ -426,13 +425,13 @@ GpuAllocator::allocateBlock(size_t size)
|
|||
|
||||
insertMemoryBlock(*mem);
|
||||
|
||||
// already make accessible to CPU
|
||||
// Already make accessible to CPU
|
||||
gpu.makeAccessibleToPCIeAndVA(*mem);
|
||||
|
||||
// create a new allocator to manage the chunk and push to chunk list
|
||||
// Create a new allocator to manage the chunk and push to chunk list
|
||||
chunks.push_front(std::make_unique<LinearAllocator>(std::move(mem)));
|
||||
|
||||
// call again, this time there's a large enough chunk
|
||||
// Call again, this time there's a large enough chunk
|
||||
return allocateBlock(size);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
namespace villas {
|
||||
namespace fpga {
|
||||
|
||||
/* Forward declarations */
|
||||
// Forward declarations
|
||||
struct vfio_container;
|
||||
class PCIeCardFactory;
|
||||
|
||||
|
@ -74,10 +74,10 @@ public:
|
|||
|
||||
ip::Core::Ptr
|
||||
lookupIp(const std::string &name) const;
|
||||
|
||||
|
||||
ip::Core::Ptr
|
||||
lookupIp(const Vlnv &vlnv) const;
|
||||
|
||||
|
||||
ip::Core::Ptr
|
||||
lookupIp(const ip::IpIdentifier &id) const;
|
||||
|
||||
|
@ -86,30 +86,30 @@ public:
|
|||
mapMemoryBlock(const MemoryBlock &block);
|
||||
|
||||
private:
|
||||
/// Cache a set of already mapped memory blocks
|
||||
// Cache a set of already mapped memory blocks
|
||||
std::set<MemoryManager::AddressSpaceId> memoryBlocksMapped;
|
||||
|
||||
public: // TODO: make this private
|
||||
ip::Core::List ips; ///< IPs located on this FPGA card
|
||||
ip::Core::List ips; // IPs located on this FPGA card
|
||||
|
||||
bool doReset; /**< Reset VILLASfpga during startup? */
|
||||
int affinity; /**< Affinity for MSI interrupts */
|
||||
bool doReset; // Reset VILLASfpga during startup?
|
||||
int affinity; // Affinity for MSI interrupts
|
||||
|
||||
std::string name; /**< The name of the FPGA card */
|
||||
std::string name; // The name of the FPGA card
|
||||
|
||||
std::shared_ptr<kernel::pci::Device> pdev; /**< PCI device handle */
|
||||
std::shared_ptr<kernel::pci::Device> pdev; // PCI device handle
|
||||
|
||||
/// The VFIO container that this card is part of
|
||||
// The VFIO container that this card is part of
|
||||
std::shared_ptr<kernel::vfio::Container> vfioContainer;
|
||||
|
||||
/// The VFIO device that represents this card
|
||||
// The VFIO device that represents this card
|
||||
kernel::vfio::Device* vfioDevice;
|
||||
|
||||
/// Slave address space ID to access the PCIe address space from the FPGA
|
||||
// Slave address space ID to access the PCIe address space from the FPGA
|
||||
MemoryManager::AddressSpaceId addrSpaceIdDeviceToHost;
|
||||
|
||||
/// Address space identifier of the master address space of this FPGA card.
|
||||
/// This will be used for address resolution of all IPs on this card.
|
||||
// Address space identifier of the master address space of this FPGA card.
|
||||
// This will be used for address resolution of all IPs on this card.
|
||||
MemoryManager::AddressSpaceId addrSpaceIdHostToDevice;
|
||||
|
||||
protected:
|
||||
|
@ -140,7 +140,7 @@ public:
|
|||
|
||||
virtual std::string
|
||||
getDescription() const
|
||||
{ return "Xilinx PCIe FPGA cards"; }
|
||||
{ return "Xilinx PCIe FPGA cards"; }
|
||||
|
||||
virtual
|
||||
std::string getType() const
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
/** PCIe BAR number of VILLASfpga registers */
|
||||
// PCIe BAR number of VILLASfpga registers
|
||||
#define FPGA_PCI_BAR 0
|
||||
#define FPGA_PCI_VID_XILINX 0x10ee
|
||||
#define FPGA_PCI_PID_VFPGA 0x7022
|
||||
|
|
|
@ -45,12 +45,12 @@
|
|||
namespace villas {
|
||||
namespace fpga {
|
||||
|
||||
// forward declaration
|
||||
// Forward declarations
|
||||
class PCIeCard;
|
||||
|
||||
namespace ip {
|
||||
|
||||
// forward declarations
|
||||
// Forward declarations
|
||||
class Core;
|
||||
class CoreFactory;
|
||||
class InterruptController;
|
||||
|
@ -108,29 +108,29 @@ public:
|
|||
using List = std::list<Core::Ptr>;
|
||||
|
||||
public:
|
||||
/* Generic management interface for IPs */
|
||||
// Generic management interface for IPs
|
||||
|
||||
/// Runtime setup of IP, should access and initialize hardware
|
||||
// Runtime setup of IP, should access and initialize hardware
|
||||
virtual bool init()
|
||||
{ return true; }
|
||||
|
||||
/// Runtime check of IP, should verify basic functionality
|
||||
// Runtime check of IP, should verify basic functionality
|
||||
virtual bool check() { return true; }
|
||||
|
||||
/// Generic disabling of IP, meaning may depend on IP
|
||||
// Generic disabling of IP, meaning may depend on IP
|
||||
virtual bool stop() { return true; }
|
||||
|
||||
/// Reset the IP, it should behave like freshly initialized afterwards
|
||||
// Reset the IP, it should behave like freshly initialized afterwards
|
||||
virtual bool reset() { return true; }
|
||||
|
||||
/// Print some debug information about the IP
|
||||
// Print some debug information about the IP
|
||||
virtual void dump();
|
||||
|
||||
protected:
|
||||
/// Key-type for accessing maps addressTranslations and slaveAddressSpaces
|
||||
// Key-type for accessing maps addressTranslations and slaveAddressSpaces
|
||||
using MemoryBlockName = std::string;
|
||||
|
||||
/// Each IP can declare via this function which memory blocks it requires
|
||||
// Each IP can declare via this function which memory blocks it requires
|
||||
virtual std::list<MemoryBlockName>
|
||||
getMemoryBlocks() const
|
||||
{ return {}; }
|
||||
|
@ -140,7 +140,7 @@ public:
|
|||
getInstanceName() const
|
||||
{ return id.getName(); }
|
||||
|
||||
/* Operators */
|
||||
// Operators
|
||||
|
||||
bool
|
||||
operator==(const Vlnv &otherVlnv) const
|
||||
|
@ -200,7 +200,7 @@ protected:
|
|||
template<typename T>
|
||||
T readMemory(const std::string &block, uintptr_t address) const
|
||||
{ return *(reinterpret_cast<T*>(getLocalAddr(block, address))); }
|
||||
|
||||
|
||||
template<typename T>
|
||||
void writeMemory(const std::string &block, uintptr_t address, T value)
|
||||
{ T* ptr = reinterpret_cast<T*>(getLocalAddr(block, address)); *ptr = value; }
|
||||
|
@ -212,25 +212,25 @@ protected:
|
|||
std::string description;
|
||||
};
|
||||
|
||||
/// Specialized logger instance with the IPs name set as category
|
||||
// Specialized logger instance with the IPs name set as category
|
||||
Logger logger;
|
||||
|
||||
/// FPGA card this IP is instantiated on (populated by FpgaIpFactory)
|
||||
// FPGA card this IP is instantiated on (populated by FpgaIpFactory)
|
||||
PCIeCard* card;
|
||||
|
||||
/// Identifier of this IP with its instance name and VLNV
|
||||
// Identifier of this IP with its instance name and VLNV
|
||||
IpIdentifier id;
|
||||
|
||||
/// All interrupts of this IP with their associated interrupt controller
|
||||
// All interrupts of this IP with their associated interrupt controller
|
||||
std::map<std::string, IrqPort> irqs;
|
||||
|
||||
/// Cached translations from the process address space to each memory block
|
||||
// Cached translations from the process address space to each memory block
|
||||
std::map<MemoryBlockName, MemoryTranslation> addressTranslations;
|
||||
|
||||
/// Lookup for IP's slave address spaces (= memory blocks)
|
||||
// Lookup for IP's slave address spaces (= memory blocks)
|
||||
std::map<MemoryBlockName, MemoryManager::AddressSpaceId> slaveAddressSpaces;
|
||||
|
||||
/// AXI bus master interfaces to access memory somewhere
|
||||
// AXI bus master interfaces to access memory somewhere
|
||||
std::map<std::string, MemoryManager::AddressSpaceId> busMasterInterfaces;
|
||||
};
|
||||
|
||||
|
@ -240,7 +240,7 @@ class CoreFactory : public plugin::Plugin {
|
|||
public:
|
||||
using plugin::Plugin::Plugin;
|
||||
|
||||
/// Returns a running and checked FPGA IP
|
||||
// Returns a running and checked FPGA IP
|
||||
static Core::List
|
||||
make(PCIeCard* card, json_t *json_ips);
|
||||
|
||||
|
@ -256,10 +256,10 @@ protected:
|
|||
{ return villas::logging.get(getName()); }
|
||||
|
||||
private:
|
||||
/// Create a concrete IP instance
|
||||
// Create a concrete IP instance
|
||||
virtual Core* create() = 0;
|
||||
|
||||
/// Configure IP instance from JSON config
|
||||
// Configure IP instance from JSON config
|
||||
virtual bool configureJson(Core& /* ip */, json_t* /* json */)
|
||||
{ return true; }
|
||||
|
||||
|
|
|
@ -29,13 +29,13 @@
|
|||
|
||||
#include <xilinx/xhls_dft.h>
|
||||
|
||||
/* Forward declaration */
|
||||
// Forward declaration
|
||||
struct ip;
|
||||
|
||||
struct dft {
|
||||
XHls_dft inst;
|
||||
|
||||
int period; /* in samples */
|
||||
int period; // in samples
|
||||
int num_harmonics;
|
||||
float *fharmonics;
|
||||
int decimation;
|
||||
|
|
|
@ -43,10 +43,10 @@ public:
|
|||
bool init();
|
||||
bool reset();
|
||||
|
||||
// memory-mapped to stream (MM2S)
|
||||
// Memory-mapped to stream (MM2S)
|
||||
bool write(const MemoryBlock &mem, size_t len);
|
||||
|
||||
// stream to memory-mapped (S2MM)
|
||||
// Stream to memory-mapped (S2MM)
|
||||
bool read(const MemoryBlock &mem, size_t len);
|
||||
|
||||
size_t writeComplete()
|
||||
|
@ -100,7 +100,7 @@ private:
|
|||
static constexpr char s2mmInterrupt[] = "s2mm_introut";
|
||||
static constexpr char s2mmInterface[] = "M_AXI_S2MM";
|
||||
|
||||
// optional Scatter-Gather interface to access descriptors
|
||||
// Optional Scatter-Gather interface to access descriptors
|
||||
static constexpr char sgInterface[] = "M_AXI_SG";
|
||||
|
||||
std::list<MemoryBlockName> getMemoryBlocks() const
|
||||
|
|
|
@ -66,9 +66,9 @@ public:
|
|||
{ return controlRegister->ap_ready; }
|
||||
|
||||
|
||||
/// Warning: the corresponding bit is cleared on read of the register, so if
|
||||
/// not used correctly, this function may never return true. Only use this
|
||||
/// function if you really know what you are doing!
|
||||
// Warning: the corresponding bit is cleared on read of the register, so if
|
||||
// not used correctly, this function may never return true. Only use this
|
||||
// function if you really know what you are doing!
|
||||
bool isDoneBit() const
|
||||
{ return controlRegister->ap_done; }
|
||||
|
||||
|
@ -84,7 +84,7 @@ private:
|
|||
}
|
||||
|
||||
protected:
|
||||
/* Memory block handling */
|
||||
// Memory block handling
|
||||
|
||||
static constexpr const char* registerMemory = "Reg";
|
||||
|
||||
|
@ -93,7 +93,7 @@ protected:
|
|||
|
||||
|
||||
public:
|
||||
/* Register definitions */
|
||||
// Register definitions
|
||||
|
||||
static constexpr uintptr_t registerControlAddr = 0x00;
|
||||
static constexpr uintptr_t registerGlobalIntEnableAddr = 0x04;
|
||||
|
|
|
@ -68,12 +68,12 @@ private:
|
|||
|
||||
|
||||
struct Interrupt {
|
||||
int eventFd; /**< Event file descriptor */
|
||||
int number; /**< Interrupt number from /proc/interrupts */
|
||||
bool polling; /**< Polled or not */
|
||||
int eventFd; // Event file descriptor
|
||||
int number; // Interrupt number from /proc/interrupts
|
||||
bool polling; // Polled or not
|
||||
};
|
||||
|
||||
int num_irqs; /**< Number of available MSI vectors */
|
||||
int num_irqs; // Number of available MSI vectors
|
||||
int efds[maxIrqs];
|
||||
int nos[maxIrqs];
|
||||
bool polling[maxIrqs];
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
#define XSG_MAPLEN 0x1000
|
||||
#define XSG_MAGIC 0xDEADBABE
|
||||
|
||||
/* Forward declaration */
|
||||
// Forward declaration
|
||||
struct ip;
|
||||
|
||||
enum model_type {
|
||||
|
@ -79,14 +79,14 @@ struct hls_model {
|
|||
};
|
||||
|
||||
struct model {
|
||||
enum model_type type; /**< Either HLS or XSG model */
|
||||
enum model_type type; // Either HLS or XSG model
|
||||
|
||||
struct list parameters; /**< List of model parameters. */
|
||||
struct list infos; /**< A list of key / value pairs with model details */
|
||||
struct list parameters; // List of model parameters.
|
||||
struct list infos; // A list of key / value pairs with model details
|
||||
|
||||
union {
|
||||
struct xsg_model xsg; /**< XSG specific model data */
|
||||
struct hls_model hls; /**< HLS specific model data */
|
||||
struct xsg_model xsg; // XSG specific model data
|
||||
struct hls_model hls; // HLS specific model data
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -96,35 +96,41 @@ struct model_info {
|
|||
};
|
||||
|
||||
struct model_parameter {
|
||||
char *name; /**< Name of the parameter */
|
||||
// Name of the parameter
|
||||
char *name;
|
||||
|
||||
enum model_parameter_direction direction; /**< Read / Write / Read-write? */
|
||||
enum model_parameter_type type; /**< Data type. Integers are represented by MODEL_GW_TYPE_(U)FIX with model_gw::binpt == 0 */
|
||||
// Read / Write / Read-write?
|
||||
enum model_parameter_direction direction;
|
||||
// Data type. Integers are represented by MODEL_GW_TYPE_(U)FIX with model_gw::binpt == 0
|
||||
enum model_parameter_type type;
|
||||
|
||||
int binpt; /**< Binary point for type == MODEL_GW_TYPE_(U)FIX */
|
||||
uintptr_t offset; /**< Register offset to model::baseaddress */
|
||||
// Binary point for type == MODEL_GW_TYPE_(U)FIX
|
||||
int binpt;
|
||||
// Register offset to model::baseaddress
|
||||
uintptr_t offset;
|
||||
|
||||
union model_parameter_value default_value;
|
||||
|
||||
struct fpga_ip *ip; /**< A pointer to the model structure to which this parameters belongs to. */
|
||||
// A pointer to the model structure to which this parameters belongs to.
|
||||
struct fpga_ip *ip;
|
||||
};
|
||||
|
||||
/** Initialize a model */
|
||||
// Initialize a model
|
||||
int model_init(struct fpga_ip *c);
|
||||
|
||||
/** Parse model */
|
||||
// Parse model
|
||||
int model_parse(struct fpga_ip *c, json_t *cfg);
|
||||
|
||||
/** Destroy a model */
|
||||
// Destroy a model
|
||||
int model_destroy(struct fpga_ip *c);
|
||||
|
||||
/** Print detailed information about the model to the screen. */
|
||||
// Print detailed information about the model to the screen.
|
||||
void model_dump(struct fpga_ip *c);
|
||||
|
||||
/** Add a new parameter to the model */
|
||||
// Add a new parameter to the model
|
||||
void model_parameter_add(struct fpga_ip *c, const char *name, enum model_parameter_direction dir, enum model_parameter_type type);
|
||||
|
||||
/** Remove an existing parameter by its name */
|
||||
// Remove an existing parameter by its name
|
||||
int model_parameter_remove(struct fpga_ip *c, const char *name);
|
||||
|
||||
/** Read a model parameter.
|
||||
|
|
|
@ -32,7 +32,7 @@ union reg_doorbell_t {
|
|||
|
||||
template<size_t N, typename T = uint32_t>
|
||||
struct Rtds2GpuMemoryBuffer {
|
||||
// this type is only for memory interpretation, it makes no sense to create
|
||||
// This type is only for memory interpretation, it makes no sense to create
|
||||
// an instance so it's forbidden
|
||||
Rtds2GpuMemoryBuffer() = delete;
|
||||
|
||||
|
|
|
@ -76,7 +76,7 @@ public:
|
|||
return vertex;
|
||||
}
|
||||
|
||||
// vertex not found, create new one
|
||||
// Vertex not found, create new one
|
||||
auto vertex = std::make_shared<StreamVertex>(node, port, isMaster);
|
||||
addVertex(vertex);
|
||||
|
||||
|
@ -109,7 +109,7 @@ public:
|
|||
bool connect(const StreamVertex &from, const StreamVertex &to, bool reverse)
|
||||
{
|
||||
bool ret;
|
||||
|
||||
|
||||
ret = connect(from, to);
|
||||
|
||||
if (reverse)
|
||||
|
@ -118,16 +118,16 @@ public:
|
|||
return ret;
|
||||
}
|
||||
|
||||
// easy-usage assuming that the slave IP to connect to only has one slave
|
||||
// Easy-usage assuming that the slave IP to connect to only has one slave
|
||||
// port and implements the getDefaultSlavePort() function
|
||||
bool connect(const Node &slaveNode, bool reverse = false)
|
||||
{ return this->connect(this->getDefaultMasterPort(), slaveNode.getDefaultSlavePort(), reverse); }
|
||||
|
||||
// used by easy-usage connect, will throw if not implemented by derived node
|
||||
// Used by easy-usage connect, will throw if not implemented by derived node
|
||||
virtual const StreamVertex&
|
||||
getDefaultSlavePort() const;
|
||||
|
||||
// used by easy-usage connect, will throw if not implemented by derived node
|
||||
// Used by easy-usage connect, will throw if not implemented by derived node
|
||||
virtual const StreamVertex&
|
||||
getDefaultMasterPort() const;
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
using namespace villas;
|
||||
using namespace villas::fpga;
|
||||
|
||||
// instantiate factory to register
|
||||
// Instantiate factory to register
|
||||
static PCIeCardFactory villas::fpga::PCIeCardFactory;
|
||||
|
||||
static const kernel::pci::Device defaultFilter((kernel::pci::Id(FPGA_PCI_VID_XILINX, FPGA_PCI_PID_VFPGA)));
|
||||
|
@ -72,20 +72,20 @@ PCIeCardFactory::make(json_t *json, std::shared_ptr<kernel::pci::DeviceList> pci
|
|||
|
||||
auto card = std::unique_ptr<PCIeCard>(create());
|
||||
|
||||
// populate generic properties
|
||||
// Populate generic properties
|
||||
card->name = std::string(card_name);
|
||||
card->vfioContainer = std::move(vc);
|
||||
card->affinity = affinity;
|
||||
card->doReset = do_reset != 0;
|
||||
|
||||
kernel::pci::Device filter = defaultFilter;
|
||||
|
||||
|
||||
if (pci_id)
|
||||
filter.id = kernel::pci::Id(pci_id);
|
||||
if (pci_slot)
|
||||
filter.slot = kernel::pci::Slot(pci_slot);
|
||||
|
||||
/* Search for FPGA card */
|
||||
// Search for FPGA card
|
||||
card->pdev = pci->lookupDevice(filter);
|
||||
if (!card->pdev) {
|
||||
logger->warn("Failed to find PCI device");
|
||||
|
@ -97,7 +97,7 @@ PCIeCardFactory::make(json_t *json, std::shared_ptr<kernel::pci::DeviceList> pci
|
|||
continue;
|
||||
}
|
||||
|
||||
/* Load IPs from a separate json file */
|
||||
// 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);
|
||||
|
@ -125,7 +125,7 @@ PCIeCard::~PCIeCard()
|
|||
{
|
||||
auto &mm = MemoryManager::get();
|
||||
|
||||
// unmap all memory blocks
|
||||
// Unmap all memory blocks
|
||||
for (auto &mappedMemoryBlock : memoryBlocksMapped) {
|
||||
auto translation = mm.getTranslation(addrSpaceIdDeviceToHost,
|
||||
mappedMemoryBlock);
|
||||
|
@ -190,7 +190,7 @@ PCIeCard::mapMemoryBlock(const MemoryBlock &block)
|
|||
const auto &addrSpaceId = block.getAddrSpaceId();
|
||||
|
||||
if (memoryBlocksMapped.find(addrSpaceId) != memoryBlocksMapped.end())
|
||||
// block already mapped
|
||||
// Block already mapped
|
||||
return true;
|
||||
else
|
||||
logger->debug("Create VFIO mapping for {}", addrSpaceId);
|
||||
|
@ -212,7 +212,7 @@ PCIeCard::mapMemoryBlock(const MemoryBlock &block)
|
|||
this->addrSpaceIdDeviceToHost,
|
||||
addrSpaceId);
|
||||
|
||||
// remember that this block has already been mapped for later
|
||||
// Remember that this block has already been mapped for later
|
||||
memoryBlocksMapped.insert(addrSpaceId);
|
||||
|
||||
return true;
|
||||
|
@ -226,19 +226,19 @@ PCIeCard::init()
|
|||
|
||||
logger->info("Initializing FPGA card {}", name);
|
||||
|
||||
/* Attach PCIe card to VFIO container */
|
||||
// Attach PCIe card to VFIO container
|
||||
kernel::vfio::Device &device = vfioContainer->attachDevice(*pdev);
|
||||
this->vfioDevice = &device;
|
||||
|
||||
/* Enable memory access and PCI bus mastering for DMA */
|
||||
// Enable memory access and PCI bus mastering for DMA
|
||||
if (not device.pciEnable()) {
|
||||
logger->error("Failed to enable PCI device");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Reset system? */
|
||||
// Reset system?
|
||||
if (doReset) {
|
||||
/* Reset / detect PCI device */
|
||||
// Reset / detect PCI device
|
||||
if (not vfioDevice->pciHotReset()) {
|
||||
logger->error("Failed to reset PCI device");
|
||||
return false;
|
||||
|
|
|
@ -56,14 +56,14 @@ CoreFactory::make(PCIeCard* card, json_t *json_ips)
|
|||
// We only have this logger until we know the factory to build an IP with
|
||||
auto loggerStatic = getStaticLogger();
|
||||
|
||||
std::list<IpIdentifier> allIps; // all IPs available in config
|
||||
std::list<IpIdentifier> allIps; // All IPs available in config
|
||||
std::list<IpIdentifier> orderedIps; // IPs ordered in initialization order
|
||||
|
||||
Core::List configuredIps; // Successfully configured IPs
|
||||
Core::List initializedIps; // Initialized, i.e. ready-to-use IPs
|
||||
|
||||
|
||||
// parse all IP instance names and their VLNV into list `allIps`
|
||||
// Parse all IP instance names and their VLNV into list `allIps`
|
||||
const char* ipName;
|
||||
json_t* json_ip;
|
||||
json_object_foreach(json_ips, ipName, json_ip) {
|
||||
|
@ -84,7 +84,7 @@ CoreFactory::make(PCIeCard* card, json_t *json_ips)
|
|||
vlnvInitializationOrder.reverse();
|
||||
|
||||
for (auto &vlnvInitFirst : vlnvInitializationOrder) {
|
||||
// iterate over IPs, if VLNV matches, push to front and remove from list
|
||||
// Iterate over IPs, if VLNV matches, push to front and remove from list
|
||||
for (auto it = allIps.begin(); it != allIps.end(); ++it) {
|
||||
if (vlnvInitFirst == it->getVlnv()) {
|
||||
orderedIps.push_front(*it);
|
||||
|
@ -93,7 +93,7 @@ CoreFactory::make(PCIeCard* card, json_t *json_ips)
|
|||
}
|
||||
}
|
||||
|
||||
// insert all other IPs at the end
|
||||
// Insert all other IPs at the end
|
||||
orderedIps.splice(orderedIps.end(), allIps);
|
||||
|
||||
loggerStatic->debug("IP initialization order:");
|
||||
|
@ -101,11 +101,11 @@ CoreFactory::make(PCIeCard* card, json_t *json_ips)
|
|||
loggerStatic->debug(" " CLR_BLD("{}"), id.getName());
|
||||
}
|
||||
|
||||
// configure all IPs
|
||||
// Configure all IPs
|
||||
for (auto &id : orderedIps) {
|
||||
loggerStatic->info("Configuring {}", id);
|
||||
|
||||
// find the appropriate factory that can create the specified VLNV
|
||||
// Find the appropriate factory that can create the specified VLNV
|
||||
// Note:
|
||||
// This is the magic part! Factories automatically register as a
|
||||
// plugin as soon as they are instantiated. If there are multiple
|
||||
|
@ -135,7 +135,7 @@ CoreFactory::make(PCIeCard* card, json_t *json_ips)
|
|||
continue;
|
||||
}
|
||||
|
||||
// setup generic IP type properties
|
||||
// Setup generic IP type properties
|
||||
ip->card = card;
|
||||
ip->id = id;
|
||||
ip->logger = villas::logging.get(id.getName());
|
||||
|
@ -191,18 +191,18 @@ CoreFactory::make(PCIeCard* card, json_t *json_ips)
|
|||
if (json_is_object(json_memory_view)) {
|
||||
logger->debug("Parse memory view of {}", *ip);
|
||||
|
||||
// now find all slave address spaces this master can access
|
||||
// Now find all slave address spaces this master can access
|
||||
const char* bus_name;
|
||||
json_t* json_bus;
|
||||
json_object_foreach(json_memory_view, bus_name, json_bus) {
|
||||
|
||||
// this IP has a memory view => it is a bus master somewhere
|
||||
// This IP has a memory view => it is a bus master somewhere
|
||||
|
||||
// assemble name for master address space
|
||||
// Assemble name for master address space
|
||||
const std::string myAddrSpaceName =
|
||||
MemoryManager::getMasterAddrSpaceName(ip->getInstanceName(),
|
||||
bus_name);
|
||||
// create a master address space
|
||||
// Create a master address space
|
||||
const MemoryManager::AddressSpaceId myAddrSpaceId =
|
||||
MemoryManager::get().getOrCreateAddressSpace(myAddrSpaceName);
|
||||
|
||||
|
@ -229,14 +229,14 @@ CoreFactory::make(PCIeCard* card, json_t *json_ips)
|
|||
|
||||
}
|
||||
|
||||
// get or create the slave address space
|
||||
// Get or create the slave address space
|
||||
const std::string slaveAddrSpace =
|
||||
MemoryManager::getSlaveAddrSpaceName(instance_name, block_name);
|
||||
|
||||
const MemoryManager::AddressSpaceId slaveAddrSpaceId =
|
||||
MemoryManager::get().getOrCreateAddressSpace(slaveAddrSpace);
|
||||
|
||||
// create a new mapping to the slave address space
|
||||
// Create a new mapping to the slave address space
|
||||
MemoryManager::get().createMapping(static_cast<uintptr_t>(base),
|
||||
0,
|
||||
static_cast<uintptr_t>(size),
|
||||
|
@ -266,23 +266,23 @@ CoreFactory::make(PCIeCard* card, json_t *json_ips)
|
|||
// the process and cache in the instance, so this has not to be done at
|
||||
// runtime.
|
||||
for (auto &memoryBlock : ip->getMemoryBlocks()) {
|
||||
// construct the global name of this address block
|
||||
// Construct the global name of this address block
|
||||
const auto addrSpaceName =
|
||||
MemoryManager::getSlaveAddrSpaceName(ip->getInstanceName(),
|
||||
memoryBlock);
|
||||
|
||||
// retrieve its address space identifier
|
||||
// Retrieve its address space identifier
|
||||
const auto addrSpaceId =
|
||||
MemoryManager::get().findAddressSpace(addrSpaceName);
|
||||
|
||||
// ... and save it in IP
|
||||
ip->slaveAddressSpaces.emplace(memoryBlock, addrSpaceId);
|
||||
|
||||
// get the translation to the address space
|
||||
// Get the translation to the address space
|
||||
const auto &translation =
|
||||
MemoryManager::get().getTranslationFromProcess(addrSpaceId);
|
||||
|
||||
// cache it in the IP instance only with local name
|
||||
// Cache it in the IP instance only with local name
|
||||
ip->addressTranslations.emplace(memoryBlock, translation);
|
||||
}
|
||||
|
||||
|
@ -296,7 +296,7 @@ CoreFactory::make(PCIeCard* card, json_t *json_ips)
|
|||
continue;
|
||||
}
|
||||
|
||||
// will only be reached if the IP successfully was initialized
|
||||
// Will only be reached if the IP successfully was initialized
|
||||
initializedIps.push_back(std::move(ip));
|
||||
}
|
||||
|
||||
|
@ -340,7 +340,7 @@ CoreFactory::lookup(const Vlnv &vlnv)
|
|||
uintptr_t
|
||||
Core::getLocalAddr(const MemoryBlockName &block, uintptr_t address) const
|
||||
{
|
||||
// throws exception if block not present
|
||||
// Throws exception if block not present
|
||||
auto &translation = addressTranslations.at(block);
|
||||
|
||||
return translation.getLocalAddr(address);
|
||||
|
|
|
@ -27,53 +27,51 @@
|
|||
#include <villas/fpga/card.hpp>
|
||||
#include <villas/fpga/ips/aurora.hpp>
|
||||
|
||||
// Register offsets
|
||||
#define AURORA_AXIS_SR_OFFSET 0x00 // Status Register (read-only)
|
||||
#define AURORA_AXIS_CR_OFFSET 0x04 // Control Register (read/write)
|
||||
#define AURORA_AXIS_CNTR_IN_HIGH_OFFSET 0x0C // Higher 32-bits of incoming frame counter
|
||||
#define AURORA_AXIS_CNTR_IN_LOW_OFFSET 0x08 // Lower 32-bits of incoming frame counter
|
||||
#define AURORA_AXIS_CNTR_OUT_HIGH_OFFSET 0x18 // Higher 32-bits of outgoing frame counter
|
||||
#define AURORA_AXIS_CNTR_OUT_LOW_OFFSET 0x1C // Lower 32-bits of outgoing frame counter
|
||||
|
||||
/* Register offsets */
|
||||
#define AURORA_AXIS_SR_OFFSET 0x00 /**< Status Register (read-only) */
|
||||
#define AURORA_AXIS_CR_OFFSET 0x04 /**< Control Register (read/write) */
|
||||
#define AURORA_AXIS_CNTR_IN_HIGH_OFFSET 0x0C /**< Higher 32-bits of incoming frame counter */
|
||||
#define AURORA_AXIS_CNTR_IN_LOW_OFFSET 0x08 /**< Lower 32-bits of incoming frame counter */
|
||||
#define AURORA_AXIS_CNTR_OUT_HIGH_OFFSET 0x18 /**< Higher 32-bits of outgoing frame counter */
|
||||
#define AURORA_AXIS_CNTR_OUT_LOW_OFFSET 0x1C /**< Lower 32-bits of outgoing frame counter */
|
||||
// Status register bits
|
||||
#define AURORA_AXIS_SR_CHAN_UP (1 << 0) // 1-bit, asserted when channel initialisation is complete and is ready for data transfer
|
||||
#define AURORA_AXIS_SR_LANE_UP (1 << 1) // 1-bit, asserted for each lane upon successful lane initialisation
|
||||
#define AURORA_AXIS_SR_HARD_ERR (1 << 2) // 1-bit hard rror status
|
||||
#define AURORA_AXIS_SR_SOFT_ERR (1 << 3) // 1-bit soft error status
|
||||
#define AURORA_AXIS_SR_FRAME_ERR (1 << 4) // 1-bit frame error status
|
||||
|
||||
/* Status register bits */
|
||||
#define AURORA_AXIS_SR_CHAN_UP (1 << 0)/**< 1-bit, asserted when channel initialisation is complete and is ready for data transfer */
|
||||
#define AURORA_AXIS_SR_LANE_UP (1 << 1)/**< 1-bit, asserted for each lane upon successful lane initialisation */
|
||||
#define AURORA_AXIS_SR_HARD_ERR (1 << 2)/**< 1-bit hard rror status */
|
||||
#define AURORA_AXIS_SR_SOFT_ERR (1 << 3)/**< 1-bit soft error status */
|
||||
#define AURORA_AXIS_SR_FRAME_ERR (1 << 4)/**< 1-bit frame error status */
|
||||
// Control register bits
|
||||
// 1-bit, assert to put Aurora IP in loopback mode.
|
||||
#define AURORA_AXIS_CR_LOOPBACK (1 << 0)
|
||||
|
||||
/* Control register bits */
|
||||
/** 1-bit, assert to put Aurora IP in loopback mode. */
|
||||
#define AURORA_AXIS_CR_LOOPBACK (1 << 0)
|
||||
// 1-bit, assert to reset counters, incoming and outgoing frame counters.
|
||||
#define AURORA_AXIS_CR_RST_CTRS (1 << 1)
|
||||
|
||||
/** 1-bit, assert to reset counters, incoming and outgoing frame counters. */
|
||||
#define AURORA_AXIS_CR_RST_CTRS (1 << 1)
|
||||
// 1-bit, assert to turn off any sequence number handling by Aurora IP
|
||||
// Sequence number must be handled in software then.
|
||||
#define AURORA_AXIS_CR_SEQ_MODE (1 << 2)
|
||||
|
||||
/** 1-bit, assert to turn off any sequence number handling by Aurora IP
|
||||
* Sequence number must be handled in software then. */
|
||||
#define AURORA_AXIS_CR_SEQ_MODE (1 << 2)
|
||||
|
||||
/** 1-bit, assert to strip the received frame of the trailing sequence
|
||||
* number. Sequence number mode must be set to handled by Aurora IP,
|
||||
/** 1-bit, assert to strip the received frame of the trailing sequence
|
||||
* number. Sequence number mode must be set to handled by Aurora IP,
|
||||
* otherwise this bit is ignored. */
|
||||
#define AURORA_AXIS_CR_SEQ_STRIP (1 << 3)
|
||||
|
||||
/** 1-bit, assert to use the same sequence number in the outgoing
|
||||
* NovaCor-bound frames as the sequence number received from the
|
||||
* incoming frames from NovaCor. Sequence number mode must be set to
|
||||
/** 1-bit, assert to use the same sequence number in the outgoing
|
||||
* NovaCor-bound frames as the sequence number received from the
|
||||
* incoming frames from NovaCor. Sequence number mode must be set to
|
||||
* handled by Aurora IP, otherwise this bit is ignored.*/
|
||||
#define AURORA_AXIS_CR_SEQ_ECHO (1 << 4)
|
||||
#define AURORA_AXIS_CR_SEQ_ECHO (1 << 4)
|
||||
|
||||
|
||||
using namespace villas::fpga::ip;
|
||||
|
||||
static AuroraFactory auroraFactoryInstance;
|
||||
|
||||
|
||||
void Aurora::dump()
|
||||
{
|
||||
/* Check Aurora AXI4 registers */
|
||||
// Check Aurora AXI4 registers
|
||||
const uint32_t sr = readMemory<uint32_t>(registerMemory, AURORA_AXIS_SR_OFFSET);
|
||||
|
||||
logger->info("Aurora-NovaCor AXI-Stream interface details:");
|
||||
|
|
|
@ -31,19 +31,19 @@
|
|||
#include <villas/fpga/ips/dma.hpp>
|
||||
#include <villas/fpga/ips/intc.hpp>
|
||||
|
||||
// max. size of a DMA transfer in simple mode
|
||||
// Max. size of a DMA transfer in simple mode
|
||||
#define FPGA_DMA_BOUNDARY 0x1000
|
||||
|
||||
|
||||
using namespace villas::fpga::ip;
|
||||
|
||||
// instantiate factory to make available to plugin infrastructure
|
||||
// Instantiate factory to make available to plugin infrastructure
|
||||
static DmaFactory factory;
|
||||
|
||||
bool
|
||||
Dma::init()
|
||||
{
|
||||
// if there is a scatter-gather interface, then this instance has it
|
||||
// If there is a scatter-gather interface, then this instance has it
|
||||
hasSG = busMasterInterfaces.count(sgInterface) == 1;
|
||||
logger->info("Scatter-Gather support: {}", hasScatterGather());
|
||||
|
||||
|
@ -55,7 +55,7 @@ Dma::init()
|
|||
xdma_cfg.HasMm2SDRE = 1;
|
||||
xdma_cfg.Mm2SDataWidth = 128;
|
||||
xdma_cfg.HasS2Mm = 1;
|
||||
xdma_cfg.HasS2MmDRE = 1; /* Data Realignment Engine */
|
||||
xdma_cfg.HasS2MmDRE = 1; // Data Realignment Engine
|
||||
xdma_cfg.HasSg = hasScatterGather();
|
||||
xdma_cfg.S2MmDataWidth = 128;
|
||||
xdma_cfg.Mm2sNumChannels = 1;
|
||||
|
@ -77,7 +77,7 @@ Dma::init()
|
|||
else
|
||||
logger->debug("DMA selftest passed");
|
||||
|
||||
/* Map buffer descriptors */
|
||||
// Map buffer descriptors
|
||||
if (hasScatterGather()) {
|
||||
logger->warn("Scatter Gather not yet implemented");
|
||||
return false;
|
||||
|
@ -91,7 +91,7 @@ Dma::init()
|
|||
// return -4;
|
||||
}
|
||||
|
||||
/* Enable completion interrupts for both channels */
|
||||
// Enable completion interrupts for both channels
|
||||
XAxiDma_IntrEnable(&xDma, XAXIDMA_IRQ_IOC_MASK, XAXIDMA_DMA_TO_DEVICE);
|
||||
XAxiDma_IntrEnable(&xDma, XAXIDMA_IRQ_IOC_MASK, XAXIDMA_DEVICE_TO_DMA);
|
||||
|
||||
|
@ -106,10 +106,10 @@ bool
|
|||
Dma::reset()
|
||||
{
|
||||
logger->info("DMA resetted");
|
||||
|
||||
|
||||
XAxiDma_Reset(&xDma);
|
||||
|
||||
// value taken from libxil implementation
|
||||
// Value taken from libxil implementation
|
||||
int timeout = 500;
|
||||
|
||||
while (timeout > 0) {
|
||||
|
@ -153,7 +153,7 @@ Dma::write(const MemoryBlock &mem, size_t len)
|
|||
{
|
||||
auto &mm = MemoryManager::get();
|
||||
|
||||
// user has to make sure that memory is accessible, otherwise this will throw
|
||||
// User has to make sure that memory is accessible, otherwise this will throw
|
||||
auto translation = mm.getTranslation(busMasterInterfaces[mm2sInterface],
|
||||
mem.getAddrSpaceId());
|
||||
const void* buf = reinterpret_cast<void*>(translation.getLocalAddr(0));
|
||||
|
@ -168,7 +168,7 @@ Dma::read(const MemoryBlock &mem, size_t len)
|
|||
{
|
||||
auto &mm = MemoryManager::get();
|
||||
|
||||
// user has to make sure that memory is accessible, otherwise this will throw
|
||||
// User has to make sure that memory is accessible, otherwise this will throw
|
||||
auto translation = mm.getTranslation(busMasterInterfaces[s2mmInterface],
|
||||
mem.getAddrSpaceId());
|
||||
void* buf = reinterpret_cast<void*>(translation.getLocalAddr(0));
|
||||
|
@ -241,27 +241,27 @@ Dma::writeSimple(const void *buf, size_t len)
|
|||
|
||||
const bool dmaToDeviceBusy = XAxiDma_Busy(&xDma, XAXIDMA_DMA_TO_DEVICE);
|
||||
|
||||
/* If the engine is doing a transfer, cannot submit */
|
||||
// If the engine is doing a transfer, cannot submit
|
||||
if (not dmaChannelHalted and dmaToDeviceBusy) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// set lower 32 bit of source address
|
||||
// Set lower 32 bit of source address
|
||||
XAxiDma_WriteReg(ring->ChanBase, XAXIDMA_SRCADDR_OFFSET,
|
||||
LOWER_32_BITS(reinterpret_cast<uintptr_t>(buf)));
|
||||
|
||||
// if neccessary, set upper 32 bit of source address
|
||||
// If neccessary, set upper 32 bit of source address
|
||||
if (xDma.AddrWidth > 32) {
|
||||
XAxiDma_WriteReg(ring->ChanBase, XAXIDMA_SRCADDR_MSB_OFFSET,
|
||||
UPPER_32_BITS(reinterpret_cast<uintptr_t>(buf)));
|
||||
}
|
||||
|
||||
// start DMA channel
|
||||
// Start DMA channel
|
||||
auto channelControl = XAxiDma_ReadReg(ring->ChanBase, XAXIDMA_CR_OFFSET);
|
||||
channelControl |= XAXIDMA_CR_RUNSTOP_MASK;
|
||||
XAxiDma_WriteReg(ring->ChanBase, XAXIDMA_CR_OFFSET, channelControl);
|
||||
|
||||
// set tail descriptor pointer
|
||||
// Set tail descriptor pointer
|
||||
XAxiDma_WriteReg(ring->ChanBase, XAXIDMA_BUFFLEN_OFFSET, len);
|
||||
|
||||
|
||||
|
@ -292,26 +292,26 @@ Dma::readSimple(void *buf, size_t len)
|
|||
|
||||
const bool deviceToDmaBusy = XAxiDma_Busy(&xDma, XAXIDMA_DEVICE_TO_DMA);
|
||||
|
||||
/* If the engine is doing a transfer, cannot submit */
|
||||
// If the engine is doing a transfer, cannot submit
|
||||
if (not dmaChannelHalted and deviceToDmaBusy) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// set lower 32 bit of destination address
|
||||
// Set lower 32 bit of destination address
|
||||
XAxiDma_WriteReg(ring->ChanBase, XAXIDMA_DESTADDR_OFFSET,
|
||||
LOWER_32_BITS(reinterpret_cast<uintptr_t>(buf)));
|
||||
|
||||
// if neccessary, set upper 32 bit of destination address
|
||||
// If neccessary, set upper 32 bit of destination address
|
||||
if (xDma.AddrWidth > 32)
|
||||
XAxiDma_WriteReg(ring->ChanBase, XAXIDMA_DESTADDR_MSB_OFFSET,
|
||||
UPPER_32_BITS(reinterpret_cast<uintptr_t>(buf)));
|
||||
|
||||
// start DMA channel
|
||||
// Start DMA channel
|
||||
auto channelControl = XAxiDma_ReadReg(ring->ChanBase, XAXIDMA_CR_OFFSET);
|
||||
channelControl |= XAXIDMA_CR_RUNSTOP_MASK;
|
||||
XAxiDma_WriteReg(ring->ChanBase, XAXIDMA_CR_OFFSET, channelControl);
|
||||
|
||||
// set tail descriptor pointer
|
||||
// Set tail descriptor pointer
|
||||
XAxiDma_WriteReg(ring->ChanBase, XAXIDMA_BUFFLEN_OFFSET, len);
|
||||
|
||||
return true;
|
||||
|
@ -351,19 +351,19 @@ Dma::readCompleteSimple()
|
|||
bool
|
||||
Dma::makeAccesibleFromVA(const MemoryBlock &mem)
|
||||
{
|
||||
// only symmetric mapping supported currently
|
||||
// Only symmetric mapping supported currently
|
||||
if (isMemoryBlockAccesible(mem, s2mmInterface) and
|
||||
isMemoryBlockAccesible(mem, mm2sInterface)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// try mapping via FPGA-card (VFIO)
|
||||
// Try mapping via FPGA-card (VFIO)
|
||||
if (not card->mapMemoryBlock(mem)) {
|
||||
logger->error("Memory not accessible by DMA");
|
||||
return false;
|
||||
}
|
||||
|
||||
// sanity-check if mapping worked, this shouldn't be neccessary
|
||||
// Sanity-check if mapping worked, this shouldn't be neccessary
|
||||
if (not isMemoryBlockAccesible(mem, s2mmInterface) or
|
||||
not isMemoryBlockAccesible(mem, mm2sInterface)) {
|
||||
logger->error("Mapping memory via card didn't work, but reported success?!");
|
||||
|
@ -381,10 +381,8 @@ Dma::isMemoryBlockAccesible(const MemoryBlock &mem, const std::string &interface
|
|||
|
||||
try {
|
||||
mm.findPath(getMasterAddrSpaceByInterface(interface), mem.getAddrSpaceId());
|
||||
} catch (const std::out_of_range&) {
|
||||
// not (yet) accessible
|
||||
return false;
|
||||
}
|
||||
} catch (const std::out_of_range&)
|
||||
return false; // Not (yet) accessible
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
|
||||
using namespace villas::fpga::ip;
|
||||
|
||||
// instantiate factory to make available to plugin infrastructure
|
||||
// Instantiate factory to make available to plugin infrastructure
|
||||
static EMCFactory factory;
|
||||
|
||||
bool
|
||||
|
@ -36,23 +36,21 @@ EMC::init()
|
|||
int ret;
|
||||
const uintptr_t base = getBaseAddr(registerMemory);
|
||||
|
||||
#ifdef XPAR_XFL_DEVICE_FAMILY_INTEL
|
||||
#if XFL_TO_ASYNCMODE
|
||||
/* Set Flash to Async mode. */
|
||||
if (FLASH_MEM_WIDTH == 1) {
|
||||
WRITE_FLASH_8(FLASH_BASE_ADDRESS + ASYNC_ADDR, 0x60);
|
||||
WRITE_FLASH_8(FLASH_BASE_ADDRESS + ASYNC_ADDR, 0x03);
|
||||
}
|
||||
else if (FLASH_MEM_WIDTH == 2) {
|
||||
WRITE_FLASH_16(FLASH_BASE_ADDRESS + ASYNC_ADDR,
|
||||
INTEL_CMD_CONFIG_REG_SETUP);
|
||||
WRITE_FLASH_16(FLASH_BASE_ADDRESS + ASYNC_ADDR,
|
||||
INTEL_CMD_CONFIG_REG_CONFIRM);
|
||||
}
|
||||
#endif
|
||||
const int busWidth = 2;
|
||||
|
||||
#if defined(XPAR_XFL_DEVICE_FAMILY_INTEL) && XFL_TO_ASYNCMODE
|
||||
// Set Flash to Async mode.
|
||||
if (busWidth == 1) {
|
||||
WRITE_FLASH_8(base + ASYNC_ADDR, 0x60);
|
||||
WRITE_FLASH_8(base + ASYNC_ADDR, 0x03);
|
||||
}
|
||||
else if (busWidth == 2) {
|
||||
WRITE_FLASH_16(base + ASYNC_ADDR, INTEL_CMD_CONFIG_REG_SETUP);
|
||||
WRITE_FLASH_16(base + ASYNC_ADDR, INTEL_CMD_CONFIG_REG_CONFIRM);
|
||||
}
|
||||
#endif
|
||||
|
||||
ret = XFlash_Initialize(&xflash, base, 2, 0);
|
||||
ret = XFlash_Initialize(&xflash, base, busWidth, 0);
|
||||
if (ret != XST_SUCCESS)
|
||||
return false;
|
||||
|
||||
|
@ -64,19 +62,16 @@ EMC::read(uint32_t offset, uint32_t length, uint8_t *data)
|
|||
{
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Reset the Flash Device. This clears the ret registers and puts
|
||||
/** Reset the Flash Device. This clears the ret registers and puts
|
||||
* the device in Read mode.
|
||||
*/
|
||||
ret = XFlash_Reset(&xflash);
|
||||
if (ret != XST_SUCCESS)
|
||||
return false;
|
||||
|
||||
/*
|
||||
* Perform the read operation.
|
||||
*/
|
||||
// Perform the read operation.
|
||||
ret = XFlash_Read(&xflash, offset, length, data);
|
||||
if(ret != XST_SUCCESS)
|
||||
if (ret != XST_SUCCESS)
|
||||
return false;
|
||||
|
||||
return false;
|
||||
|
@ -92,14 +87,14 @@ EMC::flash(uint32_t offset, const std::string &filename)
|
|||
uint8_t *buffer;
|
||||
|
||||
std::ifstream is(filename, std::ios::binary);
|
||||
|
||||
// get length of file:
|
||||
|
||||
// Get length of file:
|
||||
is.seekg(0, std::ios::end);
|
||||
length = is.tellg();
|
||||
|
||||
|
||||
is.seekg (0, std::ios::beg);
|
||||
// allocate memory:
|
||||
|
||||
// Allocate memory:
|
||||
|
||||
buffer = new uint8_t[length];
|
||||
is.read(reinterpret_cast<char *>(buffer), length);
|
||||
is.close();
|
||||
|
@ -111,7 +106,7 @@ EMC::flash(uint32_t offset, const std::string &filename)
|
|||
return result;
|
||||
}
|
||||
|
||||
/* Based on xilflash_readwrite_example.c */
|
||||
// Based on xilflash_readwrite_example.c
|
||||
bool
|
||||
EMC::flash(uint32_t offset, uint32_t length, uint8_t *data)
|
||||
{
|
||||
|
@ -137,23 +132,23 @@ EMC::flash(uint32_t offset, uint32_t length, uint8_t *data)
|
|||
return false;
|
||||
}
|
||||
|
||||
/* Perform the Erase operation. */
|
||||
// Perform the Erase operation.
|
||||
ret = XFlash_Erase(&xflash, start, length);
|
||||
if (ret != XST_SUCCESS)
|
||||
return false;
|
||||
|
||||
/* Perform the Write operation. */
|
||||
// Perform the Write operation.
|
||||
ret = XFlash_Write(&xflash, start, length, data);
|
||||
if (ret != XST_SUCCESS)
|
||||
return false;
|
||||
|
||||
/* Perform the read operation. */
|
||||
// Perform the read operation.
|
||||
ret = XFlash_Read(&xflash, start, length, verify_data);
|
||||
if(ret != XST_SUCCESS) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Compare the data read against the data Written. */
|
||||
// Compare the data read against the data Written.
|
||||
for (unsigned i = 0; i < length; i++) {
|
||||
if (verify_data[i] != data[i])
|
||||
return false;
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
|
||||
using namespace villas::fpga::ip;
|
||||
|
||||
// instantiate factory to make available to plugin infrastructure
|
||||
// Instantiate factory to make available to plugin infrastructure
|
||||
static FifoFactory factory;
|
||||
static FifoDataFactory factoryData;
|
||||
|
||||
|
@ -44,7 +44,7 @@ bool Fifo::init()
|
|||
XLlFifo_Config fifo_cfg;
|
||||
|
||||
try {
|
||||
// if this throws an exception, then there's no AXI4 data interface
|
||||
// If this throws an exception, then there's no AXI4 data interface
|
||||
fifo_cfg.Axi4BaseAddress = getBaseAddr(axi4Memory);
|
||||
fifo_cfg.Datainterface = 1;
|
||||
} catch (const std::out_of_range&) {
|
||||
|
@ -84,7 +84,7 @@ size_t Fifo::write(const void *buf, size_t len)
|
|||
if (tdfv < len)
|
||||
return -1;
|
||||
|
||||
// buf has to be re-casted because Xilinx driver doesn't use const
|
||||
// Buf has to be re-casted because Xilinx driver doesn't use const
|
||||
XLlFifo_Write(&xFifo, (void*) buf, len);
|
||||
XLlFifo_TxSetLen(&xFifo, len);
|
||||
|
||||
|
@ -101,11 +101,11 @@ size_t Fifo::read(void *buf, size_t len)
|
|||
|
||||
XLlFifo_IntClear(&xFifo, XLLF_INT_RC_MASK);
|
||||
|
||||
/* Get length of next frame */
|
||||
// Get length of next frame
|
||||
rxlen = XLlFifo_RxGetLen(&xFifo);
|
||||
nextlen = std::min(rxlen, len);
|
||||
|
||||
/* Read from FIFO */
|
||||
// Read from FIFO
|
||||
XLlFifo_Read(&xFifo, buf, nextlen);
|
||||
|
||||
return nextlen;
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
using namespace villas::fpga::ip;
|
||||
|
||||
|
||||
// instantiate factory to make available to plugin infrastructure
|
||||
// Instantiate factory to make available to plugin infrastructure
|
||||
static GeneralPurposeIOFactory factory;
|
||||
|
||||
bool
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
|
||||
using namespace villas::fpga::ip;
|
||||
|
||||
// instantiate factory to make available to plugin infrastructure
|
||||
// Instantiate factory to make available to plugin infrastructure
|
||||
static InterruptControllerFactory factory;
|
||||
|
||||
InterruptController::~InterruptController()
|
||||
|
@ -54,15 +54,15 @@ InterruptController::init()
|
|||
return false;
|
||||
}
|
||||
|
||||
/* For each IRQ */
|
||||
// For each IRQ
|
||||
for (int i = 0; i < num_irqs; i++) {
|
||||
|
||||
/* Try pinning to core */
|
||||
// Try pinning to core
|
||||
int ret = kernel::setIRQAffinity(nos[i], card->affinity, nullptr);
|
||||
|
||||
switch(ret) {
|
||||
case 0:
|
||||
// everything is fine
|
||||
// Everything is fine
|
||||
break;
|
||||
case EACCES:
|
||||
logger->warn("No permission to change affinity of VFIO-MSI interrupt, "
|
||||
|
@ -73,14 +73,14 @@ InterruptController::init()
|
|||
return false;
|
||||
}
|
||||
|
||||
/* Setup vector */
|
||||
// Setup vector
|
||||
XIntc_Out32(base + XIN_IVAR_OFFSET + i * 4, i);
|
||||
}
|
||||
|
||||
XIntc_Out32(base + XIN_IMR_OFFSET, 0x00000000); /* Use manual acknowlegement for all IRQs */
|
||||
XIntc_Out32(base + XIN_IAR_OFFSET, 0xFFFFFFFF); /* Acknowlege all pending IRQs manually */
|
||||
XIntc_Out32(base + XIN_IMR_OFFSET, 0xFFFFFFFF); /* Use fast acknowlegement for all IRQs */
|
||||
XIntc_Out32(base + XIN_IER_OFFSET, 0x00000000); /* Disable all IRQs by default */
|
||||
XIntc_Out32(base + XIN_IMR_OFFSET, 0x00000000); // Use manual acknowlegement for all IRQs
|
||||
XIntc_Out32(base + XIN_IAR_OFFSET, 0xFFFFFFFF); // Acknowlege all pending IRQs manually
|
||||
XIntc_Out32(base + XIN_IMR_OFFSET, 0xFFFFFFFF); // Use fast acknowlegement for all IRQs
|
||||
XIntc_Out32(base + XIN_IER_OFFSET, 0x00000000); // Disable all IRQs by default
|
||||
XIntc_Out32(base + XIN_MER_OFFSET, XIN_INT_HARDWARE_ENABLE_MASK | XIN_INT_MASTER_ENABLE_MASK);
|
||||
|
||||
logger->debug("enabled interrupts");
|
||||
|
@ -94,11 +94,11 @@ InterruptController::enableInterrupt(InterruptController::IrqMaskType mask, bool
|
|||
{
|
||||
const uintptr_t base = getBaseAddr(registerMemory);
|
||||
|
||||
/* Current state of INTC */
|
||||
// Current state of INTC
|
||||
const uint32_t ier = XIntc_In32(base + XIN_IER_OFFSET);
|
||||
const uint32_t imr = XIntc_In32(base + XIN_IMR_OFFSET);
|
||||
|
||||
/* Clear pending IRQs */
|
||||
// Clear pending IRQs
|
||||
XIntc_Out32(base + XIN_IAR_OFFSET, mask);
|
||||
|
||||
for (int i = 0; i < num_irqs; i++) {
|
||||
|
@ -145,21 +145,21 @@ InterruptController::waitForInterrupt(int irq)
|
|||
uint32_t isr, mask = 1 << irq;
|
||||
|
||||
do {
|
||||
// poll status register
|
||||
// Poll status register
|
||||
isr = XIntc_In32(base + XIN_ISR_OFFSET);
|
||||
pthread_testcancel();
|
||||
} while ((isr & mask) != mask);
|
||||
|
||||
// acknowledge interrupt
|
||||
// Acknowledge interrupt
|
||||
XIntc_Out32(base + XIN_IAR_OFFSET, mask);
|
||||
|
||||
// we can only tell that there has been (at least) one interrupt
|
||||
// We can only tell that there has been (at least) one interrupt
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
uint64_t count;
|
||||
|
||||
// block until there has been an interrupt, read number of interrupts
|
||||
// Block until there has been an interrupt, read number of interrupts
|
||||
ssize_t ret = read(efds[irq], &count, sizeof(count));
|
||||
if (ret != sizeof(count))
|
||||
return -1;
|
||||
|
|
|
@ -56,7 +56,7 @@ static uint32_t model_xsg_map_checksum(uint32_t *map, size_t len)
|
|||
for (int i = 2; i < len-1; i++)
|
||||
chks += map[i];
|
||||
|
||||
return chks; /* moduluo 2^32 because of overflow */
|
||||
return chks; // Moduluo 2^32 because of overflow
|
||||
}
|
||||
|
||||
static int model_xsg_map_parse(uint32_t *map, size_t len, struct list *parameters, struct list *infos)
|
||||
|
@ -65,7 +65,7 @@ static int model_xsg_map_parse(uint32_t *map, size_t len, struct list *parameter
|
|||
int j;
|
||||
struct model_info *i;
|
||||
|
||||
/* Check magic */
|
||||
// Check magic
|
||||
if (map[0] != XSG_MAGIC)
|
||||
error("Invalid magic: %#x", map[0]);
|
||||
|
||||
|
@ -78,7 +78,7 @@ static int model_xsg_map_parse(uint32_t *map, size_t len, struct list *parameter
|
|||
case XSG_BLOCK_GATEWAY_IN:
|
||||
case XSG_BLOCK_GATEWAY_OUT:
|
||||
if (length < 4)
|
||||
break; /* block is to small to describe a gateway */
|
||||
break; // Block is to small to describe a gateway
|
||||
|
||||
struct model_parameter *e, *p = (struct model_parameter *) alloc(sizeof(struct model_parameter));
|
||||
|
||||
|
@ -122,9 +122,9 @@ static uint32_t model_xsg_map_read_word(uint32_t offset, void *baseaddr)
|
|||
volatile uint32_t *addr = baseaddr + 0x00;
|
||||
volatile uint32_t *data = baseaddr + 0x04;
|
||||
|
||||
*addr = offset; /* Update addr reg */
|
||||
*addr = offset; // Update addr reg
|
||||
|
||||
return *data; /* Read data reg */
|
||||
return *data; // Read data reg
|
||||
}
|
||||
|
||||
static int model_xsg_map_read(uint32_t *map, size_t len, void *baseaddr)
|
||||
|
@ -132,7 +132,7 @@ static int model_xsg_map_read(uint32_t *map, size_t len, void *baseaddr)
|
|||
size_t maplen;
|
||||
uint32_t magic;
|
||||
|
||||
/* Check magic */
|
||||
// Check magic
|
||||
magic = model_xsg_map_read_word(0, baseaddr);
|
||||
if (magic != XSG_MAGIC)
|
||||
return -1;
|
||||
|
@ -141,7 +141,7 @@ static int model_xsg_map_read(uint32_t *map, size_t len, void *baseaddr)
|
|||
if (maplen < 3)
|
||||
return -2;
|
||||
|
||||
/* Read Data */
|
||||
// Read Data
|
||||
int i;
|
||||
for (i = 0; i < MIN(maplen, len); i++)
|
||||
map[i] = model_xsg_map_read_word(i, baseaddr);
|
||||
|
@ -232,7 +232,7 @@ int model_init(struct fpga_ip *c)
|
|||
else
|
||||
ret = 0;
|
||||
|
||||
/* Set default values for parameters */
|
||||
// Set default values for parameters
|
||||
for (size_t i = 0; i < list_length(&m->parameters); i++) {
|
||||
struct model_parameter *p = (struct model_parameter *) list_at(&m->parameters, i);
|
||||
|
||||
|
|
|
@ -42,30 +42,29 @@ AxiPciExpressBridge::init()
|
|||
// address space we can use for translation -> error
|
||||
card->addrSpaceIdHostToDevice = busMasterInterfaces.at(axiInterface);
|
||||
|
||||
/* Map PCIe BAR0 via VFIO */
|
||||
// Map PCIe BAR0 via VFIO
|
||||
const void* bar0_mapped = card->vfioDevice->regionMap(VFIO_PCI_BAR0_REGION_INDEX);
|
||||
if (bar0_mapped == MAP_FAILED) {
|
||||
logger->error("Failed to mmap() BAR0");
|
||||
return false;
|
||||
}
|
||||
|
||||
// determine size of BAR0 region
|
||||
// Determine size of BAR0 region
|
||||
const size_t bar0_size = card->vfioDevice->regionGetSize(VFIO_PCI_BAR0_REGION_INDEX);
|
||||
|
||||
// create a mapping from process address space to the FPGA card via vfio
|
||||
// Create a mapping from process address space to the FPGA card via vfio
|
||||
mm.createMapping(reinterpret_cast<uintptr_t>(bar0_mapped),
|
||||
0, bar0_size, "vfio-h2d",
|
||||
mm.getProcessAddressSpace(),
|
||||
card->addrSpaceIdHostToDevice);
|
||||
|
||||
|
||||
/* Make PCIe (IOVA) address space available to FPGA via BAR0 */
|
||||
// Make PCIe (IOVA) address space available to FPGA via BAR0
|
||||
|
||||
// IPs that can access this address space will know it via their memory view
|
||||
const auto addrSpaceNameDeviceToHost =
|
||||
mm.getSlaveAddrSpaceName(getInstanceName(), pcieMemory);
|
||||
|
||||
// save ID in card so we can create mappings later when needed (e.g. when
|
||||
// Save ID in card so we can create mappings later when needed (e.g. when
|
||||
// allocating DMA memory in host RAM)
|
||||
card->addrSpaceIdDeviceToHost =
|
||||
mm.getOrCreateAddressSpace(addrSpaceNameDeviceToHost);
|
||||
|
@ -82,7 +81,6 @@ AxiPciExpressBridge::init()
|
|||
barName[3] = '0' + region.num;
|
||||
auto pciBar = pcieToAxiTranslations.at(barName);
|
||||
|
||||
|
||||
logger->info("PCI-BAR{}: bus addr={:#x} size={:#x}",
|
||||
region.num, region.start, region_size);
|
||||
logger->info("PCI-BAR{}: AXI translation offset {:#x}",
|
||||
|
@ -91,7 +89,6 @@ AxiPciExpressBridge::init()
|
|||
mm.createMapping(region.start, pciBar.translation, region_size,
|
||||
std::string("PCI-") + barName,
|
||||
pciAddrSpaceId, card->addrSpaceIdHostToDevice);
|
||||
|
||||
}
|
||||
|
||||
for (auto& [barName, axiBar] : axiToPcieTranslations) {
|
||||
|
@ -103,7 +100,7 @@ AxiPciExpressBridge::init()
|
|||
auto barXAddrSpaceName = mm.getSlaveAddrSpaceName(getInstanceName(), barName);
|
||||
auto barXAddrSpaceId = mm.getOrCreateAddressSpace(barXAddrSpaceName);
|
||||
|
||||
// base is already incorporated into mapping of each IP by Vivado, so
|
||||
// Base is already incorporated into mapping of each IP by Vivado, so
|
||||
// the mapping src has to be 0
|
||||
mm.createMapping(0, axiBar.translation, axiBar.size,
|
||||
std::string("AXI-") + barName,
|
||||
|
|
|
@ -30,28 +30,28 @@
|
|||
|
||||
#define RTDS_HZ 100000000 // 100 MHz
|
||||
|
||||
#define RTDS_AXIS_MAX_TX 64 /**< The amount of values which is supported by the vfpga card */
|
||||
#define RTDS_AXIS_MAX_RX 64 /**< The amount of values which is supported by the vfpga card */
|
||||
#define RTDS_AXIS_MAX_TX 64 // The amount of values which is supported by the vfpga card
|
||||
#define RTDS_AXIS_MAX_RX 64 // The amount of values which is supported by the vfpga card
|
||||
|
||||
/* Register offsets */
|
||||
#define RTDS_AXIS_SR_OFFSET 0x00 /**< Status Register (read-only). See RTDS_AXIS_SR_* constant. */
|
||||
#define RTDS_AXIS_CR_OFFSET 0x04 /**< Control Register (read/write) */
|
||||
#define RTDS_AXIS_TSCNT_LOW_OFFSET 0x08 /**< Lower 32 bits of timestep counter (read-only). */
|
||||
#define RTDS_AXIS_TSCNT_HIGH_OFFSET 0x0C /**< Higher 32 bits of timestep counter (read-only). */
|
||||
#define RTDS_AXIS_TS_PERIOD_OFFSET 0x10 /**< Period in clock cycles of previous timestep (read-only). */
|
||||
#define RTDS_AXIS_COALESC_OFFSET 0x14 /**< IRQ Coalescing register (read/write). */
|
||||
#define RTDS_AXIS_VERSION_OFFSET 0x18 /**< 16 bit version field passed back to the rack for version reporting (visible from “status” command, read/write). */
|
||||
#define RTDS_AXIS_MRATE 0x1C /**< Multi-rate register */
|
||||
// Register offsets
|
||||
#define RTDS_AXIS_SR_OFFSET 0x00 // Status Register (read-only). See RTDS_AXIS_SR_* constant.
|
||||
#define RTDS_AXIS_CR_OFFSET 0x04 // Control Register (read/write)
|
||||
#define RTDS_AXIS_TSCNT_LOW_OFFSET 0x08 // Lower 32 bits of timestep counter (read-only).
|
||||
#define RTDS_AXIS_TSCNT_HIGH_OFFSET 0x0C // Higher 32 bits of timestep counter (read-only).
|
||||
#define RTDS_AXIS_TS_PERIOD_OFFSET 0x10 // Period in clock cycles of previous timestep (read-only).
|
||||
#define RTDS_AXIS_COALESC_OFFSET 0x14 // IRQ Coalescing register (read/write).
|
||||
#define RTDS_AXIS_VERSION_OFFSET 0x18 // 16 bit version field passed back to the rack for version reporting (visible from “status” command, read/write).
|
||||
#define RTDS_AXIS_MRATE 0x1C // Multi-rate register
|
||||
|
||||
/* Status register bits */
|
||||
#define RTDS_AXIS_SR_CARDDETECTED (1 << 0)/**< ‘1’ when RTDS software has detected and configured card. */
|
||||
#define RTDS_AXIS_SR_LINKUP (1 << 1)/**< ‘1’ when RTDS communication link has been negotiated. */
|
||||
#define RTDS_AXIS_SR_TX_FULL (1 << 2)/**< Tx buffer is full, writes that happen when UserTxFull=’1’ will be dropped (Throttling / buffering is performed by hardware). */
|
||||
#define RTDS_AXIS_SR_TX_INPROGRESS (1 << 3)/**< Indicates when data is being put on link. */
|
||||
#define RTDS_AXIS_SR_CASE_RUNNING (1 << 4)/**< There is currently a simulation running. */
|
||||
// Status register bits
|
||||
#define RTDS_AXIS_SR_CARDDETECTED (1 << 0) // ‘1’ when RTDS software has detected and configured card.
|
||||
#define RTDS_AXIS_SR_LINKUP (1 << 1) // ‘1’ when RTDS communication link has been negotiated.
|
||||
#define RTDS_AXIS_SR_TX_FULL (1 << 2) // Tx buffer is full, writes that happen when UserTxFull=’1’ will be dropped (Throttling / buffering is performed by hardware).
|
||||
#define RTDS_AXIS_SR_TX_INPROGRESS (1 << 3) // Indicates when data is being put on link.
|
||||
#define RTDS_AXIS_SR_CASE_RUNNING (1 << 4) // There is currently a simulation running.
|
||||
|
||||
/* Control register bits */
|
||||
#define RTDS_AXIS_CR_DISABLE_LINK 0 /**< Disable SFP TX when set */
|
||||
// Control register bits
|
||||
#define RTDS_AXIS_CR_DISABLE_LINK 0 // Disable SFP TX when set
|
||||
|
||||
using namespace villas::fpga::ip;
|
||||
|
||||
|
@ -60,7 +60,7 @@ static RtdsFactory rtdsFactoryInstance;
|
|||
|
||||
void Rtds::dump()
|
||||
{
|
||||
/* Check RTDS_Axis registers */
|
||||
// Check RTDS_Axis registers
|
||||
const uint32_t sr = readMemory<uint32_t>(registerMemory, RTDS_AXIS_SR_OFFSET);
|
||||
|
||||
logger->info("RTDS AXI Stream interface details:");
|
||||
|
|
|
@ -67,19 +67,19 @@ void Gpu2Rtds::dump(spdlog::level::level_enum logLevel)
|
|||
// getMasterAddrSpaceByInterface(axiInterface),
|
||||
// mem.getAddrSpaceId());
|
||||
|
||||
// // set address of memory block in HLS IP
|
||||
// // Set address of memory block in HLS IP
|
||||
// XGpu2Rtds_Set_baseaddr(&xInstance, translationFromIp.getLocalAddr(0));
|
||||
|
||||
// XGpu2Rtds_Set_doorbell_offset(&xInstance, doorbellOffset);
|
||||
// XGpu2Rtds_Set_data_offset(&xInstance, dataOffset);
|
||||
// XGpu2Rtds_Set_frame_size(&xInstance, frameSize);
|
||||
|
||||
// // prepare memory with all zeroes
|
||||
// // 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
|
||||
// // Start IP
|
||||
// return start();
|
||||
//}
|
||||
|
||||
|
|
|
@ -61,19 +61,19 @@ bool Rtds2Gpu::startOnce(const MemoryBlock &mem, size_t frameSize, size_t dataOf
|
|||
getMasterAddrSpaceByInterface(axiInterface),
|
||||
mem.getAddrSpaceId());
|
||||
|
||||
// set address of memory block in HLS IP
|
||||
// Set address of memory block in HLS IP
|
||||
XRtds2gpu_Set_baseaddr(&xInstance, translationFromIp.getLocalAddr(0));
|
||||
|
||||
XRtds2gpu_Set_doorbell_offset(&xInstance, doorbellOffset);
|
||||
XRtds2gpu_Set_data_offset(&xInstance, dataOffset);
|
||||
XRtds2gpu_Set_frame_size(&xInstance, frameSize);
|
||||
|
||||
// prepare memory with all zeroes
|
||||
// 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
|
||||
// Start IP
|
||||
return start();
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// File generated by Vivado(TM) HLS - High-Level Synthesis from C, C++ and SystemC
|
||||
// Version: 2017.3
|
||||
// Copyright (C) 1986-2017 Xilinx, Inc. All Rights Reserved.
|
||||
//
|
||||
//
|
||||
// ==============================================================
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
@ -58,7 +58,7 @@ u32 XRtds2gpu_IsReady(XRtds2gpu *InstancePtr) {
|
|||
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
Data = XRtds2gpu_ReadReg(InstancePtr->Ctrl_BaseAddress, XRTDS2GPU_CTRL_ADDR_AP_CTRL);
|
||||
// check ap_start to see if the pcore is ready for next input
|
||||
// Check ap_start to see if the pcore is ready for next input
|
||||
return !(Data & 0x1);
|
||||
}
|
||||
|
||||
|
|
|
@ -36,8 +36,8 @@ static AxiStreamSwitchFactory factory;
|
|||
|
||||
bool
|
||||
AxiStreamSwitch::init()
|
||||
{
|
||||
/* Setup AXI-stream switch */
|
||||
{
|
||||
// Setup AXI-stream switch
|
||||
XAxis_Switch_Config sw_cfg;
|
||||
sw_cfg.MaxNumMI = num_ports;
|
||||
sw_cfg.MaxNumSI = num_ports;
|
||||
|
@ -47,17 +47,17 @@ AxiStreamSwitch::init()
|
|||
return false;
|
||||
}
|
||||
|
||||
/* Disable all masters */
|
||||
// Disable all masters
|
||||
XAxisScr_RegUpdateDisable(&xSwitch);
|
||||
XAxisScr_MiPortDisableAll(&xSwitch);
|
||||
XAxisScr_RegUpdateEnable(&xSwitch);
|
||||
|
||||
for (auto& [masterName, masterPort] : portsMaster) {
|
||||
|
||||
// initialize internal mapping
|
||||
// Initialize internal mapping
|
||||
portMapping[masterName] = PORT_DISABLED;
|
||||
|
||||
// each slave port may be internally routed to a master port
|
||||
// Each slave port may be internally routed to a master port
|
||||
for (auto& [slaveName, slavePort] : portsSlave) {
|
||||
(void) slaveName;
|
||||
|
||||
|
@ -73,7 +73,7 @@ bool
|
|||
AxiStreamSwitch::connectInternal(const std::string &portSlave,
|
||||
const std::string &portMaster)
|
||||
{
|
||||
// check if slave port exists
|
||||
// Check if slave port exists
|
||||
try {
|
||||
getSlavePort(portSlave);
|
||||
} catch (const std::out_of_range&) {
|
||||
|
@ -81,7 +81,7 @@ AxiStreamSwitch::connectInternal(const std::string &portSlave,
|
|||
return false;
|
||||
}
|
||||
|
||||
// check if master port exists
|
||||
// Check if master port exists
|
||||
try {
|
||||
getMasterPort(portMaster);
|
||||
} catch (const std::out_of_range&) {
|
||||
|
@ -116,7 +116,7 @@ AxiStreamSwitch::connectInternal(const std::string &portSlave,
|
|||
}
|
||||
}
|
||||
|
||||
/* Reconfigure switch */
|
||||
// Reconfigure switch
|
||||
XAxisScr_RegUpdateDisable(&xSwitch);
|
||||
XAxisScr_MiPortEnable(&xSwitch, portNameToNum(portMaster), portNameToNum(portSlave));
|
||||
XAxisScr_RegUpdateEnable(&xSwitch);
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
using namespace villas::fpga::ip;
|
||||
|
||||
|
||||
// instantiate factory to make available to plugin infrastructure
|
||||
// Instantiate factory to make available to plugin infrastructure
|
||||
static TimerFactory factory;
|
||||
|
||||
bool Timer::init()
|
||||
|
@ -49,7 +49,7 @@ bool Timer::init()
|
|||
return false;
|
||||
}
|
||||
|
||||
// disable so we don't receive any stray interrupts
|
||||
// Disable so we don't receive any stray interrupts
|
||||
irqs[irqName].irqController->disableInterrupt(irqs[irqName]);
|
||||
|
||||
return true;
|
||||
|
|
|
@ -89,7 +89,7 @@ NodeFactory::configureJson(Core &ip, json_t* json_ip)
|
|||
Node::streamGraph.addDefaultEdge(thisVertex->getIdentifier(),
|
||||
connectedVertex->getIdentifier());
|
||||
Node.portsMaster[name_raw] = thisVertex;
|
||||
} else /* slave */ {
|
||||
} else { // Slave
|
||||
Node.portsSlave[name_raw] = thisVertex;
|
||||
}
|
||||
}
|
||||
|
@ -135,20 +135,17 @@ bool Node::connect(const StreamVertex &from, const StreamVertex &to)
|
|||
|
||||
auto nextHopNode = firstHopNode;
|
||||
|
||||
// check if next hop is an internal connection
|
||||
// Check if next hop is an internal connection
|
||||
if (firstHopNode->nodeName == getInstanceName()) {
|
||||
|
||||
if (not connectInternal(from.portName, firstHopNode->portName)) {
|
||||
logger->error("Making internal connection from {} to {} failed",
|
||||
from, *firstHopNode);
|
||||
return false;
|
||||
}
|
||||
|
||||
// we have to advance to next hop
|
||||
if (++currentEdge == path.end()) {
|
||||
// arrived at the end of path
|
||||
return true;
|
||||
}
|
||||
// We have to advance to next hop
|
||||
if (++currentEdge == path.end())
|
||||
return true; // Arrived at the end of path
|
||||
|
||||
auto secondEdge = streamGraph.getEdge(*currentEdge);
|
||||
auto secondHopNode = streamGraph.getVertex(secondEdge->getVertexTo());
|
||||
|
|
|
@ -30,7 +30,7 @@ using namespace villas::fpga;
|
|||
bool
|
||||
Vlnv::operator==(const Vlnv &other) const
|
||||
{
|
||||
// if a field is empty, it means wildcard matching everything
|
||||
// If a field is empty, it means wildcard matching everything
|
||||
const bool vendorWildcard = vendor.empty() or other.vendor.empty();
|
||||
const bool libraryWildcard = library.empty() or other.library.empty();
|
||||
const bool nameWildcard = name.empty() or other.name.empty();
|
||||
|
@ -47,14 +47,14 @@ Vlnv::operator==(const Vlnv &other) const
|
|||
void
|
||||
Vlnv::parseFromString(std::string vlnv)
|
||||
{
|
||||
// tokenize by delimiter
|
||||
// Tokenize by delimiter
|
||||
std::stringstream sstream(vlnv);
|
||||
std::getline(sstream, vendor, delimiter);
|
||||
std::getline(sstream, library, delimiter);
|
||||
std::getline(sstream, name, delimiter);
|
||||
std::getline(sstream, version, delimiter);
|
||||
|
||||
// represent wildcard internally as empty string
|
||||
// Represent wildcard internally as empty string
|
||||
if (vendor == "*") vendor = "";
|
||||
if (library == "*") library = "";
|
||||
if (name == "*") name = "";
|
||||
|
|
|
@ -61,7 +61,7 @@ int fpga_benchmark_datamover(struct fpga_card *c)
|
|||
if (ret)
|
||||
error("Failed to enable interrupt");
|
||||
|
||||
/* Allocate DMA memory */
|
||||
// Allocate DMA memory
|
||||
ret = dma_alloc(dm, &mem, 2 * (1 << BENCH_DM_EXP_MAX), 0);
|
||||
if (ret)
|
||||
error("Failed to allocate DMA memory");
|
||||
|
@ -70,7 +70,7 @@ int fpga_benchmark_datamover(struct fpga_card *c)
|
|||
if (ret)
|
||||
return -1;
|
||||
|
||||
/* Open file for results */
|
||||
// Open file for results
|
||||
char fn[256];
|
||||
snprintf(fn, sizeof(fn), "results/datamover_%s_%s_%s.dat", dm_name, intc_flags & INTC_POLLING ? "polling" : "irq", uts.release);
|
||||
FILE *g = fopen(fn, "w");
|
||||
|
@ -80,10 +80,10 @@ int fpga_benchmark_datamover(struct fpga_card *c)
|
|||
|
||||
#if BENCH_DM == 1
|
||||
if (exp > 11)
|
||||
break; /* FIFO and Simple DMA are limited to 4kb */
|
||||
break; // FIFO and Simple DMA are limited to 4kb
|
||||
#elif BENCH_DM == 3
|
||||
if (exp >= 12)
|
||||
break; /* FIFO and Simple DMA are limited to 4kb */
|
||||
break; // FIFO and Simple DMA are limited to 4kb
|
||||
#endif
|
||||
|
||||
read_random(src.base_virt, len);
|
||||
|
|
|
@ -60,7 +60,7 @@ int fpga_benchmark_jitter(struct fpga_card *c)
|
|||
if (cnt != 1)
|
||||
warn("fail");
|
||||
|
||||
/* Ackowledge IRQ */
|
||||
// Ackowledge IRQ
|
||||
XTmrCtr_WriteReg((uintptr_t) c->map + ip->baseaddr, 0, XTC_TCSR_OFFSET, XTmrCtr_ReadReg((uintptr_t) c->map + ip->baseaddr, 0, XTC_TCSR_OFFSET));
|
||||
|
||||
end = rdtsc();
|
||||
|
|
|
@ -49,8 +49,8 @@ int fpga_benchmark_memcpy(struct fpga_card *c)
|
|||
start = rdtsc();
|
||||
|
||||
for (int j = 0; j < len / 4; j++)
|
||||
// mapi[j] = j; // write
|
||||
dummy += mapi[j]; // read
|
||||
// mapi[j] = j; // Write
|
||||
dummy += mapi[j]; // Read
|
||||
|
||||
end = rdtsc();
|
||||
|
||||
|
|
|
@ -32,14 +32,14 @@
|
|||
|
||||
#include "bench.h"
|
||||
|
||||
/* Some hard-coded configuration for the FPGA benchmarks */
|
||||
// Some hard-coded configuration for the FPGA benchmarks
|
||||
#define BENCH_WARMUP 100
|
||||
|
||||
/* Declared in fpga-bench.c */
|
||||
// Declared in fpga-bench.c
|
||||
extern int intc_flags;
|
||||
extern struct utsname uts;
|
||||
|
||||
/* LAPACK & BLAS Fortran prototypes */
|
||||
// LAPACK & BLAS Fortran prototypes
|
||||
extern int dgemm_(char *transa, char *transb, int *m, int *n, int *k, double *alpha, double *a, int *lda, double *b, int *ldb, double *beta, double *c, int *ldc);
|
||||
extern int dgetrf_(int *m, int *n, double *a, int *lda, int *ipiv, int *info);
|
||||
extern int dgetri_(int *n, double *a, int *lda, int *ipiv, double *work, int *lwork, int *info);
|
||||
|
@ -58,7 +58,7 @@ static int lapack_generate_workload(int N, double *C)
|
|||
double alpha = 1;
|
||||
double beta = 1;
|
||||
|
||||
/* C = A' * A, to get an invertible matrix */
|
||||
// C = A' * A, to get an invertible matrix
|
||||
dgemm_(&transA, &transB, &N, &N, &N, &alpha, A, &N, A, &N, &beta, C, &N);
|
||||
|
||||
free(A);
|
||||
|
@ -105,7 +105,7 @@ int fpga_benchmark_overruns(struct fpga_card *c)
|
|||
|
||||
intc_enable(c->intc, (1 << (dm->irq + 1 )), intc_flags);
|
||||
|
||||
/* Dump results */
|
||||
// Dump results
|
||||
char fn[256];
|
||||
snprintf(fn, sizeof(fn), "results/overruns_lu_rtds_axis_%s_%s.dat", intc_flags & INTC_POLLING ? "polling" : "irq", uts.release);
|
||||
FILE *g = fopen(fn, "w");
|
||||
|
@ -142,7 +142,7 @@ int fpga_benchmark_overruns(struct fpga_card *c)
|
|||
|
||||
dma_read_complete(dm, NULL, NULL);
|
||||
|
||||
/* Send data to rtds */
|
||||
// Send data to rtds
|
||||
data_tx[0] = i;
|
||||
dma_write(dm, mem.base_phys + 0x200, 64 * sizeof(data_tx[0]));
|
||||
|
||||
|
|
|
@ -78,7 +78,7 @@ again: ret = bench->func(c);
|
|||
if (ret)
|
||||
error("Benchmark %s failed", bench->name);
|
||||
|
||||
/* Rerun test with polling */
|
||||
// Rerun test with polling
|
||||
if (intc_flags == 0) {
|
||||
intc_flags |= INTC_POLLING;
|
||||
getchar();
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
|
||||
#include "config.h"
|
||||
|
||||
/* Some hard-coded configuration for the FPGA benchmarks */
|
||||
// Some hard-coded configuration for the FPGA benchmarks
|
||||
#define BENCH_DM 3
|
||||
// 1 FIFO
|
||||
// 2 DMA SG
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
|
||||
#include <villas/fpga/card.h>
|
||||
|
||||
/* Declarations */
|
||||
// Declarations
|
||||
int fpga_benchmarks(int argc, char *argv[], struct fpga_card *c);
|
||||
|
||||
void usage()
|
||||
|
@ -56,7 +56,7 @@ int main(int argc, char *argv[])
|
|||
struct vfio_container vc;
|
||||
struct fpga_card *card;
|
||||
|
||||
/* Parse arguments */
|
||||
// Parse arguments
|
||||
char c, *endptr;
|
||||
while ((c = getopt(argc, argv, "Vh")) != -1) {
|
||||
switch (c) {
|
||||
|
@ -93,7 +93,7 @@ check: if (optarg == endptr)
|
|||
if (ret)
|
||||
return -1;
|
||||
|
||||
/* Parse FPGA configuration */
|
||||
// Parse FPGA configuration
|
||||
f = fopen(configfile, "r");
|
||||
if (!f)
|
||||
return -1;
|
||||
|
@ -117,7 +117,7 @@ check: if (optarg == endptr)
|
|||
|
||||
fpga_card_dump(card);
|
||||
|
||||
/* Run benchmarks */
|
||||
// Run benchmarks
|
||||
fpga_benchmarks(argc-optind-1, argv+optind+1, card);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -78,7 +78,7 @@ int main(int argc, char **argv) {
|
|||
|
||||
fflush(stdout);
|
||||
|
||||
/* Map one page */
|
||||
// Map one page
|
||||
printf("mmap(%d, %lu, %#x, %#x, %d, %#jx)\n", 0,
|
||||
MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED,
|
||||
fd, (intmax_t) target);
|
||||
|
|
|
@ -39,7 +39,7 @@ Test(fpga, dma, .description = "DMA")
|
|||
auto logger = logging.get("unit-test:dma");
|
||||
|
||||
std::list<std::shared_ptr<fpga::ip::Dma>> dmaIps;
|
||||
|
||||
|
||||
for (auto &ip : state.cards.front()->ips) {
|
||||
if (*ip == fpga::Vlnv("xilinx.com:ip:axi_dma:")) {
|
||||
auto dma = std::dynamic_pointer_cast<fpga::ip::Dma>(ip);
|
||||
|
@ -63,13 +63,13 @@ Test(fpga, dma, .description = "DMA")
|
|||
size_t len = 4 * (1 << 10);
|
||||
|
||||
#if 0
|
||||
/* Allocate memory to use with DMA */
|
||||
// Allocate memory to use with DMA
|
||||
auto src = HostDmaRam::getAllocator().allocate<char>(len);
|
||||
auto dst = HostDmaRam::getAllocator().allocate<char>(len);
|
||||
#elif 0
|
||||
/* ... only works with IOMMU enabled currently */
|
||||
// ... only works with IOMMU enabled currently
|
||||
|
||||
/* find a block RAM IP to write to */
|
||||
// Find a block RAM IP to write to
|
||||
auto bramIp = state.cards.front()->lookupIp(fpga::Vlnv("xilinx.com:ip:axi_bram_ctrl:"));
|
||||
auto bram = std::dynamic_pointer_cast<fpga::ip::Bram>(bramIp);
|
||||
cr_assert_not_null(bram, "Couldn't find BRAM");
|
||||
|
@ -77,25 +77,25 @@ Test(fpga, dma, .description = "DMA")
|
|||
auto src = bram->getAllocator().allocate<char>(len);
|
||||
auto dst = bram->getAllocator().allocate<char>(len);
|
||||
#else
|
||||
/* ... only works with IOMMU enabled currently */
|
||||
// ... only works with IOMMU enabled currently
|
||||
auto src = HostRam::getAllocator().allocate<char>(len);
|
||||
auto dst = HostRam::getAllocator().allocate<char>(len);
|
||||
#endif
|
||||
/* Make sure memory is accessible for DMA */
|
||||
// Make sure memory is accessible for DMA
|
||||
cr_assert(dma->makeAccesibleFromVA(src.getMemoryBlock()),
|
||||
"Source memory not accessible for DMA");
|
||||
cr_assert(dma->makeAccesibleFromVA(dst.getMemoryBlock()),
|
||||
"Destination memory not accessible for DMA");
|
||||
|
||||
/* Get new random data */
|
||||
// Get new random data
|
||||
const size_t lenRandom = utils::readRandom(&src, len);
|
||||
cr_assert(len == lenRandom, "Failed to get random data");
|
||||
|
||||
/* Start transfer */
|
||||
// Start transfer
|
||||
cr_assert(dma->memcpy(src.getMemoryBlock(), dst.getMemoryBlock(), len),
|
||||
"DMA ping pong failed");
|
||||
|
||||
/* Compare data */
|
||||
// Compare data
|
||||
cr_assert(memcmp(&src, &dst, len) == 0, "Data not equal");
|
||||
|
||||
logger->info(CLR_GRN("Passed"));
|
||||
|
|
|
@ -42,7 +42,7 @@ Test(fpga, fifo, .description = "FIFO")
|
|||
auto logger = logging.get("unit-test:fifo");
|
||||
|
||||
for (auto &ip : state.cards.front()->ips) {
|
||||
// skip non-fifo IPs
|
||||
// Skip non-fifo IPs
|
||||
if (*ip != fpga::Vlnv("xilinx.com:ip:axi_fifo_mm_s:"))
|
||||
continue;
|
||||
|
||||
|
@ -59,7 +59,7 @@ Test(fpga, fifo, .description = "FIFO")
|
|||
continue;
|
||||
}
|
||||
|
||||
/* Get some random data to compare */
|
||||
// Get some random data to compare
|
||||
memset(dst, 0, sizeof(dst));
|
||||
len = utils::readRandom((char *) src, sizeof(src));
|
||||
if (len != sizeof(src)) {
|
||||
|
@ -79,7 +79,7 @@ Test(fpga, fifo, .description = "FIFO")
|
|||
continue;
|
||||
}
|
||||
|
||||
/* Compare data */
|
||||
// Compare data
|
||||
cr_assert_eq(memcmp(src, dst, sizeof(src)), 0, "Data not equal");
|
||||
|
||||
logger->info(CLR_GRN("Passed"));
|
||||
|
|
|
@ -58,7 +58,7 @@ static void init()
|
|||
|
||||
auto vfioContainer = kernel::vfio::Container::create();
|
||||
|
||||
/* Parse FPGA configuration */
|
||||
// Parse FPGA configuration
|
||||
char *fn = getenv("TEST_CONFIG");
|
||||
f = fopen(fn ? fn : TEST_CONFIG, "r");
|
||||
cr_assert_not_null(f, "Cannot open config file");
|
||||
|
@ -72,11 +72,11 @@ static void init()
|
|||
cr_assert_not_null(fpgas, "No section 'fpgas' found in config");
|
||||
cr_assert(json_object_size(json) > 0, "No FPGAs defined in config");
|
||||
|
||||
// get the FPGA card plugin
|
||||
// Get the FPGA card plugin
|
||||
auto fpgaCardFactory = plugin::registry->lookup<fpga::PCIeCardFactory>("pcie");
|
||||
cr_assert_not_null(fpgaCardFactory, "No plugin for FPGA card found");
|
||||
|
||||
// create all FPGA card instances using the corresponding plugin
|
||||
// Create all FPGA card instances using the corresponding plugin
|
||||
state.cards = fpgaCardFactory->make(fpgas, pciDevices, vfioContainer);
|
||||
|
||||
cr_assert(state.cards.size() != 0, "No FPGA cards found!");
|
||||
|
@ -86,7 +86,7 @@ static void init()
|
|||
|
||||
static void fini()
|
||||
{
|
||||
// release all cards
|
||||
// Release all cards
|
||||
state.cards.clear();
|
||||
}
|
||||
|
||||
|
|
|
@ -28,9 +28,9 @@
|
|||
|
||||
class FpgaState {
|
||||
public:
|
||||
// list of all available FPGA cards, only first will be tested at the moment
|
||||
// List of all available FPGA cards, only first will be tested at the moment
|
||||
villas::fpga::PCIeCard::List cards;
|
||||
};
|
||||
|
||||
// global state to be shared by unittests
|
||||
// Global state to be shared by unittests
|
||||
extern FpgaState state;
|
||||
|
|
|
@ -52,12 +52,12 @@ Test(fpga, gpu_dma, .description = "GPU DMA tests")
|
|||
auto gpus = gpuPlugin->make();
|
||||
cr_assert(gpus.size() > 0, "No GPUs found");
|
||||
|
||||
// just get first cpu
|
||||
// Just get first cpu
|
||||
auto &gpu = gpus.front();
|
||||
|
||||
size_t count = 0;
|
||||
for (auto &ip : card->ips) {
|
||||
// skip non-dma IPs
|
||||
// Skip non-dma IPs
|
||||
if (*ip != fpga::Vlnv("xilinx.com:ip:axi_bram_ctrl:"))
|
||||
continue;
|
||||
|
||||
|
@ -70,7 +70,7 @@ Test(fpga, gpu_dma, .description = "GPU DMA tests")
|
|||
|
||||
size_t len = 4 * (1 << 10);
|
||||
|
||||
/* Allocate memory to use with DMA */
|
||||
// Allocate memory to use with DMA
|
||||
|
||||
auto bram0 = bram->getAllocator().allocate<char>(len);
|
||||
auto bram1 = bram->getAllocator().allocate<char>(len);
|
||||
|
@ -132,7 +132,7 @@ Test(fpga, gpu_dma, .description = "GPU DMA tests")
|
|||
for (auto& [name, memcpyFunc] : memcpyFuncs) {
|
||||
logger->info("Testing {}", name);
|
||||
|
||||
/* Get new random data */
|
||||
// Get new random data
|
||||
const size_t lenRandom = utils::read_random(&src, len);
|
||||
cr_assert(len == lenRandom, "Failed to get random data");
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ Test(fpga, hls_dft, .description = "HLS: hls_dft")
|
|||
rtds = fpga_vlnv_lookup(&card->ips, &(struct fpga_vlnv) { "acs.eonerc.rwth-aachen.de", "user", "rtds_axis", NULL });
|
||||
hls = fpga_vlnv_lookup(&card->ips, &(struct fpga_vlnv) { NULL, "hls", "hls_dft", NULL });
|
||||
|
||||
/* Check if required IP is available on FPGA */
|
||||
// Check if required IP is available on FPGA
|
||||
cr_assert(hls && rtds);
|
||||
|
||||
ret = intc_enable(card->intc, (1 << rtds->irq), 0);
|
||||
|
@ -52,7 +52,7 @@ Test(fpga, hls_dft, .description = "HLS: hls_dft")
|
|||
cr_assert_eq(ret, 0, "Failed to configure switch");
|
||||
|
||||
while (1) {
|
||||
/* Dump RTDS AXI Stream state */
|
||||
// Dump RTDS AXI Stream state
|
||||
rtds_axis_dump(rtds);
|
||||
sleep(1);
|
||||
}
|
||||
|
|
|
@ -40,18 +40,18 @@ Test(fpga, intc, .description = "Interrupt Controller")
|
|||
ret = intc_enable(card->intc, 0xFF00, 0);
|
||||
cr_assert_eq(ret, 0, "Failed to enable interrupt");
|
||||
|
||||
/* Fake IRQs in software by writing to ISR */
|
||||
// Fake IRQs in software by writing to ISR
|
||||
XIntc_Out32((uintptr_t) card->map + card->intc->baseaddr + XIN_ISR_OFFSET, 0xFF00);
|
||||
|
||||
/* Wait for 8 SW triggered IRQs */
|
||||
// Wait for 8 SW triggered IRQs
|
||||
for (int i = 0; i < 8; i++)
|
||||
intc_wait(card->intc, i+8);
|
||||
|
||||
/* Check ISR if all SW IRQs have been deliverd */
|
||||
// Check ISR if all SW IRQs have been deliverd
|
||||
isr = XIntc_In32((uintptr_t) card->map + card->intc->baseaddr + XIN_ISR_OFFSET);
|
||||
|
||||
ret = intc_disable(card->intc, 0xFF00);
|
||||
cr_assert_eq(ret, 0, "Failed to disable interrupt");
|
||||
|
||||
cr_assert_eq(isr & 0xFF00, 0); /* ISR should get cleared by MSI_Grant_signal */
|
||||
cr_assert_eq(isr & 0xFF00, 0); // ISR should get cleared by MSI_Grant_signal
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
#include <spdlog/spdlog.h>
|
||||
|
||||
extern "C" {
|
||||
/* We override criterions function here */
|
||||
// We override criterions function here
|
||||
void criterion_log_noformat(enum criterion_severity severity, const char *msg);
|
||||
void criterion_plog(enum criterion_logging_level level, const struct criterion_prefix_data *prefix, const char *msg, ...);
|
||||
void criterion_vlog(enum criterion_logging_level level, const char *msg, va_list args);
|
||||
|
@ -45,7 +45,7 @@ static int format_msg(char *buf, size_t buflen, const char *msg, va_list args)
|
|||
{
|
||||
int len = vsnprintf(buf, buflen, msg, args);
|
||||
|
||||
/* Strip new line */
|
||||
// Strip new line
|
||||
char *nl = strchr(buf, '\n');
|
||||
if (nl)
|
||||
*nl = 0;
|
||||
|
@ -56,16 +56,16 @@ static int format_msg(char *buf, size_t buflen, const char *msg, va_list args)
|
|||
void criterion_log_noformat(enum criterion_severity severity, const char *msg)
|
||||
{
|
||||
auto logger = villas::logging.get("criterion");
|
||||
|
||||
|
||||
switch (severity) {
|
||||
case CR_LOG_INFO:
|
||||
logger->info(msg);
|
||||
break;
|
||||
|
||||
|
||||
case CR_LOG_WARNING:
|
||||
logger->warn(msg);
|
||||
break;
|
||||
|
||||
|
||||
case CR_LOG_ERROR:
|
||||
logger->error(msg);
|
||||
break;
|
||||
|
@ -75,7 +75,7 @@ void criterion_log_noformat(enum criterion_severity severity, const char *msg)
|
|||
void criterion_vlog(enum criterion_logging_level level, const char *msg, va_list args)
|
||||
{
|
||||
char formatted_msg[1024];
|
||||
|
||||
|
||||
if (level < criterion_options.logging_threshold)
|
||||
return;
|
||||
|
||||
|
@ -97,7 +97,7 @@ void criterion_plog(enum criterion_logging_level level, const struct criterion_p
|
|||
va_start(args, msg);
|
||||
format_msg(formatted_msg, sizeof(formatted_msg), msg, args);
|
||||
va_end(args);
|
||||
|
||||
|
||||
auto logger = villas::logging.get("criterion");
|
||||
|
||||
if (strstr(formatted_msg, "Warning"))
|
||||
|
@ -116,7 +116,7 @@ void criterion_plog(enum criterion_logging_level level, const struct criterion_p
|
|||
logger->info("Skip: {}", formatted_msg);
|
||||
else if (!strcmp(prefix->prefix, "PASS"))
|
||||
logger->info("Pass: {}", formatted_msg);
|
||||
else if (!strcmp(prefix->prefix, "FAIL"))
|
||||
else if (!strcmp(prefix->prefix, "FAIL"))
|
||||
logger->error("Fail: {}", formatted_msg);
|
||||
else if (!strcmp(prefix->prefix, "WARN"))
|
||||
logger->warn(formatted_msg);
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
|
||||
#include <spdlog/spdlog.h>
|
||||
|
||||
/** Returns true if there is at least one enabled test in this suite */
|
||||
// Returns true if there is at least one enabled test in this suite
|
||||
static bool suite_enabled(struct criterion_test_set *tests, const char *name)
|
||||
{
|
||||
FOREACH_SET(void *suite_ptr, tests->suites) {
|
||||
|
@ -44,11 +44,11 @@ static bool suite_enabled(struct criterion_test_set *tests, const char *name)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Limit number of parallel jobs to 1 in case we use the FPGA */
|
||||
// Limit number of parallel jobs to 1 in case we use the FPGA
|
||||
ReportHook(PRE_ALL)(struct criterion_test_set *tests)
|
||||
{
|
||||
if (suite_enabled(tests, "fpga")) {
|
||||
|
@ -66,7 +66,7 @@ int main(int argc, char *argv[])
|
|||
spdlog::set_level(spdlog::level::debug);
|
||||
spdlog::set_pattern("[%T] [%l] [%n] %v");
|
||||
|
||||
/* Run criterion tests */
|
||||
// Run criterion tests
|
||||
auto tests = criterion_initialize();
|
||||
|
||||
ret = criterion_handle_args(argc, argv, true);
|
||||
|
|
|
@ -80,8 +80,7 @@ Test(fpga, rtds2gpu_loopback_dma, .description = "Rtds2Gpu")
|
|||
logger->info("Testing {}", *ip);
|
||||
|
||||
|
||||
/* Collect neccessary IPs */
|
||||
|
||||
// Collect neccessary IPs
|
||||
auto rtds2gpu = std::dynamic_pointer_cast<fpga::ip::Rtds2Gpu>(ip);
|
||||
|
||||
auto axiSwitch = std::dynamic_pointer_cast<fpga::ip::AxiStreamSwitch>(
|
||||
|
@ -106,9 +105,9 @@ Test(fpga, rtds2gpu_loopback_dma, .description = "Rtds2Gpu")
|
|||
gpu2rtds->dump(spdlog::level::debug);
|
||||
|
||||
|
||||
/* Allocate and prepare memory */
|
||||
// Allocate and prepare memory
|
||||
|
||||
// allocate space for all samples and doorbell register
|
||||
// Allocate space for all samples and doorbell register
|
||||
auto dmaMemSrc = HostDmaRam::getAllocator(0).allocate<uint32_t>(SAMPLE_COUNT + 1);
|
||||
auto dmaMemDst = HostDmaRam::getAllocator(0).allocate<uint32_t>(SAMPLE_COUNT + 1);
|
||||
auto dmaMemDst2 = HostDmaRam::getAllocator(0).allocate<uint32_t>(SAMPLE_COUNT + 1);
|
||||
|
@ -127,7 +126,7 @@ Test(fpga, rtds2gpu_loopback_dma, .description = "Rtds2Gpu")
|
|||
dumpMem(dataDst2, dmaMemDst2.getMemoryBlock().getSize());
|
||||
|
||||
|
||||
// connect AXI Stream from DMA to Rtds2Gpu IP
|
||||
// Connect AXI Stream from DMA to Rtds2Gpu IP
|
||||
cr_assert(dma->connect(rtds2gpu));
|
||||
|
||||
cr_assert(rtds2gpu.startOnce(dmaMemDst.getMemoryBlock(), SAMPLE_COUNT, DATA_OFFSET * 4, DOORBELL_OFFSET * 4),
|
||||
|
@ -153,7 +152,7 @@ Test(fpga, rtds2gpu_loopback_dma, .description = "Rtds2Gpu")
|
|||
}
|
||||
|
||||
|
||||
// connect AXI Stream from Gpu2Rtds IP to DMA
|
||||
// Connect AXI Stream from Gpu2Rtds IP to DMA
|
||||
cr_assert(gpu2rtds->connect(*dma));
|
||||
|
||||
cr_assert(dma->read(dmaMemDst2.getMemoryBlock(), FRAME_SIZE),
|
||||
|
@ -182,8 +181,7 @@ Test(fpga, rtds2gpu_rtt_cpu, .description = "Rtds2Gpu RTT via CPU")
|
|||
{
|
||||
auto logger = logging.get("unit-test:rtds2gpu");
|
||||
|
||||
/* Collect neccessary IPs */
|
||||
|
||||
// Collect neccessary IPs
|
||||
auto gpu2rtds = std::dynamic_pointer_cast<fpga::ip::Gpu2Rtds>(
|
||||
state.cards.front()->lookupIp(fpga::Vlnv("acs.eonerc.rwth-aachen.de:hls:gpu2rtds:")));
|
||||
|
||||
|
@ -224,7 +222,7 @@ Test(fpga, rtds2gpu_rtt_cpu, .description = "Rtds2Gpu RTT via CPU")
|
|||
while (not rtds2gpu->doorbellIsValid(*doorbell));
|
||||
|
||||
|
||||
// copy samples to gpu2rtds IP
|
||||
// Copy samples to gpu2rtds IP
|
||||
for (size_t i = 0; i < SAMPLE_COUNT; i++) {
|
||||
gpu2rtds->registerFrames[i] = data[i];
|
||||
}
|
||||
|
@ -254,8 +252,7 @@ Test(fpga, rtds2gpu_rtt_gpu, .description = "Rtds2Gpu RTT via GPU")
|
|||
{
|
||||
auto logger = logging.get("unit-test:rtds2gpu");
|
||||
|
||||
/* Collect neccessary IPs */
|
||||
|
||||
// Collect neccessary IPs
|
||||
auto gpu2rtds = std::dynamic_pointer_cast<fpga::ip::Gpu2Rtds>(
|
||||
state.cards.front()->lookupIp(fpga::Vlnv("acs.eonerc.rwth-aachen.de:hls:gpu2rtds:")));
|
||||
|
||||
|
@ -271,14 +268,14 @@ Test(fpga, rtds2gpu_rtt_gpu, .description = "Rtds2Gpu RTT via GPU")
|
|||
auto gpus = gpuPlugin->make();
|
||||
cr_assert(gpus.size() > 0, "No GPUs found");
|
||||
|
||||
// just get first cpu
|
||||
// Just get first cpu
|
||||
auto &gpu = gpus.front();
|
||||
|
||||
// allocate memory on GPU and make accessible by to PCIe/FPGA
|
||||
// Allocate memory on GPU and make accessible by to PCIe/FPGA
|
||||
auto gpuRam = gpu->getAllocator().allocate<uint32_t>(SAMPLE_COUNT + 1);
|
||||
cr_assert(gpu->makeAccessibleToPCIeAndVA(gpuRam.getMemoryBlock()));
|
||||
|
||||
// make Gpu2Rtds IP register memory on FPGA accessible to GPU
|
||||
// Make Gpu2Rtds IP register memory on FPGA accessible to GPU
|
||||
cr_assert(gpu->makeAccessibleFromPCIeOrHostRam(gpu2rtds->getRegisterMemory()));
|
||||
|
||||
auto tr = gpu->translate(gpuRam.getMemoryBlock());
|
||||
|
@ -310,7 +307,7 @@ Test(fpga, rtds2gpu_rtt_gpu, .description = "Rtds2Gpu RTT via GPU")
|
|||
cr_assert(rtds.connect(*rtds2gpu));
|
||||
cr_assert(gpu2rtds->connect(rtds));
|
||||
|
||||
// launch once so they are configured
|
||||
// Launch once so they are configured
|
||||
cr_assert(rtds2gpu->startOnce(gpuRam.getMemoryBlock(), SAMPLE_COUNT, DATA_OFFSET * 4, DOORBELL_OFFSET * 4));
|
||||
cr_assert(gpu2rtds->startOnce(SAMPLE_COUNT));
|
||||
|
||||
|
@ -321,9 +318,6 @@ Test(fpga, rtds2gpu_rtt_gpu, .description = "Rtds2Gpu RTT via GPU")
|
|||
|
||||
std::string dummy;
|
||||
|
||||
// logger->info("Press enter to proceed");
|
||||
// std::cin >> dummy;
|
||||
|
||||
gpu_rtds_rtt_start(dataIn, doorbellIn, frameRegister, controlRegister);
|
||||
|
||||
// while (1) {
|
||||
|
|
|
@ -42,7 +42,7 @@ Test(fpga, rtds_rtt, .description = "RTDS: tight rtt")
|
|||
std::list<villas::fpga::ip::Rtds*> rtdsIps;
|
||||
std::list<villas::fpga::ip::Dma*> dmaIps;
|
||||
|
||||
/* Get IP cores */
|
||||
// Get IP cores
|
||||
for (auto &ip : state.cards.front()->ips) {
|
||||
if (*ip == villas::fpga::Vlnv("acs.eonerc.rwth-aachen.de:user:rtds_axis:")) {
|
||||
auto rtds = reinterpret_cast<villas::fpga::ip::Rtds*>(ip.get());
|
||||
|
|
|
@ -36,10 +36,9 @@ Test(fpga, timer, .description = "Timer Counter")
|
|||
|
||||
size_t count = 0;
|
||||
for (auto &ip : state.cards.front()->ips) {
|
||||
// skip non-timer IPs
|
||||
if (*ip != villas::fpga::Vlnv("xilinx.com:ip:axi_timer:")) {
|
||||
// Skip non-timer IPs
|
||||
if (*ip != villas::fpga::Vlnv("xilinx.com:ip:axi_timer:"))
|
||||
continue;
|
||||
}
|
||||
|
||||
logger->info("Testing {}", *ip);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue