Lists are one of the key features of THDL++. They allow making loops and
All lists exist at compile-time only and are unrolled during VHDL generation. If you are looking for a way of managing lists of numbers in hardware, see Core.Primitives.FIFO and Core.RAMs.Synchronous.SimpleRAM entities from corelib.
const any MyNumbers = (1, 2, 3, 4);
The const any MyNumbers2 = (MyNumbers, 5, 6);
You can also make functions that build lists:
any BuildList(int start, int end)
{
list result = __list();
for (int i = start; i le end; i++)
result = (result, i);
return result;
}
const list MyNumbers = BuildList(1, 8);
Please use the Core.Primitives.ListFifo<__list(1,2,3,4), 8> fifo(
clk = clk,
reset = auto,
DataPull = auto,
DataPush = auto,
DataOut = auto
);
Finally, there are several built-in functions returning lists: const any stages = (SquareInput, AddOne, AddTwo);
generate Instances foreach(any stage in stages)
{
stage Inst(
Input = auto,
Output = auto
);
}
This will produce the following VHDL code:
Instances_0_Inst : Square_Input
port map (
Input => Instances_0_thp_Inst_autosig_Input,
Output => Instances_0_thp_Inst_autosig_Output
);
Instances_1_Inst : Add_One
port map (
Input => Instances_1_thp_Inst_autosig_Input,
Output => Instances_1_thp_Inst_autosig_Output
);
Instances_2_Inst : Add_Two
port map (
Input => Instances_2_thp_Inst_autosig_Input,
Output => Instances_2_thp_Inst_autosig_Output
);
Alternatively, you could use the const any stages = (SquareInput, AddOne, AddTwo);
generate Instances for(int i = 0; i lt sizeof(stages); i++)
{
stages[i] Inst(
Input = auto,
Output = auto
);
}
You can also access lists from the process testbench()
{
const any values = (1, 2, 3, 4, 5);
foreach (any val in values)
{
sig = val;
wait(10ns);
}
}
Note that you cannot declare global constants. Every constant should be declared inside an entity, class, namespace, process or function.
Please also note that functions accepting lists as arguments will not be synthesized to VHDL. I.e. the following code won't compile:
int sum_first(any lst, int index)
{
int sum = 0;
for (int i = 0; i lt sizeof(lst); i++)
{
sum += lst[i];
if (i == (index - 1))
return sum;
}
return sum;
}
process test (clk.rising)
{
sig2 = sum_first(__list(1,2,3,4), sig1);
}
As VHDL does not have an equivalent of lists, compiling sum_first into VHDL will not be possible.
On the other hand, the following code will compile:
process test (clk.rising)
{
const int sum = sum_first(__list(1,2,3,4), 3);
sig2 = sum;
}
As the call to sum_first does not depend on non-constant value (e.g. signal values), sum_first will be executed during compilation time and the VHDL code will look like that:
test : process (clk) is
begin
if rising_edge(clk) then
sig2 <= X"06";
end if;
end process test;
However, you still can compile a list-related function to VHDL if you make the list a template argument. In this case THDL++ compiler will generate a version of the function for this specific list embedding its contents into the code:
template <any lst>int sum_first(int index)
{
int sum = 0;
for (int i = 0; i lt sizeof(lst); i++)
{
sum += lst[i];
if (i == (index - 1))
return sum;
}
return sum;
}
process test (clk.rising)
{
sig2 = sum_first<__list(1,2,3,4)>(sig1);
}
The generated VHDL function will look like that:
function sum_first_list_1_2_3_4 (index: integer) return integer is
variable sum : integer;
begin
sum := 0;
sum := (sum + 1);
if (0 = (index - 1)) then
return sum;
end if;
sum := (sum + 2);
if (1 = (index - 1)) then
return sum;
end if;
sum := (sum + 3);
if (2 = (index - 1)) then
return sum;
end if;
sum := (sum + 4);
if (3 = (index - 1)) then
return sum;
end if;
return sum;
end function sum_first_list_1_2_3_4;