I tried to implement a VHDL program that add two signed numbers.
The description of the algorithm is as follows, I receive a signed 32
bits value, let's say A. This value will be added to the previous
addition and then the result will be: Result_now= A + Result_before.
So, the first thing i do is to resize A and Result_before to be 33 bits,
in order to avoid overflow, Result_now is 33 bits.
I create a test bench to test my code, but i face a strange problem, the
result is not as expected, for example when i add the value -1,26562 to
8.06250, I get 1.49691e-038.
can you help to resolve this problem please ?
The codes are below:
-- Add the library and use clauses before the design unit declarationlibrary altera;
Entity Sum_Position isGeneric ( Accu_lenght : integer-- in µs
Architecture Arch_position of sum_Position issignal position_before: signed (Accu_lenght-1downto0):= (OTHERS => '0');
-- both signals have one more bit than the originalsignal Position_s : SIGNED(Accu_lenght downto0):= (OTHERS => '0');
signal Position_Before_s : SIGNED(Accu_lenght downto0):= (OTHERS => '0');
signal Sum_Pos_s : SIGNED(Accu_lenght downto0):= (OTHERS => '0');
signal temp : std_logic_vector(2downto0):= (OTHERS => '0');
Begin-- begin of architecture-- convert type and perform a sign-extension
Position_s <=resize(signed(Position_In), Position_s'length);
Position_Before_s <= resize(signed(position_before), Position_Before_s'length);
Sum_of_position: process(Clk, Reset)
beginIF (Reset='0') THEN-- when reset is selected-- initialize all values
Sum_Pos_s<= (OTHERS => '0');
ELSIF (Clk'event and Clk = '1') then-- addition of two 33 bit values
Sum_Pos_s <= Position_s + Position_Before_s;
-- resize to require size and type conversion
position_before <= (OTHERS => '0') WHEN Raz_position='1'else-- Reset to zero when Raz_position='1'signed(resize(Sum_Pos_s, position_before'length));
Position_Out <= (OTHERS => '0') WHEN Raz_position='1'else-- Reset to zero when Raz_position='1'std_logic_vector(resize(Sum_Pos_s, Position_Out'length));
And the test Bench is this one:
ENTITY TBH ISEND TBH;
ARCHITECTURE TBH_ARCH OF TBH ISCOMPONENT Sum_Position -- to declare the block of ADC_CNLGeneric ( Accu_lenght : integer-- in µs
CONSTANT Accu_size: integer := 32;
SIGNAL CLK : STD_LOGIC := '1';
SIGNAL RESET : STD_LOGIC := '0';
SIGNAL Raz : STD_LOGIC := '0';
SIGNAL Position_In : STD_LOGIC_VECTOR(Accu_size-1DOWNTO0);
SIGNAL Position_Out : STD_LOGIC_VECTOR(Accu_size-1DOWNTO0);
BEGIN--to define the signal and the block's relationship
Position : Sum_Position genericmap (Accu_size)PORTMAP(
Clk => CLK, --COMPONENT PORT => ACTUAL SIGNAL
Reset => RESET,
Raz_position => Raz,
Position_In => Position_In,
Position_Out => Position_Out
PROCESS(CLK) --to produce CLKBEGIN
CLK <= NOT CLK AFTER10 NS;
PROCESS--to simulation the signal the AD timingBEGIN
Position_In <= (OTHERS => '0');
Position_In <= X"bfa1ffd6"; -- -1,26562WAITFOR20 NS;
Position_In <= X"41010000"; --8,0625WAITFOR20 NS;
Position_In <= X"bf31003f"; -- -0,69141WAITFOR20 NS;
Position_In <= X"3fb9ffd6"; -- +1,45312WAITFOR20 NS;
Position_In <= X"c0b80000"; -- -5,75WAITFOR20 NS;
Position_In <= X"c0f10000"; -- -7,53125WAIT ;--100 NS;
Thank you for taking time to help me.
jeorges F. wrote:> for example when i add the value -1,26562 to 8.06250, I get 1.49691e-038.
With the + operator on singed vectors you do not add any float values,
but instead you add twos-complement integer values.
And it seems to me you have some kind of very strange own number format.
This here looks like the MSB alone is the negative sign:
X"bfa1ffd6"; -- -1,26562
X"3fb9ffd6"; -- +1,45312
The binary representation of those float values look almost the same,
but only the MSB is set and the whole value gets negative.
Thats not how two's-complement binary numbers work!!! And therefore you
cannot use a two's-complement addition to add your own number format!
So: whats your numbers format?
How do you calculate the binary representation of those float numbers?
> for example when i add the value -1,26562 to 8.06250, I get 1.49691e-038.
Can you show those numbers in a test bench waveform?
Or are those numbers only in your head or on a sheet of paper?
> can you help to resolve this problem please ?
The compiler does not read comments. It just does what the sourcecode
tells him. So it looks very like the compiler does interpret X"bfa1ffd6"
different from you...
Thank you Lothar for your answer.
In fact my input comes from a Nios processor. The nios does computing in
float, so the Position_In is float inside Nios, then it's converted to
Integer 32 bits. It's arranged in my variable std_logic_vector (31
To have the equivalent from hex to float number, i use the Floating
Point to Hex Converter.
You find enclosed the test bench waveform, the values are represented in
Hex, but when i change the radix, i get the correct float equivalent.
jeorges F. wrote:> To have the equivalent from hex to float number, i use the Floating> Point to Hex Converter.
Of course you cannot add two float numbers with an
two's-complement-adder (what you are doing when adding two signed
> but when i change the radix, i get the correct float equivalent.
Read a few lines about IEEE754 then you will obviously see that you
never simply can add two float values this way. You will need to
normalize the two
float values, then you can perform the addition, then you must convert
it back to a valid float number.
Ok, i see, thank you Lothar.
In my C code, i do this:
/* Variable for position */
When i calculate the position, I put it into F_position, then i can have
the decimal value in I_position.
The I_position is then exploited as signed in my VHDL code. So
normally,i manipulate decimal representation, It's correct ?
Thanks in advance,
jeorges F. wrote:> alt_32
This is a 32 bit integer data type?
> When i calculate the position, I put it into F_position, then i can have> the decimal value in I_position.
No chance! A union does not convert anything! This way you tell the
compiler only to look at the very same bit pattern in a different
Just as an example:
The bit pattern 0xbf31003f is the float number -0,69141
The same pattern 0xbf31003f is the integer number 3207659583
But -0,69141 is a -1 when rounded to an integer...
Do you see the problem?
I understand the issue Now, thank you very much for your explanation.
Now, I have to focus on the implementation of floating addition.
Do you know some links where i can find examples or documentation about
Thanks in advance,