Error when trying to refer to components generated by "for .. generate" loop VHD - Page 1
Forum section: electronics / general

author: FlyingDutch
author_rank: Regular Contributor
timestamp: July 16, 2023, 08:47:02 am
content: Hello, forumI write a VHDL project in which I instantiate components by using the "for .. generate" loop. These components work fine (in real hardware), but I have also need to refer to them in process in top entity. I have an error when referring to generated components in process in the top entity of the project.Here is code of my top entity:Code:library IEEE;use IEEE.STD_LOGIC_1164.ALL;library work;use work.all;--use work.LAT_Channel;entity top_TSN isgeneric (NCH : natural := 22 --Liczba kanalow 20);port (clk_t : in std_logic;rst_t : in std_logic;CH_ON_t : in std_logic_vector(NCH -1 downto 0);CL_t : in std_logic_vector(NCH -1 downto 0);KSM_t : in std_logic; -- kasowanie alarmow jeden sygnalGSM_t : out std_logic; -- generator sygbalu migowego: jeden sygnalHL_t : buffer std_logic_vector(NCH -1 downto 0);HAL_t : out std_logic_vector(NCH -1 downto 0);ALARM_GLOB : buffer std_logic; -- Alarm globalny logic: 3,3 VBUCZEK : out std_logic; -- Alarm globalny logic: 12 VTEST_LED_t : std_logic; -- test LED (active Low)uart_tx : out std_logic; -- UART Tx output - do rejestratora stakubtn1 : in std_logic -- tylko do testow);end top_TSN;architecture Behavioral of top_TSN iscomponent LAT_Channelport (clk : in std_logic;reset : in std_logic;CH_ON : in std_logic;CL : in std_logic;KSM : in std_logic;GSM : in std_logic;HL : out std_logic;HAL : out std_logic;TEST_LED : in std_logic;ALARM_CH : buffer STD_LOGIC;ALARM_CH_DEL : buffer STD_LOGIC);end component;component GSMgeneric (NBit : natural := 32;Div : natural := 13000000);Port ( clk : in STD_LOGIC;clk_out : inout STD_LOGIC);end component;component uartgeneric (DELAY_FRAMES : natural := 208;NCH : natural := 20);Port ( clk : in STD_LOGIC;uart_tx : out STD_LOGIC;btn1 : in STD_LOGIC;lanterns : in std_logic_vector(19 downto 0);alarms : in std_logic_vector(19 downto 0));end component;constant TRIGGER_TIME : integer := 24000000;signal sw_mig : std_logic;signal alarm_glob_sig : std_logic := '0';signal j : integer;signal triggerUART : std_logic := '1'; -- active Lowsignal clockCounter : unsigned(28-1 downto 0):= (others => '0');signal bylo_kasowanie_alarmu : std_logic := '0';signal new_alarms : std_logic := '0';signal blokada1 : std_logic := '0';signal alarms_LAT: std_logic_vector(NCH -1 downto 0):= (others => '0');signal alarms_LAT_DEL: std_logic_vector(NCH -1 downto 0):= (others => '0');beginPort_UART : uartgeneric map(DELAY_FRAMES => 208,NCH => 20)port map ( clk => clk_t,uart_tx => uart_tx,btn1 => triggerUART,lanterns => CH_ON_t(19 downto 0),alarms => HL_t(19 downto 0));gen_SM : GSMgeneric map(NBit => 32,Div => 13000000)port map (clk => clk_t,clk_out => sw_mig);MY_GEN : for i in 0 to NCH - 1 generatechannel: entity work.LAT_Channel(Behavioral)port map (clk => clk_t,reset => rst_t,CH_ON => not CH_ON_t(i), --Active 1CL => not CL_t(i), --Active 0KSM => not KSM_t, -- kasowanie alarmow wspolne (Active 1)GSM => sw_mig, -- GSM wspolnywas_alarm := '1';HL => HL_t(i),HAL => HAL_t(i),TEST_LED => not TEST_LED_t, -- test LED wspolny (Active 0)ALARM_CH => alarms_LAT(i),ALARM_CH_DEL => alarms_LAT_DEL(i));end generate;BUCZEK <= (ALARM_GLOB and (not(bylo_kasowanie_alarmu))) or (new_alarms);-- proces: wypracowanie alarmu globalnegosum_alarms : process (clk_t, CL_t)variable alarm_g : std_logic;beginalarm_g := '0';l_sum : for k in 0 to NCH - 1 loopif CH_ON_t(k) = '0' thenalarm_g := alarm_g or (CL_t(k));end if;end loop l_sum;if TEST_LED_t = '1' thenALARM_GLOB <= '1';elseALARM_GLOB <= alarm_g;end if;end process sum_alarms;kas_alarm: process (KSM_t)beginif KSM_t = '0' thenbylo_kasowanie_alarmu <= '1';-- l_01 : for k in 0 to NCH - 1 loop-- if CH_ON_t(k) = '0' then-- old_alarms(k) <= CL_t(k);-- end if;-- end loop l_01;end if;end process kas_alarm;rerun_alarms : process (CL_t(0),CL_t(1),CL_t(2),CL_t(3),CL_t(4),CL_t(5),CL_t(6),CL_t(7),CL_t(8),CL_t(9),CL_t(10),CL_t(11),CL_t(12),CL_t(13),CL_t(14),CL_t(15),CL_t(16),CL_t(17),CL_t(18),CL_t(19))variable was_alarm : std_logic := '0';beginwas_alarm := '0';l_01 : for k in 0 to NCH - 1 loopif CH_ON_t(k) = '0' thenwas_alarm := MY_GEN(0).channel.ALARM_CH;end if;end loop l_01;new_alarms <= was_alarm;end process rerun_alarms;-- proces: trigger do wyslania danych przez UART do rejestratora statkutrig_uart : process (clk_t)beginif rising_edge(clk_t) thenclockCounter <= clockCounter + 1;if (clockCounter > TRIGGER_TIME) and (clockCounter < TRIGGER_TIME+20) thentriggerUART <= '0';elsetriggerUART <= '0';end if;if clockCounter > TRIGGER_TIME+20 thenclockCounter <= (others => '0');end if;end if;end process trig_uart;end Behavioral;The instantiated components ports areCode:entity LAT_Channel isPort ( clk : in STD_LOGIC;reset : in STD_LOGIC;CH_ON : in STD_LOGIC;CL : in STD_LOGIC;KSM : in STD_LOGIC;GSM : in STD_LOGIC;HL : out STD_LOGIC;HAL : out STD_LOGIC;TEST_LED : in STD_LOGIC;ALARM_CH : buffer STD_LOGIC;ALARM_CH_DEL : buffer STD_LOGIC);end LAT_Channel;The "for .. generate" loop code is:Code:MY_GEN : for i in 0 to NCH - 1 generatechannel: entity work.LAT_Channel(Behavioral)port map (clk => clk_t,reset => rst_t,CH_ON => not CH_ON_t(i), --Active 1CL => not CL_t(i), --Active 0KSM => not KSM_t, -- kasowanie alarmow wspolne (Active 1)GSM => sw_mig, -- GSM wspolnywas_alarm := '1';HL => HL_t(i),HAL => HAL_t(i),TEST_LED => not TEST_LED_t, -- test LED wspolny (Active 0)ALARM_CH => alarms_LAT(i),ALARM_CH_DEL => alarms_LAT_DEL(I));end generate;When I am trying to refer to one of the generated components using:Code:was_alarm := MY_GEN(0).channel.ALARM_CH;I have an error:[Synth 8-995] my_gen is illegal in an expression ["/home/bofh/_FPGA_TSN_Proj/Xilinx/TSN_FPGA_22CH_Spartan7/src/top_TSN.vhdl":191]Could somebody give me a clue why this error is generated?Thanks and Regards

