Update MPM GPIO handling for the updated X4xx GPIO SPI register
interface.
Require the FPGA compatibility number bump introduced with the new
SPI support so MPM does not operate against an incompatible FPGA image.
Bump MPM compat number.
Introduce 64-bit SPI transaction methods into the common spi_iface API,
default implementation throws an uhd::unsupported_operation exception.
Add explicit 32-bit aliases for the old/existing SPI transactions
methods.
Expose the width-specific operations through the RFNoC Python bindings.
Extend GPIO SPI transactions up to 64 bits and update the X4xx FPGA
register map and RTL to support the new access width.
Migrate the GPIO SPI register definitions to SystemVerilog.
Add testbench for X4xx GPIO SPI module covering both exisiting
32bit functionality and added 64bit functionality.
Separate TB Makefiles for X4xx and X410 implementation variant.
Bump the FPGA compatibility number so host and MPM software can reject
images that do not provide the required GPIO SPI register interface.
Extend the SPI slave model to propagate simulation failures to the test
execution framework.
Extract the timing monitor from the control-port SPI testbench so it
can be shared by the GPIO SPI simulations while keeping timing checks
centralized and consistent.
msg_task_impl's constructor waits on _start_cv until _running is set,
checking the predicate under _mutex. task_loop() set _running and
called notify_one() without taking _mutex, so a notification sent
after the constructor had checked the predicate but before it started
to wait was lost, and the constructor then blocked forever.
The condition-variable handshake replaced a boost::barrier, which
cannot lose a wakeup, in 3855516f6f ("lib: Remove boost::thread usage
from USB transports"), so UHD 4.10.0.0 and 4.11.0.0 are affected. On
a B210 the hang leaves b200_impl's constructor blocked in
msg_task::make() right after "Operating over USB 3.". It shows up
most when the device is opened at a real-time priority, as SDR
applications that raise their priority before opening the device do.
Set _running while holding _mutex, then notify.
Treat a RuntimeError raised while the periph manager is resetting as
transient. Log once at WARNING and abort with gRPC status UNAVAILABLE
so the client retries, instead of logging a scary ERROR.
Real runtime errors still log ERROR and abort when periph manager
object is live.
usrp_hwd runs all gRPC greenlets on a single gevent hub, so any
non-yielding C call blocks every other RPC. Under a uhd_find_devices
discovery flood, the GetDeviceInfo interface enumeration run long enough
And may starve most claimed RPC past its default 2s client deadline,
causing "Deadline Exceeded" failures.
Three places that this commit optimizes, all in net.py:
- get_local_ip_addrs() used pyroute2 IPDB, which spawns helper threads
and mirrors the full link/addr/route/neighbour tables on every call
(~100s of ms, non-yielding) --> Replace it with a single stateless
IPRoute get_addr() dump. Keep IFA_LOCAL (falling back to IFA_ADDRESS)
so the returned set matches IPDB's behaviour, including point-to-point
links.
- get_link_speed() used to create a new pyudev.Context() per interface,
which forks on creation, tripping gRPC's fork handlers. gRPC then
freezes all workder threads and restarts after fork is done. Fix is to
reuse one PID-guarded pyudev context per process.
- get_valid_interfaces() did an O(N) netlink round-trip per interface.
This stalls gRPC server. --> Dump all links and IPv4 addresses once
and filter in Python.
IPRoute stays per-call: it opens its own netlink socket and does not
fork, so there is no shared state to lock.
RFNoC's `multi_usrp` did not fully propagate `set_master_clock_rate()`
to the DUC/DDC chain.
Before this change, `set_master_clock_rate()` updated only the radio
rate. If a channel had a DUC or DDC, the adjacent converter rate was
left stale:
- TX: the DUC output rate was not updated to the new radio rate
- RX: the DDC input rate was not updated to the new radio rate
That caused follow-up `set_tx_rate()` / `set_rx_rate()` calls on the
same `multi_usrp` object to operate on outdated DUC/DDC state. In
practice, after changing the master clock, setting the channel sample
rate could be coerced unexpectedly because interpolation/decimation was
derived from the old converter-side rate.
This change updates `multi_usrp_rfnoc` so that `set_master_clock_rate()`:
- propagates the new radio rate to the attached DUC/DDC
- reapplies the previously requested per-channel TX/RX rate so the
DUC/DDC continues to follow the user-requested sample rate
Note that property propagation by itself is insufficient here, because
multi_usrp_rfnoc caches RX and TX rates, and these caches require
manual updating.
Co-authored-by: Martin Braun <martin.braun@ettus.com>
Use a resources file to pass RFNoC OOT source files to Vivado TCL
scripts, avoiding ARG_MAX argument list limits.
This makes B310 consistent with other USRPs that were previously
updated in commit fa7c3604.
Use --seed only to initialize a local deterministic random number
generator. Generate a new signed 32-bit BUILD_SEED for each FPGA build
attempt instead of passing --seed directly to the first build. This
avoids accidentally using sequential pipeline attempt numbers as
BUILD_SEED values.
Using the same --seed produces the same BUILD_SEED sequence, preserving
reproducibility.
Added a state machine to fix a bug in the temporal decimation code
of the decimating halfband filter module.
Additionally added a testcase to the testbench for the issue this
change is fixing.