如何在C ++和VHDL中对大于64位的整数执行乘法?

时间:2019-05-05 13:17:02

标签: c++ vhdl

我想将57位整数与11位整数相乘。结果最多可以是68位,因此我打算将结果分成2个不同的整数。我不能使用任何库,它应该尽可能简单,因为代码将转换为VHDL。

有一些方法可以上网,但所有这些都不符合我的标准。我想将结果分成60位的较低部分和8位的较高部分。

C ++

int main() {
    unsigned long long int log2 = 0b101100010111001000010111111101111101000111001111011110011;
    unsigned short int absE;
    unsigned in result_M;
    unsigned long long int result_L;

    result_L = absE * log2;
    result_M = 0;
}

VHDL

signal absE : std_logic_vector(10 downto 0);
signal log2 : std_logic_vector(57 downto 0) := "101100010111001000010111111101111101000111001111011110011";
signal result: std_logic_vector(67 downto 0);
result <= absE * log2;

3 个答案:

答案 0 :(得分:1)

您可以将57位的值拆分为较小的块以执行乘法,然后重新组合为所需的部分,例如8 + 49位:

#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>

int main() {
#define MASK(n)  ((1ULL << (n)) - 1)
    uint64_t log2 = MASK(57);                     // 57 bits
    uint16_t absE = MASK(11);                     // 11 bits
    uint32_t m1 = (log2 >> 49) * absE;            // middle 19 bits at offset 49;
    uint64_t m0 = (log2 & MASK(49)) * absE + ((m1 & MASK(11)) << 49); // low 61 bits
    uint16_t result_H = (uint16_t)(m1 >> 11) + (uint16_t)(m0 >> 60); // final high 8 bits
    uint64_t result_L = m0 & MASK(60);

    printf("%#"PRIx64" * %#"PRIx16" = %#"PRIx16"%012"PRIx64"\n",
           log2, absE, result_H, result_L);
    return 0;
}

输出:0x1ffffffffffffff * 0x7ff = 0xffdfffffffffff801

如果无法使用用于49位乘11位步进的64位乘法,则可能需要更多的步骤。

答案 1 :(得分:0)

VHDL与C不同-在这里,您可以了解如何实现乘法。将其扩展为所需的位数:

https://docs.pipenv.org/en/latest/advanced/#configuration-with-environment-variables

答案 2 :(得分:0)

在海湾合作委员会中:

__int128 a;
__int128 b;
__int128 c;
uint64_t c_lo;
uint8_t c_hi;

a = 0x789;
b = 0x123456789ABCDEF;
c = a * b;

c_lo = (uint64_t)c & ((UINT64_C(1) << 60) - 1);
c_hi = (unsigned __int128)c >> 60;

您将需要标准库。您将需要头文件<stdint.h>(在C ++中为<cstdint>),但这在转换为VHDL时不会有问题。