diff --git a/hw/dpi/float_dpi.cpp b/hw/dpi/float_dpi.cpp index f7d9a85c..70d49eae 100644 --- a/hw/dpi/float_dpi.cpp +++ b/hw/dpi/float_dpi.cpp @@ -26,9 +26,9 @@ extern "C" { void dpi_utof(int a, int frm, int* result, int* fflags); void dpi_fclss(int a, int* result); - void dpi_fsgnj(int a, int* result); - void dpi_fsgnjn(int a, int* result); - void dpi_fsgnjx(int a, int* result); + void dpi_fsgnj(int a, int b, int* result); + void dpi_fsgnjn(int a, int b, int* result); + void dpi_fsgnjx(int a, int b, int* result); void dpi_flt(int a, int b, int* result, int* fflags); void dpi_fle(int a, int b, int* result, int* fflags); @@ -244,21 +244,53 @@ void dpi_fmax(int a, int b, int* result, int* fflags) { } void dpi_fclss(int a, int* result) { - // TODO - *result = 0; + + int r = 0; // clear all bits + + bool fsign = (a >> 31); + uint32_t expo = (a >> 23) & 0xFF; + uint32_t fraction = a & 0x7FFFFF; + + if ((expo == 0) && (fraction == 0)) { + r = fsign ? (1 << 3) : (1 << 4); // +/- 0 + } else if ((expo == 0) && (fraction != 0)) { + r = fsign ? (1 << 2) : (1 << 5); // +/- subnormal + } else if ((expo == 0xFF) && (fraction == 0)) { + r = fsign ? (1<<0) : (1<<7); // +/- infinity + } else if ((expo == 0xFF ) && (fraction != 0)) { + if (!fsign && (fraction == 0x00400000)) { + r = (1 << 9); // quiet NaN + } else { + r = (1 << 8); // signaling NaN + } + } else { + r = fsign ? (1 << 1) : (1 << 6); // +/- normal + } + + *result = r; } -void dpi_fsgnj(int a, int* result) { - // TODO - *result = 0; +void dpi_fsgnj(int a, int b, int* result) { + + int sign = b & 0x80000000; + int r = sign | (a & 0x7FFFFFFF); + + *result = r; } -void dpi_fsgnjn(int a, int* result) { - // TODO - *result = 0; +void dpi_fsgnjn(int a, int b, int* result) { + + int sign = ~b & 0x80000000; + int r = sign | (a & 0x7FFFFFFF); + + *result = r; } -void dpi_fsgnjx(int a, int* result) { - // TODO - *result = 0; +void dpi_fsgnjx(int a, int b, int* result) { + + int sign1 = a & 0x80000000; + int sign2 = b & 0x80000000; + int r = (sign1 ^ sign2) | (a & 0x7FFFFFFF); + + *result = r; } \ No newline at end of file diff --git a/hw/dpi/float_dpi.vh b/hw/dpi/float_dpi.vh index 62f45432..bba4c891 100644 --- a/hw/dpi/float_dpi.vh +++ b/hw/dpi/float_dpi.vh @@ -18,9 +18,9 @@ import "DPI-C" context function void dpi_itof(input int a, input bit[2:0] frm, o import "DPI-C" context function void dpi_utof(input int a, input bit[2:0] frm, output int result, output bit[4:0] fflags); import "DPI-C" context function void dpi_fclss(input int a, output int result); -import "DPI-C" context function void dpi_fsgnj(input int a, output int result); -import "DPI-C" context function void dpi_fsgnjn(input int a, output int result); -import "DPI-C" context function void dpi_fsgnjx(input int a, output int result); +import "DPI-C" context function void dpi_fsgnj(input int a, input int b, output int result); +import "DPI-C" context function void dpi_fsgnjn(input int a, input int b, output int result); +import "DPI-C" context function void dpi_fsgnjx(input int a, input int b, output int result); import "DPI-C" context function void dpi_flt(input int a, input int b, output int result, output bit[4:0] fflags); import "DPI-C" context function void dpi_fle(input int a, input int b, output int result, output bit[4:0] fflags); diff --git a/hw/rtl/fp_cores/VX_fpu_dpi.v b/hw/rtl/fp_cores/VX_fpu_dpi.v index c18be4ec..10dab769 100644 --- a/hw/rtl/fp_cores/VX_fpu_dpi.v +++ b/hw/rtl/fp_cores/VX_fpu_dpi.v @@ -330,9 +330,9 @@ module VX_fpu_dpi #( dpi_feq (dataa[i], datab[i], result_feq[i], fflags_feq[i]); dpi_fmin (dataa[i], datab[i], result_fmin[i], fflags_fmin[i]); dpi_fmax (dataa[i], datab[i], result_fmax[i], fflags_fmax[i]); - dpi_fsgnj (dataa[i], result_fsgnj[i]); - dpi_fsgnjn (dataa[i], result_fsgnjn[i]); - dpi_fsgnjx (dataa[i], result_fsgnjx[i]); + dpi_fsgnj (dataa[i], datab[i], result_fsgnj[i]); + dpi_fsgnjn (dataa[i], datab[i], result_fsgnjn[i]); + dpi_fsgnjx (dataa[i], datab[i], result_fsgnjx[i]); result_fmv[i] = dataa[i]; end end