Перейти к содержанию
    

VHDL. Массив входных шин.

Хочу сделать генерик

вместо

entity S_SPI_REG is
    generic
    (
        DATA_WIDTH    : integer := 8;
     );
    port
    (        
        DATA1_IN : in std_logic_vector(DATA_WIDTH-1 downto 0);
        DATA2_IN : in std_logic_vector(DATA_WIDTH-1 downto 0);
        DATA3_IN : in std_logic_vector(DATA_WIDTH-1 downto 0);
        DATA4_IN : in std_logic_vector(DATA_WIDTH-1 downto 0);
        
        );
end S_SPI_REG;

что то вроде

entity S_SPI_REG is
    generic
    (
        DATA_WIDTH    : integer := 8;
        CHANNELS : integer := 4
   );
    port
    (        
        DATA_IN : in array (0 to CHANNELS) of std_logic_vector(DATA_WIDTH-1 downto 0);                  
    );
end S_SPI_REG;

но на array компайлер ругается. можно это как то сделать?

Изменено пользователем Jenya7

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

entity S_SPI_REG is
    generic
    (
        DATA_WIDTH    : integer := 8;
        CHANNELS : integer := 4
   );
    port
    (        
        DATA_IN : in std_logic_vector(DATA_WIDTH * CHANNELS - 1 downto 0);                  
    );
end S_SPI_REG;

а если так?

 

UPD: ну а если всё-таки дальше захотите видеть массив из векторов -- объявите тип в модуле, через generate раскидайте один большой вектор по массиву векторов.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

entity S_SPI_REG is
    generic
    (
        DATA_WIDTH    : integer := 8;
        CHANNELS : integer := 4
   );
    port
    (        
        DATA_IN : in std_logic_vector(DATA_WIDTH * CHANNELS - 1 downto 0);                  
    );
end S_SPI_REG;

 

а если так?

так можно. правда надо следить за границами шин. дополнительная математика.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

так можно. правда надо следить за границами шин. дополнительная математика.

это же HDL. тут такие конструкции приходится иногда заворачивать, что порой не поймёшь: плакать или смеяться. А математика -- это для синтезатора какие-нибудь лишние микросекунды.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

DATA_IN : in std_logic_vector(DATA_WIDTH * CHANNELS - 1 downto 0);

И последняя сгенерированная шина будет 32-разрядной.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

это же HDL. тут такие конструкции приходится иногда заворачивать, что порой не поймёшь: плакать или смеяться. А математика -- это для синтезатора какие-нибудь лишние микросекунды.

да но в первом случае я могу записать

 my_signal <= DATA2_IN(5 downto 3);

в случае DATA_WIDTH * CHANNELS на каждую запись надо вычислять индекс.

Изменено пользователем Jenya7

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

да но в первом случае я могу записать

 my_signal <= DATA2_IN(5 downto 3);

в случае DATA_WIDTH * CHANNELS на каждую запись надо вычислять индекс.

не обязательно на каждую. можно сделать как-то так:

 

entity S_SPI_REG is
    generic(
        DATA_WIDTH : integer := 8;
        CHANNELS : integer := 4
    );
    port(
        DATA_IN : in std_logic_vector(DATA_WIDTH * CHANNELS - 1 downto 0);
        MY_SIGNAL_OUT : out std_logic_vector(2 downto 0)
    );
end S_SPI_REG;

architecture RTL of S_SPI_REG is
    -- эта конструкция работает на "любых" параметрах без изменений кода.
    type TData is array(0 to CHANNELS - 1) of std_logic_vector(DATA_WIDTH - 1 downto 0);
    -- и эта...
    signal data : TData := (others => (others => 'X'));
begin

    -- и даже эта. пишется один раз и забывается.
    lbl_data_conv : for i in 0 to CHANNELS - 1 generate begin
        data(i) <= DATA_IN(DATA_WIDTH * (i + 1) - 1 downto DATA_WIDTH * i);
    end generate;

    -- а тут всё как и планировалось, ничего не надо "вычислять"
    MY_SIGNAL_OUT <= data(2)(5 downto 3);

end RTL;

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

не обязательно на каждую. можно сделать как-то так:

 

entity S_SPI_REG is
    generic(
        DATA_WIDTH : integer := 8;
        CHANNELS : integer := 4
    );
    port(
        DATA_IN : in std_logic_vector(DATA_WIDTH * CHANNELS - 1 downto 0);
        MY_SIGNAL_OUT : out std_logic_vector(2 downto 0)
    );
end S_SPI_REG;

architecture RTL of S_SPI_REG is
    -- эта конструкция работает на "любых" параметрах без изменений кода.
    type TData is array(0 to CHANNELS - 1) of std_logic_vector(DATA_WIDTH - 1 downto 0);
    -- и эта...
    signal data : TData := (others => (others => 'X'));
begin

    -- и даже эта. пишется один раз и забывается.
    lbl_data_conv : for i in 0 to CHANNELS - 1 generate begin
        data(i) <= DATA_IN(DATA_WIDTH * (i + 1) - 1 downto DATA_WIDTH * i);
    end generate;

    -- а тут всё как и планировалось, ничего не надо "вычислять"
    MY_SIGNAL_OUT <= data(2)(5 downto 3);

end RTL;

как много нам открытий чудных... спасибо. :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

     -- и даже эта. пишется один раз и забывается.
     lbl_data_conv : for i in 0 to CHANNELS - 1 generate begin
         data(i) <= DATA_IN(DATA_WIDTH * (i + 1) - 1 downto DATA_WIDTH * i);
     end generate;

В таких случаях я предпочитаю процесс:

process (DATA_IN)
    for i in 0 to CHANNELS - 1 loop
         data(i) <= DATA_IN(DATA_WIDTH * (i + 1) - 1 downto DATA_WIDTH * i);
     end loop;
end process;

generate попрождает ещё один уровень иерархии, и с ним неудобно работать в симуляторе.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Если ваши синтезатор/симулятор поддерживают VHDL-2008, то в отдельном package вы можете объявить unconstrained array:

type array_t is array(integer range <>) of std_logic_vector;

И в своем модуле объявить порт следующим образом:

DATA_IN        : in array_t(0 to CHANNELS-1)(DATA_WIDTH-1 downto 0);

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Если ваши синтезатор/симулятор поддерживают VHDL-2008, то в отдельном package вы можете объявить unconstrained array:

type array_t is array(integer range <>) of std_logic_vector;

И в своем модуле объявить порт следующим образом:

DATA_IN        : in array_t(0 to CHANNELS-1)(DATA_WIDTH-1 downto 0);

я понял. спасибо. в квартусе по моему есть галка для VHDL-2008.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...