Tango Tile to TPM

Tango Tile Device Construction

The TPM (or simulator) is created during the Tile’s Init command. This command is executed automatically during construction of the Tile Tango device. The decision whether to use the TPM simulator or a real hardware driver is made with the simulation_mode flag. This is currently hardcoded to SimulationMode.TRUE in tile_device.py. This means that either the TPM simulator or the real hardware driver is available as soon as the Tile Tango device is ready for use. You can swicth between simulation and real TPM driver by writing to the Tile device’s simulation_mode attribute. This will reset the Tile’s TPM object.

The Hardware tile object is actually a factory, which returns either a Tile12 or a Tile16 object, depending on the Tango property TpmVersion.

TPM Simulator Construction

@startuml
participant "Construction\nInitiator" as Constructor
participant "Tile's Init\nCommand\nClass" as Init_cmd
participant "Tile\nHardware\nManager" as Tile_HW_Man
participant "Tile\nHardware\nFactory" as Tile_HW_Factory
participant "Simulable\nHardware\nFactory" as Sim_HW_Factory
participant "TPM\nSimulator" as TPM_Sim

Constructor -> Init_cmd: Init()
Init_cmd -> Init_cmd: do()
Init_cmd -> Init_cmd: _initialise_connections()
Init_cmd -> Init_cmd: _initialise_hardware_management()
Init_cmd -> Tile_HW_Man: __init__()
Tile_HW_Man -> Tile_HW_Factory: __init__()
Tile_HW_Factory -> Sim_HW_Factory: __init__()
Sim_HW_Factory -> Sim_HW_Factory: self._hardware = _get_simulator()
Sim_HW_Factory -> Tile_HW_Factory: self._simulator = self._create_simulator()
Tile_HW_Factory -> TPM_Sim: __init__()
Tile_HW_Factory <-- TPM_Sim:
Sim_HW_Factory <-- Tile_HW_Factory:
Sim_HW_Factory <-- Sim_HW_Factory:
Tile_HW_Factory <-- Sim_HW_Factory:
Tile_HW_Man <-- Tile_HW_Factory:
Init_cmd <-- Tile_HW_Man:
Constructor <-- Init_cmd:
@enduml

TPM Driver Construction

@startuml
participant "Construction\nInitiator" as Constructor
participant "Tile's Init\nCommand\nClass" as Init_cmd
participant "Tile\nHardware\nManager" as Tile_HW_Man
participant "Tile\nHardware\nFactory" as Tile_HW_Factory
participant "Simulable\nHardware\nFactory" as Sim_HW_Factory
participant "TPM\nDriver" as TPM_Drv
participant "Hardware\nTile" as HW_Tile

Constructor -> Init_cmd: Init()
Init_cmd -> Init_cmd: do(): device = self.target (the Tile)
Init_cmd -> Init_cmd: _initialise_connections(device)
Init_cmd -> Init_cmd: _initialise_hardware_management(device)
Init_cmd -> Tile_HW_Man: __init__(..., device.tpm_ip, device.tpm_cpld_port)
Tile_HW_Man -> Tile_HW_Factory: __init__(..., tpm_ip, tpm_cpld_port)
Tile_HW_Factory -> Sim_HW_Factory: __init__()
Sim_HW_Factory -> Sim_HW_Factory: self._hardware = _get_driver()
Sim_HW_Factory -> Tile_HW_Factory: self._simulator = self._create_driver()
Tile_HW_Factory -> TPM_Drv: __init__(..., tpm_ip, tpm_cpld_port)
TPM_Drv -> HW_Tile: self.tile = __init__(ip, port, ...)
TPM_Drv <-- HW_Tile:
Tile_HW_Factory <-- TPM_Drv:
Sim_HW_Factory <-- Tile_HW_Factory:
Sim_HW_Factory <-- Sim_HW_Factory:
Tile_HW_Factory <-- Sim_HW_Factory:
Tile_HW_Man <-- Tile_HW_Factory:
Init_cmd <-- Tile_HW_Man:
Constructor <-- Init_cmd:
@enduml

Connection to TPM & Firmware Download

The firmware download is available via a command to the Tile Tango device. A path and name of a Vivado bit file are passed via the Tile’s ‘DownloadFirmware’ command to the TPM. The code checks that the file exists and then passes this file path down to the hardware (either real or simulated). If no name is specified, the name defaults to “itpm_v1_6.bit” for simulator or Tile16 hardware driver, and to “itpm_v1_2.bit” for Tile12 hardware driver.

Ursula’s Sequence Diagram

participant "Jupyter\nNotebook\nOET" as Jupyter
participant "TMC" as TMC
participant "MCCS\nController" as MCCS_Controller
participant "MCCS\nStation 1" as MCCS_Station_1
participant "MCCS\nTile 1" as MCCS_Tile_1
participant "Tile\nHardware\nManager" as Tile_HW_Man
participant "Simulable\nHardware\nFactory" as Sim_HW_Factory
participant "TPM\nHardware" as TPM_HW

Jupyter -> TMC: Startup_Telescope()
TMC -> MCCS_Controller: On()
MCCS_Controller -> MCCS_Station_1: On()
MCCS_Station_1 -> MCCS_Tile_1: On()
MCCS_Station_1 -> MCCS_Tile_1: Initialise()
MCCS_Tile_1 -> Tile_HW_Man: Initialise()
Tile_HW_Man -> Sim_HW_Factory: Initialise()
Sim_HW_Factory -> TPM_HW: DownloadFirmware(filename)
Sim_HW_Factory <-- TPM_HW: <programmed>
Sim_HW_Factory -> TPM_HW: Initialise()
Sim_HW_Factory <-- TPM_HW: <initialised>

