VHDL 克服最大整数限制

VHDL overcome maximum integer limit

我有一个通用值 X,它可以超过最大正整数限制 2147483647。我在实体声明的通用部分得到它:

X : integer := 3000000000;
Y : integer := 128; -- maximum 1024 (11 bits)
Z : integer := 1000 -- maximum 65535 (16 bits)

但是,在体系结构中并没有直接使用 X,而是使用了一个名为 C 的常量。我通过以下方式定义架构中的常量:

constant C : unsigned(63 downto 0) := to_unsigned ( (X / Y) / 1000 * Z, 64);

但是因为X可以超过整数限制,这个方案不可行。因此,我决定在实体声明中使用 unsigned(我正在使用 ieee.numeric_std 库),例如:

X : unsigned(63 downto 0) := x"00000000B2D05E00"; -- equivalent of 3000000000d
Y : integer := 128; -- maximum 1024 (11 bits)
Z : integer := 1000 -- maximum 65535 (16 bits)

然后,计算常量:

constant C : unsigned(63 downto 0) := ((X / to_unsigned(Y, 11)) / to_unsigned(1000,10) * to_unsigned(Z, 21));

我选择Z的长度为21,因为Y和1000d的总长度为21(10+11)。

但是,Vivado 给我一个错误“分配的 rhs 和 lhs 中的数组大小不匹配。”

我该如何克服这种情况?解决它的正确方法是什么?我的方法可能不正确,我对任何方法都持开放态度。

谢谢。

Vivado 是正确的 - 尺寸不匹配。 "/" 函数的结果 returns 左操作数的长度。所以在这里,你有

(X / to_unsigned(Y, 11)

其中 returns 64 位结果

/ to_unsigned(1000,10)

returns 另一个 64 位结果。最后:

* to_unsigned(Z, 21));

是一个64位的值*21位,给出一个85位的数。 您需要使用调整大小函数将结果调整为 64 位:

resize(result, X'length);

除断言警告外,此函数不检查溢出,您需要确保永远不会溢出 64 位数字。

鉴于您为 Z 指定的值范围并假设 Y=1 的最小值,我认为您将不得不使用 real 然后将其分解为整数大小的块,因为 to_unsigned() 需要一个整数。如果您的值适合 64 位,这实际上使用 mod 运算符非常容易。

    constant x : real := 300000000.0; -- no constraints provided
    constant y : real := 1.0;         -- assumed minimum
    constant z : real := 65535.0;     -- stated maximum
    constant c_real : real := x/y/1000.0*z;  -- 19660500000.0  

    constant lower32 : unsigned(31 downto 0) := to_unsigned(integer(c_real mod 2.0**31), 32);
    constant upper32 : unsigned(31 downto 0) := to_unsigned(integer(c_real / 2**31), 32);
    
    signal counter : unsigned(63 downto 0) := shift_left(resize(upper32, 64), 31) + lower32;