From b8682f56ac41f9bed6d1c7e36eaa39454f63fc3e Mon Sep 17 00:00:00 2001 From: Blaise Tine Date: Sun, 10 Oct 2021 13:20:50 -0700 Subject: [PATCH] softfloat library integration --- .gitmodules | 3 + hw/dpi/float_dpi.cpp | 347 +++++++++------------------ hw/dpi/float_dpi.vh | 44 ++-- hw/dpi/util_dpi.cpp | 26 +- hw/dpi/util_dpi.vh | 4 +- hw/rtl/VX_muldiv.sv | 10 +- hw/rtl/fp_cores/VX_fp_div.sv | 2 +- hw/rtl/fp_cores/VX_fp_fma.sv | 2 +- hw/rtl/fp_cores/VX_fp_sqrt.sv | 2 +- hw/rtl/fp_cores/VX_fpu_dpi.sv | 120 +++++----- runtime/Makefile | 2 +- sim/Makefile | 2 + sim/common/Makefile | 5 + sim/common/softfloat | 1 + sim/common/util.cpp | 84 +------ sim/common/util.h | 24 +- sim/rtlsim/Makefile | 47 ++-- sim/simX/Makefile | 22 +- sim/simX/execute.cpp | 440 +++++++++------------------------- sim/vlsim/Makefile | 25 +- tests/riscv/isa/Makefile | 6 +- 21 files changed, 400 insertions(+), 818 deletions(-) create mode 100644 sim/common/Makefile create mode 160000 sim/common/softfloat diff --git a/.gitmodules b/.gitmodules index dd60e98f..96aeefdb 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "hw/rtl/fp_cores/fpnew"] path = hw/rtl/fp_cores/fpnew url = https://github.com/pulp-platform/fpnew.git +[submodule "sim/common/softfloat"] + path = sim/common/softfloat + url = https://github.com/ucb-bar/berkeley-softfloat-3.git diff --git a/hw/dpi/float_dpi.cpp b/hw/dpi/float_dpi.cpp index 58cb06aa..7d78dde8 100644 --- a/hw/dpi/float_dpi.cpp +++ b/hw/dpi/float_dpi.cpp @@ -4,293 +4,168 @@ #include #include #include +#include #include "svdpi.h" #include "verilated_vpi.h" #include "VX_config.h" extern "C" { - void dpi_fadd(int a, int b, int frm, int* result, int* fflags); - void dpi_fsub(int a, int b, int frm, int* result, int* fflags); - void dpi_fmul(int a, int b, int frm, int* result, int* fflags); - void dpi_fmadd(int a, int b, int c, int frm, int* result, int* fflags); - void dpi_fmsub(int a, int b, int c, int frm, int* result, int* fflags); - void dpi_fnmadd(int a, int b, int c, int frm, int* result, int* fflags); - void dpi_fnmsub(int a, int b, int c, int frm, int* result, int* fflags); + void dpi_fadd(bool enable, int a, int b, const svBitVecVal* frm, int* result, svBitVecVal* fflags); + void dpi_fsub(bool enable, int a, int b, const svBitVecVal* frm, int* result, svBitVecVal* fflags); + void dpi_fmul(bool enable, int a, int b, const svBitVecVal* frm, int* result, svBitVecVal* fflags); + void dpi_fmadd(bool enable, int a, int b, int c, const svBitVecVal* frm, int* result, svBitVecVal* fflags); + void dpi_fmsub(bool enable, int a, int b, int c, const svBitVecVal* frm, int* result, svBitVecVal* fflags); + void dpi_fnmadd(bool enable, int a, int b, int c, const svBitVecVal* frm, int* result, svBitVecVal* fflags); + void dpi_fnmsub(bool enable, int a, int b, int c, const svBitVecVal* frm, int* result, svBitVecVal* fflags); - void dpi_fdiv(int a, int b, int frm, int* result, int* fflags); - void dpi_fsqrt(int a, int frm, int* result, int* fflags); + void dpi_fdiv(bool enable, int a, int b, const svBitVecVal* frm, int* result, svBitVecVal* fflags); + void dpi_fsqrt(bool enable, int a, const svBitVecVal* frm, int* result, svBitVecVal* fflags); - void dpi_ftoi(int a, int frm, int* result, int* fflags); - void dpi_ftou(int a, int frm, int* result, int* fflags); - void dpi_itof(int a, int frm, int* result, int* fflags); - void dpi_utof(int a, int frm, int* result, int* fflags); + void dpi_ftoi(bool enable, int a, const svBitVecVal* frm, int* result, svBitVecVal* fflags); + void dpi_ftou(bool enable, int a, const svBitVecVal* frm, int* result, svBitVecVal* fflags); + void dpi_itof(bool enable, int a, const svBitVecVal* frm, int* result, svBitVecVal* fflags); + void dpi_utof(bool enable, int a, const svBitVecVal* frm, int* result, svBitVecVal* fflags); - void dpi_fclss(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_fclss(bool enable, int a, int* result); + void dpi_fsgnj(bool enable, int a, int b, int* result); + void dpi_fsgnjn(bool enable, int a, int b, int* result); + void dpi_fsgnjx(bool enable, 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); - void dpi_feq(int a, int b, int* result, int* fflags); - void dpi_fmin(int a, int b, int* result, int* fflags); - void dpi_fmax(int a, int b, int* result, int* fflags); + void dpi_flt(bool enable, int a, int b, int* result, svBitVecVal* fflags); + void dpi_fle(bool enable, int a, int b, int* result, svBitVecVal* fflags); + void dpi_feq(bool enable, int a, int b, int* result, svBitVecVal* fflags); + void dpi_fmin(bool enable, int a, int b, int* result, svBitVecVal* fflags); + void dpi_fmax(bool enable, int a, int b, int* result, svBitVecVal* fflags); } -union Float_t { - float f; - int i; - struct { - uint32_t man : 23; - uint32_t exp : 8; - uint32_t sign : 1; - } parts; -}; - -void dpi_fadd(int a, int b, int frm, int* result, int* fflags) { - Float_t fa, fb, fr; - - fa.i = a; - fb.i = b; - fr.f = fa.f + fb.f; - - *result = fr.i; - *fflags = 0; +void dpi_fadd(bool enable, int a, int b, const svBitVecVal* frm, int* result, svBitVecVal* fflags) { + if (!enable) + return; + *result = rv_fadd(a, b, (*frm & 0x7), fflags); } -void dpi_fsub(int a, int b, int frm, int* result, int* fflags) { - Float_t fa, fb, fr; - - fa.i = a; - fb.i = b; - fr.f = fa.f - fb.f; - - *result = fr.i; - *fflags = 0; +void dpi_fsub(bool enable, int a, int b, const svBitVecVal* frm, int* result, svBitVecVal* fflags) { + if (!enable) + return; + *result = rv_fsub(a, b, (*frm & 0x7), fflags); } -void dpi_fmul(int a, int b, int frm, int* result, int* fflags) { - Float_t fa, fb, fr; - - fa.i = a; - fb.i = b; - fr.f = fa.f * fb.f; - - *result = fr.i; - *fflags = 0; +void dpi_fmul(bool enable, int a, int b, const svBitVecVal* frm, int* result, svBitVecVal* fflags) { + if (!enable) + return; + *result = rv_fmul(a, b, (*frm & 0x7), fflags); } -void dpi_fmadd(int a, int b, int c, int frm, int* result, int* fflags) { - Float_t fa, fb, fc, fr; - - fa.i = a; - fb.i = b; - fc.i = c; - fr.f = fa.f * fb.f + fc.f; - - *result = fr.i; - *fflags = 0; +void dpi_fmadd(bool enable, int a, int b, int c, const svBitVecVal* frm, int* result, svBitVecVal* fflags) { + if (!enable) + return; + *result = rv_fmadd(a, b, c, (*frm & 0x7), fflags); } -void dpi_fmsub(int a, int b, int c, int frm, int* result, int* fflags) { - Float_t fa, fb, fc, fr; - - fa.i = a; - fb.i = b; - fc.i = c; - fr.f = fa.f * fb.f - fc.f; - - *result = fr.i; - *fflags = 0; +void dpi_fmsub(bool enable, int a, int b, int c, const svBitVecVal* frm, int* result, svBitVecVal* fflags) { + if (!enable) + return; + *result = rv_fmsub(a, b, c, (*frm & 0x7), fflags); } -void dpi_fnmadd(int a, int b, int c, int frm, int* result, int* fflags) { - Float_t fa, fb, fc, fr; - - fa.i = a; - fb.i = b; - fc.i = c; - fr.f = -(fa.f * fb.f + fc.f); - - *result = fr.i; - *fflags = 0; +void dpi_fnmadd(bool enable, int a, int b, int c, const svBitVecVal* frm, int* result, svBitVecVal* fflags) { + if (!enable) + return; + *result = rv_fnmadd(a, b, c, (*frm & 0x7), fflags); } -void dpi_fnmsub(int a, int b, int c, int frm, int* result, int* fflags) { - Float_t fa, fb, fc, fr; - - fa.i = a; - fb.i = b; - fc.i = c; - fr.f = -(fa.f * fb.f - fc.f); - - *result = fr.i; - *fflags = 0; +void dpi_fnmsub(bool enable, int a, int b, int c, const svBitVecVal* frm, int* result, svBitVecVal* fflags) { + if (!enable) + return; + *result = rv_fnmsub(a, b, c, (*frm & 0x7), fflags); } -void dpi_fdiv(int a, int b, int frm, int* result, int* fflags) { - Float_t fa, fb, fr; - - fa.i = a; - fb.i = b; - fr.f = fa.f / fb.f; - - *result = fr.i; - *fflags = 0; +void dpi_fdiv(bool enable, int a, int b, const svBitVecVal* frm, int* result, svBitVecVal* fflags) { + if (!enable) + return; + *result = rv_fdiv(a, b, (*frm & 0x7), fflags); } -void dpi_fsqrt(int a, int frm, int* result, int* fflags) { - Float_t fa, fr; - - fa.i = a; - fr.f = sqrtf(fa.f); - - *result = fr.i; - *fflags = 0; +void dpi_fsqrt(bool enable, int a, const svBitVecVal* frm, int* result, svBitVecVal* fflags) { + if (!enable) + return; + *result = rv_fsqrt(a, (*frm & 0x7), fflags); } -void dpi_ftoi(int a, int frm, int* result, int* fflags) { - Float_t fa, fr; - - fa.i = a; - fr.i = int(fa.f); - - *result = fr.i; - *fflags = 0; +void dpi_ftoi(bool enable, int a, const svBitVecVal* frm, int* result, svBitVecVal* fflags) { + if (!enable) + return; + *result = rv_ftoi(a, (*frm & 0x7), fflags); } -void dpi_ftou(int a, int frm, int* result, int* fflags) { - Float_t fa, fr; - - fa.i = a; - fr.i = unsigned(fa.f); - - *result = fr.i; - *fflags = 0; +void dpi_ftou(bool enable, int a, const svBitVecVal* frm, int* result, svBitVecVal* fflags) { + if (!enable) + return; + *result = rv_ftou(a, (*frm & 0x7), fflags); } -void dpi_itof(int a, int frm, int* result, int* fflags) { - Float_t fa, fr; - - fr.f = (float)a; - - *result = fr.i; - *fflags = 0; +void dpi_itof(bool enable, int a, const svBitVecVal* frm, int* result, svBitVecVal* fflags) { + if (!enable) + return; + *result = rv_itof(a, (*frm & 0x7), fflags); } -void dpi_utof(int a, int frm, int* result, int* fflags) { - Float_t fa, fr; - - unsigned ua = a; - fr.f = (float)ua; - - *result = fr.i; - *fflags = 0; +void dpi_utof(bool enable, int a, const svBitVecVal* frm, int* result, svBitVecVal* fflags) { + if (!enable) + return; + *result = rv_utof(a, (*frm & 0x7), fflags); } -void dpi_flt(int a, int b, int* result, int* fflags) { - Float_t fa, fb, fr; - - fa.i = a; - fb.i = b; - fr.i = fa.f < fb.f; - - *result = fr.i; - *fflags = 0; +void dpi_flt(bool enable, int a, int b, int* result, svBitVecVal* fflags) { + if (!enable) + return; + *result = rv_flt(a, b, fflags); } -void dpi_fle(int a, int b, int* result, int* fflags) { - Float_t fa, fb, fr; - - fa.i = a; - fb.i = b; - fr.i = fa.f <= fb.f; - - *result = fr.i; - *fflags = 0; +void dpi_fle(bool enable, int a, int b, int* result, svBitVecVal* fflags) { + if (!enable) + return; + *result = rv_fle(a, b, fflags); } -void dpi_feq(int a, int b, int* result, int* fflags) { - Float_t fa, fb, fr; - - fa.i = a; - fb.i = b; - fr.i = fa.f == fb.f; - - *result = fr.i; - *fflags = 0; +void dpi_feq(bool enable, int a, int b, int* result, svBitVecVal* fflags) { + if (!enable) + return; + *result = rv_feq(a, b, fflags); } -void dpi_fmin(int a, int b, int* result, int* fflags) { - Float_t fa, fb, fr; - - fa.i = a; - fb.i = b; - fr.f = std::min(fa.f, fb.f); - - *result = fr.i; - *fflags = 0; +void dpi_fmin(bool enable, int a, int b, int* result, svBitVecVal* fflags) { + if (!enable) + return; + *result = rv_fmin(a, b, fflags); } -void dpi_fmax(int a, int b, int* result, int* fflags) { - Float_t fa, fb, fr; - - fa.i = a; - fb.i = b; - fr.f = std::max(fa.f, fb.f); - - *result = fr.i; - *fflags = 0; +void dpi_fmax(bool enable, int a, int b, int* result, svBitVecVal* fflags) { + if (!enable) + return; + *result = rv_fmax(a, b, fflags); } -void dpi_fclss(int a, int* result) { - - 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_fclss(bool enable, int a, int* result) { + if (!enable) + return; + *result = rv_fclss(a); } -void dpi_fsgnj(int a, int b, int* result) { - - int sign = b & 0x80000000; - int r = sign | (a & 0x7FFFFFFF); - - *result = r; +void dpi_fsgnj(bool enable, int a, int b, int* result) { + if (!enable) + return; + *result = rv_fsgnj(a, b); } -void dpi_fsgnjn(int a, int b, int* result) { - - int sign = ~b & 0x80000000; - int r = sign | (a & 0x7FFFFFFF); - - *result = r; +void dpi_fsgnjn(bool enable, int a, int b, int* result) { + if (!enable) + return; + *result = rv_fsgnjn(a, b); } -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; +void dpi_fsgnjx(bool enable, int a, int b, int* result) { + if (!enable) + return; + *result = rv_fsgnjx(a, b); } \ No newline at end of file diff --git a/hw/dpi/float_dpi.vh b/hw/dpi/float_dpi.vh index 8a609ca5..968f8028 100644 --- a/hw/dpi/float_dpi.vh +++ b/hw/dpi/float_dpi.vh @@ -1,31 +1,31 @@ `ifndef FLOAT_DPI `define FLOAT_DPI -import "DPI-C" function void dpi_fadd(input int a, input int b, input bit[2:0] frm, output int result, output bit[4:0] fflags); -import "DPI-C" function void dpi_fsub(input int a, input int b, input bit[2:0] frm, output int result, output bit[4:0] fflags); -import "DPI-C" function void dpi_fmul(input int a, input int b, input bit[2:0] frm, output int result, output bit[4:0] fflags); -import "DPI-C" function void dpi_fmadd(input int a, input int b, input int c, input bit[2:0] frm, output int result, output bit[4:0] fflags); -import "DPI-C" function void dpi_fmsub(input int a, input int b, input int c, input bit[2:0] frm, output int result, output bit[4:0] fflags); -import "DPI-C" function void dpi_fnmadd(input int a, input int b, input int c, input bit[2:0] frm, output int result, output bit[4:0] fflags); -import "DPI-C" function void dpi_fnmsub(input int a, input int b, input int c, input bit[2:0] frm, output int result, output bit[4:0] fflags); +import "DPI-C" function void dpi_fadd(input logic enable, input int a, input int b, input bit[2:0] frm, output int result, output bit[4:0] fflags); +import "DPI-C" function void dpi_fsub(input logic enable, input int a, input int b, input bit[2:0] frm, output int result, output bit[4:0] fflags); +import "DPI-C" function void dpi_fmul(input logic enable, input int a, input int b, input bit[2:0] frm, output int result, output bit[4:0] fflags); +import "DPI-C" function void dpi_fmadd(input logic enable, input int a, input int b, input int c, input bit[2:0] frm, output int result, output bit[4:0] fflags); +import "DPI-C" function void dpi_fmsub(input logic enable, input int a, input int b, input int c, input bit[2:0] frm, output int result, output bit[4:0] fflags); +import "DPI-C" function void dpi_fnmadd(input logic enable, input int a, input int b, input int c, input bit[2:0] frm, output int result, output bit[4:0] fflags); +import "DPI-C" function void dpi_fnmsub(input logic enable, input int a, input int b, input int c, input bit[2:0] frm, output int result, output bit[4:0] fflags); -import "DPI-C" function void dpi_fdiv(input int a, input int b, input bit[2:0] frm, output int result, output bit[4:0] fflags); -import "DPI-C" function void dpi_fsqrt(input int a, input bit[2:0] frm, output int result, output bit[4:0] fflags); +import "DPI-C" function void dpi_fdiv(input logic enable, input int a, input int b, input bit[2:0] frm, output int result, output bit[4:0] fflags); +import "DPI-C" function void dpi_fsqrt(input logic enable, input int a, input bit[2:0] frm, output int result, output bit[4:0] fflags); -import "DPI-C" function void dpi_ftoi(input int a, input bit[2:0] frm, output int result, output bit[4:0] fflags); -import "DPI-C" function void dpi_ftou(input int a, input bit[2:0] frm, output int result, output bit[4:0] fflags); -import "DPI-C" function void dpi_itof(input int a, input bit[2:0] frm, output int result, output bit[4:0] fflags); -import "DPI-C" function void dpi_utof(input int a, input bit[2:0] frm, output int result, output bit[4:0] fflags); +import "DPI-C" function void dpi_ftoi(input logic enable, input int a, input bit[2:0] frm, output int result, output bit[4:0] fflags); +import "DPI-C" function void dpi_ftou(input logic enable, input int a, input bit[2:0] frm, output int result, output bit[4:0] fflags); +import "DPI-C" function void dpi_itof(input logic enable, input int a, input bit[2:0] frm, output int result, output bit[4:0] fflags); +import "DPI-C" function void dpi_utof(input logic enable, input int a, input bit[2:0] frm, output int result, output bit[4:0] fflags); -import "DPI-C" function void dpi_fclss(input int a, output int result); -import "DPI-C" function void dpi_fsgnj(input int a, input int b, output int result); -import "DPI-C" function void dpi_fsgnjn(input int a, input int b, output int result); -import "DPI-C" function void dpi_fsgnjx(input int a, input int b, output int result); +import "DPI-C" function void dpi_fclss(input logic enable, input int a, output int result); +import "DPI-C" function void dpi_fsgnj(input logic enable, input int a, input int b, output int result); +import "DPI-C" function void dpi_fsgnjn(input logic enable, input int a, input int b, output int result); +import "DPI-C" function void dpi_fsgnjx(input logic enable, input int a, input int b, output int result); -import "DPI-C" function void dpi_flt(input int a, input int b, output int result, output bit[4:0] fflags); -import "DPI-C" function void dpi_fle(input int a, input int b, output int result, output bit[4:0] fflags); -import "DPI-C" function void dpi_feq(input int a, input int b, output int result, output bit[4:0] fflags); -import "DPI-C" function void dpi_fmin(input int a, input int b, output int result, output bit[4:0] fflags); -import "DPI-C" function void dpi_fmax(input int a, input int b, output int result, output bit[4:0] fflags); +import "DPI-C" function void dpi_flt(input logic enable, input int a, input int b, output int result, output bit[4:0] fflags); +import "DPI-C" function void dpi_fle(input logic enable, input int a, input int b, output int result, output bit[4:0] fflags); +import "DPI-C" function void dpi_feq(input logic enable, input int a, input int b, output int result, output bit[4:0] fflags); +import "DPI-C" function void dpi_fmin(input logic enable, input int a, input int b, output int result, output bit[4:0] fflags); +import "DPI-C" function void dpi_fmax(input logic enable, input int a, input int b, output int result, output bit[4:0] fflags); `endif \ No newline at end of file diff --git a/hw/dpi/util_dpi.cpp b/hw/dpi/util_dpi.cpp index ef13e696..a8db1a53 100644 --- a/hw/dpi/util_dpi.cpp +++ b/hw/dpi/util_dpi.cpp @@ -9,8 +9,8 @@ #include "VX_config.h" extern "C" { - void dpi_imul(int a, int b, bool is_signed_a, bool is_signed_b, int* resultl, int* resulth); - void dpi_idiv(int a, int b, bool is_signed, int* quotient, int* remainder); + void dpi_imul(bool enable, int a, int b, bool is_signed_a, bool is_signed_b, int* resultl, int* resulth); + void dpi_idiv(bool enable, int a, int b, bool is_signed, int* quotient, int* remainder); int dpi_register(); void dpi_assert(int inst, bool cond, int delay); @@ -93,15 +93,18 @@ void dpi_assert(int inst, bool cond, int delay) { } } -void dpi_imul(int a, int b, bool is_signed_a, bool is_signed_b, int* resultl, int* resulth) { - uint64_t first = a; - uint64_t second = b; +void dpi_imul(bool enable, int a, int b, bool is_signed_a, bool is_signed_b, int* resultl, int* resulth) { + if (!enable) + return; - if (is_signed_a && (a & 0x80000000)) { + uint64_t first = *(uint32_t*)&a; + uint64_t second = *(uint32_t*)&b; + + if (is_signed_a && (first & 0x80000000)) { first |= 0xFFFFFFFF00000000; } - if (is_signed_b && (b & 0x80000000)) { + if (is_signed_b && (second & 0x80000000)) { second |= 0xFFFFFFFF00000000; } @@ -116,9 +119,12 @@ void dpi_imul(int a, int b, bool is_signed_a, bool is_signed_b, int* resultl, in *resulth = (result >> 32) & 0xFFFFFFFF; } -void dpi_idiv(int a, int b, bool is_signed, int* quotient, int* remainder) { - uint32_t dividen = a; - uint32_t divisor = b; +void dpi_idiv(bool enable, int a, int b, bool is_signed, int* quotient, int* remainder) { + if (!enable) + return; + + uint32_t dividen = *(uint32_t*)&a; + uint32_t divisor = *(uint32_t*)&b; if (is_signed) { if (b == 0) { diff --git a/hw/dpi/util_dpi.vh b/hw/dpi/util_dpi.vh index 07e81259..c1306ff4 100644 --- a/hw/dpi/util_dpi.vh +++ b/hw/dpi/util_dpi.vh @@ -1,8 +1,8 @@ `ifndef UTIL_DPI `define UTIL_DPI -import "DPI-C" function void dpi_imul(input int a, input int b, input logic is_signed_a, input logic is_signed_b, output int resultl, output int resulth); -import "DPI-C" function void dpi_idiv(input int a, input int b, input logic is_signed, output int quotient, output int remainder); +import "DPI-C" function void dpi_imul(input logic enable, input int a, input int b, input logic is_signed_a, input logic is_signed_b, output int resultl, output int resulth); +import "DPI-C" function void dpi_idiv(input logic enable, input int a, input int b, input logic is_signed, output int quotient, output int remainder); import "DPI-C" function int dpi_register(); import "DPI-C" function void dpi_assert(int inst, input logic cond, input int delay); diff --git a/hw/rtl/VX_muldiv.sv b/hw/rtl/VX_muldiv.sv index 107e6785..5cd13f5c 100644 --- a/hw/rtl/VX_muldiv.sv +++ b/hw/rtl/VX_muldiv.sv @@ -50,12 +50,14 @@ module VX_muldiv ( `ifdef IMUL_DPI - wire [`NUM_THREADS-1:0][31:0] mul_result_tmp; + wire [`NUM_THREADS-1:0][31:0] mul_result_tmp; + + wire mul_fire_in = mul_valid_in && mul_ready_in; for (genvar i = 0; i < `NUM_THREADS; i++) begin wire [31:0] mul_resultl, mul_resulth; always @(*) begin - dpi_imul (alu_in1[i], alu_in2[i], is_signed_mul_a, is_signed_mul_b, mul_resultl, mul_resulth); + dpi_imul (mul_fire_in, alu_in1[i], alu_in2[i], is_signed_mul_a, is_signed_mul_b, mul_resultl, mul_resulth); end assign mul_result_tmp[i] = is_mulh_in ? mul_resulth : mul_resultl; end @@ -133,11 +135,13 @@ module VX_muldiv ( `ifdef IDIV_DPI wire [`NUM_THREADS-1:0][31:0] div_result_tmp; + + wire div_fire_in = div_valid_in && div_ready_in; for (genvar i = 0; i < `NUM_THREADS; i++) begin wire [31:0] div_quotient, div_remainder; always @(*) begin - dpi_idiv (alu_in1[i], alu_in2[i], is_signed_div, div_quotient, div_remainder); + dpi_idiv (div_fire_in, alu_in1[i], alu_in2[i], is_signed_div, div_quotient, div_remainder); end assign div_result_tmp[i] = is_rem_op_in ? div_remainder : div_quotient; end diff --git a/hw/rtl/fp_cores/VX_fp_div.sv b/hw/rtl/fp_cores/VX_fp_div.sv index 7bf5f75c..48e9d9b8 100644 --- a/hw/rtl/fp_cores/VX_fp_div.sv +++ b/hw/rtl/fp_cores/VX_fp_div.sv @@ -35,7 +35,7 @@ module VX_fp_div #( fflags_t f; always @(*) begin - dpi_fdiv (dataa[i], datab[i], frm, r, f); + dpi_fdiv (enable && valid_in, dataa[i], datab[i], frm, r, f); end `UNUSED_VAR (f) diff --git a/hw/rtl/fp_cores/VX_fp_fma.sv b/hw/rtl/fp_cores/VX_fp_fma.sv index 84b9653a..8f826b5f 100644 --- a/hw/rtl/fp_cores/VX_fp_fma.sv +++ b/hw/rtl/fp_cores/VX_fp_fma.sv @@ -64,7 +64,7 @@ module VX_fp_fma #( fflags_t f; always @(*) begin - dpi_fmadd (a, b, c, frm, r, f); + dpi_fmadd (enable && valid_in, a, b, c, frm, r, f); end `UNUSED_VAR (f) diff --git a/hw/rtl/fp_cores/VX_fp_sqrt.sv b/hw/rtl/fp_cores/VX_fp_sqrt.sv index 97a3b35a..441b8d95 100644 --- a/hw/rtl/fp_cores/VX_fp_sqrt.sv +++ b/hw/rtl/fp_cores/VX_fp_sqrt.sv @@ -34,7 +34,7 @@ module VX_fp_sqrt #( fflags_t f; always @(*) begin - dpi_fsqrt (dataa[i], frm, r, f); + dpi_fsqrt (enable && valid_in, dataa[i], frm, r, f); end `UNUSED_VAR (f) diff --git a/hw/rtl/fp_cores/VX_fpu_dpi.sv b/hw/rtl/fp_cores/VX_fpu_dpi.sv index ec0b3573..ae9f8306 100644 --- a/hw/rtl/fp_cores/VX_fpu_dpi.sv +++ b/hw/rtl/fp_cores/VX_fpu_dpi.sv @@ -123,15 +123,20 @@ module VX_fpu_dpi #( fflags_t [`NUM_THREADS-1:0] fflags_fnmadd; fflags_t [`NUM_THREADS-1:0] fflags_fnmsub; + wire fma_valid = (valid_in && core_select == FPU_FMA); + wire fma_ready = per_core_ready_out[FPU_FMA] || ~per_core_valid_out[FPU_FMA]; + + wire fma_fire = fma_valid && fma_ready; + always @(*) begin for (integer i = 0; i < `NUM_THREADS; i++) begin - dpi_fadd (dataa[i], datab[i], frm, result_fadd[i], fflags_fadd[i]); - dpi_fsub (dataa[i], datab[i], frm, result_fsub[i], fflags_fsub[i]); - dpi_fmul (dataa[i], datab[i], frm, result_fmul[i], fflags_fmul[i]); - dpi_fmadd (dataa[i], datab[i], datac[i], frm, result_fmadd[i], fflags_fmadd[i]); - dpi_fmsub (dataa[i], datab[i], datac[i], frm, result_fmsub[i], fflags_fmsub[i]); - dpi_fnmadd (dataa[i], datab[i], datac[i], frm, result_fnmadd[i], fflags_fnmadd[i]); - dpi_fnmsub (dataa[i], datab[i], datac[i], frm, result_fnmsub[i], fflags_fnmsub[i]); + dpi_fadd (fma_fire, dataa[i], datab[i], frm, result_fadd[i], fflags_fadd[i]); + dpi_fsub (fma_fire, dataa[i], datab[i], frm, result_fsub[i], fflags_fsub[i]); + dpi_fmul (fma_fire, dataa[i], datab[i], frm, result_fmul[i], fflags_fmul[i]); + dpi_fmadd (fma_fire, dataa[i], datab[i], datac[i], frm, result_fmadd[i], fflags_fmadd[i]); + dpi_fmsub (fma_fire, dataa[i], datab[i], datac[i], frm, result_fmsub[i], fflags_fmsub[i]); + dpi_fnmadd (fma_fire, dataa[i], datab[i], datac[i], frm, result_fnmadd[i], fflags_fnmadd[i]); + dpi_fnmsub (fma_fire, dataa[i], datab[i], datac[i], frm, result_fnmsub[i], fflags_fnmsub[i]); end end @@ -151,10 +156,7 @@ module VX_fpu_dpi #( is_fmsub ? fflags_fmsub : is_fnmadd ? fflags_fnmadd : is_fnmsub ? fflags_fnmsub : - 0; - - wire enable = per_core_ready_out[FPU_FMA] || ~per_core_valid_out[FPU_FMA]; - wire valid = (valid_in && core_select == FPU_FMA); + 0; VX_shift_register #( .DATAW (1 + TAGW + `NUM_THREADS * (32 + $bits(fflags_t))), @@ -163,13 +165,13 @@ module VX_fpu_dpi #( ) shift_reg ( .clk (clk), .reset (reset), - .enable (enable), - .data_in ({valid, tag_in, result_fma, fflags_fma}), + .enable (fma_ready), + .data_in ({fma_valid, tag_in, result_fma, fflags_fma}), .data_out ({per_core_valid_out[FPU_FMA], per_core_tag_out[FPU_FMA], per_core_result[FPU_FMA], per_core_fflags[FPU_FMA]}) ); assign per_core_has_fflags[FPU_FMA] = 1; - assign per_core_ready_in[FPU_FMA] = enable; + assign per_core_ready_in[FPU_FMA] = fma_ready; end endgenerate @@ -179,16 +181,18 @@ module VX_fpu_dpi #( wire [`NUM_THREADS-1:0][31:0] result_fdiv; fflags_t [`NUM_THREADS-1:0] fflags_fdiv; + + wire fdiv_valid = (valid_in && core_select == FPU_DIV); + wire fdiv_ready = per_core_ready_out[FPU_DIV] || ~per_core_valid_out[FPU_DIV]; + + wire fdiv_fire = fdiv_valid && fdiv_ready; always @(*) begin for (integer i = 0; i < `NUM_THREADS; i++) begin - dpi_fdiv (dataa[i], datab[i], frm, result_fdiv[i], fflags_fdiv[i]); + dpi_fdiv (fdiv_fire, dataa[i], datab[i], frm, result_fdiv[i], fflags_fdiv[i]); end end - wire enable = per_core_ready_out[FPU_DIV] || ~per_core_valid_out[FPU_DIV]; - wire valid = (valid_in && core_select == FPU_DIV); - VX_shift_register #( .DATAW (1 + TAGW + `NUM_THREADS * (32 + $bits(fflags_t))), .DEPTH (`LATENCY_FDIV), @@ -196,13 +200,13 @@ module VX_fpu_dpi #( ) shift_reg ( .clk (clk), .reset (reset), - .enable (enable), - .data_in ({valid, tag_in, result_fdiv, fflags_fdiv}), + .enable (fdiv_ready), + .data_in ({fdiv_valid, tag_in, result_fdiv, fflags_fdiv}), .data_out ({per_core_valid_out[FPU_DIV], per_core_tag_out[FPU_DIV], per_core_result[FPU_DIV], per_core_fflags[FPU_DIV]}) ); assign per_core_has_fflags[FPU_DIV] = 1; - assign per_core_ready_in[FPU_DIV] = enable; + assign per_core_ready_in[FPU_DIV] = fdiv_ready; end endgenerate @@ -212,16 +216,18 @@ module VX_fpu_dpi #( wire [`NUM_THREADS-1:0][31:0] result_fsqrt; fflags_t [`NUM_THREADS-1:0] fflags_fsqrt; + + wire fsqrt_valid = (valid_in && core_select == FPU_SQRT); + wire fsqrt_ready = per_core_ready_out[FPU_SQRT] || ~per_core_valid_out[FPU_SQRT]; + + wire fsqrt_fire = fsqrt_valid && fsqrt_ready; always @(*) begin for (integer i = 0; i < `NUM_THREADS; i++) begin - dpi_fsqrt (dataa[i], frm, result_fsqrt[i], fflags_fsqrt[i]); + dpi_fsqrt (fsqrt_fire, dataa[i], frm, result_fsqrt[i], fflags_fsqrt[i]); end end - wire enable = per_core_ready_out[FPU_SQRT] || ~per_core_valid_out[FPU_SQRT]; - wire valid = (valid_in && core_select == FPU_SQRT); - VX_shift_register #( .DATAW (1 + TAGW + `NUM_THREADS * (32 + $bits(fflags_t))), .DEPTH (`LATENCY_FSQRT), @@ -229,13 +235,13 @@ module VX_fpu_dpi #( ) shift_reg ( .clk (clk), .reset (reset), - .enable (enable), - .data_in ({valid, tag_in, result_fsqrt, fflags_fsqrt}), + .enable (fsqrt_ready), + .data_in ({fsqrt_valid, tag_in, result_fsqrt, fflags_fsqrt}), .data_out ({per_core_valid_out[FPU_SQRT], per_core_tag_out[FPU_SQRT], per_core_result[FPU_SQRT], per_core_fflags[FPU_SQRT]}) ); assign per_core_has_fflags[FPU_SQRT] = 1; - assign per_core_ready_in[FPU_SQRT] = enable; + assign per_core_ready_in[FPU_SQRT] = fsqrt_ready; end endgenerate @@ -254,13 +260,18 @@ module VX_fpu_dpi #( fflags_t [`NUM_THREADS-1:0] fflags_utof; fflags_t [`NUM_THREADS-1:0] fflags_ftoi; fflags_t [`NUM_THREADS-1:0] fflags_ftou; - + + wire fcvt_valid = (valid_in && core_select == FPU_CVT); + wire fcvt_ready = per_core_ready_out[FPU_CVT] || ~per_core_valid_out[FPU_CVT]; + + wire fcvt_fire = fcvt_valid && fcvt_ready; + always @(*) begin for (integer i = 0; i < `NUM_THREADS; i++) begin - dpi_itof (dataa[i], frm, result_itof[i], fflags_itof[i]); - dpi_utof (dataa[i], frm, result_utof[i], fflags_utof[i]); - dpi_ftoi (dataa[i], frm, result_ftoi[i], fflags_ftoi[i]); - dpi_ftou (dataa[i], frm, result_ftou[i], fflags_ftou[i]); + dpi_itof (fcvt_fire, dataa[i], frm, result_itof[i], fflags_itof[i]); + dpi_utof (fcvt_fire, dataa[i], frm, result_utof[i], fflags_utof[i]); + dpi_ftoi (fcvt_fire, dataa[i], frm, result_ftoi[i], fflags_ftoi[i]); + dpi_ftou (fcvt_fire, dataa[i], frm, result_ftou[i], fflags_ftou[i]); end end @@ -276,9 +287,6 @@ module VX_fpu_dpi #( is_ftou ? fflags_ftou : 0; - wire enable = per_core_ready_out[FPU_CVT] || ~per_core_valid_out[FPU_CVT]; - wire valid = (valid_in && core_select == FPU_CVT); - VX_shift_register #( .DATAW (1 + TAGW + `NUM_THREADS * (32 + $bits(fflags_t))), .DEPTH (`LATENCY_FCVT), @@ -286,13 +294,13 @@ module VX_fpu_dpi #( ) shift_reg ( .clk (clk), .reset (reset), - .enable (enable), - .data_in ({valid, tag_in, result_fcvt, fflags_fcvt}), + .enable (fcvt_ready), + .data_in ({fcvt_valid, tag_in, result_fcvt, fflags_fcvt}), .data_out ({per_core_valid_out[FPU_CVT], per_core_tag_out[FPU_CVT], per_core_result[FPU_CVT], per_core_fflags[FPU_CVT]}) ); assign per_core_has_fflags[FPU_CVT] = 1; - assign per_core_ready_in[FPU_CVT] = enable; + assign per_core_ready_in[FPU_CVT] = fcvt_ready; end endgenerate @@ -318,18 +326,23 @@ module VX_fpu_dpi #( fflags_t [`NUM_THREADS-1:0] fflags_feq; fflags_t [`NUM_THREADS-1:0] fflags_fmin; fflags_t [`NUM_THREADS-1:0] fflags_fmax; - + + wire fncp_valid = (valid_in && core_select == FPU_NCP); + wire fncp_ready = per_core_ready_out[FPU_NCP] || ~per_core_valid_out[FPU_NCP]; + + wire fncp_fire = fncp_valid && fncp_ready; + always @(*) begin for (integer i = 0; i < `NUM_THREADS; i++) begin - dpi_fclss (dataa[i], result_fclss[i]); - dpi_flt (dataa[i], datab[i], result_flt[i], fflags_flt[i]); - dpi_fle (dataa[i], datab[i], result_fle[i], fflags_fle[i]); - 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], datab[i], result_fsgnj[i]); - dpi_fsgnjn (dataa[i], datab[i], result_fsgnjn[i]); - dpi_fsgnjx (dataa[i], datab[i], result_fsgnjx[i]); + dpi_fclss (fncp_fire, dataa[i], result_fclss[i]); + dpi_flt (fncp_fire, dataa[i], datab[i], result_flt[i], fflags_flt[i]); + dpi_fle (fncp_fire, dataa[i], datab[i], result_fle[i], fflags_fle[i]); + dpi_feq (fncp_fire, dataa[i], datab[i], result_feq[i], fflags_feq[i]); + dpi_fmin (fncp_fire, dataa[i], datab[i], result_fmin[i], fflags_fmin[i]); + dpi_fmax (fncp_fire, dataa[i], datab[i], result_fmax[i], fflags_fmax[i]); + dpi_fsgnj (fncp_fire, dataa[i], datab[i], result_fsgnj[i]); + dpi_fsgnjn (fncp_fire, dataa[i], datab[i], result_fsgnjn[i]); + dpi_fsgnjx (fncp_fire, dataa[i], datab[i], result_fsgnjx[i]); result_fmv[i] = dataa[i]; end end @@ -354,9 +367,6 @@ module VX_fpu_dpi #( is_fmax ? fflags_fmax : 0; - wire enable = per_core_ready_out[FPU_NCP] || ~per_core_valid_out[FPU_NCP]; - wire valid = (valid_in && core_select == FPU_NCP); - VX_shift_register #( .DATAW (1 + TAGW + 1 + `NUM_THREADS * (32 + $bits(fflags_t))), .DEPTH (`LATENCY_FNCP), @@ -364,12 +374,12 @@ module VX_fpu_dpi #( ) shift_reg ( .clk (clk), .reset (reset), - .enable (enable), - .data_in ({valid, tag_in, has_fflags_fncp, result_fncp, fflags_fncp}), + .enable (fncp_ready), + .data_in ({fncp_valid, tag_in, has_fflags_fncp, result_fncp, fflags_fncp}), .data_out ({per_core_valid_out[FPU_NCP], per_core_tag_out[FPU_NCP], per_core_has_fflags[FPU_NCP], per_core_result[FPU_NCP], per_core_fflags[FPU_NCP]}) ); - assign per_core_ready_in[FPU_NCP] = enable; + assign per_core_ready_in[FPU_NCP] = fncp_ready; end endgenerate diff --git a/runtime/Makefile b/runtime/Makefile index fe486999..60c3b398 100644 --- a/runtime/Makefile +++ b/runtime/Makefile @@ -26,7 +26,7 @@ $(PROJECT).dump: $(PROJECT).a $(CC) $(CFLAGS) -c $< -o $@ $(PROJECT).a: $(OBJS) - $(AR) rc $(PROJECT).a $^ + $(AR) rcs $(PROJECT).a $^ .depend: $(SRCS) $(CC) $(CFLAGS) -MM $^ > .depend; diff --git a/sim/Makefile b/sim/Makefile index e0361709..eca60c0b 100644 --- a/sim/Makefile +++ b/sim/Makefile @@ -1,9 +1,11 @@ all: + $(MAKE) -C common $(MAKE) -C simX $(MAKE) -C rtlsim $(MAKE) -C vlsim clean: + $(MAKE) -C common clean $(MAKE) -C simX clean $(MAKE) -C rtlsim clean $(MAKE) -C vlsim clean \ No newline at end of file diff --git a/sim/common/Makefile b/sim/common/Makefile new file mode 100644 index 00000000..b17dc25b --- /dev/null +++ b/sim/common/Makefile @@ -0,0 +1,5 @@ +all: + SPECIALIZE_TYPE=RISCV SOFTFLOAT_OPTS="-fPIC -DSOFTFLOAT_ROUND_ODD -DINLINE_LEVEL=5 -DSOFTFLOAT_FAST_DIV32TO16 -DSOFTFLOAT_FAST_DIV64TO32" $(MAKE) -C softfloat/build/Linux-x86_64-GCC + +clean: + $(MAKE) -C softfloat/build/Linux-x86_64-GCC clean \ No newline at end of file diff --git a/sim/common/softfloat b/sim/common/softfloat new file mode 160000 index 00000000..b64af41c --- /dev/null +++ b/sim/common/softfloat @@ -0,0 +1 @@ +Subproject commit b64af41c3276f97f0e181920400ee056b9c88037 diff --git a/sim/common/util.cpp b/sim/common/util.cpp index 94aa3540..eb125499 100644 --- a/sim/common/util.cpp +++ b/sim/common/util.cpp @@ -1,90 +1,8 @@ #include "util.h" -#include -#include -#include -#include #include -#include -#include - -using namespace vortex; - -// Apply integer sign extension -uint32_t vortex::signExt(uint32_t w, uint32_t bit, uint32_t mask) { - if (w >> (bit - 1)) - w |= ~mask; - return w; -} - -// Convert a floating point number to IEEE-754 32-bit representation, -// so that it could be stored in a 32-bit integer register file -// Reference: https://www.wikihow.com/Convert-a-Number-from-Decimal-to-IEEE-754-Floating-Point-Representation - // https://www.technical-recipes.com/2012/converting-between-binary-and-decimal-representations-of-ieee-754-floating-point-numbers-in-c/ -uint32_t vortex::floatToBin(float in_value) { - union { - float input; // assumes sizeof(float) == sizeof(int) - int output; - } data; - - data.input = in_value; - - std::bitset bits(data.output); - std::string mystring = bits.to_string, std::allocator>(); - // Convert binary to uint32_t - uint32_t result = stoul(mystring, nullptr, 2); - return result; -} - -// https://en.wikipedia.org/wiki/Single-precision_floating-point_format -// check floating-point number in binary format is NaN -uint8_t vortex::fpBinIsNan(uint32_t din) { - bool fsign = din & 0x80000000; - uint32_t expo = (din>>23) & 0x000000FF; - uint32_t fraction = din & 0x007FFFFF; - uint32_t bit_22 = din & 0x00400000; - - if ((expo==0xFF) && (fraction!=0)) { - // if (!fsign && (fraction == 0x00400000)) - if (!fsign && (bit_22)) - return 1; // quiet NaN, return 1 - else - return 2; // signaling NaN, return 2 - } - return 0; -} - -// check floating-point number in binary format is zero -uint8_t vortex::fpBinIsZero(uint32_t din) { - bool fsign = din & 0x80000000; - uint32_t expo = (din>>23) & 0x000000FF; - uint32_t fraction = din & 0x007FFFFF; - - if ((expo==0) && (fraction==0)) { - if (fsign) - return 1; // negative 0 - else - return 2; // positive 0 - } - return 0; // not zero -} - -// check floating-point number in binary format is infinity -uint8_t vortex::fpBinIsInf(uint32_t din) { - bool fsign = din & 0x80000000; - uint32_t expo = (din>>23) & 0x000000FF; - uint32_t fraction = din & 0x007FFFFF; - - if ((expo==0xFF) && (fraction==0)) { - if (fsign) - return 1; // negative infinity - else - return 2; // positive infinity - } - return 0; // not infinity -} // return file extension -const char* vortex::fileExtension(const char* filepath) { +const char* fileExtension(const char* filepath) { const char *ext = strrchr(filepath, '.'); if (ext == NULL || ext == filepath) return ""; diff --git a/sim/common/util.h b/sim/common/util.h index d04d4fe8..dbaeb5fa 100644 --- a/sim/common/util.h +++ b/sim/common/util.h @@ -3,8 +3,6 @@ #include #include -namespace vortex { - template void unused(Args&&...) {} @@ -24,21 +22,11 @@ inline uint64_t align_size(uint64_t size, uint64_t alignment) { } // Apply integer sign extension -uint32_t signExt(uint32_t w, uint32_t bit, uint32_t mask); - -// Convert a floating point number to IEEE-754 32-bit representation -uint32_t floatToBin(float in_value); - -// check floating-point number in binary format is NaN -uint8_t fpBinIsNan(uint32_t din); - -// check floating-point number in binary format is zero -uint8_t fpBinIsZero(uint32_t din); - -// check floating-point number in binary format is infinity -uint8_t fpBinIsInf(uint32_t din); +inline uint32_t signExt(uint32_t w, uint32_t bit, uint32_t mask) { + if (w >> (bit - 1)) + w |= ~mask; + return w; +} // return file extension -const char* fileExtension(const char* filepath); - -} \ No newline at end of file +const char* fileExtension(const char* filepath); \ No newline at end of file diff --git a/sim/rtlsim/Makefile b/sim/rtlsim/Makefile index c1fb8f9d..c4d66a2d 100644 --- a/sim/rtlsim/Makefile +++ b/sim/rtlsim/Makefile @@ -1,8 +1,12 @@ -CXXFLAGS += -std=c++11 -O2 -Wall -Wextra -Wfatal-errors -#CXXFLAGS += -std=c++11 -g -O0 -Wall -Wextra -Wfatal-errors +RTL_DIR=../../hw/rtl +DPI_DIR=../../hw/dpi +CXXFLAGS += -std=c++11 -Wall -Wextra -Wfatal-errors CXXFLAGS += -fPIC -Wno-maybe-uninitialized CXXFLAGS += -I../../../hw -I../../common +CXXFLAGS += -I../../common/softfloat/source/include + +LDFLAGS += ../../common/softfloat/build/Linux-x86_64-GCC/softfloat.a # control RTL debug print states DBG_PRINT_FLAGS += -DDBG_PRINT_PIPELINE @@ -21,16 +25,10 @@ DBG_FLAGS += $(DBG_PRINT_FLAGS) DBG_FLAGS += -DDBG_CACHE_REQ_INFO DBG_FLAGS += -DVCD_OUTPUT -SINGLECORE = -DNUM_CLUSTERS=1 -DNUM_CORES=1 -DL2_ENABLE=0 -MULTICORE = -DNUM_CLUSTERS=1 -DNUM_CORES=2 -DL2_ENABLE=0 - -RTL_DIR=../../hw/rtl -DPI_DIR=../../hw/dpi - FPU_INCLUDE = -I$(RTL_DIR)/fp_cores -I$(RTL_DIR)/fp_cores/fpnew/src/common_cells/include -I$(RTL_DIR)/fp_cores/fpnew/src/common_cells/src -I$(RTL_DIR)/fp_cores/fpnew/src/fpu_div_sqrt_mvp/hdl -I$(RTL_DIR)/fp_cores/fpnew/src RTL_INCLUDE = -I$(RTL_DIR) -I$(DPI_DIR) -I$(RTL_DIR)/libs -I$(RTL_DIR)/interfaces -I$(RTL_DIR)/cache -I$(RTL_DIR)/simulate $(FPU_INCLUDE) -SRCS = ../common/util.cpp ../common/mem.cpp +SRCS = ../common/util.cpp ../common/mem.cpp ../common/rvfloats.cpp SRCS += $(DPI_DIR)/util_dpi.cpp $(DPI_DIR)/float_dpi.cpp SRCS += main.cpp simulator.cpp @@ -52,10 +50,10 @@ VL_FLAGS += $(RTL_INCLUDE) # Debugigng ifdef DEBUG VL_FLAGS += -DVCD_OUTPUT --trace --trace-structs $(DBG_FLAGS) - CXXFLAGS += -DVCD_OUTPUT $(DBG_FLAGS) + CXXFLAGS += -g -O0 -DVCD_OUTPUT $(DBG_FLAGS) else VL_FLAGS += -DNDEBUG - CXXFLAGS += -DNDEBUG + CXXFLAGS += -O2 -DNDEBUG endif # Enable perf counters @@ -69,36 +67,21 @@ VL_FLAGS += -DIMUL_DPI VL_FLAGS += -DIDIV_DPI # FPU backend -FPU_CORE ?= FPU_FPNEW +FPU_CORE ?= FPU_DPI VL_FLAGS += -D$(FPU_CORE) THREADS ?= $(shell python3 -c 'import multiprocessing as mp; print(max(1, mp.cpu_count() // 2))') PROJECT = rtlsim -all: build-s +all: $(PROJECT) -build-s: $(SRCS) - verilator --build $(VL_FLAGS) -DNDEBUG $(SRCS) $(SINGLECORE) -CFLAGS '$(CXXFLAGS) -DNDEBUG $(SINGLECORE)' -o ../$(PROJECT) +$(PROJECT): $(SRCS) + verilator --build $(VL_FLAGS) $(SRCS) -CFLAGS '$(CXXFLAGS)' -LDFLAGS '$(LDFLAGS)' -o ../$(PROJECT) -build-sd: $(SRCS) - verilator --build $(VL_FLAGS) $(SRCS) $(SINGLECORE) -CFLAGS '$(CXXFLAGS) $(DBG_FLAGS) $(SINGLECORE)' --trace --trace-structs $(DBG_FLAGS) -o ../$(PROJECT) - -build-st: $(SRCS) - verilator --build $(VL_FLAGS) -DNDEBUG $(SRCS) $(SINGLECORE) -CFLAGS '$(CXXFLAGS) -DNDEBUG $(SINGLECORE)' --threads $(THREADS) -o ../$(PROJECT) - -build-m: $(SRCS) - verilator --build $(VL_FLAGS) -DNDEBUG $(SRCS) $(MULTICORE) -CFLAGS '$(CXXFLAGS) -DNDEBUG $(MULTICORE)' -o ../$(PROJECT) - -build-md: $(SRCS) - verilator --build $(VL_FLAGS) $(SRCS) $(MULTICORE) -CFLAGS '$(CXXFLAGS) $(DBG_FLAGS) $(MULTICORE)' --trace --trace-structs $(DBG_FLAGS) -o ../$(PROJECT) - -build-mt: $(SRCS) - verilator --build $(VL_FLAGS) -DNDEBUG $(SRCS) $(MULTICORE) -CFLAGS '$(CXXFLAGS) -DNDEBUG $(MULTICORE)' --threads $(THREADS) -o ../$(PROJECT) - static: $(SRCS) - verilator --build $(VL_FLAGS) $(SRCS) -CFLAGS '$(CXXFLAGS)' - $(AR) rs lib$(PROJECT).a obj_dir/*.o + verilator --build $(VL_FLAGS) $(SRCS) -CFLAGS '$(CXXFLAGS)' -LDFLAGS '$(LDFLAGS)' + $(AR) rcs lib$(PROJECT).a obj_dir/*.o clean-static: rm -rf lib$(PROJECT).a obj_dir diff --git a/sim/simX/Makefile b/sim/simX/Makefile index b126ceb6..2dc4eaf7 100644 --- a/sim/simX/Makefile +++ b/sim/simX/Makefile @@ -1,17 +1,15 @@ -#CXXFLAGS += -std=c++11 -O2 -Wall -Wextra -Wfatal-errors -CXXFLAGS += -std=c++11 -g -O0 -Wall -Wextra -Wfatal-errors +RTL_DIR = ../hw/rtl +CXXFLAGS += -std=c++11 -Wall -Wextra -Wfatal-errors CXXFLAGS += -fPIC -Wno-maybe-uninitialized CXXFLAGS += -I. -I../common -I../../hw -CXXFLAGS += -DDUMP_PERF_STATS +CXXFLAGS += -I../common/softfloat/source/include + +LDFLAGS += ../common/softfloat/build/Linux-x86_64-GCC/softfloat.a TOP = vx_cache_sim -RTL_DIR = ../hw/rtl - -PROJECT = simX - -SRCS = ../common/util.cpp ../common/mem.cpp +SRCS = ../common/util.cpp ../common/mem.cpp ../common/rvfloats.cpp SRCS += args.cpp pipeline.cpp warp.cpp core.cpp decode.cpp execute.cpp main.cpp OBJS := $(patsubst %.cpp, obj_dir/%.o, $(notdir $(SRCS))) @@ -22,11 +20,13 @@ VPATH := $(sort $(dir $(SRCS))) # Debugigng ifdef DEBUG - CXXFLAGS += -DDEBUG_LEVEL=$(DEBUG) + CXXFLAGS += -g -O0 -DDEBUG_LEVEL=$(DEBUG) else - CXXFLAGS += -DNDEBUG + CXXFLAGS += -O2 -DNDEBUG endif +PROJECT = simX + all: $(PROJECT) $(PROJECT): $(SRCS) @@ -37,7 +37,7 @@ obj_dir/%.o: %.cpp $(CXX) $(CXXFLAGS) -c $< -o $@ static: $(OBJS) - $(AR) rs lib$(PROJECT).a $(OBJS) + $(AR) rcs lib$(PROJECT).a $(OBJS) .depend: $(SRCS) $(CXX) $(CXXFLAGS) -MM $^ > .depend; diff --git a/sim/simX/execute.cpp b/sim/simX/execute.cpp index dfb38ab4..01271e59 100644 --- a/sim/simX/execute.cpp +++ b/sim/simX/execute.cpp @@ -6,9 +6,9 @@ #include #include #include -#include #include #include +#include #include "warp.h" #include "instr.h" #include "core.h" @@ -38,30 +38,14 @@ static bool HasDivergentThreads(const ThreadMask &thread_mask, return false; } -static void update_fcrs(Core* core, int tid, int wid, bool outOfRange = false) { - if (fetestexcept(FE_INEXACT)) { - core->set_csr(CSR_FCSR, core->get_csr(CSR_FCSR, tid, wid) | 0x1, tid, wid); // set NX bit - core->set_csr(CSR_FFLAGS, core->get_csr(CSR_FFLAGS, tid, wid) | 0x1, tid, wid); // set NX bit - } - - if (fetestexcept(FE_UNDERFLOW)) { - core->set_csr(CSR_FCSR, core->get_csr(CSR_FCSR, tid, wid) | 0x2, tid, wid); // set UF bit - core->set_csr(CSR_FFLAGS, core->get_csr(CSR_FFLAGS, tid, wid) | 0x2, tid, wid); // set UF bit - } +inline uint32_t get_fpu_rm(uint32_t func3, Core* core, uint32_t tid, uint32_t wid) { + return (func3 == 0x7) ? core->get_csr(CSR_FRM, tid, wid) : func3; +} - if (fetestexcept(FE_OVERFLOW)) { - core->set_csr(CSR_FCSR, core->get_csr(CSR_FCSR, tid, wid) | 0x4, tid, wid); // set OF bit - core->set_csr(CSR_FFLAGS, core->get_csr(CSR_FFLAGS, tid, wid) | 0x4, tid, wid); // set OF bit - } - - if (fetestexcept(FE_DIVBYZERO)) { - core->set_csr(CSR_FCSR, core->get_csr(CSR_FCSR, tid, wid) | 0x8, tid, wid); // set DZ bit - core->set_csr(CSR_FFLAGS, core->get_csr(CSR_FFLAGS, tid, wid) | 0x8, tid, wid); // set DZ bit - } - - if (fetestexcept(FE_INVALID) || outOfRange) { - core->set_csr(CSR_FCSR, core->get_csr(CSR_FCSR, tid, wid) | 0x10, tid, wid); // set NV bit - core->set_csr(CSR_FFLAGS, core->get_csr(CSR_FFLAGS, tid, wid) | 0x10, tid, wid); // set NV bit +inline void update_fcrs(uint32_t fflags, Core* core, uint32_t tid, uint32_t wid) { + if (fflags) { + core->set_csr(CSR_FCSR, core->get_csr(CSR_FCSR, tid, wid) | fflags, tid, wid); + core->set_csr(CSR_FFLAGS, core->get_csr(CSR_FFLAGS, tid, wid) | fflags, tid, wid); } } @@ -514,320 +498,120 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) { } } break; - case FCI: // floating point computational instruction + case FCI: { + uint32_t frm = get_fpu_rm(func3, core_, t, id_); + uint32_t fflags = 0; switch (func7) { - case 0x00: //FADD - case 0x04: //FSUB - case 0x08: //FMUL - case 0x0c: //FDIV - case 0x2c: //FSQRT - { - if (fpBinIsNan(rsdata[0]) || fpBinIsNan(rsdata[1])) { - // if one of op is NaN, one of them is not quiet NaN, them set FCSR - if ((fpBinIsNan(rsdata[0])==2) | (fpBinIsNan(rsdata[1])==2)) { - core_->set_csr(CSR_FCSR, core_->get_csr(CSR_FCSR, t, id_) | 0x10, t, id_); // set NV bit - core_->set_csr(CSR_FFLAGS, core_->get_csr(CSR_FFLAGS, t, id_) | 0x10, t, id_); // set NV bit - } - if (fpBinIsNan(rsdata[0]) && fpBinIsNan(rsdata[1])) - rddata = 0x7fc00000; // canonical(quiet) NaN - else if (fpBinIsNan(rsdata[0])) - rddata = rsdata[1]; - else - rddata = rsdata[0]; - } else { - float fpsrc_0 = *(float*)&rsdata[0]; - float fpsrc_1 = *(float*)&rsdata[1]; - float fpDest; - - feclearexcept(FE_ALL_EXCEPT); - - if (func7 == 0x00) // FADD - fpDest = fpsrc_0 + fpsrc_1; - else if (func7==0x04) // FSUB - fpDest = fpsrc_0 - fpsrc_1; - else if (func7==0x08) // FMUL - fpDest = fpsrc_0 * fpsrc_1; - else if (func7==0x0c) // FDIV - fpDest = fpsrc_0 / fpsrc_1; - else if (func7==0x2c) // FSQRT - fpDest = sqrt(fpsrc_0); - else { - std::abort(); - } - - // update fcsrs - update_fcrs(core_, t, id_); - - D(3, "fpDest: " << fpDest); - if (fpBinIsNan(floatToBin(fpDest)) == 0) { - rddata = floatToBin(fpDest); - } else { - // According to risc-v spec p.64 section 11.3 - // If the result is NaN, it is the canonical NaN - rddata = 0x7fc00000; - } - } - } break; - - // FSGNJ.S, FSGNJN.S, FSGNJX.S - case 0x10: { - bool fsign1 = rsdata[0] & 0x80000000; - uint32_t fdata1 = rsdata[0] & 0x7FFFFFFF; - bool fsign2 = rsdata[1] & 0x80000000; - switch (func3) { - case 0: // FSGNJ.S - rddata = (fsign2 << 31) | fdata1; - break; - case 1: // FSGNJN.S - fsign2 = !fsign2; - rddata = (fsign2 << 31) | fdata1; - break; - case 2: { // FSGNJX.S - bool sign = fsign1 ^ fsign2; - rddata = (sign << 31) | fdata1; - } break; - } - } break; - - // FMIN.S, FMAX.S - case 0x14: { - if (fpBinIsNan(rsdata[0]) || fpBinIsNan(rsdata[1])) { // if one of src is NaN - // one of them is not quiet NaN, them set FCSR - if ((fpBinIsNan(rsdata[0])==2) | (fpBinIsNan(rsdata[1])==2)) { - core_->set_csr(CSR_FCSR, core_->get_csr(CSR_FCSR, t, id_) | 0x10, t, id_); // set NV bit - core_->set_csr(CSR_FFLAGS, core_->get_csr(CSR_FFLAGS, t, id_) | 0x10, t, id_); // set NV bit - } - if (fpBinIsNan(rsdata[0]) && fpBinIsNan(rsdata[1])) - rddata = 0x7fc00000; // canonical(quiet) NaN - else if (fpBinIsNan(rsdata[0])) - rddata = rsdata[1]; - else - rddata = rsdata[0]; - } else { - uint8_t sr0IsZero = fpBinIsZero(rsdata[0]); - uint8_t sr1IsZero = fpBinIsZero(rsdata[1]); - - if (sr0IsZero && sr1IsZero && (sr0IsZero != sr1IsZero)) { - // both are zero and not equal - // handle corner case that compare +0 and -0 - if (func3) { - // FMAX.S - rddata = (sr1IsZero==2) ? rsdata[1] : rsdata[0]; - } else { - // FMIM.S - rddata = (sr1IsZero==2) ? rsdata[0] : rsdata[1]; - } - } else { - float rs1 = *(float*)&rsdata[0]; - float rs2 = *(float*)&rsdata[1]; - if (func3) { - // FMAX.S - float fmax = std::max(rs1, rs2); - rddata = floatToBin(fmax); - } else { - // FMIN.S - float fmin = std::min(rs1, rs2); - rddata = floatToBin(fmin); - } - } - } - } break; - - // FCVT.W.S FCVT.WU.S - case 0x60: { - float fpSrc = *(float*)&rsdata[0]; - Word result; - bool outOfRange = false; - if (rsrc1 == 0) { - // FCVT.W.S - // Convert floating point to 32-bit signed integer - if (fpSrc > pow(2.0, 31) - 1 || fpBinIsNan(rsdata[0]) || fpBinIsInf(rsdata[0]) == 2) { - feclearexcept(FE_ALL_EXCEPT); - outOfRange = true; - // result = 2^31 - 1 - result = 0x7FFFFFFF; - } else if (fpSrc < -1*pow(2.0, 31) || fpBinIsInf(rsdata[0]) == 1) { - feclearexcept(FE_ALL_EXCEPT); - outOfRange = true; - // result = -1*2^31 - result = 0x80000000; - } else { - feclearexcept(FE_ALL_EXCEPT); - result = (int32_t) fpSrc; - } - } else { - // FCVT.WU.S - // Convert floating point to 32-bit unsigned integer - if (fpSrc > pow(2.0, 32) - 1 || fpBinIsNan(rsdata[0]) || fpBinIsInf(rsdata[0]) == 2) { - feclearexcept(FE_ALL_EXCEPT); - outOfRange = true; - // result = 2^32 - 1 - result = 0xFFFFFFFF; - } else if (fpSrc <= -1.0 || fpBinIsInf(rsdata[0]) == 1) { - feclearexcept(FE_ALL_EXCEPT); - outOfRange = true; - // result = 0 - result = 0x00000000; - } else { - feclearexcept(FE_ALL_EXCEPT); - result = (uint32_t) fpSrc; - } - } - - // update fcsrs - update_fcrs(core_, t, id_, outOfRange); - - rddata = result; - } break; - - // FMV.X.W FCLASS.S - case 0x70: { - // FCLASS.S - if (func3) { - // Examine the value in fpReg rs1 and write to integer rd - // a 10-bit mask to indicate the class of the fp number - rddata = 0; // clear all bits - - bool fsign = rsdata[0] & 0x80000000; - uint32_t expo = (rsdata[0]>>23) & 0x000000FF; - uint32_t fraction = rsdata[0] & 0x007FFFFF; - - if ((expo==0) && (fraction==0)) { - rddata = fsign ? (1<<3) : (1<<4); // +/- 0 - } else if ((expo==0) && (fraction!=0)) { - rddata = fsign ? (1<<2) : (1<<5); // +/- subnormal - } else if ((expo==0xFF) && (fraction==0)) { - rddata = fsign ? (1<<0) : (1<<7); // +/- infinity - } else if ((expo==0xFF) && (fraction!=0)) { - if (!fsign && (fraction == 0x00400000)) { - rddata = (1<<9); // quiet NaN - } else { - rddata = (1<<8); // signaling NaN - } - } else { - rddata = fsign ? (1<<1) : (1<<6); // +/- normal - } - } else { - // FMV.X.W - // Move bit values from floating-point register rs1 to integer register rd - // Since we are using integer register to represent floating point register, - // just simply assign here. - rddata = rsdata[0]; - } - } break; - - // FEQ.S FLT.S FLE.S - // rdest is integer register - case 0x50: { - // TODO: FLT.S and FLE.S perform IEEE 754-2009, signaling comparisons, set - // TODO: the invalid operation exception flag if either input is NaN - if (fpBinIsNan(rsdata[0]) || fpBinIsNan(rsdata[1])) { - // FLE.S or FLT.S - if (func3 == 0 || func3 == 1) { - // If either input is NaN, set NV bit - core_->set_csr(CSR_FCSR, core_->get_csr(CSR_FCSR, t, id_) | 0x10, t, id_); // set NV bit - core_->set_csr(CSR_FFLAGS, core_->get_csr(CSR_FFLAGS, t, id_) | 0x10, t, id_); // set NV bit - } else { // FEQ.S - // Only set NV bit if it is signaling NaN - if (fpBinIsNan(rsdata[0]) == 2 || fpBinIsNan(rsdata[1]) == 2) { - // If either input is NaN, set NV bit - core_->set_csr(CSR_FCSR, core_->get_csr(CSR_FCSR, t, id_) | 0x10, t, id_); // set NV bit - core_->set_csr(CSR_FFLAGS, core_->get_csr(CSR_FFLAGS, t, id_) | 0x10, t, id_); // set NV bit - } - } - // The result is 0 if either operand is NaN - rddata = 0; - } else { - switch(func3) { - case 0: { - // FLE.S - rddata = (*(float*)&rsdata[0] <= *(float*)&rsdata[1]); - } break; - case 1: { - // FLT.S - rddata = (*(float*)&rsdata[0] < *(float*)&rsdata[1]); - } break; - case 2: { - // FEQ.S - rddata = (*(float*)&rsdata[0] == *(float*)&rsdata[1]); - } break; - default: - std::abort(); - } - } - } break; - - case 0x68: - // Cast integer to floating point - if (rsrc1) { - // FCVT.S.WU: convert 32-bit unsigned integer to floating point - float data = rsdata[0]; - rddata = floatToBin(data); - } else { - // FCVT.S.W: convert 32-bit signed integer to floating point - // rsdata[0] is actually a unsigned number - float data = (WordI)rsdata[0]; - rddata = floatToBin(data); - } + case 0x00: //FADD + rddata = rv_fadd(rsdata[0], rsdata[1], frm, &fflags); break; - - case 0x78: { - // FMV.W.X - // Move bit values from integer register rs1 to floating register rd - // Since we are using integer register to represent floating point register, - // just simply assign here. - rddata = rsdata[0]; + case 0x04: //FSUB + rddata = rv_fsub(rsdata[0], rsdata[1], frm, &fflags); + break; + case 0x08: //FMUL + rddata = rv_fmul(rsdata[0], rsdata[1], frm, &fflags); + break; + case 0x0c: //FDIV + rddata = rv_fdiv(rsdata[0], rsdata[1], frm, &fflags); + break; + case 0x2c: //FSQRT + rddata = rv_fsqrt(rsdata[0], frm, &fflags); + break; + case 0x10: + switch (func3) { + case 0: // FSGNJ.S + rddata = rv_fsgnj(rsdata[0], rsdata[1]); + break; + case 1: // FSGNJN.S + rddata = rv_fsgnjn(rsdata[0], rsdata[1]); + break; + case 2: // FSGNJX.S + rddata = rv_fsgnjx(rsdata[0], rsdata[1]); + break; } break; + case 0x14: + if (func3) { + // FMAX.S + rddata = rv_fmax(rsdata[0], rsdata[1], &fflags); + } else { + // FMIN.S + rddata = rv_fmin(rsdata[0], rsdata[1], &fflags); + } + break; + case 0x60: + if (rsrc1 == 0) { + // FCVT.W.S + rddata = rv_ftoi(rsdata[0], frm, &fflags); + } else { + // FCVT.WU.S + rddata = rv_ftou(rsdata[0], frm, &fflags); + } + break; + case 0x70: + if (func3) { + // FCLASS.S + rddata = rv_fclss(rsdata[0]); + } else { + // FMV.X.W + rddata = rsdata[0]; + } + break; + case 0x50: + switch(func3) { + case 0: + // FLE.S + rddata = rv_fle(rsdata[0], rsdata[1], &fflags); + break; + case 1: + // FLT.S + rddata = rv_flt(rsdata[0], rsdata[1], &fflags); + break; + case 2: + // FEQ.S + rddata = rv_feq(rsdata[0], rsdata[1], &fflags); + break; + } break; + case 0x68: + if (rsrc1) { + // FCVT.S.WU: + rddata = rv_utof(rsdata[0], frm, &fflags); + } else { + // FCVT.S.W: + rddata = rv_itof(rsdata[0], frm, &fflags); + } + break; + case 0x78: + // FMV.W.X + rddata = rsdata[0]; + break; } + update_fcrs(fflags, core_, t, id_); rd_write = true; - break; - + } break; case FMADD: case FMSUB: case FMNMADD: case FMNMSUB: { - // multiplicands are infinity and zero, them set FCSR - if (fpBinIsZero(rsdata[0]) || fpBinIsZero(rsdata[1]) || fpBinIsInf(rsdata[0]) || fpBinIsInf(rsdata[1])) { - core_->set_csr(CSR_FCSR, core_->get_csr(CSR_FCSR, t, id_) | 0x10, t, id_); // set NV bit - core_->set_csr(CSR_FFLAGS, core_->get_csr(CSR_FFLAGS, t, id_) | 0x10, t, id_); // set NV bit - } - if (fpBinIsNan(rsdata[0]) || fpBinIsNan(rsdata[1]) || fpBinIsNan(rsdata[2])) { - // if one of op is NaN, if addend is not quiet NaN, them set FCSR - if ((fpBinIsNan(rsdata[0])==2) | (fpBinIsNan(rsdata[1])==2) | (fpBinIsNan(rsdata[1])==2)) { - core_->set_csr(CSR_FCSR, core_->get_csr(CSR_FCSR, t, id_) | 0x10, t, id_); // set NV bit - core_->set_csr(CSR_FFLAGS, core_->get_csr(CSR_FFLAGS, t, id_) | 0x10, t, id_); // set NV bit - } - rddata = 0x7fc00000; // canonical(quiet) NaN - } else { - float rs1 = *(float*)&rsdata[0]; - float rs2 = *(float*)&rsdata[1]; - float rs3 = *(float*)&rsdata[2]; - float fpDest(0.0); - feclearexcept(FE_ALL_EXCEPT); - switch (opcode) { - case FMADD: - // rd = (rs1*rs2)+rs3 - fpDest = (rs1 * rs2) + rs3; break; - case FMSUB: - // rd = (rs1*rs2)-rs3 - fpDest = (rs1 * rs2) - rs3; break; - case FMNMADD: - // rd = -(rs1*rs2)+rs3 - fpDest = -1*(rs1 * rs2) - rs3; break; - case FMNMSUB: - // rd = -(rs1*rs2)-rs3 - fpDest = -1*(rs1 * rs2) + rs3; break; - default: - std::abort(); - break; - } - - // update fcsrs - update_fcrs(core_, t, id_); - - rddata = floatToBin(fpDest); - } + int frm = get_fpu_rm(func3, core_, t, id_); + Word fflags = 0; + switch (opcode) { + case FMADD: + rddata = rv_fmadd(rsdata[0], rsdata[1], rsdata[2], frm, &fflags); + break; + case FMSUB: + rddata = rv_fmsub(rsdata[0], rsdata[1], rsdata[2], frm, &fflags); + break; + case FMNMADD: + rddata = rv_fnmadd(rsdata[0], rsdata[1], rsdata[2], frm, &fflags); + break; + case FMNMSUB: + rddata = rv_fnmsub(rsdata[0], rsdata[1], rsdata[2], frm, &fflags); + break; + default: + break; + } + update_fcrs(fflags, core_, t, id_); rd_write = true; } break; case GPGPU: diff --git a/sim/vlsim/Makefile b/sim/vlsim/Makefile index a299c62f..b58429fc 100644 --- a/sim/vlsim/Makefile +++ b/sim/vlsim/Makefile @@ -1,8 +1,13 @@ -CXXFLAGS += -std=c++11 -O2 -Wall -Wextra -Wfatal-errors -#CXXFLAGS += -std=c++11 -g -O0 -Wall -Wextra -Wfatal-errors +RTL_DIR = ../../hw/rtl +DPI_DIR = ../../hw/dpi +SCRIPT_DIR=../../hw/scripts +CXXFLAGS += -std=c++11 -Wall -Wextra -Wfatal-errors CXXFLAGS += -fPIC -Wno-maybe-uninitialized CXXFLAGS += -I.. -I../../../hw -I../../common +CXXFLAGS += -I../../common/softfloat/source/include + +LDFLAGS += -shared ../../common/softfloat/build/Linux-x86_64-GCC/softfloat.a # control RTL debug print states DBG_PRINT_FLAGS += -DDBG_PRINT_PIPELINE @@ -23,15 +28,9 @@ DBG_FLAGS += -DDBG_CACHE_REQ_INFO CONFIGS ?= -DNUM_CLUSTERS=1 -DNUM_CORES=1 CXXFLAGS += $(CONFIGS) -CXXFLAGS += -DDUMP_PERF_STATS +CXXFLAGS += -D -LDFLAGS += -shared - -RTL_DIR = ../../hw/rtl -DPI_DIR = ../../hw/dpi -SCRIPT_DIR=../../hw/scripts - -SRCS = ../common/util.cpp ../common/mem.cpp +SRCS = ../common/util.cpp ../common/mem.cpp ../common/rvfloats.cpp SRCS += $(DPI_DIR)/util_dpi.cpp $(DPI_DIR)/float_dpi.cpp SRCS += fpga.cpp opae_sim.cpp @@ -56,10 +55,10 @@ VL_FLAGS += $(RTL_INCLUDE) # Debugigng ifdef DEBUG VL_FLAGS += -DVCD_OUTPUT --trace --trace-structs $(DBG_FLAGS) - CXXFLAGS += -DVCD_OUTPUT $(DBG_FLAGS) + CXXFLAGS += -g -O0 -DVCD_OUTPUT $(DBG_FLAGS) else VL_FLAGS += -DNDEBUG - CXXFLAGS += -DNDEBUG + CXXFLAGS += -O2 -DNDEBUG endif # Enable scope analyzer @@ -98,7 +97,7 @@ shared: $(SRCS) vortex_afu.h static: $(SRCS) vortex_afu.h verilator --build $(VL_FLAGS) $(SRCS) -CFLAGS '$(CXXFLAGS)' -LDFLAGS '$(LDFLAGS)' - $(AR) rs $(PROJECT).a obj_dir/*.o + $(AR) rcs $(PROJECT).a obj_dir/*.o clean-static: rm -rf $(PROJECT).a obj_dir vortex_afu.h diff --git a/tests/riscv/isa/Makefile b/tests/riscv/isa/Makefile index b3d22140..fba3bdd1 100644 --- a/tests/riscv/isa/Makefile +++ b/tests/riscv/isa/Makefile @@ -7,8 +7,12 @@ EXCLUDED_TESTS := $(V_TESTS) $(D_TESTS) rv32si-p-scall.hex rv32si-p-sbreak.hex r TESTS := $(filter-out $(EXCLUDED_TESTS), $(ALL_TESTS)) +all: + run-simx: $(foreach test, $(TESTS), ../../../sim/simX/simX -r -a rv32i -c 1 -i $(test) || exit;) run-rtlsim: - $(foreach test, $(TESTS), ../../../sim/rtlsim/rtlsim -r $(test) || exit;) \ No newline at end of file + $(foreach test, $(TESTS), ../../../sim/rtlsim/rtlsim -r $(test) || exit;) + +clean: \ No newline at end of file