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
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!).
# 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.
# 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.
[<peripheral>.<ignored>.<field>][<offset>]
0x000000a1
0x000000a2
0x000000a3
0x000000a4
[<peripheral>.<ignored>.<field>][<offset>]
0x000000b1
e.g. to set the secondcornerturn
peripheral’s beams_enabled
register to 1:
[secondcornerturn.config.beams_enabled][0]
0x00000001