Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
11 years ago

VHDL Preprocessor?

Hello!

I am trying to make a reusable piece of code which has some generics on top and some constant declarations following. My problem is that depending on some generic values the constants need to have different values. Since i cannot use code outside before the "begin" keyword of the "architecture" then how can I do it? I cannot find any preprocessor directives like "define" for VHDL...

Does anybody have a solution for this?

Thanks in advance

7 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    
    library ieee;
    use ieee.std_logic_1164.all;
    use ieee.numeric_std.all;
    entity MyEntity is
    	generic
    	(
    		PARAM_SIGN : NATURAL := 0 -- 0: above zero, 1: below zero
    		
    	);
    	port
    	(
    		clock	: in STD_LOGIC;
    		reset	: in STD_LOGIC
    	);
    end MyEntity;
    architecture RTL of MyEntity is
    # if PARAM_SIGN = 0
    constant myconst1 : SIGNED(15 DOWNTO 0) := TO_SIGNED(1000,16);
    # else
    constant myconst1 : SIGNED(15 DOWNTO 0) := TO_SIGNED(0,16);
    # end if
    begin
    ..................................
    end RTL;
    

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    VHDL has no pre-processor, instead you must write functions to set the values:

    
    function create_my_const_1 return signed is
    begin
      if PARAM_SIGN = 0 then
        return to_signed(1000, 16);
      else 
        return to_signed(0,16);
      end if;
    end function create_my_const_1;
    constant my_const1 : signed(15 downto 0) := create_my_const_1;
    
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    "Ifdef" is "if generate" to be equivalent with VHDL.

    
    begin
    above_zero : if PARAM_SIGN=0 generate
    	process(clock)
    		constant myconst1 : SIGNED(15 DOWNTO 0) := TO_SIGNED(1000,16);
    	begin
    		if rising_edge(clock) then
    			dout <= myconst1;
    		end if;
    	end process;
    end generate;
    below_zero : if PARAM_SIGN=1 generate
    	process(clock)
    		constant myconst1 : SIGNED(15 DOWNTO 0) := TO_SIGNED(0,16);
    	begin
    		if rising_edge(clock) then
    			dout <= myconst1;
    		end if;
    	end process;
    end generate;
    
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    ifdef and if generate are NOT the same thing.

    You could not use a generate to set the value of a constant available to the whole file. Using a generate like you suggest would lead to a doubling up of code (not a good idea).
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Different ways to do it. In this case, the shortest is

    constant  myconst1 : SIGNED(15 DOWNTO 0) := TO_SIGNED((1-PARAM_SIGN)*1000,16);
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    Different ways to do it. In this case, the shortest is

    constant  myconst1 : SIGNED(15 DOWNTO 0) := TO_SIGNED((1-PARAM_SIGN)*1000,16);

    --- Quote End ---

    Yes, but it requires 'decoding' every time the poor chap after you has to read it.

    I wrote a 'ternary' function (with almost a dozen overloads) in my utilities package.

     constant myconst2 : signed(15 downto 0) := to_signed( ternary( PARAM_SIGN = 1, 0, 1000 ) , 16) ;

    It is not as nice as the C construct ? : though but it saves a lot of 'if then else' clutter.