Search code examples
vhdl

VHDL - Why are you not allowed to use variables in generate loops


I know, variables are only allowed in processes, but why are you not allowed to use them in generate loops. There are no problems for synthesizing such constructs, because they are evaluated before.

The code could get more readable without this restriction.

lbl1: for i in data_out'range generate
    lbl2a: component comp_a 
        port map(
            clk => clk,
            out => out(0)(i)
            in_a => data_in(i*w + offset to i*w + w + offset));
    lbl2b: component comp_b
        port map(
            clk => clk,
            out => out(1)(i)
            in_b => data_in(i*w + offset to i*w + w + offset));
    .
    . 
    . 
    lbl2n: component comp_n
        port map(
            clk => clk,
            out => out(n)(i)
            in_n => data_in(i*w + offset to i*w + w + offset));
end generate lbl1;

Or just write

lbl1: for i in data_out'range generate
    variable lower : integer := i*w + offset;
    variable upper : integer := i*w + w + offset;
    lbl2a: component comp_a 
        port map(
            clk => clk,
            out => out(0)(i)
            in_a => data_in(lower to upper));
    lbl2b: component comp_b
        port map(
            clk => clk,
            out => out(1)(i)
            in_b => data_in(lower to upper));
    .
    . 
    . 
    lbl2n: component comp_n
        port map(
            clk => clk,
            out => out(n)(i)
            in_n => data_in(lower to upper));
end generate lbl1;

The code is not from any example, it could fail at any point, but i think you get my point. It would be easier to read and maintain. The generated variable could get out of scope outside the generate process.

So is there any reason WHY this isn't allowed or is it just a historical artefact from previous vhdl standards?


Solution

  • If you would like to declare something, it needs to be in a declarative region. A generate statement is a bit special in that it does not need a begin; you can (as you have) use:

    GenerateLoop : for i in data_out'range generate
      -- Code here
    end generate;
    

    If you would like to declare things as part of the loop, you must have a declarative region, which, with a generate statement, would look like this:

    GenerateLoop : for i in data_out'range generate
      -- Declarative region
    begin
      -- Code here
    end generate;
    

    You should be able to declare things in this declarative region. Note that you will need to use a signal or constant (it looks like a constant will be more appropriate) instead of a variable.