/* Driver for AXI Stream read cache. * * This module is used to lower latency of * a DMA Scatter Gather engine's descriptor fetching. The driver allows for * invalidating the cache. * * Author: Niklas Eiling * SPDX-FileCopyrightText: 2024 Niklas Eiling * SPDX-License-Identifier: Apache-2.0 */ #include #include using namespace villas::fpga::ip; #define REGISTER_OUT(NUM) (4 * NUM) AxisCache::AxisCache() : Node() {} bool AxisCache::init() { invalidate(); return true; } bool AxisCache::check() { logger->debug("Checking register interface: Base address: 0x{:08x}", getBaseAddr(registerMemory)); uint32_t buf; // We should not change the rate register, because this can lead to hardware fault, so start at 1 for (size_t i = 1; i < registerNum; i++) { setRegister(i, static_cast(0x00FF00FF)); } for (size_t i = 1; i < registerNum; i++) { if (!getRegister(i, buf)) { logger->error("Failed to read register {}", i); return false; } if (buf != 0x00FF00FF) { logger->error("Register {}: 0x{:08x} != 0x{:08x}", i, buf, i); return false; } } // Reset Registers resetAllRegisters(); for (size_t i = 0; i < registerNum; i++) { if (!getRegister(i, buf)) { logger->error("Failed to read register {}", i); return false; } logger->debug("Register {}: 0x{:08x}", i, buf); } return true; } void AxisCache::invalidate() { setRegister(0, 1U << 31); logger->info("invalidated AXIS cache."); } bool AxisCache::setRegister(size_t reg, uint32_t value) { if (reg >= registerNum) { logger->error("Register index out of range: {}/{}", reg, registerNum); return false; } Xil_Out32(getBaseAddr(registerMemory) + REGISTER_OUT(reg), value); return true; } bool AxisCache::getRegister(size_t reg, uint32_t &value) { if (reg >= registerNum) { logger->error("Register index out of range: {}/{}", reg, registerNum); return false; } value = Xil_In32(getBaseAddr(registerMemory) + REGISTER_OUT(reg)); return true; } bool AxisCache::resetRegister(size_t reg) { return setRegister(reg, 0); } bool AxisCache::resetAllRegisters() { bool result = true; for (size_t i = 1; i < registerNum; i++) { result &= resetRegister(i); } return result; } AxisCache::~AxisCache() {} static char n[] = "axis_cache"; static char d[] = "Register interface VHDL module 'axi_read_cache'"; static char v[] = "xilinx.com:module_ref:axi_read_cache:"; static CorePlugin f;