在VHDL中注册地图实现

Bre*_*men 0 arrays vhdl

在我的设计中,我试图创建一个寄存器映射,可以由单独的组件灵活地使用它。例如,假设我创建了以下寄存器映射类型:

package regmap_package is

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

end package regmap_package;
Run Code Online (Sandbox Code Playgroud)

因此,这将是我的寄存器映射,其中包含x个8位寄存器。然后在我的顶级实体中声明寄存器映射的总大小:

signal regs : regmap_t(0 to 15);
Run Code Online (Sandbox Code Playgroud)

因此,在此示例中,我将具有16 x 8位寄存器映射。我的问题来了:假设我要创建一些子组件。每个组件仅需要这些寄存器的一部分即可进行操作。

例如,component1需要从地址0到地址7的寄存器,而component 2则需要从地址8到地址15的寄存器。该组件的实体声明如何,以及如何将整个寄存器数组的一部分传递给它?这些组件是否将根据自己的本地寻址方案(每个从0到7)运行?

Pae*_*els 5

您可以使用枚举来声明寄存器名称:

type RegisterNames is (Command, Status, VendorID, DeviceID, Error);
Run Code Online (Sandbox Code Playgroud)

现在您可以创建您的注册图:

type RegisterType is array(RegisterNames range <>) of std_logic_vector(7 downto 0);
Run Code Online (Sandbox Code Playgroud)

通过使用range <>,您可以创建该类型的任何范围。

从这里您可以生成您的注册图:

signal RegisterMap : RegisterType(RegisterNames);
Run Code Online (Sandbox Code Playgroud)

您可以按如下方式对该寄存器映射进行切片:

signal SubRegisters : RegisterType(VendorID to DeviceID);
SubRegister <= RegisterMap(SubRegister'range);
Run Code Online (Sandbox Code Playgroud)

评论的答案

可以使用全局标签创建可用于索引的包吗?

是的,您可以在包中定义描述的枚举类型。因此,寄存器名称和寄存器类型本身可用作端口和更高级别的实体。

不幸的是,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;
Run Code Online (Sandbox Code Playgroud)

用法:

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;
Run Code Online (Sandbox Code Playgroud)

对VHDL-2008的这种误解将在VHDL-2018中修复。包不完整的泛型类型的以下行:

type RegisterNames;
Run Code Online (Sandbox Code Playgroud)

会变成这样:

type RegisterNames is ();
Run Code Online (Sandbox Code Playgroud)

...表示它是一种枚举类型。因此,它是离散类型,可以用作数组中的索引。

另外,是否可以在此处进行特定的索引设置(自然数)?

是的,您可以将枚举文字转换为索引。每个离散类型(包括枚举)的所有值都有位置编号。

constant position : natural := RegisterNames'pos(VendorID);
Run Code Online (Sandbox Code Playgroud)

会回来的2。对于声明中最左侧的枚举文字,位置从0开始。右边的每个后续文字都会得到一个加1的位置。

从位置编号(自然)到属性枚举文字的反向操作,该属性'val(5)返回Error