I’ve written (and verified with csim and cosim) and HLS core that performs a multichannel direct digital downconversion operation. The core accepts an axi stream of 8 complex ap_fixed<16,-9> numbers (256 bits) and outputs a stream of 8 complex ap_fixed <-16,7> numbers (also 256 bits). The streams are 256 TDM, so I’ve effectively got 2048 DDCs.
Configuration is via two arrays (ap_fixed<16,1> toneinc and ap_ufixed<16,1> phase0) used to set the phase accumulator increment and offset. Arrays use an s_axilite interface.
Each transaction the core loads the appropriate 8 increments, phase offsets, and stored phases, computes the current phases, queries sin cos LUTs to get complex numbers, does a complex multiply on the input samples. Finally it stores the updated accumulated phases.
The trouble I’m running into is that I can’t seem to reliably get the core to work from python. It seems that my driver writes and reads the toneinc and phase0 arrays properly but they do not seem to reliably impact the data that moves through the core.
For example I’d expect to be able to send 20 packets of data (20x2048) with real only values, 0 tone inc, 0 phase0, change to 0.5 phase0, send 20 packets, change to .0 phase0, and send 20 packets again. If I’m sending the same data each time I’d expect to see the output go from out=in to out.real=in.imag & out.imag=in.real to out=-in. This doesn’t happen.
I’ve attached a tcl block design from 2019.2, the exported HLS IP, the HLS project source, and an ipython notebook that highlights the issue.
To run the code I added the nice FpBinary library to my pynq image via pip install git+https://github.com/smlgit/fpbinary.git
pynq_post.zip (592.5 KB)
This is on the ZCU111 (though I doubt that is particularly relevant).
Edit: This new notebook makes it a bit clearer: test_ddc.ipynb (156.0 KB) and eases use with the SystemILA