Skip to content
This repository was archived by the owner on Feb 29, 2024. It is now read-only.

Commit 8ecc64d

Browse files
committed
ips/register: add IP for the new register interface
Signed-off-by: Niklas Eiling <[email protected]>
1 parent e311709 commit 8ecc64d

File tree

3 files changed

+154
-0
lines changed

3 files changed

+154
-0
lines changed

include/villas/fpga/ips/register.hpp

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/* Driver for register interface 'registerif'
2+
*
3+
* Author: Niklas Eiling <[email protected]>
4+
* SPDX-FileCopyrightText: 2024 Niklas Eiling
5+
* SPDX-License-Identifier: Apache-2.0
6+
*/
7+
8+
#pragma once
9+
10+
#include <villas/fpga/node.hpp>
11+
12+
namespace villas {
13+
namespace fpga {
14+
namespace ip {
15+
16+
class Register : public Node {
17+
public:
18+
Register();
19+
virtual ~Register();
20+
virtual bool init() override;
21+
virtual bool check() override;
22+
void setRegister(size_t reg, uint32_t value);
23+
void setRegister(size_t reg, float value);
24+
uint32_t getRegister(size_t reg);
25+
float getRegisterFloat(size_t reg);
26+
void resetRegister(size_t reg);
27+
void resetAllRegisters();
28+
29+
protected:
30+
const size_t registerNum = 4;
31+
const size_t registerSize = 32;
32+
static constexpr char registerMemory[] = "reg0";
33+
std::list<MemoryBlockName> getMemoryBlocks() const {
34+
return {registerMemory};
35+
}
36+
};
37+
38+
} // namespace ip
39+
} // namespace fpga
40+
} // namespace villas
41+
42+
#ifndef FMT_LEGACY_OSTREAM_FORMATTER
43+
template <>
44+
class fmt::formatter<villas::fpga::ip::Register>
45+
: public fmt::ostream_formatter {};
46+
template <>
47+
#endif

lib/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ set(SOURCES
2727
ips/switch.cpp
2828
ips/timer.cpp
2929
ips/i2c.cpp
30+
ips/register.cpp
3031

3132
ips/rtds2gpu/rtds2gpu.cpp
3233
ips/rtds2gpu/xrtds2gpu.c

lib/ips/register.cpp

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
/* Driver for register interface 'registerif'
2+
*
3+
* Author: Niklas Eiling <[email protected]>
4+
* SPDX-FileCopyrightText: 2024 Niklas Eiling
5+
* SPDX-License-Identifier: Apache-2.0
6+
*/
7+
8+
#include <xilinx/xil_io.h>
9+
10+
#include <villas/fpga/ips/register.hpp>
11+
12+
using namespace villas::fpga::ip;
13+
14+
#define REGISTER_RESET (512)
15+
#define REGISTER_OUT(NUM) (4 * NUM)
16+
17+
Register::Register() : Node() {}
18+
19+
bool Register::init() { return true; }
20+
21+
bool Register::check() {
22+
23+
logger->debug("Checking register interface: Base address: 0x{:08x}",
24+
getBaseAddr(registerMemory));
25+
uint32_t buf;
26+
// we shouldn't change the rate register, because this can lead to hardware fault, so start at 1
27+
for (size_t i = 1; i < registerNum; i++) {
28+
setRegister(i, static_cast<uint32_t>(i));
29+
}
30+
31+
for (size_t i = 1; i < registerNum; i++) {
32+
buf = getRegister(i);
33+
if (buf != i) {
34+
logger->error("Register {}: 0x{:08x} != 0x{:08x}", i, buf, i);
35+
return false;
36+
}
37+
}
38+
39+
resetAllRegisters();
40+
41+
for (size_t i = 0; i < registerNum; i++) {
42+
logger->trace("Register {}: 0x{:08x}", i, getRegister(i));
43+
}
44+
45+
// This is Dino specific for now - we should possibly move this to Dino in the future
46+
uint32_t rate = getRegister(0);
47+
float scale = getRegisterFloat(1);
48+
float offset = getRegisterFloat(2);
49+
logger->info("Check: Register configuration: Rate: {}, Scale: {}, Offset: {}",
50+
rate, scale, offset);
51+
52+
return true;
53+
}
54+
55+
void Register::setRegister(size_t reg, uint32_t value) {
56+
if (reg >= registerNum) {
57+
logger->error("Register index out of range: {}/{}", reg, registerNum);
58+
throw std::out_of_range("Register index out of range");
59+
}
60+
Xil_Out32(getBaseAddr(registerMemory) + REGISTER_OUT(reg), value);
61+
}
62+
63+
void Register::setRegister(size_t reg, float value) {
64+
if (reg >= registerNum) {
65+
logger->error("Register index out of range: {}/{}", reg, registerNum);
66+
throw std::out_of_range("Register index out of range");
67+
}
68+
Xil_Out32(getBaseAddr(registerMemory) + REGISTER_OUT(reg),
69+
reinterpret_cast<uint32_t &>(value));
70+
}
71+
72+
uint32_t Register::getRegister(size_t reg) {
73+
if (reg >= registerNum) {
74+
logger->error("Register index out of range: {}/{}", reg, registerNum);
75+
throw std::out_of_range("Register index out of range");
76+
}
77+
return Xil_In32(getBaseAddr(registerMemory) + REGISTER_OUT(reg));
78+
}
79+
80+
float Register::getRegisterFloat(size_t reg) {
81+
if (reg >= registerNum) {
82+
logger->error("Register index out of range: {}/{}", reg, registerNum);
83+
throw std::out_of_range("Register index out of range");
84+
}
85+
uint32_t value = Xil_In32(getBaseAddr(registerMemory) + REGISTER_OUT(reg));
86+
return reinterpret_cast<float &>(value);
87+
}
88+
89+
void Register::resetRegister(size_t reg) {
90+
if (reg >= registerNum) {
91+
logger->error("Register index out of range: {}/{}", reg, registerNum);
92+
throw std::out_of_range("Register index out of range");
93+
}
94+
Xil_Out32(getBaseAddr(registerMemory) + REGISTER_RESET, (1 << reg));
95+
}
96+
97+
void Register::resetAllRegisters() {
98+
Xil_Out32(getBaseAddr(registerMemory) + REGISTER_RESET, 0xFFFFFFFF);
99+
}
100+
101+
Register::~Register() {}
102+
103+
static char n[] = "register";
104+
static char d[] = "Register interface VHDL module 'registerif'";
105+
static char v[] = "xilinx.com:module_ref:registerif:";
106+
static CorePlugin<Register, n, d, v> f;

0 commit comments

Comments
 (0)