我目前正在使用三种不同大小(128,192和256位)的密钥进行AES加密。
我想知道我是否可以声明/使用可变大小的std_logic_vector
?例如,我可以只有一个输入端口,我知道它是128,192,还是基于用户输入的256位?
否则如果我选择最大密钥长度(256位),我可以为std_logic_vector
分配128或192位密钥吗?或者会出现错误信息?
答案 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
约束数组范围。