2017-11-21 21:31:08 +01:00
/** Driver for AXI Stream wrapper around RTDS_InterfaceModule (rtds_axis )
*
* @ author Steffen Vogel < stvogel @ eonerc . rwth - aachen . de >
2018-06-25 15:33:14 +02:00
* @ copyright 2017 - 2018 , Steffen Vogel
2017-11-21 21:31:08 +01:00
* @ license GNU General Public License ( version 3 )
*
* VILLASfpga
*
* This program is free software : you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation , either version 3 of the License , or
* any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program . If not , see < http : //www.gnu.org/licenses/>.
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2018-06-04 14:13:33 +02:00
# include <cstdint>
2017-11-21 21:31:08 +01:00
2018-06-04 14:13:33 +02:00
# include <villas/utils.h>
# include <villas/fpga/card.hpp>
# include <villas/fpga/ips/rtds.hpp>
2017-11-21 21:31:08 +01:00
# define RTDS_HZ 100000000 // 100 MHz
# define RTDS_AXIS_MAX_TX 64 /**< The amount of values which is supported by the vfpga card */
# define RTDS_AXIS_MAX_RX 64 /**< The amount of values which is supported by the vfpga card */
/* Register offsets */
# define RTDS_AXIS_SR_OFFSET 0x00 /**< Status Register (read-only). See RTDS_AXIS_SR_* constant. */
# define RTDS_AXIS_CR_OFFSET 0x04 /**< Control Register (read/write) */
# define RTDS_AXIS_TSCNT_LOW_OFFSET 0x08 /**< Lower 32 bits of timestep counter (read-only). */
# define RTDS_AXIS_TSCNT_HIGH_OFFSET 0x0C /**< Higher 32 bits of timestep counter (read-only). */
# define RTDS_AXIS_TS_PERIOD_OFFSET 0x10 /**< Period in clock cycles of previous timestep (read-only). */
# define RTDS_AXIS_COALESC_OFFSET 0x14 /**< IRQ Coalescing register (read/write). */
# define RTDS_AXIS_VERSION_OFFSET 0x18 /**< 16 bit version field passed back to the rack for version reporting (visible from “status” command, read/write). */
# define RTDS_AXIS_MRATE 0x1C /**< Multi-rate register */
/* Status register bits */
# define RTDS_AXIS_SR_CARDDETECTED (1 << 0) /**< ‘ 1’ when RTDS software has detected and configured card. */
# define RTDS_AXIS_SR_LINKUP (1 << 1) /**< ‘ 1’ when RTDS communication link has been negotiated. */
# define RTDS_AXIS_SR_TX_FULL (1 << 2) /**< Tx buffer is full, writes that happen when UserTxFull=’ 1’ will be dropped (Throttling / buffering is performed by hardware). */
# define RTDS_AXIS_SR_TX_INPROGRESS (1 << 3) /**< Indicates when data is being put on link. */
# define RTDS_AXIS_SR_CASE_RUNNING (1 << 4) /**< There is currently a simulation running. */
/* Control register bits */
# define RTDS_AXIS_CR_DISABLE_LINK 0 /**< Disable SFP TX when set */
2018-06-04 14:13:33 +02:00
namespace villas {
namespace fpga {
namespace ip {
static RtdsFactory rtdsFactoryInstance ;
void Rtds : : dump ( )
{
/* Check RTDS_Axis registers */
const uint32_t sr = readMemory < uint32_t > ( registerMemory , RTDS_AXIS_SR_OFFSET ) ;
logger - > info ( " RTDS AXI Stream interface details: " ) ;
logger - > info ( " RTDS status: {:#x} " , sr ) ;
logger - > info ( " Card detected: {} " , sr & RTDS_AXIS_SR_CARDDETECTED ? CLR_GRN ( " yes " ) : CLR_RED ( " no " ) ) ;
logger - > info ( " Link up: {} " , sr & RTDS_AXIS_SR_LINKUP ? CLR_GRN ( " yes " ) : CLR_RED ( " no " ) ) ;
logger - > info ( " TX queue full: {} " , sr & RTDS_AXIS_SR_TX_FULL ? CLR_RED ( " yes " ) : CLR_GRN ( " no " ) ) ;
logger - > info ( " TX in progress: {} " , sr & RTDS_AXIS_SR_TX_INPROGRESS ? CLR_YEL ( " yes " ) : " no " ) ;
logger - > info ( " Case running: {} " , sr & RTDS_AXIS_SR_CASE_RUNNING ? CLR_GRN ( " yes " ) : CLR_RED ( " no " ) ) ;
logger - > info ( " RTDS control: {:#x} " , readMemory < uint32_t > ( registerMemory , RTDS_AXIS_CR_OFFSET ) ) ;
logger - > info ( " RTDS IRQ coalesc: {} " , readMemory < uint32_t > ( registerMemory , RTDS_AXIS_COALESC_OFFSET ) ) ;
logger - > info ( " RTDS IRQ version: {:#x} " , readMemory < uint32_t > ( registerMemory , RTDS_AXIS_VERSION_OFFSET ) ) ;
logger - > info ( " RTDS IRQ multi-rate: {} " , readMemory < uint32_t > ( registerMemory , RTDS_AXIS_MRATE ) ) ;
const uint64_t timestepLow = readMemory < uint32_t > ( registerMemory , RTDS_AXIS_TSCNT_LOW_OFFSET ) ;
const uint64_t timestepHigh = readMemory < uint32_t > ( registerMemory , RTDS_AXIS_TSCNT_HIGH_OFFSET ) ;
const uint64_t timestep = ( timestepHigh < < 32 ) | timestepLow ;
logger - > info ( " RTDS timestep counter: {} " , timestep ) ;
logger - > info ( " RTDS timestep period: {:.3f} us " , getDt ( ) * 1e6 ) ;
}
double Rtds : : getDt ( )
{
const auto dt = readMemory < uint16_t > ( registerMemory , RTDS_AXIS_TS_PERIOD_OFFSET ) ;
return ( dt = = 0xFFFF ) ? 0.0 : ( double ) dt / RTDS_HZ ;
}
2017-11-21 21:31:08 +01:00
2018-06-04 14:13:33 +02:00
RtdsFactory : : RtdsFactory ( ) :
IpNodeFactory ( getName ( ) )
{
}
2017-11-21 21:31:08 +01:00
2018-06-04 14:13:33 +02:00
} // namespace ip
} // namespace fpga
} // namespace villas