Is hierarchical reference to the loop index variable in a for loop generate block possible?

I am confused by the two following statements in section 27.4 in System Verilog LRM -

“A genvar shall not be referenced anywhere other than in a loop generate scheme.”

“Within the generate block of a loop generate construct, there is an implicit localparam declaration. This is an integer parameter that has the same name and type as the loop index variable, and its value within each instance of the generate block is the value of the index variable at the time the instance was elaborated. This parameter can be used anywhere within the generate block that a normal parameter with an integer value can be used. It can be referenced with a hierarchical name.”

Can I do the following -

module bot;
mod imod #(top.sub.gen_block[0].i) (); // gen_block is a generate block
endmodule

Also a related question here is can I hierarchically reference a signal inside a generate block from another generate block using the loop index variable? Like the following -

genvar i;
for (i = 0; i < MAX_LIMIT; i++) begin: a
wire sig;
assign sig = top.bot.gen_block[i].sig // “gen_block” is a generate block instantiated inside “bot”
end

The first sentence you quote is about referencing the genvar identifier - in your example ‘i’ is the genvar identifier. You can’t reference ‘i’ outside of the generate block because the generate block gets unrolled replacing ‘i’ with a literal digit. It similar to macro text expansion. You generate block gets expanded into

begin : a[0]
  wire sig;
  assign sig = top.bot.gen_block[0].sig;
end
begin : a[1]
  wire sig;
  assign sig = top.bot.gen_block[1].sig;
end
begin : a[2]
  wire sig;
  assign sig = top.bot.gen_block[2].sig;
end
...

Note the the wire sig does not become an array of wires. Instead it becomes a set of named wires called a[0].sig, a[1].sig, … that you can only access by specifying a with a constant index. That is because an array of scopes in not like a regular array. Each instance can hold different types. For example:

genvar i;
for (i = 0; i < MAX_LIMIT; i++) begin: a
wire [i+1:0] sig;
end

a[0].sig is a 2-bit wire, a[1].sig is a 3-bit wire. So referencing a[j].sig does not compile. But you can use another generate block genvar to index into another generated block instance as you did in your example with the assign statement.