Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"GENERIC constants" in VHDL

Tags:

vhdl

is it possible to have different constants depending on the GENERIC input? E.g.:

entity smth is
   generic(
      constant_width : integer := 32
   );
end smth;

architecture Behavioral of smth is
   if(constant_width = 32) then
        constant ROM_tan : rom_type := ( .....
           ....
       );
   else
        constant ROM_tan : rom_type := ( ....
       );
   );

begin
.
.

One workaround is to create two constants and let Vivado trim one away(using generate and if) if it's not used, but that doesn't look elegant. The other one is to concatenate two constants, since in my case the difference between constants is only the size, i.e precision, of the constants depending on the input width, but that’s not very elegant for me either. Is there any other way? (Maybe something with package?)

Kind Regards,

Den

like image 245
refDL Avatar asked Dec 03 '25 13:12

refDL


2 Answers

A generate statement has a declarative region, like an architecture.

label : if (condition) generate
  constant myConst ....
begin
  -- ...
end generate;

You can even declare new types in this region. This is also true for block statements.

So rewriting your example gives:

entity smth is
  generic(
    constant_width : integer := 32
   );
end smth;

architecture Behavioral of smth is

begin
  gen1 : if (constant_width = 32) generate
    type ROM_type is ...
    constant ROM_tan : ROM_type := (..);
  begin
    -- ...
  end generate;
  gen2 : if (constant_width /= 32) generate
    type ROM_type is ...
    constant ROM_tan : ROM_type := (..);
  begin
    -- ...
  end generate;
end architecture;
like image 155
Paebbels Avatar answered Dec 06 '25 10:12

Paebbels


All the hand waving is driving me nuts. There are no language constructs comprised of consecutive '.' characters.

You can use generics in the type declaration and the function to fill your ROM:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity smth is
   generic (
      constant_width : integer := 32
   );
end entity smth;

architecture foo of smth is
    type rom_type is array (0 to 129) of 
                    signed (constant_width - 1 downto 0);
    function fill_rom return rom_type is  -- if we're going to get all hand wavy
        variable ret_val:   rom_type;
    begin
        for i in rom_type'range loop
            ret_val(i) := to_signed(i,constant_width); -- all look like 45 from here
        end loop;
        return ret_val;
    end function;
    constant ROM_tan:  rom_type := fill_rom;  -- to constant_width accuracy
begin
-- imagine a boat load of lines with three or more periods here.
end architecture;

This example actually analyzes, elaborates and simulates (while literally not doing anything).

You can also move the generic backward (to a package) potentially the function as well. If synthesis ever catches up you could use package instantiation (-2008) with it's own generic map aspect.


Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!