在我的设计中,我试图创建一个寄存器映射,可以由单独的组件灵活地使用它。例如,假设我创建了以下寄存器映射类型:
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位寄存器映射。我的问题来了:假设我要创建一些子组件。每个组件只需要这些寄存器的一部分即可使用。
例如,component1需要从地址0到地址7的寄存器,而component 2则需要从地址8到地址15的寄存器。该组件的实体声明如何,以及如何将整个寄存器数组的部分传递给它?这些组件是否可以按自己的本地寻址方案(每个从0到7)运行?
答案 0 :(得分:4)
您可以使用枚举来声明寄存器名称:
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
。