Gianni’s Code (Modified to hook into Ursula’s sequence)

@startuml

participant "Jupyter\nNotebook\nOET" as Jupyter
participant "TMC" as TMC
participant "MCCS\nController" as MCCS_Controller
participant "MCCS\nStation 1" as MCCS_Station_1
participant "MCCS\nTile 1\n(On\nCommand)" as MCCS_Tile_1
participant "MCCS\nTile\nPower\nManager" as MCCS_Tile_PM
participant "Tile\nHardware\nManager" as Tile_HW_Man
participant "TPM\nDriver" as TPM_Drv
participant "Hardware\nTile" as HW_Tile
participant "pyfabil\nTPM" as TPM

Jupyter -> TMC: Startup_Telescope()
note over MCCS_Controller: state = OFF
TMC -> MCCS_Controller: On()
note over MCCS_Station_1: state = OFF
MCCS_Controller -> MCCS_Station_1: On()

note over MCCS_Tile_1: state = STANDBY

MCCS_Station_1 -> MCCS_Tile_1: On()

MCCS_Tile_1 -> MCCS_Tile_PM: Off()
MCCS_Tile_1 <-- MCCS_Tile_PM:

note over MCCS_Tile_1: state = OFF

MCCS_Tile_1 -> MCCS_Tile_PM: On()
MCCS_Tile_1 <-- MCCS_Tile_PM:

note over MCCS_Tile_1: state = ON

MCCS_Tile_1 -> Tile_HW_Man: initialise()

Tile_HW_Man -> TPM_Drv: initialise()
TPM_Drv -> HW_Tile: perform_connectivity_checks()
TPM_Drv <-- HW_Tile:
TPM_Drv -> HW_Tile: connect(simulation=True)
HW_Tile -> TPM: TPM()
HW_Tile <-- TPM:
HW_Tile -> TPM: tpm.connect(...)
HW_Tile <-- TPM:
TPM_Drv <-- HW_Tile:
TPM_Drv -> TPM: tpm.is_programmed()
TPM_Drv <-- TPM: <no>

TPM_Drv -> HW_Tile: program_fpgas()
HW_Tile -> HW_Tile: connect(simulation=True)
activate HW_Tile
HW_Tile -> TPM: TPM()
HW_Tile <-- TPM:
HW_Tile -> TPM: tpm.connect(...)
HW_Tile <-- TPM:
HW_Tile <-- HW_Tile:
deactivate HW_Tile
HW_Tile -> TPM: download_firmware(Device.FPGA_1, bitfile)
HW_Tile <-- TPM:
TPM_Drv <-- HW_Tile:

TPM_Drv -> HW_Tile: initialise()

HW_Tile -> HW_Tile: connect(initialise=True)
activate HW_Tile
HW_Tile -> TPM: TPM()
HW_Tile <-- TPM:
HW_Tile -> TPM: tpm.connect(...)
HW_Tile <-- TPM:
HW_Tile <-- HW_Tile:
deactivate HW_Tile
TPM_Drv <-- HW_Tile:

TPM_Drv -> TPM: tpm.is_programmed()
TPM_Drv <-- TPM: <yes>

TPM_Drv -> HW_Tile: perform_health_check()
TPM_Drv <-- HW_Tile:

Tile_HW_Man <-- TPM_Drv:
MCCS_Tile_1 <-- Tile_HW_Man:

MCCS_Station_1 <-- MCCS_Tile_1:
note over MCCS_Station_1: state = ON

MCCS_Controller <-- MCCS_Station_1:
note over MCCS_Controller: state = ON

TMC <-- MCCS_Controller:
Jupyter <-- TMC:

@enduml

Notes

  • Station devices holds Vivado firmware bitfile name. But filename can be a symlink with the standard name, pointing to the correct default filename, so it does not need to be propagated in most cases.

  • Tile devices hold specific information about the TPM’s IP address

  • Tile device holds information about TPM hardware version. This allows use of same software architecture as hardware is upgraded.

  • Programming occurs during STANDBY-> OFF transition. It can occur at any time usng command DownloadFirmware(). Call will be asynchronous as programming takes several seconds.

    • For the demo, a sleep() call is used.

    • A more clever solution would be to cycle from STANDBY to OFF and having the programming done in a separate thred. The thread will change the device state when the operation is completed

  • TPM initialise is not currenty called. It would be called in the second option above

    The commend also takes several (up to 10) seconds to complete.

  • After this sequence has finished, the Tile WebJive pages can be queried to return values read from the TPM hardware

Tile Power Management

The system is considered to be in a low power mode until the TPM firmware has been loaded and is running. The whole topic of power management is an evolving area with conversations being had between Gianni, Mark and Alan…It involves the subrack, network switches as well as the TPM itself. For feature SPO-943, we will need to determine the initial state with respect to power and power mode. These initial conditions are also being flushed out by Daniel Hayden. It’s likely the initial conditions will involve a manual setup to ensure the TPM is powered and in a state that the Tile Tango device can communicate with it.

Proposed mapping between status and power modes are:

  • Disabled: power mode OFF

  • Standby: Power mode ON, low power

  • OFF: Power mode ON, 80% full power, typ.

  • ON: Power 80-100%, depending on operation

This implies that the board is programmed and initialised when going from STANDBY to OFF. A default firmware name is coded in the device. The specific firmware name, if different, is provided before the STANDBY to OFF transition. Entering the STANDBY state deprograms the FPGAs.