Author Topic: VHDL: Initializing large arrays and using lookup tables  (Read 14450 times)

0 Members and 1 Guest are viewing this topic.

Offline Pack34Topic starter

  • Frequent Contributor
  • **
  • Posts: 753
VHDL: Initializing large arrays and using lookup tables
« on: October 29, 2015, 05:43:10 pm »
I think I can get this to work the way I want, but it could be a lot cleaner.

The goal: generate a large lookup table to eliminate the need to calculations. Just grab the pre-calculated data from a large array and pass it along.

Initialization:
Is there a clean way to generate a large array? For example, in C I could do something like:

Code: [Select]
int array[256] = {0, 1, 2, 3, ... 255};

But in VHDL, I've found myself doing:

Code: [Select]
Array_Int_s(0) <= '0';
Array_Int_s(1) <= '1';
...

Is there a way to write it in a more compact way like in C, or am I stuck to doing it this way?

I'm currently doing this in a process that is kicked off with the system reset signal. Is there a clean way to do this as a constant? I've never really worked with arrays in VHDL and I'm having trouble getting the syntax for this correct.

Thanks in advance!
 

Offline hamster_nz

  • Super Contributor
  • ***
  • Posts: 2803
  • Country: nz
Re: VHDL: Initializing large arrays and using lookup tables
« Reply #1 on: October 29, 2015, 05:59:55 pm »
I think I can get this to work the way I want, but it could be a lot cleaner.

The goal: generate a large lookup table to eliminate the need to calculations. Just grab the pre-calculated data from a large array and pass it along.

Initialization:
Is there a clean way to generate a large array? For example, in C I could do something like:

Code: [Select]
int array[256] = {0, 1, 2, 3, ... 255};

But in VHDL, I've found myself doing:

Code: [Select]
Array_Int_s(0) <= '0';
Array_Int_s(1) <= '1';
...

Is there a way to write it in a more compact way like in C, or am I stuck to doing it this way?

yes:
Code: [Select]
    type a_symbols is array(0 to 511) of std_logic_vector(9 downto 0);
    constant d_symbols : a_symbols := (
        -- Pos RD,       Neg RD
        "0110001011", "1001110100",  -- D0.0
        "1000101011", "0111010100",  -- D1.0
        "0100101011", "1011010100",  -- D2.0
        "1100010100", "1100011011",  -- D3.0
        "0010101011", "1101010100",  -- D4.0
        "1010010100", "1010011011",  -- D5.0
       ....
   );

And you can also do stuff like:

Code: [Select]
    type a_symbols is array(0 to 511) of std_logic_vector(9 downto 0);
    constant d_symbols : a_symbols := (
        12       => "0110001011",
        15       => "1001110100",
        99       => (2=>'1',others =>'0'),    -- set only bit 2 of entry 99
        others => "0000000000"
   );

... if you are doing sparse arrays.

Gaze not into the abyss, lest you become recognized as an abyss domain expert, and they expect you keep gazing into the damn thing.
 

Offline Pack34Topic starter

  • Frequent Contributor
  • **
  • Posts: 753
Re: VHDL: Initializing large arrays and using lookup tables
« Reply #2 on: October 29, 2015, 06:08:55 pm »
Awesome, but now I'm getting an HDLParser:3285 error. This states

Quote
No array or record type can be found that has elements of types matching the aggregate
 

Offline hamster_nz

  • Super Contributor
  • ***
  • Posts: 2803
  • Country: nz
Re: VHDL: Initializing large arrays and using lookup tables
« Reply #3 on: October 29, 2015, 06:25:22 pm »
Awesome, but now I'm getting an HDLParser:3285 error. This states

Quote
No array or record type can be found that has elements of types matching the aggregate
You most likely have mixed up single and double quotes somewhere.... can you post the code?
Gaze not into the abyss, lest you become recognized as an abyss domain expert, and they expect you keep gazing into the damn thing.
 

Offline jahonen

  • Super Contributor
  • ***
  • Posts: 1054
  • Country: fi
Re: VHDL: Initializing large arrays and using lookup tables
« Reply #4 on: October 29, 2015, 07:02:06 pm »
I'd write an initializer function:

Code: [Select]
type int_array_t is array(natural range <>) of integer;

function init_array(size : integer) return int_array_t is
begin
 variable rv : int_array_t(0 to size-1);
  for i in rv'range loop
    rv(i) := i;
  end loop;
  return rv;
end function;

constant TEST_DATA : int_array_t(0 to 255) := init_array(256);

Regards,
Janne
 

Offline Jope

  • Regular Contributor
  • *
  • Posts: 110
  • Country: de
Re: VHDL: Initializing large arrays and using lookup tables
« Reply #5 on: October 29, 2015, 07:23:45 pm »
I'd write an initializer function:

Code: [Select]
type int_array_t is array(natural range <>) of integer;

