RFSoC 4x2 issue with DAC signal generation

So I’m working on a signal generator of sorts but this is early stages so it’s just a setup to divide a signal by a factor of 2 or 3 and I am trying to use HLS to accomplish this. I’ve connected a DDS compiler directly to the DAC and observed the output as a regular 3.7MHz sine output. I then used a block that divides by 2 and another block that divides by 3. The results and the block diagrams are attached below. The division is odd in that it also performs a frequency division, which doesn’t make too much sense as the division operation is supposed to be linear but the frequency division is very much non-linear.

I’m not sure if HLS is the appropriate platform for what I intend as perhaps straight verilog might actually give me what I want. In any case, I think it might have something to do with the clocking but I’m not sure where to start looking for the issue. I’ve also attached the block diagram for reference.

  1. Block diagram
    bd_pynq

  2. No division by 2
    no div — Postimages

  3. Divsion by 2
    div 2 — Postimages

From the above images, the signal goes deteriorating as the division factor increases. Not to mention the non-linear behaviour previously discussed. The RF data converter for the DAC is set to real->real and it gets a 16-bit alue from the DDS.

As always, any help or direction to material to assist me with this would be much appreciated.

Here’s division by 3 where the signal further deteriorates. I’m fairly new so can’t post that many links or embedded images but this should be adequate information in any case.

So this I guess is pretty embarassing to state, but the throughput of my blocks wasn’t optimal. The HLS block throughput was not the standard one output every clock cycle. (I discovered this weeks ago but felt I should update this in any case) Despite the operation being fairly straight-forward I don’t think HLS is built for such fast processing. The frequency division by 2 correlates to one sample every clock cycle and any further division is as a result of this inoptimality. Going forward, I’d suggest making such kind of blocks either in hard-code HDL or if you have the luxury and know-how, using Xilinx’s Model Composer. With those 2 options, one has the flexibility and freedom to pipeline their operations at will.

1 Like

Thank you @benja for posting the solution back.

I would like to state that HLS reports the initiation interval (after how many cycles you can process a new input) and using pragmas you can achieve II=1.

It is important to highlight as you mention, that any IP in the pipeline should match the throughput of its source.

Mario

1 Like