1
0
Fork 0
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:
Daniel Krebs 2018-05-23 20:04:10 +02:00
parent b03b94d754
commit bf286568dd
12 changed files with 767 additions and 35 deletions

View file

@ -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": {

View file

@ -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()

View 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

View 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

View 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

View file

@ -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

View file

@ -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);
}

View 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

View 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);
}

View file

@ -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

View file

@ -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
View 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"));
}
}