Как указать целочисленный массив как общий в VHDL?

Я пытаюсь создать универсальный драйвер для расширителя ввода-вывода на основе SPI. Идея состоит в том, чтобы передать значения инициализации в экземпляре, который соответствует запрошенной настройке ввода-вывода.

Моя текущая попытка выглядит так:

entity max7301_simple is
   generic ( 
        IO_cfg : array (1 to 7) OF integer range 0 to 255 := (16#55#, 16#55#, 16#55#, 16#55#, 16#55#, 16#55#, 16#55#)
           );
     port  (
        -- Application interface :
        clk_i       :   in std_logic;        -- input clock, xx MHz.
        rst_i       :   in std_logic;        -- sync reset.
        en_i        :   in std_logic;        -- enable, forces re-init of pins on MAX7301.
        output_i    :   in std_logic_vector(27 downto 0);   --data to write to output pins on MAX7301
        irq_o       :   out std_logic;       -- IRQ, TODO: what triggers, change on inputs ?
        input_o     :   out std_logic_vector(27 downto 0);  --data read from input pins on MAX7301
        -- MAX7301 SPI interface
        sclk        :   out std_logic;        -- SPI clock
        din         :   in std_logic;        -- SPI data input
        dout        :   out std_logic;       -- SPI read data
        cs          :   out std_logic        -- SPI chip select
    );
end max7301_simple;

Проблема связана с массивом IO_cfg, я пробовал разные попытки с значениями инициализации w/wo и т. д. И не могу понять, как указать массив.

Я полагаю, что читал, что вы можете передать массив как общий, но все еще не повезло с этим. Xilinx ISE просто сообщает med «синтаксическая ошибка рядом с« массивом »», что недостаточно информативно, чтобы продвинуть меня вперед.

Любая помощь будет оценена

Мне всегда нужно 7 значений при создании экземпляра этого модуля.


person opprud    schedule 03.08.2012    source источник


Ответы (3)


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

Вы должны сначала объявить свой целочисленный тип массива в отдельном пакете (который может быть в том же файле или в отдельном), а затем use пакет в вашей сущности и при его создании.

Вот пример того, как вы можете это сделать:

-- package declaration
package mytypes_pkg is

     type my_array_t is array (1 to 7) of integer range 0 to 255;

end package mytypes_pkg;

-- entity "uses" the package   
use work.mytypes_pkg.all;

entity max7301_simple is
   generic ( 
        IO_cfg : my_array_t := (16#55#, 16#55#, 16#55#, 16#55#, 16#55#, 16#55#, 16#55#)
           );
   -- ports [...]
end max7301_simple;

Будьте осторожны, чтобы также useпакет в архитектуре, который создает экземпляр вашей сущности.


(Необязательное чтение)

Почему на самом деле это синтаксическая ошибка, если написать так, как вы?

Глядя на грамматику VHDL в VHDL (2002), объявление каждого универсального параметра является interface_constant_declaration, и у вас есть следующие правила грамматики:

[§ 4.3.2]
interface_constant_declaration ::=  
            [ constant ] identifier_list : [ in ] subtype_indication [ := static_expression ]

[§ 4.2]
subtype_indication ::= 
            [ resolution_function_name ] type_mark [ constraint ]

Ссылка на тип может быть только именем существующего типа (type_mark) или ограничением существующего типа.

person wap26    schedule 03.08.2012

Я предлагаю немного более общий подход с использованием стандартных и предопределенных атрибутов 2008 VHDL — это позволяет передавать массив любой длины. Определите свой тип в своем пакете следующим образом:

package data_types is
    type array_of_integers is array(natural range <>) of integer;
end package;

Теперь в вашем коде передайте общий массив следующим образом:

generic(
    COEFFICIENTS : array_of_integers := (-1, 0, 1)
);

Теперь программное обеспечение будет использовать схему индексации по умолчанию. Это можно учесть с помощью предопределенного атрибута 'left (ссылку можно найти по адресу: http://www.csee.umbc.edu/portal/help/VHDL/attribute.html):

-- First coefficient
    ... <= COEFFICIENTS(COEFFICIENTS'left);
-- Second coefficient
    ... <= COEFFICIENTS(COEFFICIENTS'left + 1);

Как правило, вы должны использовать этот массив в каком-либо операторе loop или generate:

GENERATE_STATEMENT: for entry in 0 to COEFFICIENTS'length-1 generate
    out(entry) <= std_logic_vector(to_signed(COEFFICIENTS(COEFFICIENTS'left + entry), out(entry)'length));
end generate;

Небольшое замечание для пользователей Quartus II: в файлах схем .bdf также можно использовать общие массивы. Установите тип параметра на Авто и перепишите значение параметра в этом формате - A(D"-1", D"0", D"1"), где D означает десятичный тип данных (полезная ссылка: http://quartushelp.altera.com/14.0/mergedProjects/assign/asd/asd_tab_param.htm)

person teaholic    schedule 29.08.2016

Если вы не возражаете против менее ограниченного универсального, вы можете сделать:

generic (IO_cfg : integer_vector);

Пока у вас есть компилятор VHDL-2008.

person Martin Thompson    schedule 06.08.2012
comment
Действительно, VHDL-2008 определяет тип массива (естественный диапазон) для логических , целые, вещественные и временные типы. Однако поддержка VHDL-2008 по-прежнему очень ограничена, по крайней мере, в инструментах, которые я использую (ModelSim, QuartusII). - person wap26; 07.08.2012
comment
@ wap26: очень ограниченный — это немного сильно. Сейчас MOdelsim поддерживает большинство из них, Aldex поддерживает все. Altera и Xilinx поддерживают довольно большой объем. Генераторы типов/пакетов кажутся худшим аспектом. integer_vector поддерживается в режиме 2008 для всех инструментов, о которых я знаю. - person Martin Thompson; 07.08.2012
comment
хорошо, спасибо за свежие новости. Я проверю последнюю версию своих инструментов! - person wap26; 08.08.2012