mirror of
https://git.rwth-aachen.de/acs/public/villas/node/
synced 2025-03-09 00:00:00 +01:00
fpga: make dino sampling rate configurable at top level and via json
Signed-off-by: Niklas Eiling <niklas.eiling@eonerc.rwth-aachen.de>
This commit is contained in:
parent
bb57c75a4b
commit
1e0bfa9b73
4 changed files with 49 additions and 15 deletions
|
@ -19,8 +19,9 @@ fpgas = {
|
|||
nodes = {
|
||||
fpga_0 = {
|
||||
type = "fpga",
|
||||
card = "vc707"
|
||||
connect = ["0->3", "3->dma", "0<-dma"]
|
||||
card = "vc707",
|
||||
connect = ["0->3", "3->dma", "0<-dma"],
|
||||
timestep = 10e-3,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -244,6 +244,14 @@ int main(int argc, char *argv[]) {
|
|||
}
|
||||
}
|
||||
}
|
||||
auto reg = std::dynamic_pointer_cast<fpga::ip::Register>(
|
||||
card->lookupIp(fpga::Vlnv("xilinx.com:module_ref:registerif:")));
|
||||
|
||||
if (reg != nullptr &&
|
||||
card->lookupIp(fpga::Vlnv("xilinx.com:module_ref:dinoif_fast:"))) {
|
||||
fpga::ip::DinoAdc::setRegisterConfigTimestep(reg, 10e-3);
|
||||
}
|
||||
|
||||
if (writeToStdout || readFromStdin) {
|
||||
auto dma = std::dynamic_pointer_cast<fpga::ip::Dma>(
|
||||
card->lookupIp(fpga::Vlnv("xilinx.com:ip:axi_dma:")));
|
||||
|
|
|
@ -45,6 +45,15 @@ protected:
|
|||
// Improves read/write latency by approx. 40%.
|
||||
bool lowLatencyMode;
|
||||
|
||||
// This sets the requested timestep in the FPGA timestep generation IP.
|
||||
// The value is interpreted as seconds (i.e. 10e-3 is a timestep of 10ms).
|
||||
// It is used to program the Register IP that in turn generates conversions
|
||||
// of DinoAdc. This means that this setting represents the inverse of the
|
||||
// Dino sampling rate.
|
||||
// The setting must be programmed using DinoAdc::setRegisterConfigTimestep,
|
||||
// which FpgaNode does in prepare only if a Register and a DinoAdc is present.
|
||||
double timestep;
|
||||
|
||||
// State
|
||||
std::shared_ptr<fpga::Card> card;
|
||||
std::shared_ptr<villas::fpga::ip::Dma> dma;
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
#include <villas/super_node.hpp>
|
||||
#include <villas/utils.hpp>
|
||||
|
||||
#include <villas/fpga/ips/dino.hpp>
|
||||
#include <villas/fpga/ips/register.hpp>
|
||||
#include <villas/fpga/ips/switch.hpp>
|
||||
#include <villas/fpga/utils.hpp>
|
||||
|
||||
|
@ -34,7 +36,7 @@ static std::shared_ptr<kernel::vfio::Container> vfioContainer;
|
|||
|
||||
FpgaNode::FpgaNode(const uuid_t &id, const std::string &name)
|
||||
: Node(id, name), cardName(""), connectStrings(), lowLatencyMode(false),
|
||||
card(nullptr), dma(), blockRx(), blockTx() {}
|
||||
timestep(10e-3), card(nullptr), dma(), blockRx(), blockTx() {}
|
||||
|
||||
FpgaNode::~FpgaNode() {}
|
||||
|
||||
|
@ -67,6 +69,17 @@ int FpgaNode::prepare() {
|
|||
parsedConnectString.configCrossBar(card);
|
||||
}
|
||||
|
||||
auto reg = std::dynamic_pointer_cast<fpga::ip::Register>(
|
||||
card->lookupIp(fpga::Vlnv("xilinx.com:module_ref:registerif:")));
|
||||
|
||||
if (reg != nullptr &&
|
||||
card->lookupIp(fpga::Vlnv("xilinx.com:module_ref:dinoif_fast:"))) {
|
||||
// constexpr double sampleRate = 20e3; // We want to achieve a timestep of 50us
|
||||
fpga::ip::DinoAdc::setRegisterConfigTimestep(reg, 10e-3);
|
||||
} else {
|
||||
logger->warn("No DinoAdc or no Register found on FPGA.");
|
||||
}
|
||||
|
||||
dma = std::dynamic_pointer_cast<fpga::ip::Dma>(
|
||||
card->lookupIp(fpga::Vlnv("xilinx.com:ip:axi_dma:")));
|
||||
if (dma == nullptr) {
|
||||
|
@ -106,9 +119,10 @@ int FpgaNode::parse(json_t *json) {
|
|||
vfioContainer = std::make_shared<kernel::vfio::Container>();
|
||||
}
|
||||
|
||||
ret = json_unpack_ex(json, &err, 0, "{ s: o, s?: o, s?: b, s?: b}", "card",
|
||||
&jsonCard, "connect", &jsonConnectStrings,
|
||||
"lowLatencyMode", &lowLatencyMode);
|
||||
ret =
|
||||
json_unpack_ex(json, &err, 0, "{ s: o, s?: o, s?: b, s?: b, s?: f}",
|
||||
"card", &jsonCard, "connect", &jsonConnectStrings,
|
||||
"lowLatencyMode", &lowLatencyMode, "timestep", ×tep);
|
||||
if (ret) {
|
||||
throw ConfigError(json, err, "node-config-fpga",
|
||||
"Failed to parse configuration of node {}",
|
||||
|
@ -167,20 +181,20 @@ const std::string &FpgaNode::getDetails() {
|
|||
return details;
|
||||
}
|
||||
|
||||
int FpgaNode::check() { return 0; }
|
||||
int FpgaNode::check() { return Node::check(); }
|
||||
|
||||
int FpgaNode::start() {
|
||||
if (getInputSignalsMaxCount() * sizeof(float) > blockRx->getSize()) {
|
||||
logger->error("Input signals exceed block size.");
|
||||
throw villas ::RuntimeError("Input signals exceed block size.");
|
||||
if (getOutputSignalsMaxCount() * sizeof(float) > blockRx->getSize()) {
|
||||
logger->error("Output signals exceed block size.");
|
||||
throw villas ::RuntimeError("Output signals exceed block size.");
|
||||
}
|
||||
if (lowLatencyMode) {
|
||||
dma->readScatterGatherPrepare(*blockRx, blockRx->getSize());
|
||||
if (getInputSignalsMaxCount() != 0) {
|
||||
dma->writeScatterGatherPrepare(*blockTx,
|
||||
getInputSignalsMaxCount() * sizeof(float));
|
||||
if (getOutputSignalsMaxCount() != 0) {
|
||||
dma->writeScatterGatherPrepare(*blockTx, getOutputSignalsMaxCount() *
|
||||
sizeof(float));
|
||||
} else {
|
||||
logger->warn("No input signals defined. Not preparing write buffer - "
|
||||
logger->warn("No output signals defined. Not preparing write buffer - "
|
||||
"writes will not work.");
|
||||
}
|
||||
}
|
||||
|
@ -212,7 +226,8 @@ int FpgaNode::fastWrite(Sample *smps[], unsigned cnt) {
|
|||
mem[i] = smp->data[i].i;
|
||||
}
|
||||
}
|
||||
|
||||
logger->info("Writing sample: {}, {}, {:#x}", smp->data[0].f,
|
||||
smp->signals->getByIndex(0)->type, mem[0]);
|
||||
dma->writeScatterGatherFast();
|
||||
auto written = dma->writeScatterGatherPoll() /
|
||||
sizeof(float); // The number of samples written
|
||||
|
@ -242,6 +257,7 @@ int FpgaNode::fastRead(Sample *smps[], unsigned cnt) {
|
|||
smp->length = 0;
|
||||
for (unsigned i = 0; i < MIN(read / sizeof(float), smp->capacity); i++) {
|
||||
smp->data[i].f = static_cast<double>(mem[i]);
|
||||
// logger->info("Read sample: {}", smp->data[i].f);
|
||||
smp->length++;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue