import time
import ska_low_sps_tpm_api.boards.tpm_hw_definitions as tpm_hw_definitions
from ska_low_sps_tpm_api.base.definitions import *
from ska_low_sps_tpm_api.base.utils import *
from ska_low_sps_tpm_api.plugins.firmwareblock import FirmwareBlock
__author__ = "Alessio Magro"
[docs]
class TpmFpga(FirmwareBlock):
"""TpmFPGA plugin"""
[docs]
@compatibleboards(BoardMake.TpmBoard)
@friendlyname("tpm_fpga")
@maxinstances(1)
def __init__(self, board, logger=None, **kwargs):
"""
TpmFpga initialiser.
:param board: Pointer to board instance
"""
super(TpmFpga, self).__init__(board, logger=logger)
self._board_type = kwargs.get("board_type", "XTPM")
if "device" not in list(kwargs.keys()):
raise PluginError("TpmFpga: Require a node instance")
self._device = kwargs["device"]
if self._device == Device.FPGA_1:
self._device = "fpga1"
elif self._device == Device.FPGA_2:
self._device = "fpga2"
else:
raise PluginError("TpmFpga: Invalid device %s" % self._device)
self._nof_inputs = 16
self._fpga_firmware = None
if self.board.is_programmed(0):
self._fpga_firmware = self.board["fpga1.regfile.rev"]
# On TPM 1.6 check if we are using the special firmware supporting 800 MHz clock from PLL
self._config_800MHz = False
if (
self.board.hw_rev >= tpm_hw_definitions.TPM_HW_REV_1_5
and self._fpga_firmware is not None
):
if (
self._fpga_firmware
== tpm_hw_definitions.FPGA_FW_800MHZ_EXCEPTION_TPM_V1_5
):
self._config_800MHz = True
self.logger.info("FPGA FIRMWARE VERSION: %s" % hex(self._fpga_firmware))
self.logger.info("Using 800 MHz FPGA clock exception!")
#######################################################################################
[docs]
def fpga_start(self):
"""
Set up FPGA.
:param input_list: List of channel to enable
:param enabled_list:
:return:
"""
self.board["%s.jesd204_if.regfile_ctrl.reset_n" % self._device] = 0x0
self.board["%s.jesd204_if.regfile_ctrl.reset_n" % self._device] = 0x1
if (
do_until_eq(
lambda: self.board[
"%s.jesd204_if.regfile_status.qpll_locked" % self._device
],
1,
ms_retry=100,
s_timeout=10,
)
is None
):
self.logger.fatal("QPLL not locked")
return
[docs]
def fpga_stop(self):
"""Stop FPGA acquisition and data downloading through 1Gbit Ethernet"""
self.board["%s.jesd204_if.regfile_ctrl" % self._device] = 0x0
time.sleep(1)
[docs]
def fpga_global_reset(self):
"""Reset FPGA"""
try:
self.board["%s.regfile.reset.global_rst" % self._device] = 0x1
self.board["%s.regfile.reset.global_rst" % self._device] = 0x0
except BoardError:
pass # We won't receive a reply for this command
[docs]
def fpga_reset(self):
"""Reset FPGA"""
self.board["%s.regfile.reset" % self._device] = 0xFFFFFFFE
self.board["%s.regfile.reset" % self._device] = 0x0
[docs]
def fpga_apply_sync_delay(self, delay):
"""Apply synchronous operation delay"""
self.board["%s.pps_manager.timestamp_req_val" % self._device] = delay
[docs]
def fpga_mmcm_start(self):
self.board["%s.drp_jesd_mmcm.reg_23" % self._device] = 0x3
while True:
rd = self.board["%s.drp_jesd_mmcm.status.lock" % self._device]
if rd == 0x1:
break
time.sleep(0.01)
[docs]
def fpga_mmcm_config(self, freq, custom_config=None):
# if custom configuration is used
if custom_config is not None:
for n in range(23):
self.board["%s.drp_jesd_mmcm.reg_%d" % (self._device, n)] = (
custom_config[n]
)
self.fpga_mmcm_start()
self.logger.debug(
self._device.upper() + " MMCM configured with custom configuration"
)
return
# if 800 MHz firmware exception is used, skip configuration
if self._config_800MHz:
self.logger.warning(
"TpmFpga: FPGA FIRMWARE VERSION: %s"
% hex(tpm_hw_definitions.FPGA_FW_800MHZ_EXCEPTION_TPM_V1_5)
)
self.logger.warning(
"TpmFpga: fpga_mmcm_config method disabled [experimental] [exception for fw %s only]"
% hex(tpm_hw_definitions.FPGA_FW_800MHZ_EXCEPTION_TPM_V1_5)
)
return
# Get the clock manager version implmented in the firmware
if self.board.has_register(
"%s.regfile.feature_extended.clock_manager_version" % self._device
):
clock_manager_version = self.board[
"%s.regfile.feature_extended.clock_manager_version" % self._device
]
else:
clock_manager_version = 1
if clock_manager_version == 2:
if freq == 350e6:
self.board["%s.drp_jesd_mmcm.reg_0" % self._device] = 0xFFFF
self.board["%s.drp_jesd_mmcm.reg_1" % self._device] = 0x1208
self.board["%s.drp_jesd_mmcm.reg_2" % self._device] = 0x0000
self.board["%s.drp_jesd_mmcm.reg_3" % self._device] = 0x1208
self.board["%s.drp_jesd_mmcm.reg_4" % self._device] = 0x0100
self.board["%s.drp_jesd_mmcm.reg_5" % self._device] = 0x11C7
self.board["%s.drp_jesd_mmcm.reg_6" % self._device] = 0x0000
self.board["%s.drp_jesd_mmcm.reg_7" % self._device] = 0x1104
self.board["%s.drp_jesd_mmcm.reg_8" % self._device] = 0x0000
self.board["%s.drp_jesd_mmcm.reg_9" % self._device] = 0x1E38
self.board["%s.drp_jesd_mmcm.reg_10" % self._device] = 0x0100
self.board["%s.drp_jesd_mmcm.reg_11" % self._device] = 0x1041
self.board["%s.drp_jesd_mmcm.reg_12" % self._device] = 0x00C0
self.board["%s.drp_jesd_mmcm.reg_13" % self._device] = 0x1041
self.board["%s.drp_jesd_mmcm.reg_14" % self._device] = 0x00C0
self.board["%s.drp_jesd_mmcm.reg_15" % self._device] = 0x1041
self.board["%s.drp_jesd_mmcm.reg_16" % self._device] = 0x11C7
self.board["%s.drp_jesd_mmcm.reg_17" % self._device] = 0x0000
self.board["%s.drp_jesd_mmcm.reg_18" % self._device] = 0x02BC
self.board["%s.drp_jesd_mmcm.reg_19" % self._device] = 0x7C01
self.board["%s.drp_jesd_mmcm.reg_20" % self._device] = 0x7FE9
self.board["%s.drp_jesd_mmcm.reg_21" % self._device] = 0x0800
self.board["%s.drp_jesd_mmcm.reg_22" % self._device] = 0x1190
elif freq == 400e6:
self.board["%s.drp_jesd_mmcm.reg_0" % self._device] = 0xFFFF
self.board["%s.drp_jesd_mmcm.reg_1" % self._device] = 0x1041
self.board["%s.drp_jesd_mmcm.reg_2" % self._device] = 0x4800
self.board["%s.drp_jesd_mmcm.reg_3" % self._device] = 0x11C7
self.board["%s.drp_jesd_mmcm.reg_4" % self._device] = 0x0000
self.board["%s.drp_jesd_mmcm.reg_5" % self._device] = 0x11C7
self.board["%s.drp_jesd_mmcm.reg_6" % self._device] = 0x0000
self.board["%s.drp_jesd_mmcm.reg_7" % self._device] = 0x1105
self.board["%s.drp_jesd_mmcm.reg_8" % self._device] = 0x0080
self.board["%s.drp_jesd_mmcm.reg_9" % self._device] = 0x1041
self.board["%s.drp_jesd_mmcm.reg_10" % self._device] = 0x00C0
self.board["%s.drp_jesd_mmcm.reg_11" % self._device] = 0x1041
self.board["%s.drp_jesd_mmcm.reg_12" % self._device] = 0xC0C0
self.board["%s.drp_jesd_mmcm.reg_13" % self._device] = 0x1041
self.board["%s.drp_jesd_mmcm.reg_14" % self._device] = 0x00C0
self.board["%s.drp_jesd_mmcm.reg_15" % self._device] = 0x1041
self.board["%s.drp_jesd_mmcm.reg_16" % self._device] = 0x11C7
self.board["%s.drp_jesd_mmcm.reg_17" % self._device] = 0x0000
self.board["%s.drp_jesd_mmcm.reg_18" % self._device] = 0x02BC
self.board["%s.drp_jesd_mmcm.reg_19" % self._device] = 0x7C01
self.board["%s.drp_jesd_mmcm.reg_20" % self._device] = 0x7FE9
self.board["%s.drp_jesd_mmcm.reg_21" % self._device] = 0x0900
self.board["%s.drp_jesd_mmcm.reg_22" % self._device] = 0x8890
elif freq == 700e6:
self.board["%s.drp_jesd_mmcm.reg_0" % self._device] = 0xFFFF
self.board["%s.drp_jesd_mmcm.reg_1" % self._device] = 0x1041
self.board["%s.drp_jesd_mmcm.reg_2" % self._device] = 0x4800
self.board["%s.drp_jesd_mmcm.reg_3" % self._device] = 0x1104
self.board["%s.drp_jesd_mmcm.reg_4" % self._device] = 0x0000
self.board["%s.drp_jesd_mmcm.reg_5" % self._device] = 0x11C7
self.board["%s.drp_jesd_mmcm.reg_6" % self._device] = 0x0000
self.board["%s.drp_jesd_mmcm.reg_7" % self._device] = 0x1105
self.board["%s.drp_jesd_mmcm.reg_8" % self._device] = 0x0080
self.board["%s.drp_jesd_mmcm.reg_9" % self._device] = 0x1041
self.board["%s.drp_jesd_mmcm.reg_10" % self._device] = 0x00C0
self.board["%s.drp_jesd_mmcm.reg_11" % self._device] = 0x1041
self.board["%s.drp_jesd_mmcm.reg_12" % self._device] = 0xC0C0
self.board["%s.drp_jesd_mmcm.reg_13" % self._device] = 0x1041
self.board["%s.drp_jesd_mmcm.reg_14" % self._device] = 0x00C0
self.board["%s.drp_jesd_mmcm.reg_15" % self._device] = 0x1041
self.board["%s.drp_jesd_mmcm.reg_16" % self._device] = 0x11C7
self.board["%s.drp_jesd_mmcm.reg_17" % self._device] = 0x0000
self.board["%s.drp_jesd_mmcm.reg_18" % self._device] = 0x02BC
self.board["%s.drp_jesd_mmcm.reg_19" % self._device] = 0x7C01
self.board["%s.drp_jesd_mmcm.reg_20" % self._device] = 0x7FE9
self.board["%s.drp_jesd_mmcm.reg_21" % self._device] = 0x0900
self.board["%s.drp_jesd_mmcm.reg_22" % self._device] = 0x8890
elif freq == 800e6:
self.board["%s.drp_jesd_mmcm.reg_0" % self._device] = 0xFFFF
self.board["%s.drp_jesd_mmcm.reg_1" % self._device] = 0x1041
self.board["%s.drp_jesd_mmcm.reg_2" % self._device] = 0x4800
self.board["%s.drp_jesd_mmcm.reg_3" % self._device] = 0x10C4
self.board["%s.drp_jesd_mmcm.reg_4" % self._device] = 0x0080
self.board["%s.drp_jesd_mmcm.reg_5" % self._device] = 0x11C7
self.board["%s.drp_jesd_mmcm.reg_6" % self._device] = 0x0000
self.board["%s.drp_jesd_mmcm.reg_7" % self._device] = 0x1105
self.board["%s.drp_jesd_mmcm.reg_8" % self._device] = 0x0080
self.board["%s.drp_jesd_mmcm.reg_9" % self._device] = 0x1041
self.board["%s.drp_jesd_mmcm.reg_10" % self._device] = 0x00C0
self.board["%s.drp_jesd_mmcm.reg_11" % self._device] = 0x1041
self.board["%s.drp_jesd_mmcm.reg_12" % self._device] = 0xC0C0
self.board["%s.drp_jesd_mmcm.reg_13" % self._device] = 0x1041
self.board["%s.drp_jesd_mmcm.reg_14" % self._device] = 0x00C0
self.board["%s.drp_jesd_mmcm.reg_15" % self._device] = 0x1041
self.board["%s.drp_jesd_mmcm.reg_16" % self._device] = 0x11C7
self.board["%s.drp_jesd_mmcm.reg_17" % self._device] = 0x0000
self.board["%s.drp_jesd_mmcm.reg_18" % self._device] = 0x02BC
self.board["%s.drp_jesd_mmcm.reg_19" % self._device] = 0x7C01
self.board["%s.drp_jesd_mmcm.reg_20" % self._device] = 0x7FE9
self.board["%s.drp_jesd_mmcm.reg_21" % self._device] = 0x0900
self.board["%s.drp_jesd_mmcm.reg_22" % self._device] = 0x8890
elif freq == 1000e6:
self.board["%s.drp_jesd_mmcm.reg_0" % self._device] = 0xFFFF
self.board["%s.drp_jesd_mmcm.reg_1" % self._device] = 0x1041
self.board["%s.drp_jesd_mmcm.reg_2" % self._device] = 0x6800
self.board["%s.drp_jesd_mmcm.reg_3" % self._device] = 0x10C3
self.board["%s.drp_jesd_mmcm.reg_4" % self._device] = 0x0000
self.board["%s.drp_jesd_mmcm.reg_5" % self._device] = 0x11C8
self.board["%s.drp_jesd_mmcm.reg_6" % self._device] = 0x0080
self.board["%s.drp_jesd_mmcm.reg_7" % self._device] = 0x1145
self.board["%s.drp_jesd_mmcm.reg_8" % self._device] = 0x0000
self.board["%s.drp_jesd_mmcm.reg_9" % self._device] = 0x1041
self.board["%s.drp_jesd_mmcm.reg_10" % self._device] = 0x00C0
self.board["%s.drp_jesd_mmcm.reg_11" % self._device] = 0x1041
self.board["%s.drp_jesd_mmcm.reg_12" % self._device] = 0xE0C0
self.board["%s.drp_jesd_mmcm.reg_13" % self._device] = 0x1041
self.board["%s.drp_jesd_mmcm.reg_14" % self._device] = 0x00C0
self.board["%s.drp_jesd_mmcm.reg_15" % self._device] = 0x1041
self.board["%s.drp_jesd_mmcm.reg_16" % self._device] = 0x11C8
self.board["%s.drp_jesd_mmcm.reg_17" % self._device] = 0x0080
self.board["%s.drp_jesd_mmcm.reg_18" % self._device] = 0x028A
self.board["%s.drp_jesd_mmcm.reg_19" % self._device] = 0x7C01
self.board["%s.drp_jesd_mmcm.reg_20" % self._device] = 0x7FE9
self.board["%s.drp_jesd_mmcm.reg_21" % self._device] = 0x1000
self.board["%s.drp_jesd_mmcm.reg_22" % self._device] = 0x1890
else:
raise PluginError("TpmFpga: Invalid frequency %s Hz" % str(freq))
else:
if freq == 350e6:
self.board["%s.drp_jesd_mmcm.reg_0" % self._device] = 0xFFFF
self.board["%s.drp_jesd_mmcm.reg_1" % self._device] = 0x10C4
self.board["%s.drp_jesd_mmcm.reg_2" % self._device] = 0x0080
self.board["%s.drp_jesd_mmcm.reg_3" % self._device] = 0x1104
self.board[
"%s.drp_jesd_mmcm.reg_4" % self._device
] = 0x0100 # This bit enable fine phase shift on the clock output # fmt: skip
self.board["%s.drp_jesd_mmcm.reg_5" % self._device] = 0x171C
self.board[
"%s.drp_jesd_mmcm.reg_6" % self._device
] = 0x0100 # This bit enable fine phase shift on the clock output # fmt: skip
self.board["%s.drp_jesd_mmcm.reg_7" % self._device] = 0x1041
self.board["%s.drp_jesd_mmcm.reg_8" % self._device] = 0x00C0
self.board["%s.drp_jesd_mmcm.reg_9" % self._device] = 0x1041
self.board["%s.drp_jesd_mmcm.reg_10" % self._device] = 0x00C0
self.board["%s.drp_jesd_mmcm.reg_11" % self._device] = 0x1041
self.board["%s.drp_jesd_mmcm.reg_12" % self._device] = 0x00C0
self.board["%s.drp_jesd_mmcm.reg_13" % self._device] = 0x1041
self.board["%s.drp_jesd_mmcm.reg_14" % self._device] = 0x00C0
self.board["%s.drp_jesd_mmcm.reg_15" % self._device] = 0x1041
self.board["%s.drp_jesd_mmcm.reg_16" % self._device] = 0x10C4
self.board["%s.drp_jesd_mmcm.reg_17" % self._device] = 0x0080
self.board["%s.drp_jesd_mmcm.reg_18" % self._device] = 0x03E8
self.board["%s.drp_jesd_mmcm.reg_19" % self._device] = 0x4C01
self.board["%s.drp_jesd_mmcm.reg_20" % self._device] = 0x4FE9
self.board["%s.drp_jesd_mmcm.reg_21" % self._device] = 0x0800
self.board["%s.drp_jesd_mmcm.reg_22" % self._device] = 0x1990
elif freq == 400e6:
self.board["%s.drp_jesd_mmcm.reg_0" % self._device] = 0xFFFF
self.board["%s.drp_jesd_mmcm.reg_1" % self._device] = 0x1145
self.board["%s.drp_jesd_mmcm.reg_2" % self._device] = 0x0000
self.board["%s.drp_jesd_mmcm.reg_3" % self._device] = 0x1145
self.board["%s.drp_jesd_mmcm.reg_4" % self._device] = 0x0100
self.board["%s.drp_jesd_mmcm.reg_5" % self._device] = 0x1514
self.board["%s.drp_jesd_mmcm.reg_6" % self._device] = 0x0100
self.board["%s.drp_jesd_mmcm.reg_7" % self._device] = 0x1041
self.board["%s.drp_jesd_mmcm.reg_8" % self._device] = 0x00C0
self.board["%s.drp_jesd_mmcm.reg_9" % self._device] = 0x1041
self.board["%s.drp_jesd_mmcm.reg_10" % self._device] = 0x00C0
self.board["%s.drp_jesd_mmcm.reg_11" % self._device] = 0x1041
self.board["%s.drp_jesd_mmcm.reg_12" % self._device] = 0x00C0
self.board["%s.drp_jesd_mmcm.reg_13" % self._device] = 0x1041
self.board["%s.drp_jesd_mmcm.reg_14" % self._device] = 0x00C0
self.board["%s.drp_jesd_mmcm.reg_15" % self._device] = 0x1041
self.board["%s.drp_jesd_mmcm.reg_16" % self._device] = 0x1145
self.board["%s.drp_jesd_mmcm.reg_17" % self._device] = 0x0000
self.board["%s.drp_jesd_mmcm.reg_18" % self._device] = 0x03E8
self.board["%s.drp_jesd_mmcm.reg_19" % self._device] = 0x7001
self.board["%s.drp_jesd_mmcm.reg_20" % self._device] = 0x73E9
self.board["%s.drp_jesd_mmcm.reg_21" % self._device] = 0x0800
self.board["%s.drp_jesd_mmcm.reg_22" % self._device] = 0x9190
elif freq == 700e6:
self.board["%s.drp_jesd_mmcm.reg_0" % self._device] = 0xFFFF
self.board["%s.drp_jesd_mmcm.reg_1" % self._device] = 0x10C4
self.board["%s.drp_jesd_mmcm.reg_2" % self._device] = 0x0080
self.board["%s.drp_jesd_mmcm.reg_3" % self._device] = 0x1082
self.board["%s.drp_jesd_mmcm.reg_4" % self._device] = 0x0100
self.board["%s.drp_jesd_mmcm.reg_5" % self._device] = 0x138E
self.board["%s.drp_jesd_mmcm.reg_6" % self._device] = 0x0100
self.board["%s.drp_jesd_mmcm.reg_7" % self._device] = 0x1041
self.board["%s.drp_jesd_mmcm.reg_8" % self._device] = 0x00C0
self.board["%s.drp_jesd_mmcm.reg_9" % self._device] = 0x1041
self.board["%s.drp_jesd_mmcm.reg_10" % self._device] = 0x00C0
self.board["%s.drp_jesd_mmcm.reg_11" % self._device] = 0x1041
self.board["%s.drp_jesd_mmcm.reg_12" % self._device] = 0x00C0
self.board["%s.drp_jesd_mmcm.reg_13" % self._device] = 0x1041
self.board["%s.drp_jesd_mmcm.reg_14" % self._device] = 0x00C0
self.board["%s.drp_jesd_mmcm.reg_15" % self._device] = 0x1041
self.board["%s.drp_jesd_mmcm.reg_16" % self._device] = 0x10C4
self.board["%s.drp_jesd_mmcm.reg_17" % self._device] = 0x0080
self.board["%s.drp_jesd_mmcm.reg_18" % self._device] = 0x03E8
self.board["%s.drp_jesd_mmcm.reg_19" % self._device] = 0x4C01
self.board["%s.drp_jesd_mmcm.reg_20" % self._device] = 0x4FE9
self.board["%s.drp_jesd_mmcm.reg_21" % self._device] = 0x0800
self.board["%s.drp_jesd_mmcm.reg_22" % self._device] = 0x1990
elif freq == 800e6:
self.board["%s.drp_jesd_mmcm.reg_0" % self._device] = 0xFFFF
self.board["%s.drp_jesd_mmcm.reg_1" % self._device] = 0x1145
self.board["%s.drp_jesd_mmcm.reg_2" % self._device] = 0x0000
self.board["%s.drp_jesd_mmcm.reg_3" % self._device] = 0x1083
self.board["%s.drp_jesd_mmcm.reg_4" % self._device] = 0x0180
self.board["%s.drp_jesd_mmcm.reg_5" % self._device] = 0x1514
self.board["%s.drp_jesd_mmcm.reg_6" % self._device] = 0x0100
self.board["%s.drp_jesd_mmcm.reg_7" % self._device] = 0x1041
self.board["%s.drp_jesd_mmcm.reg_8" % self._device] = 0x00C0
self.board["%s.drp_jesd_mmcm.reg_9" % self._device] = 0x1041
self.board["%s.drp_jesd_mmcm.reg_10" % self._device] = 0x00C0
self.board["%s.drp_jesd_mmcm.reg_11" % self._device] = 0x1041
self.board["%s.drp_jesd_mmcm.reg_12" % self._device] = 0x00C0
self.board["%s.drp_jesd_mmcm.reg_13" % self._device] = 0x1041
self.board["%s.drp_jesd_mmcm.reg_14" % self._device] = 0x00C0
self.board["%s.drp_jesd_mmcm.reg_15" % self._device] = 0x1041
self.board["%s.drp_jesd_mmcm.reg_16" % self._device] = 0x1145
self.board["%s.drp_jesd_mmcm.reg_17" % self._device] = 0x0000
self.board["%s.drp_jesd_mmcm.reg_18" % self._device] = 0x03E8
self.board["%s.drp_jesd_mmcm.reg_19" % self._device] = 0x7001
self.board["%s.drp_jesd_mmcm.reg_20" % self._device] = 0x73E9
self.board["%s.drp_jesd_mmcm.reg_21" % self._device] = 0x0800
self.board["%s.drp_jesd_mmcm.reg_22" % self._device] = 0x9190
elif freq == 1000e6:
self.board["%s.drp_jesd_mmcm.reg_0" % self._device] = 0xFFFF
self.board["%s.drp_jesd_mmcm.reg_1" % self._device] = 0x1145
self.board["%s.drp_jesd_mmcm.reg_2" % self._device] = 0x0000
self.board["%s.drp_jesd_mmcm.reg_3" % self._device] = 0x1082
self.board["%s.drp_jesd_mmcm.reg_4" % self._device] = 0x0100
self.board["%s.drp_jesd_mmcm.reg_5" % self._device] = 0x1514
self.board["%s.drp_jesd_mmcm.reg_6" % self._device] = 0x0100
self.board["%s.drp_jesd_mmcm.reg_7" % self._device] = 0x1041
self.board["%s.drp_jesd_mmcm.reg_8" % self._device] = 0x00C0
self.board["%s.drp_jesd_mmcm.reg_9" % self._device] = 0x1041
self.board["%s.drp_jesd_mmcm.reg_10" % self._device] = 0x00C0
self.board["%s.drp_jesd_mmcm.reg_11" % self._device] = 0x1041
self.board["%s.drp_jesd_mmcm.reg_12" % self._device] = 0x00C0
self.board["%s.drp_jesd_mmcm.reg_13" % self._device] = 0x1041
self.board["%s.drp_jesd_mmcm.reg_14" % self._device] = 0x00C0
self.board["%s.drp_jesd_mmcm.reg_15" % self._device] = 0x1041
self.board["%s.drp_jesd_mmcm.reg_16" % self._device] = 0x1145
self.board["%s.drp_jesd_mmcm.reg_17" % self._device] = 0x0000
self.board["%s.drp_jesd_mmcm.reg_18" % self._device] = 0x03E8
self.board["%s.drp_jesd_mmcm.reg_19" % self._device] = 0x7001
self.board["%s.drp_jesd_mmcm.reg_20" % self._device] = 0x73E9
self.board["%s.drp_jesd_mmcm.reg_21" % self._device] = 0x0800
self.board["%s.drp_jesd_mmcm.reg_22" % self._device] = 0x9190
else:
raise PluginError("TpmFpga: Invalid frequency %s Hz" % str(freq))
self.fpga_mmcm_start()
self.logger.debug(
self._device.upper() + " MMCM configured at " + str(freq / 1e6) + " MHz"
)
[docs]
def fpga_jesd_gth_config(self, freq=None):
if self._config_800MHz:
self.logger.warning(
"TpmFpga: FPGA FIRMWARE VERSION: %s"
% hex(tpm_hw_definitions.FPGA_FW_800MHZ_EXCEPTION_TPM_V1_5)
)
self.logger.warning(
"TpmFpga: fpga_jesd_gth_config method disabled [experimental] [exception for fw %s only]"
% hex(tpm_hw_definitions.FPGA_FW_800MHZ_EXCEPTION_TPM_V1_5)
)
return
# GTH DRP register configuration has been read-back from GTH after compiling and running bitfile with different
# default frequency configurations. Only changing registers in different frequencies configurations are modified.
#
# GTH Common DRP registers configuration
if freq is None:
self.logger.warning(
self._device.upper() + " GTH using default configuration"
)
return
supported_frequency = [400e6, 700e6, 800e6, 1000e6]
if freq not in supported_frequency:
self.logger.warning(
self._device.upper()
+ " GTH configuration not modified as requested frequency "
+ str(freq)
+ " MHz is not supported. Using default configuration"
)
return
frequency_idx = supported_frequency.index(freq)
# GTH Common DRP registers configuration
drp_addr = [18, 20, 22, 25, 29, 48]
drp_data = [
[
0x25E8,
0x9E,
0x1F,
0x3F4,
0x25E8,
0x1B,
], # 400e6
[
0x21E8,
0x8A,
0x1FF,
0x3FC,
0x21E8,
0x1B,
], # 700e6
[
0x25E8,
0x9E,
0x1F,
0x3F4,
0x25E8,
0x1B,
], # 800e6
[
0x21E8,
0x62,
0x1FF,
0x3FC,
0x21E8,
0x0,
],
] # 1000e6
drp_data_sel = drp_data[frequency_idx]
for i in range(4):
try:
jesd_gth_drp_base_addr = self.board.memory_map[
"%s.drp.gth_common_%d" % (self._device, i)
].address
except:
jesd_gth_drp_base_addr = self.board.memory_map[
"%s.jesd_drp.gth_common_%d" % (self._device, i)
].address
for a in range(len(drp_addr)):
self.board[int(jesd_gth_drp_base_addr + 4 * drp_addr[a])] = (
drp_data_sel[a]
)
# GTH Channel DRP registers configuration
drp_addr = [16, 82, 99, 102, 124, 149, 156, 157, 173, 188]
drp_data = [
[
0x746,
0x2,
0x80C2,
0xB0F9,
0x2E0,
0xF800,
0x0,
0x0,
0x1900,
0xF007,
],
[
0x756,
0x2,
0x80C1,
0xB0F9,
0x1E0,
0xF000,
0x0,
0x0,
0x1900,
0xF007,
],
[
0x756,
0x2,
0x80C1,
0xB0F9,
0x1E0,
0xF800,
0x0,
0x0,
0x1F00,
0xF007,
],
[
0x766,
0x402,
0x80C0,
0xB0FD,
0xE0,
0xF000,
0xAAC,
0x5568,
0x1F00,
0x7,
],
]
drp_data_sel = drp_data[frequency_idx]
for i in range(16):
try:
jesd_gth_drp_base_addr = self.board.memory_map[
"%s.drp.gth_channel_%d" % (self._device, i)
].address
except:
jesd_gth_drp_base_addr = self.board.memory_map[
"%s.jesd_drp.gth_channel_%d" % (self._device, i)
].address
for a in range(len(drp_addr)):
self.board[int(jesd_gth_drp_base_addr + 4 * drp_addr[a])] = (
drp_data_sel[a]
)
[docs]
def fpga_align_adc_clk(self, vco_freq):
self.board["%s.pps_manager.sync_tc_adc_clk" % self._device] = 0x0007
time.sleep(0.1)
while (
self.board["%s.pps_manager.sync_phase.cnt_adc_clock" % self._device] != 0xFF
):
self.fpga_mmcm_phase_shift(vco_freq)
rd = hex(self.board["%s.pps_manager.sync_phase.cnt_adc_clock" % self._device])
self.logger.debug("%s ADC CLOCK Phase %s" % (self._device.upper(), rd))
[docs]
def fpga_mmcm_phase_shift(self, vco_freq):
vco_divider = 56.0
single_step_delay = (1.0 / vco_freq) / vco_divider
steps = 10.0e-9 / single_step_delay # 10 ns steps
for n in range(int(steps)):
self.board["%s.regfile.mmcm_phase_shift_control" % self._device] = 0x3
while True:
if (
self.board["%s.regfile.mmcm_phase_shift_control.en" % self._device]
== 0
):
break
##################### Superclass method implementations ###############################
[docs]
def initialise(self):
"""Initialise TpmFpga"""
self.logger.info("TpmFpga has been initialised")
return True
[docs]
def status_check(self):
"""Perform status check.
:return: Status
"""
self.logger.debug("TpmFpga : Checking status")
# Check FPGA QPLL is locked and receiving data from the FPGA
if (
self.board["%s.jesd204_if.regfile_status.qpll_locked" % self._device] == 0x1
and self.board["%s.jesd204_if.regfile_status.valid" % self._device] == 0x1
):
self.logger.debug("FPGA %s already initialised" % self._device)
return Status.OK
else:
return Status.BoardError
[docs]
def clean_up(self):
"""Perform cleanup.
:return: Success
"""
self.logger.info("TpmFpga : Cleaning up")
return True