Using Interactive station.py

Once the SPS Test Suite has been installed a station can be deployed.

This requires a Station Configuration YAML corresponding to the used system. Configuration files for persistent deployments are provided in the config directory of this project. If a new configuration file is needed, it is suggested to copy, rename and modify an existing configuration according to the used system. Configurations can also be generated from templates. These are available within the config/templates directory and can be generated using scripts/config/python/generate_templates.py. See the CI Pipeline .gitlab-ci.yml for an example.

Even if using an existing config file, the Tile Processing Modules being used may need to be changed. For example the RAL station config files default to only a selection of the TPMs available.

There are two possible syntax for this, tiles and subracks. See the Station Configuration YAML page for more information.

# List of Subrack IPs (or names), and TPM slots which will form station
subracks:
    subrack_1:
        cpu_ip: "10.192.0.24"
        # slots: [1, 2, 3, 4, 5, 6, 7, 8]
        slots: []

    subrack_2:
        cpu_ip: "10.192.0.74"
        # slots: [1, 2, 3, 4, 5, 6, 7, 8]
        slots: []

# List of TPM IPs (or names) which will form station
tiles:
# Subrack 1
    - "10.132.0.21"
    - "10.132.0.22"
#    - "10.132.0.23"
#    - "10.132.0.24"
#    - "10.132.0.25"
#    - "10.132.0.26"
#    - "10.132.0.27"
#    - "10.132.0.28"
#
# Subrack 2
#    - "10.132.0.41"
#    - "10.132.0.42"
#    - "10.132.0.43"
#    - "10.132.0.44"
#    - "10.132.0.45"
#    - "10.132.0.46"
#    - "10.132.0.47"
#    - "10.132.0.48"

The station can then be deployed with ipython as below. The arguments IPB initialise, program the FPGAs and start the beamformers. The full set of command line arguments are available below but this is the most common usage when deploying a station with ipython.

pushd src/ska_low_sps_testsuite/common/
ipython -i station.py -- --config=config.yml -IPB

NOTE: The installation creates symbolic links to many files and directories that are commonly used, including the station.py file, the bitfiles directory and the config files directory. In most commands and YAML files where paths are required, it is typically easier to provide absolute paths based on the install location. For example /opt/sps/bitfiles/tpm_firmware_6_2_0.bit for the FPGA firmware.

For example on one of the machines at STFC-RAL te7dastardly:

pushd src/ska_low_sps_testsuite/common/
ipython -i station.py -- --config=/opt/sps/config/ral_subrack_te7dastardly.yml -IPB

A station can be deployed without an ipython shell from any directory, so long as the virtual environment is sourced:

station.py --config=/opt/sps/config/<config>.yml -IPB

Below are all command line arguments supported by station.py :

Options:
  -h, --help            show this help message and exit
  --config=CONFIG       Configuration file [default: None]
  --port=PORT           Port [default: None]
  --lmc_ip=LMC_IP       IP [default: None]
  --lmc_port=LMC_PORT   Port [default: None]
  -f BITFILE, --bitfile=BITFILE
                        Bitfile to use (-P still required) [default: None]
  -t TILES, --tiles=TILES
                        Tiles to add to station [default: None]
  -P, --program         Program FPGAs [default: False]
  -I, --initialise      Initialise TPM [default: False]
  --single_tile_mode    Program all tiles as a single tile station, for
                          testing
  --qsfp_detection=QSFP_DETECTION
                        Force QSFP cable detection: auto, qsfp1, qsfp2, all,
                        none [default: auto]
  --use_teng            Use 10G for LMC [default: None]
  --chan-trunc=CHAN_TRUNC
                        Channeliser truncation [default: None]
  -B, --beamf_start     Start network beamformer [default: False]
  --channel-integration-time=CHANNEL_INTEG
                        Integrated channel integration time [default: None]
  --beam-integration-time=BEAM_INTEG
                        Integrated beam integration time [default: None]
  --beamformer-scaling=BEAM_SCALING
                        Beamformer scaling [default: None]
  --beam-start_frequency=START_FREQUENCY_CHANNEL
                        Beamformer scaling [default: None]
  --beam-bandwidth=BEAM_BANDWIDTH
                        Beamformer scaling [default: None]
  --fft_sign_invert     Conjugate FFT output [default: False]
  --log_level=LOG_LEVEL
                          Specifies the log level [default: STEP]

Tile methods

Once the station is initialised you will find yourself in an ipython shell. At this stage some useful functionality is as follows:

