在 VHDL 中注册映射实现
Register map implementation in VHDL
在我的设计中,我试图创建一个寄存器映射,它可以被不同的组件以灵活的方式使用。例如,假设我创建了以下寄存器映射类型:
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 的寄存器,而 components 2 需要从地址 8 到地址 15 的寄存器。这样的组件的实体声明是什么样的以及如何传递整个寄存器的一部分阵地呢?这些组件会根据自己的本地寻址方案(每个从 0 到 7)运行吗?
您可以使用枚举来声明寄存器名称:
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);
回复评论
Can a package be created with the global labels available to be used as indexes?
是的,您可以在包中定义描述的枚举类型。因此,寄存器名称和寄存器类型本身可用作端口和更高级别的实体。
不幸的是,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 ();
...表示,它是一个枚举类型。因此,它是一种离散类型,可以用作数组中的索引。
Also, is specific index setting (natural number) possible here?
是的,您可以将枚举文字转换为索引。每个离散类型(包括枚举)都有其所有值的位置编号。
constant position : natural := RegisterNames'pos(VendorID);
将 return 2
。对于声明中最左侧的枚举文字,位置从 0 开始。右边的每个后续文字的位置都会增加 1。
从位置编号(自然)到枚举文字的反向操作它是属性 'val(5)
,其中 returns Error
.
在我的设计中,我试图创建一个寄存器映射,它可以被不同的组件以灵活的方式使用。例如,假设我创建了以下寄存器映射类型:
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 的寄存器,而 components 2 需要从地址 8 到地址 15 的寄存器。这样的组件的实体声明是什么样的以及如何传递整个寄存器的一部分阵地呢?这些组件会根据自己的本地寻址方案(每个从 0 到 7)运行吗?
您可以使用枚举来声明寄存器名称:
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);
回复评论
Can a package be created with the global labels available to be used as indexes?
是的,您可以在包中定义描述的枚举类型。因此,寄存器名称和寄存器类型本身可用作端口和更高级别的实体。
不幸的是,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 ();
...表示,它是一个枚举类型。因此,它是一种离散类型,可以用作数组中的索引。
Also, is specific index setting (natural number) possible here?
是的,您可以将枚举文字转换为索引。每个离散类型(包括枚举)都有其所有值的位置编号。
constant position : natural := RegisterNames'pos(VendorID);
将 return 2
。对于声明中最左侧的枚举文字,位置从 0 开始。右边的每个后续文字的位置都会增加 1。
从位置编号(自然)到枚举文字的反向操作它是属性 'val(5)
,其中 returns Error
.