Skip to content
Snippets Groups Projects
Select Git revision
  • 285db097376017b51e20527c4ebe489ea1e3f042
  • master default protected
  • L2SS-1914-fix_job_dispatch
  • TMSS-3170
  • TMSS-3167
  • TMSS-3161
  • TMSS-3158-Front-End-Only-Allow-Changing-Again
  • TMSS-3133
  • TMSS-3319-Fix-Templates
  • test-fix-deploy
  • TMSS-3134
  • TMSS-2872
  • defer-state
  • add-custom-monitoring-points
  • TMSS-3101-Front-End-Only
  • TMSS-984-choices
  • SDC-1400-Front-End-Only
  • TMSS-3079-PII
  • TMSS-2936
  • check-for-max-244-subbands
  • TMSS-2927---Front-End-Only-PXII
  • Before-Remove-TMSS
  • LOFAR-Release-4_4_318 protected
  • LOFAR-Release-4_4_317 protected
  • LOFAR-Release-4_4_316 protected
  • LOFAR-Release-4_4_315 protected
  • LOFAR-Release-4_4_314 protected
  • LOFAR-Release-4_4_313 protected
  • LOFAR-Release-4_4_312 protected
  • LOFAR-Release-4_4_311 protected
  • LOFAR-Release-4_4_310 protected
  • LOFAR-Release-4_4_309 protected
  • LOFAR-Release-4_4_308 protected
  • LOFAR-Release-4_4_307 protected
  • LOFAR-Release-4_4_306 protected
  • LOFAR-Release-4_4_304 protected
  • LOFAR-Release-4_4_303 protected
  • LOFAR-Release-4_4_302 protected
  • LOFAR-Release-4_4_301 protected
  • LOFAR-Release-4_4_300 protected
  • LOFAR-Release-4_4_299 protected
41 results

pkgdoc-howto.cfg