Calling station level methods like starting and stopping the beamformer:

In [1]: station.stop_beamformer()

In [2]: station.start_beamformer()

Hardware, firmware and network information such as build dates, hardware and bios revisions and IP addresses can be displayed by printing the tile object:

In [1]: for tile in station.tiles:
            print(tile)

Out [1]:
Tile Processing Module v2.0.1a Serial Number: 0850423050010
__________________________________________________________________________________________
                             |
Classification               | iTPM_ADU_2.0-NO-ADA
Hardware Revision            | v2.0.1a
Serial Number                | 0850423050010
BIOS Revision                | v0.5.0 (CPLD_0x23092511-MCU_0xb000011a_0x20230209_0x0)
Board Location               | 65535:255:255
DDR Memory Capacity          | 4 GB per FPGA
_____________________________|____________________________________________________________
                             |
FPGA Firmware Design         | tpm_ska_low
FPGA Firmware Release        | 6.2.1
FPGA Firmware Build          | 2007
FPGA Firmware Compile Time   | 2025-02-19 19:15:13.771050 UTC
FPGA Firmware Compile User   | gitlab-runner (created by hajira bazaz)
FPGA Firmware Compile Host   | te7nelson linux-4.18.0-553.33.1.el8_10.x86_64-x86_64-with-glibc2.28
FPGA Firmware Git Branch     | detached head
FPGA Firmware Git Commit     | db395557dcff7e5aa9d140045b4ff532dd41d86f  janus-76: removed std.textio from tb_tb_example.vhd
_____________________________|____________________________________________________________
                             |
1G (MGMT) IP Address         | 10.132.0.62
1G (MGMT) MAC Address        | fc:0f:e7:e6:f4:b0
1G (MGMT) Netmask            | 255.255.255.0
1G (MGMT) Gateway IP         | 10.132.0.254
EEP IP Address               | 10.0.10.2
EEP Netmask                  | 255.255.255.0
EEP Gateway IP               | 255.255.255.255
40G Port 1 IP Address        | 10.130.0.53
40G Port 1 MAC Address       | 62:00:0A:82:00:35
40G Port 1 Netmask           | 255.255.255.128
40G Port 1 Gateway IP        | 10.130.0.126
40G Port 2 IP Address        | 0.0.0.0
40G Port 2 MAC Address       | 02:00:00:00:00:00
40G Port 2 Netmask           | 255.255.255.128
40G Port 2 Gateway IP        | 10.130.0.126

Accessing the tiles in a station and some basic examples of reading attributes:

In [1]: tile = station.tiles[0]

In [2]: tile.get_temperature()
Out[2]: 58.8125

In [3]: tile.get_voltage(voltage_name='FPGA0_CORE')
Out[3]: {'FPGA0_CORE': 0.94}

Getting the health status dictionary for a tile:

In [4]: health_dict = tile.get_health_status()

Calling plugin methods

In the TPM API, plugins are used to represent hardware components of the TPM (Tile Processing Module) and the associated hierachy.

During development you may want to call a plugin method directly from ipython, for example the tpm_test_firmware plugin. These objects represent the FPGA, each tile has two.

In [1]: tile = station.tiles[0]

In [2]: fpga0_firmware = tile.tpm.tpm_test_firmware[0]

In [3]: fpga1_firmware = tile.tpm.tpm_test_firmware[1]

In [4]: fpga0_firmware.check_ddr_initialisation()
Out[4]: True

In [5]: fpga1_firmware.check_ddr_initialisation()
Out[5]: False

Or the mcu plugin. This represents the micro controller, each tile has one.

In [1]: tile = station.tiles[0]

In [2]: tpm_monitor = tile.tpm.tpm_monitor[0]

In [3]: tpm_monitor.get_version()
Out[3]:

NOTE: Only access plugin methods directly if you know what you are doing. This is only intended for development purposes, for production code plugin methods should have a corresponding method exposed at the tile level.

Accessing TPM Registers directly

Although methods such as the above exist to access top station and tile methods,, TPM registers can be accessed directly.

To find a register using a string match i.e:

In [1]: tile.find_register('rst')

Reading the value of a register, i.e the F2F interface reset:

In [1]: tile['fpga1.f2f_0.ctrl.rst']

Writing the same register, for example with the value 1, can simply be done with:

In [2]: tile['fpga1.f2f_0.ctrl.rst'] = 1

NOTE: Only access registers directly if you know what you are doing. This is only intended for development purposes, for production code registers should have a corresponding plugin methods.