EEVblog Electronics Community Forum
Electronics => Microcontrollers => Topic started by: Pack34 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:
int array[256] = {0, 1, 2, 3, ... 255};
But in VHDL, I've found myself doing:
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!
-
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:
int array[256] = {0, 1, 2, 3, ... 255};
But in VHDL, I've found myself doing:
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:
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:
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.
-
Awesome, but now I'm getting an HDLParser:3285 error. This states
No array or record type can be found that has elements of types matching the aggregate
-
Awesome, but now I'm getting an HDLParser:3285 error. This states
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?
-
I'd write an initializer function:
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
-
I'd write an initializer function:
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.
-
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
-
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.
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...
-
Here's what I'm doing:
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.
-
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.
-
Here's what I'm doing:
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.
-
Python script spitting out VHDL.
-
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.
-
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!