Search code examples
vhdl

how do I take the absolute value of a std_logic_vector? in VHDL


I can't figure out how to take the absolute value of two std_logic_vector(31 downto 0);

here is an example of the code:

library ieee;
use ieee.std_logic_1164.all;        
use ieee.numeric_std.all;       -- for the signed, unsigned types and arithmetic ops
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
...
...
port (  
    X: in std_logic_vector(31 downto 0); 
    Y: in std_logic_vector(31 downto 0); 
    F: out std_logic_vector(31 downto 0) 
  );

..
..
..
process(X,Y)
 begin
 F <= abs(X-Y)     --this doesnt work

Solution

  • Ditch the non-standard library includes and use the standard signed type which has a built-in abs function:

    library ieee;
    use ieee.std_logic_1164.all;        
    use ieee.numeric_std.all; -- this is the standard package where signed is defined
    -- never use non-standard ieee.std_logic_arith and ieee.std_logic_unsigned
    
    ...
    
    port (  
      X: in  std_logic_vector(31 downto 0); 
      Y: in  std_logic_vector(31 downto 0); 
      F: out std_logic_vector(31 downto 0) 
    );
    
    ...
    
    process(X,Y) is
    begin
      F <= std_logic_vector(abs(signed(X)-signed(Y)));
    end process;
    

    That last line has a lot of [probably needless] converting between std_logic_vector and signed, so you might prefer this interface instead if it makes sense with the rest of your design:

    port (  
      X: in  signed(31 downto 0); 
      Y: in  signed(31 downto 0); 
      F: out signed(31 downto 0) 
    );
    

    Then the last line is just:

     F <= abs(X-Y);