Blame
  • Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    fpga.cpp 22.11 KiB
    /* *************************************************************************
    * Copyright 2020
    * ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
    * P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
    *
    * Licensed under the Apache License, Version 2.0 (the "License");
    * you may not use this file except in compliance with the License.
    * You may obtain a copy of the License at
    *
    * http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing, software
    * distributed under the License is distributed on an "AS IS" BASIS,
    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    * See the License for the specific language governing permissions and
    * limitations under the License.
    * *********************************************************************** */
    
    /* *************************************************************************
    * Author:
    * . Leon Hiemstra
    * . Pieter Donker
    * Purpose:
    * . opc-ua to ucp translator
    * Description:
    * . class with fpga registers available for opc-ua server
    * *********************************************************************** */
    
    #ifndef _REENTRANT
    #error ACK! You need to compile with _REENTRANT defined since this uses threads
    #endif
    
    #include <cstdio>
    #include <stdexcept>
    #include <iostream>
    #include <sstream>
    #include <exception>
    
    #include "constants.h"
    #include "fpga.h"
    #include "tools/parse.h"
    
    using namespace std;
    
    // Everything addressed with FPGA_...
    
    extern int debug;
    
    Fpga::Fpga(list<class Node*>& nodelist)
    {
        FPGA = nodelist;
        pointMap = new CPointMap();
    
        // Add points:
        vector<int> nodes = get_all_nodes();
    
        pointMap->add_register("FPGA_temp_R",                                    "fpga/temp",                                   nodes.size(), 1, "RO", REG_FORMAT_DOUBLE);
        pointMap->add_register("FPGA_firmware_version_R",                        "fpga/firmware_version",                       nodes.size(), 1, "RO", REG_FORMAT_STRING);
        pointMap->add_register("FPGA_hardware_version_R",                        "fpga/hardware_version",                       nodes.size(), 1, "RO", REG_FORMAT_STRING);
    
        pointMap->add_register("FPGA_sst_offload_weighted_subbands_R",           "fpga/sst_offload_weighted_subbands",          nodes.size(), 1, "RO", REG_FORMAT_BOOLEAN);
        pointMap->add_register("FPGA_sst_offload_weighted_subbands_RW",          "fpga/sst_offload_weighted_subbands",          nodes.size(), 1, "RW", REG_FORMAT_BOOLEAN);
        pointMap->add_register("FPGA_sst_offload_enable_R",                      "fpga/sst_offload_enable",                     nodes.size(), 1, "RO", REG_FORMAT_BOOLEAN);
        pointMap->add_register("FPGA_sst_offload_enable_RW",                     "fpga/sst_offload_enable",                     nodes.size(), 1, "RW", REG_FORMAT_BOOLEAN);
        pointMap->add_register("FPGA_sst_offload_hdr_eth_destination_mac_R",     "fpga/sst_offload_hdr_eth_destination_mac",    nodes.size(), 1, "RO", REG_FORMAT_STRING);
        pointMap->add_register("FPGA_sst_offload_hdr_eth_destination_mac_RW",    "fpga/sst_offload_hdr_eth_destination_mac",    nodes.size(), 1, "RW", REG_FORMAT_STRING);
        pointMap->add_register("FPGA_sst_offload_hdr_ip_destination_address_R",  "fpga/sst_offload_hdr_ip_destination_address", nodes.size(), 1, "RO", REG_FORMAT_STRING);
        pointMap->add_register("FPGA_sst_offload_hdr_ip_destination_address_RW", "fpga/sst_offload_hdr_ip_destination_address", nodes.size(), 1, "RW", REG_FORMAT_STRING);
        pointMap->add_register("FPGA_sst_offload_hdr_udp_destination_port_R",    "fpga/sst_offload_hdr_udp_destination_port",   nodes.size(), 1, "RO", REG_FORMAT_UINT16);
        pointMap->add_register("FPGA_sst_offload_hdr_udp_destination_port_RW",   "fpga/sst_offload_hdr_udp_destination_port",   nodes.size(), 1, "RW", REG_FORMAT_UINT16);
    
        pointMap->add_register("FPGA_bst_offload_enable_R",                      "fpga/bst_offload_enable",                     nodes.size(), C_N_beamsets, "RO", REG_FORMAT_BOOLEAN);
        pointMap->add_register("FPGA_bst_offload_enable_RW",                     "fpga/bst_offload_enable",                     nodes.size(), C_N_beamsets, "RW", REG_FORMAT_BOOLEAN);
        pointMap->add_register("FPGA_bst_offload_hdr_eth_destination_mac_R",     "fpga/bst_offload_hdr_eth_destination_mac",    nodes.size(), C_N_beamsets, "RO", REG_FORMAT_STRING);
        pointMap->add_register("FPGA_bst_offload_hdr_eth_destination_mac_RW",    "fpga/bst_offload_hdr_eth_destination_mac",    nodes.size(), C_N_beamsets, "RW", REG_FORMAT_STRING);
        pointMap->add_register("FPGA_bst_offload_hdr_ip_destination_address_R",  "fpga/bst_offload_hdr_ip_destination_address", nodes.size(), C_N_beamsets, "RO", REG_FORMAT_STRING);
        pointMap->add_register("FPGA_bst_offload_hdr_ip_destination_address_RW", "fpga/bst_offload_hdr_ip_destination_address", nodes.size(), C_N_beamsets, "RW", REG_FORMAT_STRING);
        pointMap->add_register("FPGA_bst_offload_hdr_udp_destination_port_R",    "fpga/bst_offload_hdr_udp_destination_port",   nodes.size(), C_N_beamsets, "RO", REG_FORMAT_UINT16);
        pointMap->add_register("FPGA_bst_offload_hdr_udp_destination_port_RW",   "fpga/bst_offload_hdr_udp_destination_port",   nodes.size(), C_N_beamsets, "RW", REG_FORMAT_UINT16);
        // pointMap->add_register("FPGA_bst_offload_nof_beamlets_per_packet_R",     "fpga/bst_offload_nof_beamlets_per_packet",    nodes.size(), C_N_beamsets, "RO", REG_FORMAT_UINT32);
        // pointMap->add_register("FPGA_bst_offload_nof_beamlets_per_packet_RW",    "fpga/bst_offload_nof_beamlets_per_packet",    nodes.size(), C_N_beamsets, "RW", REG_FORMAT_UINT32);
    
        pointMap->add_register("FPGA_xst_subband_select_R",                      "fpga/xst_subband_select",                     nodes.size(), 1+C_N_crosslets_max, "RO", REG_FORMAT_UINT32);
        pointMap->add_register("FPGA_xst_subband_select_RW",                     "fpga/xst_subband_select",                     nodes.size(), 1+C_N_crosslets_max, "RW", REG_FORMAT_UINT32);
        pointMap->add_register("FPGA_xst_integration_interval_R",                "fpga/xst_integration_interval",               nodes.size(), 1, "RO", REG_FORMAT_DOUBLE);
        pointMap->add_register("FPGA_xst_integration_interval_RW",               "fpga/xst_integration_interval",               nodes.size(), 1, "RW", REG_FORMAT_DOUBLE);
        pointMap->add_register("FPGA_xst_processing_enable_R",                   "fpga/xst_processing_enable",                  nodes.size(), 1, "RO", REG_FORMAT_BOOLEAN);
        pointMap->add_register("FPGA_xst_processing_enable_RW",                  "fpga/xst_processing_enable",                  nodes.size(), 1, "RW", REG_FORMAT_BOOLEAN);
        pointMap->add_register("FPGA_xst_offload_enable_R",                      "fpga/xst_offload_enable",                     nodes.size(), 1, "RO", REG_FORMAT_BOOLEAN);
        pointMap->add_register("FPGA_xst_offload_enable_RW",                     "fpga/xst_offload_enable",                     nodes.size(), 1, "RW", REG_FORMAT_BOOLEAN);
        pointMap->add_register("FPGA_xst_offload_hdr_eth_destination_mac_R",     "fpga/xst_offload_hdr_eth_destination_mac",    nodes.size(), 1, "RO", REG_FORMAT_STRING);
        pointMap->add_register("FPGA_xst_offload_hdr_eth_destination_mac_RW",    "fpga/xst_offload_hdr_eth_destination_mac",    nodes.size(), 1, "RW", REG_FORMAT_STRING);
        pointMap->add_register("FPGA_xst_offload_hdr_ip_destination_address_R",  "fpga/xst_offload_hdr_ip_destination_address", nodes.size(), 1, "RO", REG_FORMAT_STRING);
        pointMap->add_register("FPGA_xst_offload_hdr_ip_destination_address_RW", "fpga/xst_offload_hdr_ip_destination_address", nodes.size(), 1, "RW", REG_FORMAT_STRING);
        pointMap->add_register("FPGA_xst_offload_hdr_udp_destination_port_R",    "fpga/xst_offload_hdr_udp_destination_port",   nodes.size(), 1, "RO", REG_FORMAT_UINT16);
        pointMap->add_register("FPGA_xst_offload_hdr_udp_destination_port_RW",   "fpga/xst_offload_hdr_udp_destination_port",   nodes.size(), 1, "RW", REG_FORMAT_UINT16);
    
        pointMap->add_register("FPGA_processing_enable_R",                       "fpga/processing_enable",                      nodes.size(), 1, "RO", REG_FORMAT_BOOLEAN);
        pointMap->add_register("FPGA_processing_enable_RW",                      "fpga/processing_enable",                      nodes.size(), 1, "RW", REG_FORMAT_BOOLEAN);
        pointMap->add_register("FPGA_sdp_info_station_id_R",                     "fpga/sdp_info_station_id",                    nodes.size(), 1, "RO", REG_FORMAT_UINT32);
        pointMap->add_register("FPGA_sdp_info_station_id_RW",                    "fpga/sdp_info_station_id",                    nodes.size(), 1, "RW", REG_FORMAT_UINT32);
        pointMap->add_register("FPGA_sdp_info_observation_id_R",                 "fpga/sdp_info_observation_id",                nodes.size(), 1, "RO", REG_FORMAT_UINT32);
        pointMap->add_register("FPGA_sdp_info_observation_id_RW",                "fpga/sdp_info_observation_id",                nodes.size(), 1, "RW", REG_FORMAT_UINT32);
        pointMap->add_register("FPGA_sdp_info_nyquist_sampling_zone_index_R",    "fpga/sdp_info_nyquist_sampling_zone_index",   nodes.size(), 1, "RO", REG_FORMAT_UINT32);
        pointMap->add_register("FPGA_sdp_info_nyquist_sampling_zone_index_RW",   "fpga/sdp_info_nyquist_sampling_zone_index",   nodes.size(), 1, "RW", REG_FORMAT_UINT32);
        pointMap->add_register("FPGA_sdp_info_antenna_band_index_R",             "fpga/sdp_info_antenna_band_index",            nodes.size(), 1, "RO", REG_FORMAT_UINT32);
        pointMap->add_register("FPGA_sdp_info_f_adc_R",                          "fpga/sdp_info_f_adc",                         nodes.size(), 1, "RO", REG_FORMAT_UINT32);
        pointMap->add_register("FPGA_sdp_info_fsub_type_R",                      "fpga/sdp_info_fsub_type",                     nodes.size(), 1, "RO", REG_FORMAT_UINT32);
        pointMap->add_register("FPGA_sdp_info_block_period_R",                   "fpga/sdp_info_block_period",                  nodes.size(), 1, "RO", REG_FORMAT_UINT32);
    
        pointMap->add_register("FPGA_wg_enable_R",                               "fpga/wg_enable",                              nodes.size(), C_S_pn, "RO", REG_FORMAT_BOOLEAN);
        pointMap->add_register("FPGA_wg_enable_RW",                              "fpga/wg_enable",                              nodes.size(), C_S_pn, "RW", REG_FORMAT_BOOLEAN);
        pointMap->add_register("FPGA_wg_amplitude_R",                            "fpga/wg_amplitude",                           nodes.size(), C_S_pn, "RO", REG_FORMAT_DOUBLE);
        pointMap->add_register("FPGA_wg_amplitude_RW",                           "fpga/wg_amplitude",                           nodes.size(), C_S_pn, "RW", REG_FORMAT_DOUBLE);
        pointMap->add_register("FPGA_wg_phase_R",                                "fpga/wg_phase",                               nodes.size(), C_S_pn, "RO", REG_FORMAT_DOUBLE);
        pointMap->add_register("FPGA_wg_phase_RW",                               "fpga/wg_phase",                               nodes.size(), C_S_pn, "RW", REG_FORMAT_DOUBLE);
        pointMap->add_register("FPGA_wg_frequency_R",                            "fpga/wg_frequency",                           nodes.size(), C_S_pn, "RO", REG_FORMAT_DOUBLE);
        pointMap->add_register("FPGA_wg_frequency_RW",                           "fpga/wg_frequency",                           nodes.size(), C_S_pn, "RW", REG_FORMAT_DOUBLE);
    
        pointMap->add_register("FPGA_bsn_monitor_input_bsn_R",                   "fpga/bsn_monitor_input_bsn",                  nodes.size(), 1, "RO", REG_FORMAT_INT64);
        pointMap->add_register("FPGA_bsn_monitor_input_nof_packets_R",           "fpga/bsn_monitor_input_nof_packets",          nodes.size(), 1, "RO", REG_FORMAT_INT32);
        pointMap->add_register("FPGA_bsn_monitor_input_nof_valid_R",             "fpga/bsn_monitor_input_nof_valid",            nodes.size(), 1, "RO", REG_FORMAT_INT32);
        pointMap->add_register("FPGA_bsn_monitor_input_nof_err_R",               "fpga/bsn_monitor_input_nof_err",              nodes.size(), 1, "RO", REG_FORMAT_INT32);
    
        pointMap->add_register("FPGA_jesd204b_csr_rbd_count_R",                  "fpga/jesd204b_csr_rbd_count",                 nodes.size(), C_S_pn, "RO", REG_FORMAT_UINT32);
        pointMap->add_register("FPGA_jesd204b_csr_dev_syncn_R",                  "fpga/jesd204b_csr_dev_syncn",                 nodes.size(), C_S_pn, "RO", REG_FORMAT_UINT32);
        pointMap->add_register("FPGA_jesd204b_rx_err0_R",                        "fpga/jesd204b_rx_err0",                       nodes.size(), C_S_pn, "RO", REG_FORMAT_UINT32);
        pointMap->add_register("FPGA_jesd204b_rx_err1_R",                        "fpga/jesd204b_rx_err1",                       nodes.size(), C_S_pn, "RO", REG_FORMAT_UINT32);
    
        pointMap->add_register("FPGA_signal_input_samples_delay_R",              "fpga/signal_input_samples_delay",             nodes.size(), C_S_pn, "RO", REG_FORMAT_UINT32);
        pointMap->add_register("FPGA_signal_input_samples_delay_RW",             "fpga/signal_input_samples_delay",             nodes.size(), C_S_pn, "RW", REG_FORMAT_UINT32);
    
        pointMap->add_register("FPGA_subband_weights_R",                         "fpga/subband_weights",                        nodes.size(), C_S_pn*C_N_sub, "RO", REG_FORMAT_UINT32);
        pointMap->add_register("FPGA_subband_weights_RW",                        "fpga/subband_weights",                        nodes.size(), C_S_pn*C_N_sub, "RW", REG_FORMAT_UINT32);
    
        pointMap->add_register("FPGA_scrap_R",                                   "fpga/scrap",                                  nodes.size(), C_N_scrap, "RO", REG_FORMAT_UINT32);
        pointMap->add_register("FPGA_scrap_RW",                                  "fpga/scrap",                                  nodes.size(), C_N_scrap, "RW", REG_FORMAT_UINT32);
    
        pointMap->add_register("FPGA_weights_R",                                 "fpga/weights",                                nodes.size(), C_S_pn*C_N_beamlets, "RO", REG_FORMAT_INT16);
        pointMap->add_register("FPGA_weights_RW",                                "fpga/weights",                                nodes.size(), C_S_pn*C_N_beamlets, "RW", REG_FORMAT_INT16);
    }
    
    Fpga::~Fpga()
    {
        if (pointMap != NULL) {
            delete pointMap;
        }
    }
    
    Node * Fpga::select_node(const int nr)
    {
        for (auto node : FPGA) {
            if (node->GetGlobalNr() == (uint)nr) {
                return node;
            }
        }
        throw runtime_error("select_node: not found");
    }
    
    vector<int> Fpga::get_all_nodes(void)
    {
        vector<int> nodes;
        for (auto node : FPGA) {
            nodes.push_back(node->GetGlobalNr());
        }
        return nodes;
    }
    
    vector<bool> Fpga::get_all_enabled_nodes(void)
    {
        vector<bool> enabled;
        for (auto node : FPGA) {
            enabled.push_back(node->isEnabled());
        }
        return enabled;
    }
    
    vector<bool> Fpga::get_all_masked_nodes(void)
    {
        vector<bool> masked;
        for (auto node : FPGA) {
            masked.push_back(node->isMasked());
        }
        return masked;
    }
    
    vector<bool> Fpga::get_all_offline_nodes(void)
    {
        vector<bool> online;
        for (auto node : FPGA) {
            online.push_back(!node->isOnline());
        }
        return online;
    }
    
    void Fpga::set_all_masked_nodes(std::vector<bool> masked)
    {
        vector<int> nodes = get_all_nodes();
        for (uint idx = 0; idx<nodes.size(); idx++) {
            auto node = select_node(nodes[idx]);
            node->setMasked(masked[idx]);
        }
    }
    
    vector<uint32_t> Fpga::get_all_pps_offset_cnt(void)
    {
        vector<uint32_t> pps_offset_cnt;
        for (auto node : FPGA) {
            pps_offset_cnt.push_back(node->ppsOffsetCnt());
        }
        return pps_offset_cnt;
    }
    
    
    uint Fpga::node_number(Node *node)
    {
        return (node->GetUniboardNr() * 4) + node->GetLocalNr();
    }
    
    CPointMap * Fpga::get_pointMap(void)
    {
        return pointMap;
    }
    
    bool Fpga::point(TermOutput& termout, const char cmd, const string addr,
                     const char *data, const int nvalues)
    {
        bool ret, retval = false;
        uint mask_cnt = 0;
        uint exec_cnt = 0;
        uint reply_cnt = 0;
        uint retcnt = 0;
    
        termout.clear();
        string relative_addr = pointMap->getRelativeName(addr);
        string type = "fpga";
        string instance = "";
    
        try {
            if (cmd == 'R') {
                pointMap->getReadPermission(addr);
            }
            else if (cmd == 'W') {
                pointMap->getWritePermission(addr);
            }
        } catch (exception& e) {
            cerr << "Fpga::point: " << addr << " error: " << e.what() << endl;
            return false;
        }
    
        int format = pointMap->getFormat(addr);
        int nof_values = pointMap->getDataSize(addr);
    
        vector<int> nodes = get_all_nodes();
    
        TermOutput termresults;
    
        if (cmd == 'R') {
            retval = true;
        }
        else if (cmd == 'W') {
            if (nvalues < nof_values) {
                return false;
            }
            retval = true;
        }
    
        for (uint idx = 0; idx<nodes.size(); idx++) {
    
            mask_cnt++;
            auto node = select_node(nodes[idx]);
            // if (node->getEnabled() == false) { continue; }
    
    
            ret = false;
            try {
                uint didx = 0;
                if (cmd == 'W') {
                    didx = idx * nof_values * reg_format_size_in_bytes(format);
                }
                if ((ret = node->exec_cmd(cmd, relative_addr, type, instance,
                                          &data[didx], nof_values, format))) {
                    retcnt++;
                    exec_cnt++;
                }
            } catch (exception& e) {
                cerr << e.what() << endl;
            }
    
        }
        retval = (retcnt == nodes.size());
        if (!retval) {
            return false;
        }
    
        termout.nof_vals = pointMap->getNodesSize(addr) * pointMap->getDataSize(addr);
        termout.datatype = pointMap->getFormat(addr);
    
        for (uint idx=0; idx<nodes.size(); idx++) {
            auto node = select_node(nodes[idx]);
    
            ret = false;
            termresults.clear();
            try {
                if ((ret = node->exec_reply(termresults))) {
                    retcnt++;
                    reply_cnt++;
                }
            } catch (exception& e) {
                cerr << e.what() << endl;
            }
            if (cmd == 'R') {
                switch (termresults.datatype) {
                    case REG_FORMAT_BOOLEAN: {
                        bool *ptr_in = (bool *)termresults.val;
                        bool *ptr_out = (bool *)termout.val;
                        for (unsigned int i=0; i<termresults.nof_vals; i++) {
                            ptr_out[idx * termresults.nof_vals + i] = ptr_in[i];
                        }
                    } break;
                    case REG_FORMAT_INT64: {
                        int64_t *ptr_in = (int64_t *)termresults.val;
                        int64_t *ptr_out = (int64_t *)termout.val;
                        for (uint i=0; i<termresults.nof_vals; i++) {
                            ptr_out[idx * termresults.nof_vals + i] = ptr_in[i];
                        }
                    } break;
                    case REG_FORMAT_UINT64: {
                        uint64_t *ptr_in = (uint64_t *)termresults.val;
                        uint64_t *ptr_out = (uint64_t *)termout.val;
                        for (uint i=0; i<termresults.nof_vals; i++) {
                            ptr_out[idx * termresults.nof_vals + i] = ptr_in[i];
                        }
                    } break;
                    case REG_FORMAT_INT32: {
                        int32_t *ptr_in = (int32_t *)termresults.val;
                        int32_t *ptr_out = (int32_t *)termout.val;
                        for (uint i=0; i<termresults.nof_vals; i++) {
                            ptr_out[idx * termresults.nof_vals + i] = ptr_in[i];
                        }
                    } break;
                    case REG_FORMAT_UINT32: {
                        uint32_t *ptr_in = (uint32_t *)termresults.val;
                        uint32_t *ptr_out = (uint32_t *)termout.val;
                        for (uint i=0; i<termresults.nof_vals; i++) {
                            ptr_out[idx * termresults.nof_vals + i] = ptr_in[i];
                        }
                    } break;
                    case REG_FORMAT_INT16: {
                        int16_t *ptr_in = (int16_t *)termresults.val;
                        int16_t *ptr_out = (int16_t *)termout.val;
                        for (uint i=0; i<termresults.nof_vals; i++) {
                            ptr_out[idx * termresults.nof_vals + i] = ptr_in[i];
                        }
                    } break;
                    case REG_FORMAT_UINT16: {
                        uint16_t *ptr_in = (uint16_t *)termresults.val;
                        uint16_t *ptr_out = (uint16_t *)termout.val;
                        for (uint i=0; i<termresults.nof_vals; i++) {
                            ptr_out[idx * termresults.nof_vals + i] = ptr_in[i];
                        }
                    } break;
                    case REG_FORMAT_FLOAT: {
                        float *ptr_in = (float *)termresults.val;
                        float *ptr_out = (float *)termout.val;
                        for (unsigned int i=0; i<termresults.nof_vals; i++) {
                            ptr_out[idx * termresults.nof_vals + i] = ptr_in[i];
                        }
                    } break;
                    case REG_FORMAT_DOUBLE: {
                        double *ptr_in = (double *)termresults.val;
                        double *ptr_out = (double *)termout.val;
                        for (unsigned int i=0; i<termresults.nof_vals; i++) {
                            ptr_out[idx * termresults.nof_vals + i] = ptr_in[i];
                        }
                    } break;
                    case REG_FORMAT_STRING: {
                        char *ptr_in = (char *)termresults.val;
                        char *ptr_out = (char *)termout.val;
                        ptr_out += (idx * termresults.nof_vals * SIZE1STRING);
                        for (unsigned int i=0; i<termresults.nof_vals; i++) {
                            ptr_in += (i * SIZE1STRING);
                            ptr_out += (i * SIZE1STRING);
                            strcpy(ptr_out, ptr_in);
                        }
                    } break;
                    default: {
                        cout << "fpga-r320, Not supported datatype (" << termresults.datatype << " in " << addr << endl;
                    } break;
                }
            }
            else if (cmd == 'W') {
                // nothing
            }
        }
    
        if (nodes.size() == 0) {
            cerr << "no nodes";
            retval = false;
        }
    
        return retval;
    }
    
    bool Fpga::is_fpga(const string addr)
    {
        bool retval = false;
        stringstream strs(addr);
        string token;
        vector<string> tokens;
    
        while (getline(strs, token, '_')) {
            tokens.push_back(token);
        }
        if (tokens.size() > 1) {
            if (tokens[0] == "FPGA") {
                retval = true;
            }
        }
        return retval;
    }