Вы можете использовать перечисление для объявления имен регистров:
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
.