function init_array(size : integer) return int_array_t is
begin
 variable rv : int_array_t(0 to size-1);
  for i in rv'range loop
    rv(i) := i;
  end loop;
  return rv;
end function;

constant TEST_DATA : int_array_t(0 to 255) := init_array(256);

Your code is pointless. An array where the elements have the same value as the index makes no sense. You can just use the index to begin with.
I'm sure Pack34's array example was just meant to show the problem, not as an example of the values in his array.
« Last Edit: October 29, 2015, 07:25:51 pm by Jope »
 

Offline jahonen

  • Super Contributor
  • ***
  • Posts: 1054
  • Country: fi
Re: VHDL: Initializing large arrays and using lookup tables
« Reply #6 on: October 29, 2015, 07:40:35 pm »
Your code is pointless. An array where the elements have the same value as the index makes no sense. You can just use the index to begin with.
I'm sure Pack34's array example was just meant to show the problem, not as an example of the values in his array.

Yes, pointless as it is but it shows that one can use a function to initialize a constant array. It is left as an exercise to the reader to make it useful.

Regards,
Janne
 

Offline hamster_nz

  • Super Contributor
  • ***
  • Posts: 2803
  • Country: nz
Re: VHDL: Initializing large arrays and using lookup tables
« Reply #7 on: October 29, 2015, 08:01:02 pm »
Your code is pointless. An array where the elements have the same value as the index makes no sense. You can just use the index to begin with.
I'm sure Pack34's array example was just meant to show the problem, not as an example of the values in his array.


Code: [Select]
type int_array_t is array(natural range <>) of integer;

function init_array(size : integer) return int_array_t is
begin
 variable rv : int_array_t(0 to size-1);
  for i in rv'range loop
    rv(i) := i*i*i;
  end loop;
  return rv;
end function;

constant TEST_DATA : int_array_t(0 to 255) := init_array(256);

There - FTFY. With a little imagination It's now a lookup table for x^3...
Gaze not into the abyss, lest you become recognized as an abyss domain expert, and they expect you keep gazing into the damn thing.
 

Offline Pack34Topic starter

  • Frequent Contributor
  • **
  • Posts: 753
Re: VHDL: Initializing large arrays and using lookup tables
« Reply #8 on: October 29, 2015, 09:26:46 pm »
Here's what I'm doing:

Code: [Select]
type Translation_array is array(0 to 255) of std_logic_vector(7 downto 0);
CONSTANT Translation : Translation_array  := (

     "0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
     "10", "11", "12", "13", "14", "15", "16", "17", "18", "19",
  "20", "21", "22", "23", "24", "25", "26", "27", "28", "29",
  "30", "31", "32", "33", "34", "35", "36", "37", "38", "39",
  "40", "41", "42", "43", "44", "45", "46", "47", "48", "49",
  "50", "51", "52", "53", "54", "55", "56", "57", "58", "59",
  "60", "61", "62", "63", "64", "65", "66", "67", "68", "69",
  "70", "71", "72", "73", "74", "75", "76", "77", "78", "79",
  "80", "81", "82", "83", "84", "85", "86", "87", "88", "89",
  "90", "91", "92", "93", "94", "95", "96", "97", "98", "99",
 
  "100", "101", "102", "103", "104", "105", "106", "107", "108", "109",
  "110", "111", "112", "113", "114", "115", "116", "117", "118", "119",
  "120", "121", "122", "123", "124", "125", "126", "127", "128", "129",
  "130", "131", "132", "133", "134", "135", "136", "137", "138", "139",
  "140", "141", "142", "143", "144", "145", "146", "147", "148", "149",
  "150", "151", "152", "153", "154", "155", "156", "157", "158", "159",
  "160", "161", "162", "163", "164", "165", "166", "167", "168", "169",
  "170", "171", "172", "173", "174", "175", "176", "177", "178", "179",
  "180", "181", "182", "183", "184", "185", "186", "187", "188", "189",
  "190", "191", "192", "193", "194", "195", "196", "197", "198", "199",
 
  "200", "201", "202", "203", "204", "205", "206", "207", "208", "209",
  "210", "211", "212", "213", "214", "215", "216", "217", "218", "219",
  "220", "221", "222", "223", "224", "225", "226", "227", "228", "229",
  "230", "231", "232", "233", "234", "235", "236", "237", "238", "239",
  "240", "241", "242", "243", "244", "245", "246", "247", "248", "249",
  "250", "251", "252", "253", "254", "255"  ) ;

The final contents of the array will not be sequential, nor simple pattern.

EDIT:// This is all being declared in the package file.
« Last Edit: October 29, 2015, 09:28:58 pm by Pack34 »
 

Offline Pack34Topic starter

  • Frequent Contributor
  • **
  • Posts: 753
Re: VHDL: Initializing large arrays and using lookup tables
« Reply #9 on: October 29, 2015, 10:00:39 pm »
Okay... now... How do you properly indicate decimal numbers in VHDL? I chopped it down to a size of 10, moved it into the VHD file that's going to use it, and switched to a hex syntax and it's compiling now.
 

