vhdl中的变量std_logic_vector或数组条目

时间:2016-05-10 00:08:45

标签: aes vhdl

我目前正在使用三种不同大小(128,192和256位)的密钥进行AES加密。

我想知道我是否可以声明/使用可变大小的std_logic_vector?例如,我可以只有一个输入端口,我知道它是128,192,还是基于用户输入的256位?

否则如果我选择最大密钥长度(256位),我可以为std_logic_vector分配128或192位密钥吗?或者会出现错误信息?

1 个答案:

答案 0 :(得分:0)

如果密钥大小在运行时更改,则必须声明 与之对应的对象(信号,常量,变量) 最大可能尺寸。然后,实际密钥长度将由另一个密钥长度定义 信号或变量。最大尺寸可以定义如下。

如果声明具有最大可能大小的std_logic_vector类型的对象,则分配较短的std_logic_vector将导致错误。您必须首先将赋值的右侧扩展到目标对象的大小,例如,使用PoC Library中的以下resize函数,我是其中一位作者:

function resize(vec : std_logic_vector; length : natural; fill : std_logic := '0') return std_logic_vector is
constant  high2b : natural := vec'low+length-1;
    constant  highcp : natural := imin(vec'high, high2b);
variable  res_up : std_logic_vector(vec'low to high2b);
variable  res_dn : std_logic_vector(high2b downto vec'low);
begin
if vec'ascending then
  res_up := (others => fill);
  res_up(vec'low to highcp) := vec(vec'low to highcp);
  return  res_up;
else
  res_dn := (others => fill);
  res_dn(highcp downto vec'low) := vec(highcp downto vec'low);
  return  res_dn;
    end if;
end function;

例如,给定一个名为std_logic_vector的128位source,可以通过以下方式将其重新调整为256位:

resize(source, 256) -- returns a 256-bit std_logic_vector

该功能与resize上的unsigned功能和signed包中的numeric_std类似。

如果在编译(elaboraton)时知道密钥大小,那么你会 有两种选择。通常的方法是通过a定义密钥大小 常量并通过泛型将键大小传递给子组件。 以下实体test具有指定密钥的通用SIZE 尺寸。现在可以定义端口以及其他对象的长度 取决于这个通用。

library ieee;
use ieee.std_logic_1164.all;

entity test is
  generic (
    SIZE : positive := 128); -- the default value can be omitted
  port (
    x : in  std_logic_vector(SIZE-1 downto 0);
    y : out std_logic_vector(SIZE-1 downto 0));
end entity test;

architecture rtl of test is
begin  -- architecture rtl
  y <= not x;
end architecture rtl;

现在可以在实体的实例化期间绑定泛型, 例如:

library ieee;
use ieee.std_logic_1164.all;

entity test_tb is
end entity test_tb;

architecture rtl of test_tb is
  constant SIZE : positive := 192;
  signal x : std_logic_vector(SIZE-1 downto 0) := (others => '0');
  signal y : std_logic_vector(SIZE-1 downto 0);
begin  -- architecture rtl

  dut: entity work.test
    generic map (
      SIZE => SIZE)
    port map (
      x => x,
      y => y);

end architecture rtl;

当然,实际的长度(端口图中的右侧)必须 匹配正式的长度(端口映射中的左侧)。这种方法 得到所有(主要)VHDL综合工具的支持。如果是默认值 对于泛型存在,则test可以直接合成为 顶级模块。

第二个选项,对于精心制作期间的固定键大小,将是 在端口中使用无约束数组(std_logic_vector) 实体的声明。数组的实际大小可以是 用length属性确定,用实际范围确定 range属性,例如:

library ieee;
use ieee.std_logic_1164.all;

entity test2 is
  port (
    x : in  std_logic_vector;
    y : out std_logic_vector);
end entity test2;

architecture rtl of test2 is
  signal z : std_logic_vector(x'range);
begin  -- architecture rtl
  z <= x;
  y <= not z;

  assert false report "x'length=" & integer'image(x'length) severity note;
end architecture rtl;

然后是端口信号的范围(和长度) 由组件实例化中的关联实际约束。

library ieee;
use ieee.std_logic_1164.all;

entity test2_tb is
end entity test2_tb;

architecture rtl of test2_tb is
  constant SIZE : positive := 192;
  signal x : std_logic_vector(SIZE-1 downto 0) := (others => '0');
  signal y : std_logic_vector(SIZE-1 downto 0);
begin  -- architecture rtl

  dut: entity work.test2
    port map (
      x => x,
      y => y);

end architecture rtl;

这适用于模拟。但是,我不确定它是否得到了支持 (主要)VHDL综合工具。当然,合成test2 需要另一个顶级实体来实例化test2 约束数组范围。