Как выполнить умножение для целых чисел больше 64 бит в C ++ и VHDL? - PullRequest
0 голосов
/ 05 мая 2019

Я хочу умножить 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;
}

1008 * 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 ]

1 голос
/ 05 мая 2019

Вы можете разбить 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

Вам может потребоваться больше шагов, если вы не можете использовать 64-битное умножение, используемое для 49-битного на 11-битный шаг.

0 голосов
/ 05 мая 2019

В GCC:

__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> (<cstdint> в C ++), но это не должно быть проблемой при переводе на VHDL.

0 голосов
/ 05 мая 2019

VHDL отличается от C - здесь у вас есть документ, как реализовать умножение. Разверните его до необходимого количества битов:

http://www.eng.auburn.edu/~nelsovp/courses/elec4200/Slides/VHDL%207%20Multiplier%20Example.pdf

...