[Discuss OpenCPI] Re: DRC and AD9361 Config

From: Brian Padalino <bpadalino_at_gmail.com>
Date: Fri, 12 Mar 21 17:50:58 -0500

On Thu, Mar 11, 2021 at 10:52 PM Davis Hoover <dhoover_at_geontech.com> wrote:

> All but 3 lines of the 39 results refer to older or lower-level RCC
> proxies that overlap in functionality with the DRC (which should probably
> be consolidated...).
>

It's great that you know that. How is that useful to someone who is not
intimately familiar with OpenCPI?


>
> Here is a DRC briefing - slide 18 might provide a little more context (and
> exemplify the degree of abstraction!)
>
> https://opencpi.gitlab.io/releases/latest/docs/briefings/Briefing_14_Digital_Radio_Controller.pdf
>
>
It isn't very helpful because it doesn't show the interaction of how
callback structures/objects work with each other. Moreover, the structure
is called DoSlave which isn't very descriptive. As I said above, it's
great that someone knows what it does, but for someone coming into it, even
with the briefing, it isn't well documented at all.


> Abstraction does contribute to complexity here, but it also enables the
> interoperability afforded by DRC. DRC solves two essential problems: 1)
> abstraction and portability of radio command/control, and 2) intelligent
> erroring and prevention of radio misconfiguration. No. 2 is a hard problem,
> especially in the AD9361 case (whack-a-mole issues where changing one
> setting changes another setting) - you're solving that hard problem now so
> application developers down the road don't have to know a thing about
> AD9361. I'm not aware of any other framework that solves problem 2.
>

For (1) I don't think OpenCPI adds anything that JTRS or any other
framework didn't already try to solve beforehand. It may be less
cumbersome, but I don't think it's time to declare Mission Accomplished.

As for (2), I am surprised you're trying to take some type of credit for
wrapping the ADI no-os ad9361 library. Credit should go to ADI for
creating not only a spectacularly well documented linux kernel driver, but
also porting it over for implementations that want to run bare metal.
Moreover, when multiple ad9361's are instantiated, OpenCPI doesn't fail
gracefully at all. It confuses the two devices even though they have
unique names associated with their instantiations. As of v2.1.0-rc.2, I've
gotten segfaults in applications due to this confusion and
misconfiguration, so I don't have the confidence in (2) that you seem to
have.

My problem with your approach to (2) is that the ADI library is completely
hidden away from the developer. Also, the ad9361 OpenCPI HDL
implementation doesn't support the dynamic calibration for TX/RX data that
is included with the ADI HDL/drivers. Instead, the LVDS delays are built
into the FPGA image which doesn't make any sense to me.


