Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)
16666 Discussions

Fixed point arithmetic not working for digital signal processing application

Altera_Forum
Honored Contributor II
2,065 Views

Hi, 

 

I am currently trying to do some simple digital signal processing using the Terasic AD/DA card attached to the Terasic DE0 board (which has a Cyclone III on board). My situation is that I am sending a sine wave an an input to the AD/DA card, and I wish to multiply the amplitude of this sine wave by a factor, then output the result through the AD/DA card again. 

 

The AD/DA card recieves a signal and associates to it a signed number (in two's complement format) of 14 bits in length. Similarly, when provided a 14 bit signed number in two's complement format, the AD/DA card outputs a voltage corresponding to the number send to the card (ex. 01111111111111 input = 2 Volts output). 

 

So far, it works perfectly when I multiply by integer factors. 

 

Then I tried to do somethig similar with fixed point arithmetic (using David Bishop's compatibility VHDL libraries for fixed-point arithmetic in Quartus 12.1). I have uploaded the code. I have also uploaded the resulting image (the red sine wave is the input, and the blue shape is the ouput from the AD/DA card). Here is the idea: 

 

There are two channels in the AD/DA card, and so every operation is done twice. When "button" is pressed (If button = '0'), then the level (the signed number coming from the analog-digital converter) is scaled to be between -1 and 1 (representing volts). Then, the voltage is multiplied by a factor (here the factor is 1.45786 as declared at the top of the code). Then, the voltage_op (the voltage resulting from the mathematical operation) is scaled back to a signed number (level_op) that will be sent to the digital-analog converter 

 

For completeness, I have also tried to implement a similar program using the following method: 

When the digital-analog converter provides a number (call it "level"), and I want to multiply by a "factor" (which might be fractional, e.g. factor = 1.5), then I can use integer arithmetic like so: 

 

temp = (level * 2^10) * (factor * 2^10) -- Everything is integer 

output = temp / (2^20)  

 

Then, the output should be multiplied like desired. This approached yielded the same result as the code I have provided using fixed-point arithmetic. 

 

I suspect I have overlooked a small detail in VHDL coding, but I have been looking for a solution for a week and still haven't found a solution. Can anyone see a flaw in my code? Thank you immensely for your time. 

 

For the record, I am a student but this is not homework. I have a job in a physics lab that requires digital signal processing. 

 

[EDIT] I contacted Terasic and my assumption that the binary format is two's complement is wrong. The Terasic AD/DA daughter card is using offset binary, meaning that sending the unsigned 14-bit number representation of "0" will output -1V from the Digital-to-analog converter (DAC), while sending the unsigned 14-bit representation of "16383" (2^14 - 1) will output +1V
0 Kudos
8 Replies
Altera_Forum
Honored Contributor II
673 Views

We can see that by assembling the top and bottom of the blue curve, we get the right sine wave. This is observed for all factor I have tried. Inverting the sign bit in the signed number "level_B_op" and "level_A_op" does not yield the desired result, but comes close.

0 Kudos
Altera_Forum
Honored Contributor II
673 Views

It looks to me like you have an issue with the bit-width somewhere in your code. 

 

Take a look at this tutorial document: 

 

http://www.ovro.caltech.edu/~dwh/correlator/pdf/esc-104paper_hawkins.pdf 

http://www.ovro.caltech.edu/~dwh/correlator/pdf/esc-104slides_hawkins.pdf 

http://www.ovro.caltech.edu/~dwh/correlator/pdf/esc-104code_hawkins.zip 

 

You will see several examples of what happens when things go wrong. Look at your code to see if you can figure out your error. 

 

Cheers, 

Dave
0 Kudos
Altera_Forum
Honored Contributor II
673 Views

Thank you for your documents. I will keep them at hand. 

The size of my signals do not seem to be the problem though. I have followed the guidelines that are outlined in the .pdf and I still get the same result for my output. 

 

Moreover, the output waveform does not look like a sine with a horizontal "cut" at some height (notice that the cut seems asymmetric). This suggests to me that there is somethign else than a bit-width problem.
0 Kudos
Altera_Forum
Honored Contributor II
673 Views

 

--- Quote Start ---  

 

The size of my signals do not seem to be the problem though. I have followed the guidelines that are outlined in the .pdf and I still get the same result for my output. 

 

--- Quote End ---  

 

Convince me - where are your Modelsim simulations of the logic? 

 

If you have a difference between simulation and hardware, then it would point to an error in the interface to the DAC, eg., your DAC might not use signed integer format, but straight-binary (which requires inverting the MSB of the data before sending it to the DAC). 

 

Cheers, 

Dave
0 Kudos
Altera_Forum
Honored Contributor II
673 Views

Thank you for your feedback, Dave. I contacted Terasic and they pointed out to me that the card is using offset binary format, that is, sending the unsigned number "0" to the DAC outputs -1V while sending the unsigned number "16383" (2^14 - 1) outputs +1 V. 

 

Thanks again, 

Laurent
0 Kudos
Altera_Forum
Honored Contributor II
673 Views

 

--- Quote Start ---  

the card is using offset binary format 

 

--- Quote End ---  

 

 

Excellent. Now that you have seen this effect, you'll be aware of it next time. You quite often have to perform some data-format conversion between ADCs and DACs, and your signed number DSP logic. 

 

Cheers, 

Dave
0 Kudos
Altera_Forum
Honored Contributor II
673 Views

Hi Dave. I have a problem with AD/DA terasic conversion card. I have done some projects with DE0-Nano and it's ADC. That one is different and has a clear guidance by Altera (pins, how data transfer, and ...).  

Let me explain a simple example, Consider a variable resistor and its output for using as an analog input signal for ADC. When we changes the resistance the voltage changes and of course converted bytes also. This is the first project which I want to do it by this AD/DA board and DE2-115!  

As I see in the Data_conversition_HSMC_reference_manual I have Channel A and B as SMA inputs. Why two channel? Can I do it by one channel only?  

And so far I have done this simple vhdl code and pin assignment just to see such a simple analog input in LEDs of DE2-115. But it doesn't work!  

 

library ieee; 

use ieee.std_logic_1164.all; 

USE IEEE.NUMERIC_STD.ALL;  

 

entity test is 

port( ADA_D : in std_logic_vector (13 downto 0); 

clk : in std_logic; 

ADA_DCO: in std_logic; 

ADA_OE : out std_logic; 

ADA_OR : in std_logic; 

ADA_SPI_CS: out std_logic; 

AD_SCLK : inout std_logic; 

AD_SDIO : inout std_logic; 

AIC_BCLK : inout std_logic; 

AIC_DIN : out std_logic; 

AIC_DOUT : in std_logic; 

AIC_LRCIN: inout std_logic; 

AIC_LRCOUT: inout std_logic; 

AIC_SPI_CS: out std_logic; 

AIC_XCLK : out std_logic; 

CLKIN1 : in std_logic; 

CLKOUT0: out std_logic; 

FPGA_CLK_A_N: inout std_logic; 

FPGA_CLK_A_P: inout std_logic; 

J1_152: inout std_logic; 

XT_IN_N : in std_logic; 

XT_IN_P : in std_logic; 

bit_out1: out std_logic_vector (13 downto 0) 

); 

end test; 

 

architecture behavioral of test is 

 

 

begin 

process (ADA_D) 

begin 

bit_out1 <= ADA_D; 

end process; 

 

end behavioral; 

 

bit_out1 is assigned to LEDs to see the voltage changing. 

 

I have done the pin assignment according to DE2-115 projects and I think it is fine.  

I do not know where is the real input? which signal is that one? 

Am I completely wrong or a part of? 

 

Hope you can help me to solve the problem. 

Thanks
0 Kudos
Altera_Forum
Honored Contributor II
673 Views

 

--- Quote Start ---  

 

Hope you can help me to solve the problem 

 

--- Quote End ---  

 

The Terasic AD/DA card has input transformers. I have not looked at the documentation, but I suspect you need to input a signal with a frequency of a few MHz (I'd start with 10MHz) before you will see the ADC samples change. Do not route the sampled ADC bits to the LEDs, as they will be changing too fast (so the LEDs will appear to be on all the time), use the SignalTap II logic analyzer and trace some of the samples coming from the ADC. SignalTap II can plot the samples like an analog signal, eg., see the slides on pages 26 and 28 

 

https://www.ovro.caltech.edu/~dwh/correlator/pdf/ee_live_14_hawkins.pdf 

 

Cheers, 

Dave
0 Kudos
Reply