Author Topic: Error when trying to refer to components generated by "for .. generate" loop VHD  (Read 3303 times)

0 Members and 2 Guests are viewing this topic.

Offline FlyingDutchTopic starter

  • Regular Contributor
  • *
  • Posts: 147
  • Country: pl
Hello, forum

I 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: [Select]
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
library work;
use work.all;
--use work.LAT_Channel;

entity top_TSN is
     generic (
          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 sygnal
           GSM_t   : out std_logic;      -- generator sygbalu migowego: jeden sygnal
           HL_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 V
           BUCZEK : out std_logic;         -- Alarm globalny logic: 12 V
           TEST_LED_t : std_logic;        -- test LED (active Low)
           uart_tx : out std_logic;       -- UART Tx output - do rejestratora staku
           btn1    : in std_logic         -- tylko do testow
          );
end top_TSN;

architecture Behavioral of top_TSN is

  component LAT_Channel
        port (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 GSM
       generic (
            NBit : natural := 32;
            Div : natural := 13000000
         );
       Port ( clk : in  STD_LOGIC;
              clk_out : inout  STD_LOGIC);
  end component;

component uart
       generic (
            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 Low
  signal 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');

begin

    Port_UART : uart
      generic 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 : GSM
      generic map(
        NBit => 32,
        Div => 13000000
        )
      port map (clk   => clk_t,
                clk_out => sw_mig
               );
                 
    MY_GEN : for i in 0 to NCH - 1 generate
 
    channel: entity work.LAT_Channel(Behavioral)
    port map (
              clk   => clk_t,
              reset => rst_t,
              CH_ON => not CH_ON_t(i),  --Active 1
              CL    => not CL_t(i),     --Active 0
              KSM   => 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 globalnego
    sum_alarms : process (clk_t, CL_t)
      variable alarm_g : std_logic;
    begin
      alarm_g := '0';
      l_sum : for k in 0 to NCH - 1 loop
      if CH_ON_t(k) = '0' then
         alarm_g := alarm_g or (CL_t(k));
      end if;
      end loop l_sum;
      if TEST_LED_t = '1' then
        ALARM_GLOB <= '1';
      else
        ALARM_GLOB <= alarm_g;
      end if;
    end process sum_alarms;


    kas_alarm: process (KSM_t)
    begin
      if KSM_t = '0' then
        bylo_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';
     begin
      was_alarm := '0';

      l_01 : for k in 0 to NCH - 1 loop
      if CH_ON_t(k) = '0' then
        was_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 statku
    trig_uart : process (clk_t)
    begin
       if rising_edge(clk_t) then
          clockCounter <= clockCounter + 1;
          if (clockCounter > TRIGGER_TIME) and (clockCounter < TRIGGER_TIME+20) then
            triggerUART <= '0';
          else
             triggerUART <= '0';
          end if;
          if clockCounter > TRIGGER_TIME+20 then
             clockCounter <= (others => '0');
          end if;
       end if;
    end process trig_uart;

end Behavioral;
The instantiated components ports are
Code: [Select]
entity LAT_Channel is
    Port ( 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: [Select]
MY_GEN : for i in 0 to NCH - 1 generate
 
    channel: entity work.LAT_Channel(Behavioral)
    port map (
              clk   => clk_t,
              reset => rst_t,
              CH_ON => not CH_ON_t(i),  --Active 1
              CL    => not CL_t(i),     --Active 0
              KSM   => 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: [Select]
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

 

Offline FlyingDutchTopic starter

  • Regular Contributor
  • *
  • Posts: 147
  • Country: pl
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:

1828852-0

The components has names: MY_GEN[index].channel

Thanks in advance
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 17810
  • Country: fr
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: [Select]
was_alarm := alarms_LAT(0);
Since this is what the corresponding port is tied to.
 
The following users thanked this post: Someone, FlyingDutch

Online Someone

  • Super Contributor
  • ***
  • Posts: 6080
  • Country: au
    • send complaints here
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.
 
The following users thanked this post: FlyingDutch

Online Someone

  • Super Contributor
  • ***
  • Posts: 6080
  • Country: au
    • send complaints here
special static constructs for external name references:
https://stackoverflow.com/questions/64464051/vhdl-2008-index-in-external-names-containing-generated-instances

Using it for synthesis sounds like the start of spaghetti.
 
The following users thanked this post: FlyingDutch

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 17810
  • Country: fr
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.
 
The following users thanked this post: FlyingDutch


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf

 

-->