>
> There could certainly be improvements. As for documentation, much effort
> was initially put into Doxygen comments (e.g.
> https://gitlab.com/opencpi/opencpi/-/blob/develop/runtime/drc/ad9361/include/RadioCtrlrNoOSTuneResamp.hh).
> Please feel free to offer specific recommendations or alternatives -
> documentation or otherwise.
>

I don't see what doxygen comments you're looking at in the link. There's
nothing really around getRfOutput() or getRfInput(). Further down in the
file, why are there functions talking about CIC's and complex mixers for
the Radio Controller? What resampling is going on here? If I were just
given that header file, I am not sure where to start or what it means.
Even the filename just sounds like a lot of terms crammed together.

Examples of documentation I like:


https://github.com/Nuand/bladeRF/blob/master/host/libraries/libbladeRF/include/libbladeRF.h
which creates ...
  https://nuand.com/bladeRF-doc/libbladeRF/v2.2.1/ and has full examples
like ...
  https://nuand.com/bladeRF-doc/libbladeRF/v2.2.1/sync_rx_meta.html with
appropriate error handling included in the examples


https://wiki.analog.com/resources/tools-software/linux-drivers/iio-transceiver/ad9361
which has devicetree documentation ....

https://github.com/analogdevicesinc/linux/blob/master/Documentation/devicetree/bindings/iio/adc/adi,ad9361.txt
which is verbosely documented and has an example at the bottom

Since you asked for recommendations, I can only speak to my experience with
taking an existing radio based on a Zynq architecture that was already
working and OpenCPI support was requested to be added. Here's my list:

* OpenCPI Environment setup is long, cumbersome, and unnecessary
When setting up OpenCPI, I need to build assets for configurations that I
do not need for my FPGA implementation. This is very long, and
cumbersome. The time it takes to set up OpenCPI should be no longer than
it takes to compile the runtime, and source the cdk environment.

When synthesizing designs, or compiling code, all source required should be
generated on the fly and referenced. Get rid of having to build EDIF
netlists for every small component in every possible configuration. The
configurations are just generics anyway - use them in the code. This makes
doing ILA debugging significantly easier as well.

My ideal scenario is to:

  - Clone the OpenCPI repository and build the runtime (this step works
fine as it is)
  - Clone an osp project and add it to OpenCPI (this step works fine as it
is)
  - Navigate to an assembly in that osp, and run `ocpidev build` to
generate all required code across all OpenCPI projects as needed, create a
project from that source, and build the assembly

This allows me to examine the full source of the system in a single project
and minimizes my time building unnecessary netlists that I won't ever
need. Moreover, it allows me to modify core OpenCPI components without
having to rebuild multiple configurations when I only need one. Sure, I
could comment out the build of the other unnecessary configurations, but
why should that be necessary? I have no idea why this can't be done right
now other than lack of development effort.

My last complaint about the OpenCPI build environment is that it is so slow
that re-running `ocpidev build` in the assets project where all HDL
components are 100% completely built and there is no new code generation or
rebuilding still takes many minutes. Minutes to check that files exist and
do nothing. Why does it take so long? I have no idea what is being done
behind the scenes, but this seems terrible to me.

* OpenCPI wants to be the ecosystem, and not a component in an existing
ecosystem
Instead of being a component of my entire system, OpenCPI wants to run
everything. This is backwards. The DRC FSK application is a great example
since it could have been amazingly simple, but instead is absurdly
cumbersome.

The fsk_modem assembly only cares about getting a complex data input in
some format, doing some small signal processing, and then outputting a
decimated/filtered complex data stream output. If the assembly were built
as an AXI component I can instantiate in my system, I could have had a
massive amount of code reuse. The ad9361 interfaces were all vetted and
working. I just needed the actual guts of the HDL (MFSK mapper, filtering,
etc) and the RCC to be able to talk to that HDL component.

Instead, OpenCPI wants to run everything. So I lose the fully proven
ad9361 interface with dynamic timing adjustments, and the control over
custom RF boards, and instead I need to bring all of that into OpenCPI
which is error prone and cumbersome to say the least. In fact, if I want
to have a few different Xilinx soft IP AXI slaves (maybe some GPIO or UART
slaves) hanging off the same bus - that's just impossible.

I understand OpenCPI has a desire to provide a full solution for
development kits and therefore needs to have the full platform support, but
at least make that part optional. Adding OpenCPI to a Zynq system should
be nothing more than plopping down an AXI connected component.

* OpenCPI doesn't know what value it wants to add
Your claims above that OpenCPI provides portable command/control and
intelligent error handling sounds like great value. Frameworks should
strive to provide that without getting in the way. Unfortunately, OpenCPI
also requires me to build and install custom kernel drivers, and needs to
handle loading FPGA images. OpenCPI handling these functions does not add
value.

Here's a userspace mappable DMA buffer:

  https://github.com/ikwzm/udmabuf

Couple that with uio in the standard kernel, and device tree overlay
support in the standard kernel, and you have a much better system than you
do today regarding FPGA images. In fact, OpenCPI would be much easier to
adopt if a conglomeration of OpenCPI workers/components just had an AXI
interface on it and spit out a device tree entry/overlay to add to the
system. Then OpenCPI can focus on being an addition to a system rather
than trying to take it over.

I hope you take this list seriously from someone who has worked for the
past year porting OpenCPI (v1.5.1, v1.6.0, v1.7.0, v2.0.0, v2.0.1, and
v2.1.0) to the same platforms - always having bugs, problems, and needing
patches to get things working. In my experience, "easy to use" and
"portable" are not words I would use to describe OpenCPI.

Feel free to address my comments and suggestions on or off list.

Brian

>






Received on Fri Mar 12 2021 - 22:50:58 CST

This archive was generated by hypermail 2.3.0 : Fri Jun 05 2026 - 08:45:25 CDT