Altera_Forum
Honored Contributor
9 years agoSigned Addition in VHDL
Hi everyone,
I want to implement an addition operation using VHDL. I have one input that comes from my Nios. this value is calculated in float format, then it sent to the VHDL block that i want to implement. to sent this value to vhdl block using internal connection, I use this :union position
{
alt_32 I_position;
float F_position;
}; FI_position.F_position =float_value;
Posit_mask=FI_position.I_position;
IOWR_ALTERA_AVALON_PIO_DATA(REGISTRE_POSITION_BASE,Posit_mask); In the VHDL side, this value becomes Position_In: in std_logic_vector(31 downto 0); So, the description of the algorithm is as follows: Result_now= Position_In + Result_before. To do this i convert all values to be signed. My vhdl program looks like this : library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
Library altera_mf;
USE altera_mf.all;
-- Add the library and use clauses before the design unit declaration
library altera;
use altera.altera_primitives_components.all;
Entity Sum_Position is
Generic ( Accu_lenght : integer -- in µs
);
port
(
Clk: in std_logic;
Reset: in std_logic;
Raz_position: in std_logic;
Position_In: in std_logic_vector(Accu_lenght-1 downto 0);
Position_Out: out std_logic_vector(Accu_lenght-1 downto 0)
);
end Sum_Position;
Architecture Arch_position of sum_Position is
signal position_before: signed (Accu_lenght-1 downto 0):= (OTHERS => '0');
-- both signals have one more bit than the original
signal Position_s : SIGNED(Accu_lenght downto 0):= (OTHERS => '0');
signal Position_Before_s : SIGNED(Accu_lenght downto 0):= (OTHERS => '0');
signal Sum_Pos_s : SIGNED(Accu_lenght downto 0):= (OTHERS => '0');
signal temp : std_logic_vector(2 downto 0):= (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)
begin
IF (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;
END IF;
end process Sum_of_position;
-- 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));
end Arch_position;
I create a test bench, to test my algorithm. this are the inputs to test: Position_In <= (OTHERS => '0');
WAIT FOR 20 NS;
RESET <='1';
WAIT FOR 20 NS;
Position_In <= X"bfa1ffd6"; -- -1,26562
WAIT FOR 20 NS;
Position_In <= X"41010000"; --8,0625
WAIT FOR 20 NS;
Position_In <= X"bf31003f"; -- -0,69141
WAIT FOR 20 NS;
Position_In <= X"3fb9ffd6"; -- +1,45312
WAIT FOR 20 NS;
Position_In <= X"c0b80000"; -- -5,75
WAIT FOR 20 NS;
Position_In <= X"c0f10000"; -- -7,53125
WAIT ;--100 NS;
I don't have the result expected, my logic is correct ? Thank you in advance for help. Best regards,