Реализовать реализацию карты в VHDL - PullRequest
0 голосов
/ 10 декабря 2018

В своем дизайне я пытаюсь создать карту регистров, которая может гибко использоваться отдельными компонентами.Например, допустим, я создаю следующий тип карты регистров:

package regmap_package is

    type regmap_t is array(natural range <>) of std_logic_vector(7 downto 0);

end package regmap_package;

Так что это будет моя карта регистров с количеством x 8-битных регистров.Затем в моем верхнем объекте я объявляю общий размер карты регистров:

signal regs : regmap_t(0 to 15);

Так что в этом примере у меня будет 16 x 8-битная карта регистров.Вот моя проблема: допустим, я хочу создать несколько подкомпонентов.Каждому из этих компонентов потребуется только некоторая часть этих регистров для работы.

Например, компоненту 1 потребуется регистр с адреса 0 по адрес 7, а компонентам 2 - с адреса 8 по адрес 15. Как быкак выглядит объявление сущности для такого компонента и как передать ему часть целого массива регистров?Будут ли компоненты работать по своим собственным схемам локальной адресации (от 0 до 7 каждая)?

1 Ответ

0 голосов
/ 10 декабря 2018

Вы можете использовать перечисление для объявления имен регистров:

type RegisterNames is (Command, Status, VendorID, DeviceID, Error);

Теперь вы можете создать свою карту регистров:

type RegisterType is array(RegisterNames range <>) of std_logic_vector(7 downto 0);

Используя range <>, вы можете создать любой диапазонэтого типа.

Отсюда вы можете создать свою карту регистров:

signal RegisterMap : RegisterType(RegisterNames);

Вы можете нарезать эту карту регистров следующим образом:

signal SubRegisters : RegisterType(VendorID to DeviceID);
SubRegister <= RegisterMap(SubRegister'range);

Ответы на комментарии

Можно ли создать пакет с глобальными метками, доступными для использования в качестве индексов?

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

К сожалению, в VHDL-2008 сломана поддержка неполных универсальных типов.Вы можете передать тип перечисления в пакет, а затем передать этот экземплярный экземпляр в сущность, реализующую универсальный интерфейс регистра, например, для AXI4 Lite, но этот универсальный тип поставляется без операций.Таким образом, у вас нет операторов и атрибутов общего типа.

Как это будет выглядеть?

package GenericRegisterPackage is
  generic (
    constant ShortName        : string;   -- e.g. PWM
    type     RegisterNames;
    constant AXI4_AddressBits : positive;
    constant AXI4_DataBits    : positive
  );

  subtype RegisterType is std_logic_vector(AXI4_DataBits - 1 downto 0);

  -- THE FOLLOWING LINE IS NOT SUPPORTED in VHDL-2008
  type    RegisterFile is array(RegisterNames range <>) of RegisterType;

end package;

entity GenericAXI4LiteRegister is
  generic (
    package GenericRegisterPackage
  );
  port (
    Clock : in std_logic;
    -- ...
  );
end entity;

Использование:

architecture rtl of Controller is
  type RegisterNames is (Command, Status, Error, Frequency);

  package RegisterPackage is new work.GenericAXI4LiteRegister
    generic map (
      ShortName        => "PWM Controller",
      RegisterNames    => RegisterNames,
      AXI4_AddressBits => 8,
      AXI4_DataBits    => 32
    );
begin
  reg: entity work.GenericAXI4LiteRegister
    generic map (
      GenericRegisterPackage => RegisterPackage
    )
    port map (
      Clock => Clock,
      -- ...
    );
end architecture;

Это неправильное представление о VHDL-2008 будет исправлено в VHDL-2018.Следующая строка из неполного универсального типа пакета:

type RegisterNames;

станет такой:

type RegisterNames is ();

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

Кроме того, возможна ли здесь конкретная настройка индекса (натуральное число)?

Да, выможет преобразовывать литералы перечисления в индексы.Каждый дискретный тип (включая перечисления) имеет номера позиций для всех своих значений.

constant position : natural := RegisterNames'pos(VendorID);

вернет 2.Позиции начинаются с 0 для самого левого литерала перечисления в объявлении.Каждый следующий литерал справа получает позиции, увеличенные на 1.

Операция обратного преобразования от номера позиции (натурального) к литералу перечисления с атрибутом 'val(5), который возвращает Error.

...