- Move the configuration of SPLL and MMCM into its own method
- In set_master_clock_rate(), call this with intermediate clock settings
if we decide that going direct from one clock setting to another would
cause harm/failures
Co-authored-by: Martin Braun <martin.braun@ettus.com>
Before this commit, set_sync_source() would require the master clock
rate to be set after reclocking, but would pull it out of the
X4xxClockManager object (using the _master_clock_rates attribute). Now,
the new master clock rate is passed to set_sync_source() via the args
argument.
Note that it is still possible (for backward compat) to not provide
a new MCR, in which case the assumption is that the current MCR still
remains valid.
This avoids unnecessary statefulness of this function and fixes an issue
where during init(), external reference clock frequencies would be
validated against the wrong master clock rates.
This enables querying the converter rate through the sensor API:
```python
>>> U = uhd.usrp.MultiUSRP("type=x4xx")
>>> print(U.get_tx_sensor('rfdc_rate').to_real())
3000000000.0
```
This change ensures that ADC selfcal is triggered during session start
if the clocking was reconfigured. So it saves time if several
consecutive sessions are opened with always the same settings.
It also makes the ADC self cal run if in an open session either
set_clock_source(), set_time_source() or set_sync_source() are called
and a clock reconfiguration was triggered by that.
This changes the default master clock rate for X440 to 368.64 MHz which
results in a converter rate of 2.94912 GSps which is in line with what
X410 uses.
Changes:
- X410 Honors the force_reinit flag now (like N310). When given, it will
force a reinit of all clocking settings.
- When master_clock_rate is not given, and nothing else changes, then
clocking configuration will be skipped. This shaves approx. 3s of
startup time and avoids issues that can occur during clocking
configuration.
- If anything changes, incl. clock/time source, then full clock
configuration is still done.
- Multi-tile sync is done in all cases, as that happens outside of init()
This inherits RuntimeError and saves from logging and throwing in
separate steps. Instead of
```python
log.error("Error X occured!")
raise RuntimeError("Error X occured!")
```
do
```python
raise LogRuntimeError(log, "Error X occured!")
```
This demotes the sync_tiles() error to a warning to be consistent with
what the code does. We only raise a RuntimeError if the tile latencies
are not equal for all tiles, which is a little bit later. This is where
an error log was added now.
sync_tiles() may fail with some rare user configurations but it won't
make the device unusable for all use-cases. Therefore a warning is okay
in that place while bad latencies lead to an error.
This changes the clock-configuration order of operations such that all
SPLL-related settings are applied first (including syncing R-dividers to
PPS), and only then are MMCM and RFDC configured.
Previously, syncing R-dividers would happen after everything was
configured.
This adds an updateable_components overridable dictionary into the
daughterboards base class.
On X410, because some of the FPGA compatibility stems from DB-specific
components, they are moved into class ZBX.
This change fixes issues with the reset strategy for devices that don't
use default clocking parameters. That used to cause issues when
restarting the tiles and made those devices have some bigger variations
in power measurements. For X410 this should not change the behavior
compared to uhd master.
This adds X4xxRfdcCtrl.reset_tiles(), which resets all enabled tiles and
sets their registers and settings back to initial defaults. The same
functionality was previously implemented in reset_rfdc(), but we want to
be able to reset the RFDC clocks without clearing all registers.
During device initialization, however, we retain this reset of all tiles
by modifying the initialization sequence.
Before this change, we indiscriminately first set the sync source in
init(), then the master clock rate again (it is already set in
set_sync_source(), albeit to a potentially older value).
This adds checks to the args to see if things have actually changed, and
sets all settings in one go.
FPGA:
- Split up MB registers that control daughterboard specific settings so
that daughterboards 0 and 1 could have different setings, in
preparation for future devices that require different settings.
This requires a compat number bump to 8.0.
- Add registers for additional RFDC information, including the
block/tile mapping of the individual channels, and information about
resampling capabilities
- Identify sections of code that would be specific to X410/ZBX and move
them to their own headers, so it's trivial to add device-specific
sections of code instead for other devices in the future.
- This includes constraints for clocks and I/O pins.
- Remove ability to do timed ctrlport transactions to the MB CPLD, this
was unused and possibly broken.
- Move daughterboard-specific code into its own code location
(dboards/zbx)
- Move X410-specific register documentation to its own location
(doc/X410)
- Refactor Makefiles to split out X410/ZBX specific components and allow
switching between device types
- Add 512-bit AXI interconnects
- Make number of timekeepers configurable (X410 keeps the single
timekeeper)
MPM:
- Required compat is bumped to 8.0
- Now supports new registers for detecting DSP capabilities and
multi-rate settings for the daughterboards
- Adds MMCM controls (currently unused)
Co-authored-by: Wade Fife <wade.fife@ni.com>
Co-authored-by: Ryan Marlow <ryan@lmarlow.com>
Co-authored-by: Martin Braun <martin.braun@ettus.com>
Co-authored-by: Humberto Jimenez <humberto.jimenez@ni.com>
Resetting MMCM and RFDC separately will become a requirement once we
start to also program the MMCM. As of now, it is merely a refactoring,
and we continue to use default MMCM settings.
- Adds startup_tiles() and shutdown_tiles()
- The latter is called on tear_down() to be compliant with Xilinx'
documentation on bitstream reconfiguration
This is a debugging utility for MPM, where gdb-based debugging sometimes
leads to issues with timing. To use it, replace class instantiations
such as:
```python
c = SomeClass(arg1, arg2)
```
with
```python
c = LogWrapper(
parent_log.getChild("SomeClass"), "info", SomeClass(arg1, arg2))
```
The class can be used as before, but the MPM log will include calls with
arguments, return values, and execution times, like this:
```
[MPM.PeriphManager.rfdcctl] [INFO] set_if(1, 0, True, 1058240000.0)
[MPM.PeriphManager.rfdcctl] [INFO] --> True [Execution time: 0.108 ms]
```
This change adds a flag to the clock policy that tells the sample PLL to
enable or disable the PLL ref clock (PRC) that goes to the
daughterboards. While for X410 the PRC is required, future USRPs may not
want the clock signal to propagate to the board.
This by itself does not enable dual-rate (or multi-mcr), but it
refactors the code to enable it in the future. Additional changes may be
required.
X4xxClockMgr is renamed to X4xxClockManager.
Before this change, x4xx_rfdc_ctrl.py had various backdoors to read out
required settings. Now that we have the clock policy object, we can
simply read them out from there.
This obviates some code paths (get_rfdc_resampling_factor(),
get_default_mcr(), set_rfdc_reset_cb()).
On tear_down() (this is most commonly seen by users when updating the
FPGA image), we add a check to verify that subcomponents of the X4xx are
actually initialized, to avoid displaying a non-fatal error message that
looks like this:
[ERROR] [MPM.RPCServer] Error in update_component while resetting:
'NoneType' object has no attribute 'tear_down'
The most common/easy way to trigger this error is by loading MPM with
a bitfile that has an invalid compat number (which would stop MPM from
initializing the RFDC controls) and then running `uhd_image_loader`
(which would force a tear_down()). In that circumstance, MPM would try
to call tear_down() on an uninitialized object.
In 01ccb69, changes to the MB CPLD code were made which caused the
following issue when updating the CPLD:
root@ni-x4xx-xxxxxxx:~# zbx_update_cpld --dboards 0
Traceback (most recent call last):
File "/usr/bin/zbx_update_cpld", line 22, in <module>
from usrp_mpm.periph_manager.x4xx_mb_cpld import MboardCPLD
ImportError: cannot import name 'MboardCPLD' from
'usrp_mpm.periph_manager.x4xx_mb_cpld'
(/usr/lib/python3.7/site-packages/usrp_mpm/periph_manager/x4xx_mb_cpld.py)
This fixes this bug.
This fixes two issues:
- RfdcRegsControl.enable_iq_swap() now is consistent with other APIs in
that it takes a channel number, not a block ID
- X4xxDboardIface.enable_iq_swap() doesn't use a backdoor API call to
fish the enable_iq_swap() API out of the _rfdc_regs object that it
doesn't own