Emulating a hardware signed multiplier
Børge Strand-Bergesen
borge.strand at gmail.com
Sat Oct 24 22:40:22 CEST 2009
Hi,
I'm using GMP to write a C program that emulates a signed multiplier
that I have implement in an FPGA. The hardware multiplier uses various
hardware optimization, so I need to be confident in it before I put it
to its actual use. (MAC for digital cross-over filter.) I intend to
have GMP generate random input, send it on a UART to the hardware
multiplier, receive its result and compare that to the one GMP
calculated. If no flaws are found during a couple nights of this, the
hardware multiplier is quite likely holding up. My setup is Cygwin on
XP with GCC 3.4.4 and GMP 4.2.4-1 from a very recent Cygwin
repository.
The hardware multiplier takes two signed 64-bit numbers and produces a
signed 128-bit number. I'm new to GMP and I'm looking for a way to
make it interpret numbers the same way the hardware multiplier does.
In the hardware, the inputs are fixed to 64 bits and the output is
fixed to 128. So 0xFFFFFFFFFFFFFFF is interpreted as -1, and
0xFFFFFFFFFFFFFFFF x 0x0000000000000001 = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
I have attempted this in GMP, and what I'm probably looking for is a
way for it to interpret the MSB of the input as the sign bit. And then
use the sign to format 2's complement style output. I was hoping for
some help to find the right track here. (After I get the
multiplication up and running I plan to simulate added/accumulated
multiplication results. And just like the signed 128-bit hardware
accumulator, I'll need a way to make GMP overflow and throw away
anything above the MSB.)
My current test code and its output:
#include <stdio.h>
#include <gmp.h>
int main(void) {
mpz_t a, b, result;
mpz_init2(a, 64);
mpz_init2(b, 64);
mpz_init2(result, 128);
mpz_set_str(a, "747262FA8DE38F37", 16); // Load 64-bit hex numbers
mpz_set_str(b, "4728AD47CE37F092", 16);
mpz_mul (result, a, b);
gmp_printf("%#032Zx\n", result); // 128-bit number as 32 hex chars.
// Prints "0x205e3a24eaea8b4d4b85d44d48dc3d5e" as expected
mpz_set_str(a, "FFFFFFFFFFFFFFFF", 16); // Load 64-bit hex numbers
mpz_set_str(b, "0000000000000001", 16);
mpz_mul (result, a, b);
gmp_printf("%#032Zx\n", result); // 128-bit number as 32 hex chars.
// Prints "0x00000000000000ffffffffffffffff" which is not 32 characters
// FPGA_mult "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" if MSBs were
interpreted as sign
}
Thanks,
Borge
More information about the gmp-discuss
mailing list