mirror of
https://git.rwth-aachen.de/acs/public/villas/node/
synced 2025-03-09 00:00:00 +01:00
ips/register: add IP for the new register interface
Signed-off-by: Niklas Eiling <niklas.eiling@eonerc.rwth-aachen.de>
This commit is contained in:
parent
1bb6c221f6
commit
d54e4eb3f0
3 changed files with 154 additions and 0 deletions
47
fpga/include/villas/fpga/ips/register.hpp
Normal file
47
fpga/include/villas/fpga/ips/register.hpp
Normal file
|
@ -0,0 +1,47 @@
|
|||
/* Driver for register interface 'registerif'
|
||||
*
|
||||
* Author: Niklas Eiling <niklas.eiling@eonerc.rwth-aachen.de>
|
||||
* SPDX-FileCopyrightText: 2024 Niklas Eiling
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <villas/fpga/node.hpp>
|
||||
|
||||
namespace villas {
|
||||
namespace fpga {
|
||||
namespace ip {
|
||||
|
||||
class Register : public Node {
|
||||
public:
|
||||
Register();
|
||||
virtual ~Register();
|
||||
virtual bool init() override;
|
||||
virtual bool check() override;
|
||||
void setRegister(size_t reg, uint32_t value);
|
||||
void setRegister(size_t reg, float value);
|
||||
uint32_t getRegister(size_t reg);
|
||||
float getRegisterFloat(size_t reg);
|
||||
void resetRegister(size_t reg);
|
||||
void resetAllRegisters();
|
||||
|
||||
protected:
|
||||
const size_t registerNum = 4;
|
||||
const size_t registerSize = 32;
|
||||
static constexpr char registerMemory[] = "reg0";
|
||||
std::list<MemoryBlockName> getMemoryBlocks() const {
|
||||
return {registerMemory};
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace ip
|
||||
} // namespace fpga
|
||||
} // namespace villas
|
||||
|
||||
#ifndef FMT_LEGACY_OSTREAM_FORMATTER
|
||||
template <>
|
||||
class fmt::formatter<villas::fpga::ip::Register>
|
||||
: public fmt::ostream_formatter {};
|
||||
template <>
|
||||
#endif
|
|
@ -27,6 +27,7 @@ set(SOURCES
|
|||
ips/switch.cpp
|
||||
ips/timer.cpp
|
||||
ips/i2c.cpp
|
||||
ips/register.cpp
|
||||
|
||||
ips/rtds2gpu/rtds2gpu.cpp
|
||||
ips/rtds2gpu/xrtds2gpu.c
|
||||
|
|
106
fpga/lib/ips/register.cpp
Normal file
106
fpga/lib/ips/register.cpp
Normal file
|
@ -0,0 +1,106 @@
|
|||
/* Driver for register interface 'registerif'
|
||||
*
|
||||
* Author: Niklas Eiling <niklas.eiling@eonerc.rwth-aachen.de>
|
||||
* SPDX-FileCopyrightText: 2024 Niklas Eiling
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <xilinx/xil_io.h>
|
||||
|
||||
#include <villas/fpga/ips/register.hpp>
|
||||
|
||||
using namespace villas::fpga::ip;
|
||||
|
||||
#define REGISTER_RESET (512)
|
||||
#define REGISTER_OUT(NUM) (4 * NUM)
|
||||
|
||||
Register::Register() : Node() {}
|
||||
|
||||
bool Register::init() { return true; }
|
||||
|
||||
bool Register::check() {
|
||||
|
||||
logger->debug("Checking register interface: Base address: 0x{:08x}",
|
||||
getBaseAddr(registerMemory));
|
||||
uint32_t buf;
|
||||
// we shouldn't 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<uint32_t>(i));
|
||||
}
|
||||
|
||||
for (size_t i = 1; i < registerNum; i++) {
|
||||
buf = getRegister(i);
|
||||
if (buf != i) {
|
||||
logger->error("Register {}: 0x{:08x} != 0x{:08x}", i, buf, i);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
resetAllRegisters();
|
||||
|
||||
for (size_t i = 0; i < registerNum; i++) {
|
||||
logger->trace("Register {}: 0x{:08x}", i, getRegister(i));
|
||||
}
|
||||
|
||||
// This is Dino specific for now - we should possibly move this to Dino in the future
|
||||
uint32_t rate = getRegister(0);
|
||||
float scale = getRegisterFloat(1);
|
||||
float offset = getRegisterFloat(2);
|
||||
logger->info("Check: Register configuration: Rate: {}, Scale: {}, Offset: {}",
|
||||
rate, scale, offset);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Register::setRegister(size_t reg, uint32_t value) {
|
||||
if (reg >= registerNum) {
|
||||
logger->error("Register index out of range: {}/{}", reg, registerNum);
|
||||
throw std::out_of_range("Register index out of range");
|
||||
}
|
||||
Xil_Out32(getBaseAddr(registerMemory) + REGISTER_OUT(reg), value);
|
||||
}
|
||||
|
||||
void Register::setRegister(size_t reg, float value) {
|
||||
if (reg >= registerNum) {
|
||||
logger->error("Register index out of range: {}/{}", reg, registerNum);
|
||||
throw std::out_of_range("Register index out of range");
|
||||
}
|
||||
Xil_Out32(getBaseAddr(registerMemory) + REGISTER_OUT(reg),
|
||||
reinterpret_cast<uint32_t &>(value));
|
||||
}
|
||||
|
||||
uint32_t Register::getRegister(size_t reg) {
|
||||
if (reg >= registerNum) {
|
||||
logger->error("Register index out of range: {}/{}", reg, registerNum);
|
||||
throw std::out_of_range("Register index out of range");
|
||||
}
|
||||
return Xil_In32(getBaseAddr(registerMemory) + REGISTER_OUT(reg));
|
||||
}
|
||||
|
||||
float Register::getRegisterFloat(size_t reg) {
|
||||
if (reg >= registerNum) {
|
||||
logger->error("Register index out of range: {}/{}", reg, registerNum);
|
||||
throw std::out_of_range("Register index out of range");
|
||||
}
|
||||
uint32_t value = Xil_In32(getBaseAddr(registerMemory) + REGISTER_OUT(reg));
|
||||
return reinterpret_cast<float &>(value);
|
||||
}
|
||||
|
||||
void Register::resetRegister(size_t reg) {
|
||||
if (reg >= registerNum) {
|
||||
logger->error("Register index out of range: {}/{}", reg, registerNum);
|
||||
throw std::out_of_range("Register index out of range");
|
||||
}
|
||||
Xil_Out32(getBaseAddr(registerMemory) + REGISTER_RESET, (1 << reg));
|
||||
}
|
||||
|
||||
void Register::resetAllRegisters() {
|
||||
Xil_Out32(getBaseAddr(registerMemory) + REGISTER_RESET, 0xFFFFFFFF);
|
||||
}
|
||||
|
||||
Register::~Register() {}
|
||||
|
||||
static char n[] = "register";
|
||||
static char d[] = "Register interface VHDL module 'registerif'";
|
||||
static char v[] = "xilinx.com:module_ref:registerif:";
|
||||
static CorePlugin<Register, n, d, v> f;
|
Loading…
Add table
Reference in a new issue