IIO driver cf_axi_dds writes IIO_CHAN_INFO_SCALE attribute data to FPGA as fixed point 1.1.14 (sign, integer and fractional bits) Sign/magnitude format and not in Two's complement.
E.g. scale -0.5 is written as 0xA000 (in Two's complement is 0xE000).
Since FPGA multiplier operates with signed 2nd complement operands the conversion must be/is done in FPGA.
What is the rationale behind this approach?
One would expect that sw makes the translation to 2nd complement and write the multiplier coefficient as expected by FPGA arithmetic primitives.
1.1.14 format look like a two's complement representation to me. :) See this site for clarification: http://www-inst.eecs.berkeley.edu/~cs61c/sp06/handout/fixedpt.html
Our DDS architecture expect this format for the scale attribute, and there isn't any conversion there: https://github.com/analogdevicesinc/hdl/blob/master/library/common/ad_dds_1.v#L91-L110
The basic idea behind this is that the resolution of the DAC will be different for each device. The DDS will generate a full scale sine wave, which will be scaled by the scale attribute. (See the logic in the link above)
This is purely an HDL point of view, how the software will define this 16 bit value in the driver, that's another question.
Hope this helps,
I was not clear enough in my question.
I have analyzed the Analog IIO cf_axi_dds.c IIO driver (LX drivers/iio/frequency directory) source implementation and then follow the scale value written to FPGA register (in up_dac_channel.v) and from there to final multiplayer in ad_dds.v with FPGA simulation test bench.
You can see that LX drivers/iio/frequency/cf_axi_dds.c in its IIO_CHAN_INFO_SCALE implementation converts scale value of -0.5 to 0xA000, which is not Two's complement FixedPoint 1.1.14 presentation of float value -0.5 (it is Sign/magnitude presentation). The correct Two's complement FixedPoint 1.1.14 presentation of scale value -0.5 is 0xE000.
Since FPGA multipliers expect Two's complement operands the conversion from Sign/magnitude to Two's complement is done in FPGA. You have to look here https://github.com/analogdevicesinc/hdl/blob/master/library/common/up_dac_channel.v (function [15:0] sm2tc;).
The cf_axi_dds.c (IIO drivers) and corresponding DDS FPGA modules are tightly connected, so I was wondering what is rationale (reason) behind decision that scale conversion to Two's complement is done in FPGA and not already in SW.
Yes, you're right. I missed the function in the register map.
But I don't think that there is a particular reasoning behind this. It was a simple design decision at the beginning, and we stick with it. I don't really see any clear advantage or disadvantage on doing this conversion in the SW or HDL. Or if you see one feel free to let us know.
Maybe there is some reason from the software side, that I don't see, but hopefully one of our software guy will comment on that.
Usually one design FPGA logic by optimizing resource utilization and also think on timing (catching timing constrains at high clocks).
Seeing this conversion to Two's complement done in FPGA I was wondering about reason.
I don't know everything and there could be good reason behind this decision.
E.g. I know only Xilinx FPGA and there could be other FPGA vendors (Altera, Lattice, ...) with their different multiplier logic that requires different format of multiplier operands. Keeping compatibility (common sw and FPGA specific implementation) is good reason for such approach.
"Usually one design FPGA logic by optimizing resource utilization and also think on timing." -- the conversion is done in the register map clock domain, which is 100MHz and I can not see any reason to increase this, taking the fact the registers will not be changed frequently.
About other FPGA vendors, I don't think the this will be or is a problem. This logic is used with different Intel architectures without an issue (Intel's DSP are supporting both 2's complement and offset binary as far as I know), and I'm confident that this is not on issue with Lattice devices either.