=== ICL === The core of the FPGA interface is implemented across three files: * **args_fpga.py** - defines the interfaces to be used by drivers * **fpga_icl.py** - provides infrastructure for higher-level abstractions of FPGA functions to be implemented * **args_map.py** - decodes the ARGS map into register names & addresses .. image:: diagrams/fpga_classes.png :alt: UML Class diagram, surrounding text describes the key points args_fpga --------- ``ArgsFpgaIface`` defines a common interface used by drivers. The ICL code will use this interface to communicate with the FPGA. ``ArgsFpgaDriver`` defines the common functions expected of any FPGA driver. Some examples are shown on the diagram: ArgsXrt, ArgsSimulator. These derived classes will implement the 'heavy lifting' of actually talking to the FPGA. fpga_icl -------- Users are expected to implement classes derived from ``FpgaPersonality`` and ``FpgaPeripheral`` to implement their desired functionality. The term "personality" refers to a FPGA firmware image with a distinct functionality. Peripherals may be shared between multiple personalities. ``FpgaPersonality`` brings all the pieces together. Given at least one ``ArgsFpgaInterface`` and exactly one ``ArgsMap``, it will create ``FpgaPeripheral`` objects for each peripheral. ``FpgaPeripheral`` also provides shortcuts to access certain members of its default interface. ``FpgaPeripheral`` collects the 'fields' (registers) of a peripheral together. Derived classes can provide additional configuration and abstraction functions. ``IclField`` is a data class that should be returned by any methods or attributes that are added to ``FpgaPeripheral`` or ``FpgaPersonality`` for use in the control system. It supports all the usual python operators. It also inherits from typing.Generic, to allow the type of its value to be specified in a type hint. This could be used for static type checking, or at run-time. Note that I have not yet been able to link the type hint to the ``type_`` attribute (if you know how to do this, please let me know!). .. code-block:: python # setting type hints def my_icl_name() -> IclField[str]: return IclField(value="Andrew") def show_name(name: IclField[str]): print("My name is", name.value) show_name(my_icl_name()) # inspecting type hints at run time from typing import get_args, get_type_hint return_class = get_origin(get_type_hints(my_int_af)["return"]) assert return_class is IclField # True return_value_type = get_args(get_type_hints(my_icl_name)["return"])[0] assert return_value_type is str # True ``IclFpgaField`` is a data class used for FPGA registers. It adds read & write interfaces to ``IclField``. The required instances of this class should be created automatically. .. code-block:: python # increment a register value demo_fpga.packetiser.control_vector += 1 # compare register value if demo_fpga.packetiser.control_vector > 0: pass args_map -------- ``ArgsMap`` takes a build timestamp and a search directory, and looks there for a specially-named python file (e.g. fpgamap_21080211.py). For sensible results, provide the build timestamp read from the FPGA via the relevant ArgsFpgaDriver. ======= Drivers ======= Common Interface ---------------- All drivers inherit from ``ArgsFpgaDriverIface``, which specifies a common interface: * read * write * read_memory * write_memory See the docstrings in the code for usage details. Information about the FPGA card hardware, if present, is available via ``.info`` - this will be either ``None`` (by default) or an instance of ``XrtInfo`` (if instantiated by the driver). ArgsSimulator ------------- A simulation of an FPGA, for development/testing when FPGA hardware is not available. ArgsXrt ------- Uses Xilinx's PyXRT to communicate with a Xilinx Alveo FPGA card registers & memories. ================= Status Monitoring ================= XrtInfo ------- Provides extra information about the Alveo FPGA card, including parameters for health and status monitoring. Access to most information is via array index syntax (UUID is via a property), returned data is in a range of formats. ===== Other ===== RegisterLoader -------------- Used to load a text file of register values into the FPGA. These files are usually generated by other software, for testing/verification. The file uses 32-bit hexadecimal values, and multiple values can be specified for large registers. .. code-block:: [..][] 0x000000a1 0x000000a2 0x000000a3 0x000000a4 [..][] 0x000000b1 e.g. to set the ``secondcornerturn`` peripheral's ``beams_enabled`` register to 1: .. code-block:: [secondcornerturn.config.beams_enabled][0] 0x00000001