mirror of
https://git.rwth-aachen.de/acs/public/villas/node/
synced 2025-03-09 00:00:00 +01:00
rtds2gpu IP works
This commit is contained in:
parent
b03b94d754
commit
bf286568dd
12 changed files with 767 additions and 35 deletions
|
@ -33,14 +33,25 @@
|
|||
"hier_0_axi_dma_axi_dma_0": {
|
||||
"vlnv": "xilinx.com:ip:axi_dma:7.1",
|
||||
"memory-view": {
|
||||
"M_AXI_SG": {
|
||||
"bram_0_axi_bram_ctrl_0": {
|
||||
"Mem0": {
|
||||
"M_AXI_MM2S": {
|
||||
"pcie_0_axi_pcie_0": {
|
||||
"BAR0": {
|
||||
"baseaddr": 0,
|
||||
"highaddr": 8191,
|
||||
"size": 8192
|
||||
"highaddr": 4294967295,
|
||||
"size": 4294967296
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
"M_AXI_S2MM": {
|
||||
"pcie_0_axi_pcie_0": {
|
||||
"BAR0": {
|
||||
"baseaddr": 0,
|
||||
"highaddr": 4294967295,
|
||||
"size": 4294967296
|
||||
}
|
||||
}
|
||||
},
|
||||
"M_AXI_SG": {
|
||||
"hier_0_axi_dma_axi_dma_1": {
|
||||
"Reg": {
|
||||
"baseaddr": 8192,
|
||||
|
@ -109,6 +120,27 @@
|
|||
"size": 4096
|
||||
}
|
||||
},
|
||||
"mem_0": {
|
||||
"Reg": {
|
||||
"baseaddr": 57344,
|
||||
"highaddr": 61439,
|
||||
"size": 4096
|
||||
}
|
||||
},
|
||||
"rtds2gpu_0": {
|
||||
"Reg": {
|
||||
"baseaddr": 61440,
|
||||
"highaddr": 65535,
|
||||
"size": 4096
|
||||
}
|
||||
},
|
||||
"bram_0_axi_bram_ctrl_0": {
|
||||
"Mem0": {
|
||||
"baseaddr": 65536,
|
||||
"highaddr": 73727,
|
||||
"size": 8192
|
||||
}
|
||||
},
|
||||
"pcie_0_axi_pcie_0": {
|
||||
"CTL0": {
|
||||
"baseaddr": 268435456,
|
||||
|
@ -116,24 +148,6 @@
|
|||
"size": 268435456
|
||||
}
|
||||
}
|
||||
},
|
||||
"M_AXI_MM2S": {
|
||||
"pcie_0_axi_pcie_0": {
|
||||
"BAR0": {
|
||||
"baseaddr": 0,
|
||||
"highaddr": 4294967295,
|
||||
"size": 4294967296
|
||||
}
|
||||
}
|
||||
},
|
||||
"M_AXI_S2MM": {
|
||||
"pcie_0_axi_pcie_0": {
|
||||
"BAR0": {
|
||||
"baseaddr": 0,
|
||||
"highaddr": 4294967295,
|
||||
"size": 4294967296
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"ports": [
|
||||
|
@ -234,7 +248,7 @@
|
|||
"name": "S04_AXIS"
|
||||
}
|
||||
],
|
||||
"num_ports": 7
|
||||
"num_ports": 8
|
||||
},
|
||||
"hier_0_hls_dft_0": {
|
||||
"vlnv": "acs.eonerc.rwth-aachen.de:hls:hls_dft:1.1",
|
||||
|
@ -274,17 +288,24 @@
|
|||
"irq_case": "pcie_0_axi_pcie_intc_0:7"
|
||||
}
|
||||
},
|
||||
"mem_0": {
|
||||
"vlnv": "xilinx.com:hls:mem:1.6",
|
||||
"memory-view": {
|
||||
"m_axi_gmem": {
|
||||
"pcie_0_axi_pcie_0": {
|
||||
"BAR0": {
|
||||
"baseaddr": 0,
|
||||
"highaddr": 4294967295,
|
||||
"size": 4294967296
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"pcie_0_axi_pcie_0": {
|
||||
"vlnv": "xilinx.com:ip:axi_pcie:2.8",
|
||||
"memory-view": {
|
||||
"M_AXI": {
|
||||
"bram_0_axi_bram_ctrl_0": {
|
||||
"Mem0": {
|
||||
"baseaddr": 0,
|
||||
"highaddr": 8191,
|
||||
"size": 8192
|
||||
}
|
||||
},
|
||||
"hier_0_axi_dma_axi_dma_1": {
|
||||
"Reg": {
|
||||
"baseaddr": 8192,
|
||||
|
@ -353,6 +374,27 @@
|
|||
"size": 4096
|
||||
}
|
||||
},
|
||||
"mem_0": {
|
||||
"Reg": {
|
||||
"baseaddr": 57344,
|
||||
"highaddr": 61439,
|
||||
"size": 4096
|
||||
}
|
||||
},
|
||||
"rtds2gpu_0": {
|
||||
"Reg": {
|
||||
"baseaddr": 61440,
|
||||
"highaddr": 65535,
|
||||
"size": 4096
|
||||
}
|
||||
},
|
||||
"bram_0_axi_bram_ctrl_0": {
|
||||
"Mem0": {
|
||||
"baseaddr": 65536,
|
||||
"highaddr": 73727,
|
||||
"size": 8192
|
||||
}
|
||||
},
|
||||
"pcie_0_axi_pcie_0": {
|
||||
"CTL0": {
|
||||
"baseaddr": 268435456,
|
||||
|
@ -382,6 +424,27 @@
|
|||
"pcie_0_axi_reset_0": {
|
||||
"vlnv": "xilinx.com:ip:axi_gpio:2.0"
|
||||
},
|
||||
"rtds2gpu_0": {
|
||||
"vlnv": "xilinx.com:hls:rtds2gpu:1.0",
|
||||
"memory-view": {
|
||||
"m_axi_axi_mm": {
|
||||
"pcie_0_axi_pcie_0": {
|
||||
"BAR0": {
|
||||
"baseaddr": 0,
|
||||
"highaddr": 4294967295,
|
||||
"size": 4294967296
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"ports": [
|
||||
{
|
||||
"role": "slave",
|
||||
"target": "hier_0_axis_interconnect_0_axis_interconnect_0_xbar:7",
|
||||
"name": "rtds_input"
|
||||
}
|
||||
]
|
||||
},
|
||||
"timer_0_axi_timer_0": {
|
||||
"vlnv": "xilinx.com:ip:axi_timer:2.0",
|
||||
"irqs": {
|
||||
|
|
|
@ -43,7 +43,10 @@ public:
|
|||
bool init();
|
||||
bool reset();
|
||||
|
||||
// memory-mapped to stream (MM2S)
|
||||
bool write(const MemoryBlock& mem, size_t len);
|
||||
|
||||
// stream to memory-mapped (S2MM)
|
||||
bool read(const MemoryBlock& mem, size_t len);
|
||||
|
||||
size_t writeComplete()
|
||||
|
|
59
fpga/include/villas/fpga/ips/rtds2gpu.hpp
Normal file
59
fpga/include/villas/fpga/ips/rtds2gpu.hpp
Normal file
|
@ -0,0 +1,59 @@
|
|||
#pragma once
|
||||
|
||||
#include <villas/memory.hpp>
|
||||
#include <villas/fpga/ip_node.hpp>
|
||||
|
||||
#include "rtds2gpu/xrtds2gpu.h"
|
||||
|
||||
namespace villas {
|
||||
namespace fpga {
|
||||
namespace ip {
|
||||
|
||||
|
||||
class Rtds2Gpu : public IpNode
|
||||
{
|
||||
public:
|
||||
friend class Rtds2GpuFactory;
|
||||
|
||||
bool init();
|
||||
|
||||
void dump();
|
||||
|
||||
bool startOnce(const MemoryBlock& mem, size_t frameSize);
|
||||
|
||||
bool isDone();
|
||||
|
||||
private:
|
||||
static constexpr const char* registerMemory = "Reg";
|
||||
static constexpr const char* axiInterface = "m_axi_axi_mm";
|
||||
static constexpr const char* streamInterface = "rtds_input";
|
||||
|
||||
std::list<MemoryBlockName> getMemoryBlocks() const
|
||||
{ return { registerMemory }; }
|
||||
|
||||
XRtds2gpu xInstance;
|
||||
};
|
||||
|
||||
|
||||
class Rtds2GpuFactory : public IpNodeFactory {
|
||||
public:
|
||||
Rtds2GpuFactory();
|
||||
|
||||
IpCore* create()
|
||||
{ return new Rtds2Gpu; }
|
||||
|
||||
std::string
|
||||
getName() const
|
||||
{ return "Rtds2Gpu"; }
|
||||
|
||||
std::string
|
||||
getDescription() const
|
||||
{ return "HLS RTDS2GPU IP"; }
|
||||
|
||||
Vlnv getCompatibleVlnv() const
|
||||
{ return {"xilinx.com:hls:rtds2gpu:"}; }
|
||||
};
|
||||
|
||||
} // namespace ip
|
||||
} // namespace fpga
|
||||
} // namespace villas
|
114
fpga/include/villas/fpga/ips/rtds2gpu/xrtds2gpu.h
Normal file
114
fpga/include/villas/fpga/ips/rtds2gpu/xrtds2gpu.h
Normal file
|
@ -0,0 +1,114 @@
|
|||
// ==============================================================
|
||||
// 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.
|
||||
//
|
||||
// ==============================================================
|
||||
|
||||
#ifndef XRTDS2GPU_H
|
||||
#define XRTDS2GPU_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
#ifndef __linux__
|
||||
#include "xil_types.h"
|
||||
#include "xil_assert.h"
|
||||
#include "xstatus.h"
|
||||
#include "xil_io.h"
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#include <assert.h>
|
||||
#include <dirent.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/mman.h>
|
||||
#include <unistd.h>
|
||||
#include <stddef.h>
|
||||
#endif
|
||||
#include "xrtds2gpu_hw.h"
|
||||
|
||||
/**************************** Type Definitions ******************************/
|
||||
#ifdef __linux__
|
||||
typedef uint8_t u8;
|
||||
typedef uint16_t u16;
|
||||
typedef uint32_t u32;
|
||||
#else
|
||||
typedef struct {
|
||||
u16 DeviceId;
|
||||
u32 Ctrl_BaseAddress;
|
||||
} XRtds2gpu_Config;
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
u32 Ctrl_BaseAddress;
|
||||
u32 IsReady;
|
||||
} XRtds2gpu;
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
#ifndef __linux__
|
||||
#define XRtds2gpu_WriteReg(BaseAddress, RegOffset, Data) \
|
||||
Xil_Out32((BaseAddress) + (RegOffset), (u32)(Data))
|
||||
#define XRtds2gpu_ReadReg(BaseAddress, RegOffset) \
|
||||
Xil_In32((BaseAddress) + (RegOffset))
|
||||
#else
|
||||
#define XRtds2gpu_WriteReg(BaseAddress, RegOffset, Data) \
|
||||
*(volatile u32*)((BaseAddress) + (RegOffset)) = (u32)(Data)
|
||||
#define XRtds2gpu_ReadReg(BaseAddress, RegOffset) \
|
||||
*(volatile u32*)((BaseAddress) + (RegOffset))
|
||||
|
||||
#define Xil_AssertVoid(expr) assert(expr)
|
||||
#define Xil_AssertNonvoid(expr) assert(expr)
|
||||
|
||||
#define XST_SUCCESS 0
|
||||
#define XST_DEVICE_NOT_FOUND 2
|
||||
#define XST_OPEN_DEVICE_FAILED 3
|
||||
#define XIL_COMPONENT_IS_READY 1
|
||||
#endif
|
||||
|
||||
/************************** Function Prototypes *****************************/
|
||||
#ifndef __linux__
|
||||
int XRtds2gpu_Initialize(XRtds2gpu *InstancePtr, u16 DeviceId);
|
||||
XRtds2gpu_Config* XRtds2gpu_LookupConfig(u16 DeviceId);
|
||||
int XRtds2gpu_CfgInitialize(XRtds2gpu *InstancePtr, XRtds2gpu_Config *ConfigPtr);
|
||||
#else
|
||||
int XRtds2gpu_Initialize(XRtds2gpu *InstancePtr, const char* InstanceName);
|
||||
int XRtds2gpu_Release(XRtds2gpu *InstancePtr);
|
||||
#endif
|
||||
|
||||
void XRtds2gpu_Start(XRtds2gpu *InstancePtr);
|
||||
u32 XRtds2gpu_IsDone(XRtds2gpu *InstancePtr);
|
||||
u32 XRtds2gpu_IsIdle(XRtds2gpu *InstancePtr);
|
||||
u32 XRtds2gpu_IsReady(XRtds2gpu *InstancePtr);
|
||||
void XRtds2gpu_EnableAutoRestart(XRtds2gpu *InstancePtr);
|
||||
void XRtds2gpu_DisableAutoRestart(XRtds2gpu *InstancePtr);
|
||||
|
||||
void XRtds2gpu_Set_baseaddr(XRtds2gpu *InstancePtr, u32 Data);
|
||||
u32 XRtds2gpu_Get_baseaddr(XRtds2gpu *InstancePtr);
|
||||
void XRtds2gpu_Set_data_offset(XRtds2gpu *InstancePtr, u32 Data);
|
||||
u32 XRtds2gpu_Get_data_offset(XRtds2gpu *InstancePtr);
|
||||
void XRtds2gpu_Set_doorbell_offset(XRtds2gpu *InstancePtr, u32 Data);
|
||||
u32 XRtds2gpu_Get_doorbell_offset(XRtds2gpu *InstancePtr);
|
||||
void XRtds2gpu_Set_status_i(XRtds2gpu *InstancePtr, u32 Data);
|
||||
u32 XRtds2gpu_Get_status_i(XRtds2gpu *InstancePtr);
|
||||
u32 XRtds2gpu_Get_status_o(XRtds2gpu *InstancePtr);
|
||||
void XRtds2gpu_Set_frame_size(XRtds2gpu *InstancePtr, u32 Data);
|
||||
u32 XRtds2gpu_Get_frame_size(XRtds2gpu *InstancePtr);
|
||||
|
||||
void XRtds2gpu_InterruptGlobalEnable(XRtds2gpu *InstancePtr);
|
||||
void XRtds2gpu_InterruptGlobalDisable(XRtds2gpu *InstancePtr);
|
||||
void XRtds2gpu_InterruptEnable(XRtds2gpu *InstancePtr, u32 Mask);
|
||||
void XRtds2gpu_InterruptDisable(XRtds2gpu *InstancePtr, u32 Mask);
|
||||
void XRtds2gpu_InterruptClear(XRtds2gpu *InstancePtr, u32 Mask);
|
||||
u32 XRtds2gpu_InterruptGetEnabled(XRtds2gpu *InstancePtr);
|
||||
u32 XRtds2gpu_InterruptGetStatus(XRtds2gpu *InstancePtr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
63
fpga/include/villas/fpga/ips/rtds2gpu/xrtds2gpu_hw.h
Normal file
63
fpga/include/villas/fpga/ips/rtds2gpu/xrtds2gpu_hw.h
Normal file
|
@ -0,0 +1,63 @@
|
|||
// ==============================================================
|
||||
// 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.
|
||||
//
|
||||
// ==============================================================
|
||||
|
||||
// CTRL
|
||||
// 0x00 : Control signals
|
||||
// bit 0 - ap_start (Read/Write/COH)
|
||||
// bit 1 - ap_done (Read/COR)
|
||||
// bit 2 - ap_idle (Read)
|
||||
// bit 3 - ap_ready (Read)
|
||||
// bit 7 - auto_restart (Read/Write)
|
||||
// others - reserved
|
||||
// 0x04 : Global Interrupt Enable Register
|
||||
// bit 0 - Global Interrupt Enable (Read/Write)
|
||||
// others - reserved
|
||||
// 0x08 : IP Interrupt Enable Register (Read/Write)
|
||||
// bit 0 - Channel 0 (ap_done)
|
||||
// bit 1 - Channel 1 (ap_ready)
|
||||
// others - reserved
|
||||
// 0x0c : IP Interrupt Status Register (Read/TOW)
|
||||
// bit 0 - Channel 0 (ap_done)
|
||||
// bit 1 - Channel 1 (ap_ready)
|
||||
// others - reserved
|
||||
// 0x10 : Data signal of baseaddr
|
||||
// bit 31~0 - baseaddr[31:0] (Read/Write)
|
||||
// 0x14 : reserved
|
||||
// 0x18 : Data signal of data_offset
|
||||
// bit 31~0 - data_offset[31:0] (Read/Write)
|
||||
// 0x1c : reserved
|
||||
// 0x20 : Data signal of doorbell_offset
|
||||
// bit 31~0 - doorbell_offset[31:0] (Read/Write)
|
||||
// 0x24 : reserved
|
||||
// 0x28 : Data signal of status_i
|
||||
// bit 31~0 - status_i[31:0] (Read/Write)
|
||||
// 0x2c : reserved
|
||||
// 0x30 : Data signal of status_o
|
||||
// bit 31~0 - status_o[31:0] (Read)
|
||||
// 0x34 : reserved
|
||||
// 0x38 : Data signal of frame_size
|
||||
// bit 31~0 - frame_size[31:0] (Read/Write)
|
||||
// 0x3c : reserved
|
||||
// (SC = Self Clear, COR = Clear on Read, TOW = Toggle on Write, COH = Clear on Handshake)
|
||||
|
||||
#define XRTDS2GPU_CTRL_ADDR_AP_CTRL 0x00
|
||||
#define XRTDS2GPU_CTRL_ADDR_GIE 0x04
|
||||
#define XRTDS2GPU_CTRL_ADDR_IER 0x08
|
||||
#define XRTDS2GPU_CTRL_ADDR_ISR 0x0c
|
||||
#define XRTDS2GPU_CTRL_ADDR_BASEADDR_DATA 0x10
|
||||
#define XRTDS2GPU_CTRL_BITS_BASEADDR_DATA 32
|
||||
#define XRTDS2GPU_CTRL_ADDR_DATA_OFFSET_DATA 0x18
|
||||
#define XRTDS2GPU_CTRL_BITS_DATA_OFFSET_DATA 32
|
||||
#define XRTDS2GPU_CTRL_ADDR_DOORBELL_OFFSET_DATA 0x20
|
||||
#define XRTDS2GPU_CTRL_BITS_DOORBELL_OFFSET_DATA 32
|
||||
#define XRTDS2GPU_CTRL_ADDR_STATUS_I_DATA 0x28
|
||||
#define XRTDS2GPU_CTRL_BITS_STATUS_I_DATA 32
|
||||
#define XRTDS2GPU_CTRL_ADDR_STATUS_O_DATA 0x30
|
||||
#define XRTDS2GPU_CTRL_BITS_STATUS_O_DATA 32
|
||||
#define XRTDS2GPU_CTRL_ADDR_FRAME_SIZE_DATA 0x38
|
||||
#define XRTDS2GPU_CTRL_BITS_FRAME_SIZE_DATA 32
|
||||
|
|
@ -15,6 +15,9 @@ set(SOURCES
|
|||
ips/bram.cpp
|
||||
ips/rtds.cpp
|
||||
|
||||
ips/rtds2gpu/rtds2gpu.cpp
|
||||
ips/rtds2gpu/xrtds2gpu.c
|
||||
|
||||
kernel/kernel.c
|
||||
kernel/pci.c
|
||||
kernel/vfio.cpp
|
||||
|
|
|
@ -165,7 +165,7 @@ Dma::write(const MemoryBlock& mem, size_t len)
|
|||
mem.getAddrSpaceId());
|
||||
const void* buf = reinterpret_cast<void*>(translation.getLocalAddr(0));
|
||||
|
||||
logger->debug("Write to address: {:p}", buf);
|
||||
logger->debug("Write to stream from address {:p}", buf);
|
||||
return hasScatterGather() ? writeSG(buf, len) : writeSimple(buf, len);
|
||||
}
|
||||
|
||||
|
@ -180,7 +180,7 @@ Dma::read(const MemoryBlock& mem, size_t len)
|
|||
mem.getAddrSpaceId());
|
||||
void* buf = reinterpret_cast<void*>(translation.getLocalAddr(0));
|
||||
|
||||
logger->debug("Read from address: {:p}", buf);
|
||||
logger->debug("Read from stream and write to address {:p}", buf);
|
||||
return hasScatterGather() ? readSG(buf, len) : readSimple(buf, len);
|
||||
}
|
||||
|
||||
|
|
87
fpga/lib/ips/rtds2gpu/rtds2gpu.cpp
Normal file
87
fpga/lib/ips/rtds2gpu/rtds2gpu.cpp
Normal file
|
@ -0,0 +1,87 @@
|
|||
#include <unistd.h>
|
||||
#include <cstring>
|
||||
|
||||
#include <villas/memory_manager.hpp>
|
||||
#include <villas/fpga/ips/rtds2gpu.hpp>
|
||||
|
||||
#include "log.hpp"
|
||||
|
||||
namespace villas {
|
||||
namespace fpga {
|
||||
namespace ip {
|
||||
|
||||
static Rtds2GpuFactory factory;
|
||||
|
||||
bool Rtds2Gpu::init()
|
||||
{
|
||||
xInstance.IsReady = XIL_COMPONENT_IS_READY;
|
||||
xInstance.Ctrl_BaseAddress = getBaseAddr(registerMemory);
|
||||
|
||||
// make sure IP is stopped for now
|
||||
XRtds2gpu_DisableAutoRestart(&xInstance);
|
||||
|
||||
dump();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Rtds2Gpu::dump()
|
||||
{
|
||||
const auto baseaddr = XRtds2gpu_Get_baseaddr(&xInstance);
|
||||
const auto data_offset = XRtds2gpu_Get_data_offset(&xInstance);
|
||||
const auto doorbell_offset = XRtds2gpu_Get_doorbell_offset(&xInstance);
|
||||
const auto frame_size = XRtds2gpu_Get_frame_size(&xInstance);
|
||||
const auto status = XRtds2gpu_Get_status_o(&xInstance);
|
||||
|
||||
logger->debug("Rtds2Gpu registers (IP base {:#x}):", xInstance.Ctrl_BaseAddress);
|
||||
logger->debug(" Base address (bytes): {:#x}", baseaddr);
|
||||
logger->debug(" Doorbell offset (bytes): {:#x}", doorbell_offset);
|
||||
logger->debug(" Data offset (bytes): {:#x}", data_offset);
|
||||
logger->debug(" Frame size (words): {:#x}", frame_size);
|
||||
logger->debug(" Status: {:#x}", status);
|
||||
}
|
||||
|
||||
bool Rtds2Gpu::startOnce(const MemoryBlock& mem, size_t frameSize)
|
||||
{
|
||||
auto& mm = MemoryManager::get();
|
||||
|
||||
auto translationFromIp = mm.getTranslation(
|
||||
getMasterAddrSpaceByInterface(axiInterface),
|
||||
mem.getAddrSpaceId());
|
||||
|
||||
// make sure IP is stopped for now
|
||||
XRtds2gpu_DisableAutoRestart(&xInstance);
|
||||
// while(not XRtds2gpu_IsIdle(&xInstance) and not XRtds2gpu_IsDone(&xInstance));
|
||||
|
||||
// set address of memory block in HLS IP
|
||||
XRtds2gpu_Set_baseaddr(&xInstance, translationFromIp.getLocalAddr(0));
|
||||
|
||||
XRtds2gpu_Set_doorbell_offset(&xInstance, 0);
|
||||
XRtds2gpu_Set_data_offset(&xInstance, 4);
|
||||
XRtds2gpu_Set_frame_size(&xInstance, frameSize);
|
||||
|
||||
// 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
|
||||
// XRtds2gpu_EnableAutoRestart(&xInstance);
|
||||
XRtds2gpu_Start(&xInstance);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Rtds2Gpu::isDone()
|
||||
{
|
||||
return XRtds2gpu_IsDone(&xInstance);
|
||||
}
|
||||
|
||||
Rtds2GpuFactory::Rtds2GpuFactory() :
|
||||
IpNodeFactory(getName())
|
||||
{
|
||||
}
|
||||
|
||||
} // namespace ip
|
||||
} // namespace fpga
|
||||
} // namespace villas
|
228
fpga/lib/ips/rtds2gpu/xrtds2gpu.c
Normal file
228
fpga/lib/ips/rtds2gpu/xrtds2gpu.c
Normal file
|
@ -0,0 +1,228 @@
|
|||
// ==============================================================
|
||||
// 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 *********************************/
|
||||
#include <villas/fpga/ips/rtds2gpu/xrtds2gpu.h>
|
||||
|
||||
/************************** Function Implementation *************************/
|
||||
#ifndef __linux__
|
||||
int XRtds2gpu_CfgInitialize(XRtds2gpu *InstancePtr, XRtds2gpu_Config *ConfigPtr) {
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
Xil_AssertNonvoid(ConfigPtr != NULL);
|
||||
|
||||
InstancePtr->Ctrl_BaseAddress = ConfigPtr->Ctrl_BaseAddress;
|
||||
InstancePtr->IsReady = XIL_COMPONENT_IS_READY;
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
void XRtds2gpu_Start(XRtds2gpu *InstancePtr) {
|
||||
u32 Data;
|
||||
|
||||
Xil_AssertVoid(InstancePtr != NULL);
|
||||
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
Data = XRtds2gpu_ReadReg(InstancePtr->Ctrl_BaseAddress, XRTDS2GPU_CTRL_ADDR_AP_CTRL) & 0x80;
|
||||
XRtds2gpu_WriteReg(InstancePtr->Ctrl_BaseAddress, XRTDS2GPU_CTRL_ADDR_AP_CTRL, Data | 0x01);
|
||||
}
|
||||
|
||||
u32 XRtds2gpu_IsDone(XRtds2gpu *InstancePtr) {
|
||||
u32 Data;
|
||||
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
Data = XRtds2gpu_ReadReg(InstancePtr->Ctrl_BaseAddress, XRTDS2GPU_CTRL_ADDR_AP_CTRL);
|
||||
return (Data >> 1) & 0x1;
|
||||
}
|
||||
|
||||
u32 XRtds2gpu_IsIdle(XRtds2gpu *InstancePtr) {
|
||||
u32 Data;
|
||||
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
Data = XRtds2gpu_ReadReg(InstancePtr->Ctrl_BaseAddress, XRTDS2GPU_CTRL_ADDR_AP_CTRL);
|
||||
return (Data >> 2) & 0x1;
|
||||
}
|
||||
|
||||
u32 XRtds2gpu_IsReady(XRtds2gpu *InstancePtr) {
|
||||
u32 Data;
|
||||
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
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
|
||||
return !(Data & 0x1);
|
||||
}
|
||||
|
||||
void XRtds2gpu_EnableAutoRestart(XRtds2gpu *InstancePtr) {
|
||||
Xil_AssertVoid(InstancePtr != NULL);
|
||||
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
XRtds2gpu_WriteReg(InstancePtr->Ctrl_BaseAddress, XRTDS2GPU_CTRL_ADDR_AP_CTRL, 0x80);
|
||||
}
|
||||
|
||||
void XRtds2gpu_DisableAutoRestart(XRtds2gpu *InstancePtr) {
|
||||
Xil_AssertVoid(InstancePtr != NULL);
|
||||
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
XRtds2gpu_WriteReg(InstancePtr->Ctrl_BaseAddress, XRTDS2GPU_CTRL_ADDR_AP_CTRL, 0);
|
||||
}
|
||||
|
||||
void XRtds2gpu_Set_baseaddr(XRtds2gpu *InstancePtr, u32 Data) {
|
||||
Xil_AssertVoid(InstancePtr != NULL);
|
||||
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
XRtds2gpu_WriteReg(InstancePtr->Ctrl_BaseAddress, XRTDS2GPU_CTRL_ADDR_BASEADDR_DATA, Data);
|
||||
}
|
||||
|
||||
u32 XRtds2gpu_Get_baseaddr(XRtds2gpu *InstancePtr) {
|
||||
u32 Data;
|
||||
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
Data = XRtds2gpu_ReadReg(InstancePtr->Ctrl_BaseAddress, XRTDS2GPU_CTRL_ADDR_BASEADDR_DATA);
|
||||
return Data;
|
||||
}
|
||||
|
||||
void XRtds2gpu_Set_data_offset(XRtds2gpu *InstancePtr, u32 Data) {
|
||||
Xil_AssertVoid(InstancePtr != NULL);
|
||||
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
XRtds2gpu_WriteReg(InstancePtr->Ctrl_BaseAddress, XRTDS2GPU_CTRL_ADDR_DATA_OFFSET_DATA, Data);
|
||||
}
|
||||
|
||||
u32 XRtds2gpu_Get_data_offset(XRtds2gpu *InstancePtr) {
|
||||
u32 Data;
|
||||
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
Data = XRtds2gpu_ReadReg(InstancePtr->Ctrl_BaseAddress, XRTDS2GPU_CTRL_ADDR_DATA_OFFSET_DATA);
|
||||
return Data;
|
||||
}
|
||||
|
||||
void XRtds2gpu_Set_doorbell_offset(XRtds2gpu *InstancePtr, u32 Data) {
|
||||
Xil_AssertVoid(InstancePtr != NULL);
|
||||
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
XRtds2gpu_WriteReg(InstancePtr->Ctrl_BaseAddress, XRTDS2GPU_CTRL_ADDR_DOORBELL_OFFSET_DATA, Data);
|
||||
}
|
||||
|
||||
u32 XRtds2gpu_Get_doorbell_offset(XRtds2gpu *InstancePtr) {
|
||||
u32 Data;
|
||||
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
Data = XRtds2gpu_ReadReg(InstancePtr->Ctrl_BaseAddress, XRTDS2GPU_CTRL_ADDR_DOORBELL_OFFSET_DATA);
|
||||
return Data;
|
||||
}
|
||||
|
||||
void XRtds2gpu_Set_status_i(XRtds2gpu *InstancePtr, u32 Data) {
|
||||
Xil_AssertVoid(InstancePtr != NULL);
|
||||
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
XRtds2gpu_WriteReg(InstancePtr->Ctrl_BaseAddress, XRTDS2GPU_CTRL_ADDR_STATUS_I_DATA, Data);
|
||||
}
|
||||
|
||||
u32 XRtds2gpu_Get_status_i(XRtds2gpu *InstancePtr) {
|
||||
u32 Data;
|
||||
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
Data = XRtds2gpu_ReadReg(InstancePtr->Ctrl_BaseAddress, XRTDS2GPU_CTRL_ADDR_STATUS_I_DATA);
|
||||
return Data;
|
||||
}
|
||||
|
||||
u32 XRtds2gpu_Get_status_o(XRtds2gpu *InstancePtr) {
|
||||
u32 Data;
|
||||
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
Data = XRtds2gpu_ReadReg(InstancePtr->Ctrl_BaseAddress, XRTDS2GPU_CTRL_ADDR_STATUS_O_DATA);
|
||||
return Data;
|
||||
}
|
||||
|
||||
void XRtds2gpu_Set_frame_size(XRtds2gpu *InstancePtr, u32 Data) {
|
||||
Xil_AssertVoid(InstancePtr != NULL);
|
||||
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
XRtds2gpu_WriteReg(InstancePtr->Ctrl_BaseAddress, XRTDS2GPU_CTRL_ADDR_FRAME_SIZE_DATA, Data);
|
||||
}
|
||||
|
||||
u32 XRtds2gpu_Get_frame_size(XRtds2gpu *InstancePtr) {
|
||||
u32 Data;
|
||||
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
Data = XRtds2gpu_ReadReg(InstancePtr->Ctrl_BaseAddress, XRTDS2GPU_CTRL_ADDR_FRAME_SIZE_DATA);
|
||||
return Data;
|
||||
}
|
||||
|
||||
void XRtds2gpu_InterruptGlobalEnable(XRtds2gpu *InstancePtr) {
|
||||
Xil_AssertVoid(InstancePtr != NULL);
|
||||
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
XRtds2gpu_WriteReg(InstancePtr->Ctrl_BaseAddress, XRTDS2GPU_CTRL_ADDR_GIE, 1);
|
||||
}
|
||||
|
||||
void XRtds2gpu_InterruptGlobalDisable(XRtds2gpu *InstancePtr) {
|
||||
Xil_AssertVoid(InstancePtr != NULL);
|
||||
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
XRtds2gpu_WriteReg(InstancePtr->Ctrl_BaseAddress, XRTDS2GPU_CTRL_ADDR_GIE, 0);
|
||||
}
|
||||
|
||||
void XRtds2gpu_InterruptEnable(XRtds2gpu *InstancePtr, u32 Mask) {
|
||||
u32 Register;
|
||||
|
||||
Xil_AssertVoid(InstancePtr != NULL);
|
||||
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
Register = XRtds2gpu_ReadReg(InstancePtr->Ctrl_BaseAddress, XRTDS2GPU_CTRL_ADDR_IER);
|
||||
XRtds2gpu_WriteReg(InstancePtr->Ctrl_BaseAddress, XRTDS2GPU_CTRL_ADDR_IER, Register | Mask);
|
||||
}
|
||||
|
||||
void XRtds2gpu_InterruptDisable(XRtds2gpu *InstancePtr, u32 Mask) {
|
||||
u32 Register;
|
||||
|
||||
Xil_AssertVoid(InstancePtr != NULL);
|
||||
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
Register = XRtds2gpu_ReadReg(InstancePtr->Ctrl_BaseAddress, XRTDS2GPU_CTRL_ADDR_IER);
|
||||
XRtds2gpu_WriteReg(InstancePtr->Ctrl_BaseAddress, XRTDS2GPU_CTRL_ADDR_IER, Register & (~Mask));
|
||||
}
|
||||
|
||||
void XRtds2gpu_InterruptClear(XRtds2gpu *InstancePtr, u32 Mask) {
|
||||
Xil_AssertVoid(InstancePtr != NULL);
|
||||
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
XRtds2gpu_WriteReg(InstancePtr->Ctrl_BaseAddress, XRTDS2GPU_CTRL_ADDR_ISR, Mask);
|
||||
}
|
||||
|
||||
u32 XRtds2gpu_InterruptGetEnabled(XRtds2gpu *InstancePtr) {
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
return XRtds2gpu_ReadReg(InstancePtr->Ctrl_BaseAddress, XRTDS2GPU_CTRL_ADDR_IER);
|
||||
}
|
||||
|
||||
u32 XRtds2gpu_InterruptGetStatus(XRtds2gpu *InstancePtr) {
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
return XRtds2gpu_ReadReg(InstancePtr->Ctrl_BaseAddress, XRTDS2GPU_CTRL_ADDR_ISR);
|
||||
}
|
||||
|
|
@ -36,7 +36,9 @@ whitelist = [
|
|||
[ 'xilinx.com', 'ip', 'axi_gpio' ],
|
||||
[ 'xilinx.com', 'ip', 'axi_bram_ctrl' ],
|
||||
[ 'xilinx.com', 'ip', 'axis_data_fifo' ],
|
||||
[ 'xilinx.com', 'ip', 'axi_pcie' ]
|
||||
[ 'xilinx.com', 'ip', 'axi_pcie' ],
|
||||
[ 'xilinx.com', 'hls', 'rtds2gpu' ],
|
||||
[ 'xilinx.com', 'hls', 'mem' ]
|
||||
]
|
||||
|
||||
# List of VLNI ids of AXI4-Stream infrastructure IP cores which do not alter data
|
||||
|
|
|
@ -5,6 +5,7 @@ set(SOURCES
|
|||
dma.cpp
|
||||
fifo.cpp
|
||||
rtds.cpp
|
||||
rtds2gpu.cpp
|
||||
timer.cpp
|
||||
graph.cpp
|
||||
)
|
||||
|
|
109
fpga/tests/rtds2gpu.cpp
Normal file
109
fpga/tests/rtds2gpu.cpp
Normal file
|
@ -0,0 +1,109 @@
|
|||
/** FIFO unit test.
|
||||
*
|
||||
* @file
|
||||
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
|
||||
* @copyright 2017, Steffen Vogel
|
||||
* @license GNU General Public License (version 3)
|
||||
*
|
||||
* VILLASfpga
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*********************************************************************************/
|
||||
|
||||
#include <criterion/criterion.h>
|
||||
|
||||
#include <villas/log.hpp>
|
||||
#include <villas/memory.hpp>
|
||||
#include <villas/fpga/card.hpp>
|
||||
|
||||
#include <villas/fpga/ips/rtds2gpu.hpp>
|
||||
#include <villas/fpga/ips/switch.hpp>
|
||||
#include <villas/fpga/ips/dma.hpp>
|
||||
|
||||
#include "global.hpp"
|
||||
|
||||
|
||||
static constexpr size_t SAMPLE_SIZE = 4;
|
||||
static constexpr size_t SAMPLE_COUNT = 8;
|
||||
static constexpr size_t FRAME_SIZE = SAMPLE_COUNT * SAMPLE_SIZE;
|
||||
|
||||
|
||||
Test(fpga, rtds2gpu, .description = "Rtds2Gpu")
|
||||
{
|
||||
auto logger = loggerGetOrCreate("unittest:rtds2gpu");
|
||||
|
||||
for(auto& ip : state.cards.front()->ips) {
|
||||
if(*ip != villas::fpga::Vlnv("xilinx.com:hls:rtds2gpu:"))
|
||||
continue;
|
||||
|
||||
logger->info("Testing {}", *ip);
|
||||
|
||||
auto rtds2gpu = reinterpret_cast<villas::fpga::ip::Rtds2Gpu&>(*ip);
|
||||
|
||||
auto dmaMem0 = villas::HostDmaRam::getAllocator(0).allocate<char>(FRAME_SIZE + 4);
|
||||
auto dmaMem1 = villas::HostDmaRam::getAllocator(0).allocate<char>(FRAME_SIZE + 4);
|
||||
|
||||
// continue;
|
||||
|
||||
|
||||
|
||||
auto axiSwitch = reinterpret_cast<villas::fpga::ip::AxiStreamSwitch*>(
|
||||
state.cards.front()->lookupIp(villas::fpga::Vlnv("xilinx.com:ip:axis_switch:")));
|
||||
cr_assert_not_null(axiSwitch);
|
||||
|
||||
auto dma = reinterpret_cast<villas::fpga::ip::Dma*>(
|
||||
state.cards.front()->lookupIp(villas::fpga::Vlnv("xilinx.com:ip:axi_dma:")));
|
||||
cr_assert_not_null(dma);
|
||||
|
||||
memset(&dmaMem0, 0x55, dmaMem0.getMemoryBlock().getSize());
|
||||
memset(&dmaMem1, 0x11, dmaMem1.getMemoryBlock().getSize());
|
||||
|
||||
puts("Before:");
|
||||
for(size_t i = 0; i < dmaMem0.getMemoryBlock().getSize(); i++) {
|
||||
printf("0x%02x ", dmaMem0[i]);
|
||||
}
|
||||
puts("");
|
||||
|
||||
rtds2gpu.dump();
|
||||
|
||||
cr_assert(axiSwitch->connect(7, 6));
|
||||
cr_assert(axiSwitch->connect(6, 7));
|
||||
|
||||
|
||||
|
||||
cr_assert(rtds2gpu.startOnce(dmaMem0.getMemoryBlock(), SAMPLE_COUNT),
|
||||
"Preparing Rtds2Gpu IP failed");
|
||||
|
||||
cr_assert(dma->write(dmaMem1.getMemoryBlock(), FRAME_SIZE));
|
||||
|
||||
// cr_assert(axiSwitch->connect(6, 6)); // loopback
|
||||
// cr_assert(dma->read(dmaMem1.getMemoryBlock(), FRAME_SIZE));
|
||||
// cr_assert(dma->readComplete());
|
||||
|
||||
cr_assert(dma->writeComplete());
|
||||
|
||||
puts("After:");
|
||||
for(size_t i = 0; i < dmaMem0.getMemoryBlock().getSize(); i++) {
|
||||
printf("0x%02x ", dmaMem0[i]);
|
||||
}
|
||||
puts("");
|
||||
|
||||
|
||||
rtds2gpu.dump();
|
||||
|
||||
cr_assert(rtds2gpu.isDone());
|
||||
|
||||
logger->info(TXT_GREEN("Passed"));
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue