Various debugging tools are provided through a command line tool, which can be executed with the command fpga or python3 -m ska_low_cbf_fpga. You must provide either a kernel -f path/to/your.xclbin or a register map to simulate -s path/to/fpgamap_nnnnnnnn.py.

usage: fpga [-h] [-f KERNELS [KERNELS ...]] [-d DEVICES [DEVICES ...]] [-m MEMORIES [MEMORIES ...]] [-s SIMULATE [SIMULATE ...]]
        [-r REGISTERS] [-i] [-c] [-e EXEC]

ska-low-cbf FPGA Command-Line Utility

options:
  -h, --help            show this help message and exit
  -f KERNELS [KERNELS ...], --kernel KERNELS [KERNELS ...]
                        path to xclbin kernel file(s)
  -d DEVICES [DEVICES ...], --device DEVICES [DEVICES ...]
                        Bus:Device.Function PCIe addresses of card(s) to use
  -m MEMORIES [MEMORIES ...], --memory MEMORIES [MEMORIES ...]
                        HBM configuration(s) per card - <size><unit><s|i>. size: int unit: k, M, G (powers of 1024) s: shared i: FPGA
                        internal e.g. '128Ms:1Gi'
  -s SIMULATE [SIMULATE ...], --simulate SIMULATE [SIMULATE ...]
                        path(s) to fpgamap_nnnnnnnn.py file to simulate
  -r REGISTERS, --registers REGISTERS
                        register setting text file to load
  -i, --interactive     use interactive interface (unsupported!)
  -c, --console         use IPython console
  -e EXEC, --exec EXEC  Python file to execute

Debug Console

An interactive IPython console that comes in very handy when developing new functionality. Select this with --console or -c.

When only one device & kernel is specified, it can be accessed with the fpga object:

IPython console showing an fpga object and reading its ARGS magic number

Multiple FPGAs can be used at once. Supply a device, kernel, and memory map for each FPGA, e.g.

fpga -d 0000:63:00.1 0000:62:00.1 -f cnic.xclbin cnic.xclbin -m 2Gs:2Gi:2Gi:2Gi 2Gs:2Gi:2Gi:2Gi -c

The FpgaPersonality (or subclass thereof) objects will be exposed as fpgas, a dict using the device identifier as its keys:

for dev, fpga in fpgas.items():
    print(dev, "is a", type(fpga).__name__, "it has been up for",
          fpga.system.time_uptime.value, "sec")
0000:63:00.1 is a CnicFpga it has been up for 2832 sec
0000:62:00.1 is a CnicFpga it has been up for 2776 sec

Register Viewer

The register viewer has not really been maintained, but it might still work. Select it with the --interactive or -i.

Interactive register viewer in simulation mode, listing registers and their values

Downstream Projects

The command line interface is designed to be extended by downstream projects, using their derived FpgaPersonality objects.

A simple example:

from ska_low_cbf_fpga.fpga_cmdline import FpgaCmdline
from my_project.my_fpga import MyFpga

class MyCmdline(FpgaCmdline):
"""My Command Line class"""

    def configure_parser(self):
        """Add my command-line arguments"""
        super().configure_parser()

        self.parser.add_argument(
            "--id",
            type=int,
            help="Example extra parameter to MyFpga",
            default=1,
        )

    def set_personality_args(self):
        """Add MyFpga personality extra arguments"""
        self.personality_args["id"] = self.args.id

def main():
    # preferred: use a mapping of firmware-reported personality to class
    # (values are read from the system.firmware_personality register)
    MyCmdline(personality_map={"MINE": MyFpga})

    # or, you could set the default personality
    MyCmdline(personality=MyFpga)

if __name__ == "__main__":
    main()