author: FlyingDutch
author_rank: Regular Contributor
timestamp: July 16, 2023, 08:49:04 am
content: I forget to tell you: I am using Xilinx Vivado v2019.1 (64-bit) on Linux Mint. What is interesting - I can see components instantiated by "for .. generate" loop in synthesised project (on Schematics) - see screen:The components has names: MY_GEN.channelThanks in advance

author: SiliconWizard
author_rank: Super Contributor
timestamp: July 16, 2023, 08:37:50 pm
content: Well, I'd have to dig into the VHDL standard (2008 and later), but I have never tried to use such an expression and I don't think it's supported at all.The names that are listed in the netlist are not proper VHDL. They are just netlist names.I your case, you're trying a convoluted (yet, as I said, most certainly unsupported) way of doing this:Code:was_alarm := alarms_LAT(0);Since this is what the corresponding port is tied to.

author: Someone
author_rank: Super Contributor
timestamp: July 16, 2023, 10:14:41 pm
content: Sounds like Hierarchical Names from verilog, which were introduced in VHDL 2008 (good luck on vendor support!)Indexing into a loop is by an array structure for verilog:https://www.verilogpro.com/verilog-generate-configurable-rtl/But no idea for VHDL (may be vendor specific?) as it has strict typing so you'd need an array of instances type.

author: Someone
author_rank: Super Contributor
timestamp: July 16, 2023, 10:32:44 pm
content: special static constructs forexternal namereferences:https://stackoverflow.com/questions/64464051/vhdl-2008-index-in-external-names-containing-generated-instancesUsing it for synthesis sounds like the start of spaghetti.

author: SiliconWizard
author_rank: Super Contributor
timestamp: July 17, 2023, 12:52:10 am
content: I'll look into that a bit deeper.While it could have the benefit of being able to access signals internal to entities outside of them (without having to make said signals go through ports) - which I guess could be used for test benches - I don't see the point if you're accessing a *port*, which is already accessible outside of the entity anyway.