Offline hamster_nz

  • Super Contributor
  • ***
  • Posts: 2803
  • Country: nz
Re: VHDL: Initializing large arrays and using lookup tables
« Reply #10 on: October 29, 2015, 10:53:10 pm »
Here's what I'm doing:

Code: [Select]
type Translation_array is array(0 to 255) of std_logic_vector(7 downto 0);
CONSTANT Translation : Translation_array  := (

     "0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
     "10", "11", "12", "13", "14", "15", "16", "17", "18", "19",
  "20", "21", "22", "23", "24", "25", "26", "27", "28", "29",
  "30", "31", "32", "33", "34", "35", "36", "37", "38", "39",
  "40", "41", "42", "43", "44", "45", "46", "47", "48", "49",
  "50", "51", "52", "53", "54", "55", "56", "57", "58", "59",
  "60", "61", "62", "63", "64", "65", "66", "67", "68", "69",
  "70", "71", "72", "73", "74", "75", "76", "77", "78", "79",
  "80", "81", "82", "83", "84", "85", "86", "87", "88", "89",
  "90", "91", "92", "93", "94", "95", "96", "97", "98", "99",
 
  "100", "101", "102", "103", "104", "105", "106", "107", "108", "109",
  "110", "111", "112", "113", "114", "115", "116", "117", "118", "119",
  "120", "121", "122", "123", "124", "125", "126", "127", "128", "129",
  "130", "131", "132", "133", "134", "135", "136", "137", "138", "139",
  "140", "141", "142", "143", "144", "145", "146", "147", "148", "149",
  "150", "151", "152", "153", "154", "155", "156", "157", "158", "159",
  "160", "161", "162", "163", "164", "165", "166", "167", "168", "169",
  "170", "171", "172", "173", "174", "175", "176", "177", "178", "179",
  "180", "181", "182", "183", "184", "185", "186", "187", "188", "189",
  "190", "191", "192", "193", "194", "195", "196", "197", "198", "199",
 
  "200", "201", "202", "203", "204", "205", "206", "207", "208", "209",
  "210", "211", "212", "213", "214", "215", "216", "217", "218", "219",
  "220", "221", "222", "223", "224", "225", "226", "227", "228", "229",
  "230", "231", "232", "233", "234", "235", "236", "237", "238", "239",
  "240", "241", "242", "243", "244", "245", "246", "247", "248", "249",
  "250", "251", "252", "253", "254", "255"  ) ;

The final contents of the array will not be sequential, nor simple pattern.

EDIT:// This is all being declared in the package file.

As the array is 8-bit std_logic_vector then I would recommend using hex constants (e.g. x"00", x"01", x"02"..... x"FE", x"FF").... all it takes is six extra fingers (there is a KickStarter idea in that - prosthetic fingers for learning to count in hex, or maybe octopus gloves with 0-7 and 8-F on the tentacles...).

Decimal constants are a pain - if you wanted a super-generic way, you could use a whole lot of "std_logic_vector(to_unsigned( a_number_between_0_and_255, 8 )" type conversions or equivalent, but that is just super-fugly.

« Last Edit: October 29, 2015, 11:11:04 pm by hamster_nz »
Gaze not into the abyss, lest you become recognized as an abyss domain expert, and they expect you keep gazing into the damn thing.
 

Offline Kalvin

  • Super Contributor
  • ***
  • Posts: 2145
  • Country: fi
  • Embedded SW/HW.
Re: VHDL: Initializing large arrays and using lookup tables
« Reply #11 on: October 30, 2015, 07:19:32 am »
Python script spitting out VHDL.
 

Offline Scrts

  • Frequent Contributor
  • **
  • Posts: 797
  • Country: lt
Re: VHDL: Initializing large arrays and using lookup tables
« Reply #12 on: October 30, 2015, 09:07:49 am »
Maybe use internal blockram for this big array and prepare initialization hex file for it? It would remain in configuration flash and would be preloaded when FPGA is configured.
 

Offline Pack34Topic starter

  • Frequent Contributor
  • **
  • Posts: 753
Re: VHDL: Initializing large arrays and using lookup tables
« Reply #13 on: October 30, 2015, 02:26:10 pm »
As the array is 8-bit std_logic_vector then I would recommend using hex constants (e.g. x"00", x"01", x"02"..... x"FE", x"FF").... all it takes is six extra fingers (there is a KickStarter idea in that - prosthetic fingers for learning to count in hex, or maybe octopus gloves with 0-7 and 8-F on the tentacles...).

Decimal constants are a pain - if you wanted a super-generic way, you could use a whole lot of "std_logic_vector(to_unsigned( a_number_between_0_and_255, 8 )" type conversions or equivalent, but that is just super-fugly.

Hex isn't a problem. I tend to prefer to use hex when working with low level communication. It was just a little bit of a pain to convert everything over. But, it's all in there and works.

Thanks for your help guys!
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf