I'm looking for some help with hierarchical reference when using generate statements. Apologies, I am short on time and haven't yet been able to make a MCVE for this. I've scoured many posts, but so far haven't found an answer to my question.
The two generate
blocks are qualified on the same generics. If these generics are not set accordingly, a different uut
will be instantiated, using a netlist where the hierarchical signals no longer exist. Since the signals won't exist in that case, I would run into problems. The signals are initialized in the test bench declarative region, so even if the generate
isn't qualified to assign them (i.e. in the case when a different uut
is being used), they will, at minimum, have a default value.
There seems to be an elaboration order issue where the hierarchical signals being elaborated in rtl_sig_gen
are elaborated before the uut
in rtl_gen
, which is where the hierarchical references should be pointing to. This seems to be the case whether the signals are placed before, after, or even within the same generate
statement as the uut
.
This is the type of error I get. This is with QuestaSim 2021.4 FYI.
** Error (suppressible): ../Utilities/pld_top_tb.vhd(105): (vopt-1565) Failed to find 'i_nSysReset' in hierarchical name '.pld_top_tb.rtl_gen.uut.i_nSysReset'.
** Error (suppressible): ../Utilities/pld_top_tb.vhd(106): (vopt-1565) Failed to find 'i_a2dif' in hierarchical name '.pld_top_tb.rtl_gen.uut.i_a2dif.i_AD_Data'.
Below is the general setup where I'm seeing this. Is it even possible to hierarchical reference to a conditionally instantiated entity within a generate statement? Any insight would be helpful.
rtl_sig_gen: if not g1_g and not g2_g generate
i_nSysReset_h <= << signal .pld_top_tb.rtl_gen.uut.i_nSysReset : std_logic >>;
i_AD_DATA_h <= << signal .pld_top_tb.rtl_gen.uut.i_a2dif.i_AD_Data : std_logic_vector(11 downto 0) >>;
end generate rtl_sig_gen;
rtl_gen: if not g1_g and not g2_g generate
uut: PLD_TOP
port map (
signal1 => ...,
signal2 => ...,
signal3 => ...
);
end generate rtl_gen;
VHDL requires that an object be elaborated before an external name is used to reference it. VHDL elaborates designs in textual order.
It should be sufficient to reverse the order of your generate statements.
rtl_gen: if not g1_g and not g2_g generate
uut: PLD_TOP
port map (
signal1 => ...,
signal2 => ...,
signal3 => ...
);
end generate rtl_gen;
rtl_sig_gen: if not g1_g and not g2_g generate
i_nSysReset_h <= << signal .pld_top_tb.rtl_gen.uut.i_nSysReset : std_logic >>;
i_AD_DATA_h <= << signal .pld_top_tb.rtl_gen.uut.i_a2dif.i_AD_Data : std_logic_vector(11 downto 0) >>;
end generate rtl_sig_gen;
If we take @Tricky suggestion in the comments above, this can be simplified to the following. Note the range constraint on std_logic_vector is also not required:
rtl_gen: if not g1_g and not g2_g generate
uut: PLD_TOP
port map (
signal1 => ...,
signal2 => ...,
signal3 => ...
);
i_nSysReset_h <= << signal uut.i_nSysReset : std_logic >>;
i_AD_DATA_h <= << signal uut.i_a2dif.i_AD_Data : std_logic_vector>>;
end generate rtl_gen;