diff --git a/hw/dpi/float_dpi.cpp b/hw/dpi/float_dpi.cpp index 570d6bf2..1f438ed9 100644 --- a/hw/dpi/float_dpi.cpp +++ b/hw/dpi/float_dpi.cpp @@ -37,6 +37,7 @@ extern "C" { void dpi_fdiv(bool enable, int dst_fmt, int64_t a, int64_t b, const svBitVecVal* frm, int64_t* result, svBitVecVal* fflags); void dpi_fsqrt(bool enable, int dst_fmt, int64_t a, const svBitVecVal* frm, int64_t* result, svBitVecVal* fflags); + void dpi_fexp(bool enable, int dst_fmt, int64_t a, int64_t* result, svBitVecVal* fflags); void dpi_ftoi(bool enable, int dst_fmt, int src_fmt, int64_t a, const svBitVecVal* frm, int64_t* result, svBitVecVal* fflags); void dpi_ftou(bool enable, int dst_fmt, int src_fmt, int64_t a, const svBitVecVal* frm, int64_t* result, svBitVecVal* fflags); @@ -83,6 +84,22 @@ inline int64_t check_boxing(int64_t a) { return a; } +inline float bits_to_float(uint32_t value) { + union { + uint32_t u; + float f; + } bits = {value}; + return bits.f; +} + +inline uint32_t float_to_bits(float value) { + union { + float f; + uint32_t u; + } bits = {value}; + return bits.u; +} + void dpi_fadd(bool enable, int dst_fmt, int64_t a, int64_t b, const svBitVecVal* frm, int64_t* result, svBitVecVal* fflags) { if (!enable) return; @@ -173,6 +190,38 @@ void dpi_fsqrt(bool enable, int dst_fmt, int64_t a, const svBitVecVal* frm, int6 } } +void dpi_fexp(bool enable, int dst_fmt, int64_t a, int64_t* result, svBitVecVal* fflags) { + if (!enable) + return; + *fflags = 0; + if (dst_fmt) { + double input; + static_assert(sizeof(input) == sizeof(a), "unexpected double size"); + __builtin_memcpy(&input, &a, sizeof(input)); + double output = exp(input); + __builtin_memcpy(result, &output, sizeof(output)); + if (isinf(output) && isfinite(input)) { + *fflags |= 0x05; // OF | NX + } else if (output == 0.0 && input < 0.0 && isfinite(input)) { + *fflags |= 0x03; // UF | NX + } else if (isfinite(input)) { + *fflags |= 0x01; // NX + } + } else { + uint32_t boxed = static_cast(check_boxing(a)); + float input = bits_to_float(boxed); + float output = expf(input); + *result = nan_box(float_to_bits(output)); + if (isinf(output) && isfinite(input)) { + *fflags |= 0x05; // OF | NX + } else if (output == 0.0f && input < 0.0f && isfinite(input)) { + *fflags |= 0x03; // UF | NX + } else if (isfinite(input)) { + *fflags |= 0x01; // NX + } + } +} + void dpi_ftoi(bool enable, int dst_fmt, int src_fmt, int64_t a, const svBitVecVal* frm, int64_t* result, svBitVecVal* fflags) { if (!enable) return; diff --git a/hw/dpi/float_dpi.vh b/hw/dpi/float_dpi.vh index 08abf25b..0644ac68 100644 --- a/hw/dpi/float_dpi.vh +++ b/hw/dpi/float_dpi.vh @@ -26,6 +26,7 @@ import "DPI-C" function void dpi_fnmsub(input logic enable, input int dst_fmt, i import "DPI-C" function void dpi_fdiv(input logic enable, input int dst_fmt, input longint a, input longint b, input bit[2:0] frm, output longint result, output bit[4:0] fflags); import "DPI-C" function void dpi_fsqrt(input logic enable, input int dst_fmt, input longint a, input bit[2:0] frm, output longint result, output bit[4:0] fflags); +import "DPI-C" function void dpi_fexp(input logic enable, input int dst_fmt, input longint a, output longint result, output bit[4:0] fflags); import "DPI-C" function void dpi_ftoi(input logic enable, input int dst_fmt, input int src_fmt, input longint a, input bit[2:0] frm, output longint result, output bit[4:0] fflags); import "DPI-C" function void dpi_ftou(input logic enable, input int dst_fmt, input int src_fmt, input longint a, input bit[2:0] frm, output longint result, output bit[4:0] fflags); diff --git a/hw/rtl/VX_config.vh b/hw/rtl/VX_config.vh index 9e43fc34..ee8cef1e 100644 --- a/hw/rtl/VX_config.vh +++ b/hw/rtl/VX_config.vh @@ -422,6 +422,11 @@ `endif `endif +// FEXP Latency +`ifndef LATENCY_FEXP +`define LATENCY_FEXP 8 +`endif + // FCVT Latency `ifndef LATENCY_FCVT `define LATENCY_FCVT 5 diff --git a/hw/rtl/VX_define.vh b/hw/rtl/VX_define.vh index b164f945..8f03747c 100644 --- a/hw/rtl/VX_define.vh +++ b/hw/rtl/VX_define.vh @@ -227,7 +227,7 @@ `define INST_FPU_SQRT 4'b0100 `define INST_FPU_CMP 4'b0101 // mod: LE=0, LT=1, EQ=2 `define INST_FPU_F2F 4'b0110 -`define INST_FPU_MISC 4'b0111 // mod: SGNJ=0, SGNJN=1, SGNJX=2, CLASS=3, MVXW=4, MVWX=5, FMIN=6, FMAX=7 +`define INST_FPU_MISC 4'b0111 // mod: SGNJ=0, SGNJN=1, SGNJX=2, CLASS=3, MVXW=4, MVWX=5, FMIN=6, FMAX=7 `define INST_FPU_F2I 4'b1000 `define INST_FPU_F2U 4'b1001 `define INST_FPU_I2F 4'b1010 @@ -236,10 +236,11 @@ `define INST_FPU_MSUB 4'b1101 `define INST_FPU_NMSUB 4'b1110 `define INST_FPU_NMADD 4'b1111 -`define INST_FPU_BITS 4 -`define INST_FPU_IS_W(mod) (mod[4]) -`define INST_FPU_IS_CLASS(op, mod) (op == `INST_FPU_MISC && mod == 3) -`define INST_FPU_IS_MVXW(op, mod) (op == `INST_FPU_MISC && mod == 4) +`define INST_FPU_BITS 4 +`define INST_FPU_IS_W(mod) (mod[4]) +`define INST_FPU_IS_CLASS(op, mod) (op == `INST_FPU_MISC && mod == 3) +`define INST_FPU_IS_MVXW(op, mod) (op == `INST_FPU_MISC && mod == 4) +`define INST_FPU_IS_EXP(op, mod) (op == `INST_FPU_MISC && mod == 8) `define INST_SFU_TMC 4'h0 `define INST_SFU_WSPAWN 4'h1 diff --git a/hw/rtl/core/VX_decode.sv b/hw/rtl/core/VX_decode.sv index ed81c5cf..1fd7f1c6 100644 --- a/hw/rtl/core/VX_decode.sv +++ b/hw/rtl/core/VX_decode.sv @@ -538,6 +538,18 @@ module VX_decode #( endcase end end + `ifdef EXT_F_ENABLE + 3'h2: begin + if (func7 == 7'h30 && rs2 == 5'd0) begin + ex_type = `EX_FPU; + op_type = `INST_OP_BITS'(`INST_FPU_MISC); + op_mod = `INST_MOD_BITS'(8); // FEXP.S + use_rd = 1; + `USED_FREG (rd); + `USED_FREG (rs1); + end + end + `endif default:; endcase end diff --git a/hw/rtl/core/VX_fpu_unit.sv b/hw/rtl/core/VX_fpu_unit.sv index 306db012..2c3bd8f6 100644 --- a/hw/rtl/core/VX_fpu_unit.sv +++ b/hw/rtl/core/VX_fpu_unit.sv @@ -145,6 +145,7 @@ module VX_fpu_unit import VX_fpu_pkg::*; #( .valid_in (fpu_req_valid), .op_type (execute_if[block_idx].data.op_type), + .op_mod (execute_if[block_idx].data.op_mod), .lane_mask (execute_if[block_idx].data.tmask), .fmt (fpu_fmt), .frm (fpu_req_frm), @@ -174,6 +175,7 @@ module VX_fpu_unit import VX_fpu_pkg::*; #( .valid_in (fpu_req_valid), .op_type (execute_if[block_idx].data.op_type), + .op_mod (execute_if[block_idx].data.op_mod), .lane_mask (execute_if[block_idx].data.tmask), .fmt (fpu_fmt), .frm (fpu_req_frm), @@ -204,6 +206,7 @@ module VX_fpu_unit import VX_fpu_pkg::*; #( .valid_in (fpu_req_valid), .lane_mask (execute_if[block_idx].data.tmask), .op_type (execute_if[block_idx].data.op_type), + .op_mod (execute_if[block_idx].data.op_mod), .fmt (fpu_fmt), .frm (fpu_req_frm), .dataa (execute_if[block_idx].data.rs1_data), diff --git a/hw/rtl/core/VX_trace.vh b/hw/rtl/core/VX_trace.vh index 2f7ceeee..9e498a7d 100644 --- a/hw/rtl/core/VX_trace.vh +++ b/hw/rtl/core/VX_trace.vh @@ -327,6 +327,7 @@ task trace_ex_op(input int level, `INST_FPU_MISC: begin if (fdst_d) begin case (op_mod) + 8: `TRACE(level, ("FEXP.D")); 0: `TRACE(level, ("FSGNJ.D")); 1: `TRACE(level, ("FSGNJN.D")); 2: `TRACE(level, ("FSGNJX.D")); @@ -338,6 +339,7 @@ task trace_ex_op(input int level, endcase end else begin case (op_mod) + 8: `TRACE(level, ("FEXP.S")); 0: `TRACE(level, ("FSGNJ.S")); 1: `TRACE(level, ("FSGNJN.S")); 2: `TRACE(level, ("FSGNJX.S")); diff --git a/hw/rtl/fpu/VX_fpu_dpi.sv b/hw/rtl/fpu/VX_fpu_dpi.sv index 1542d3aa..6f598140 100644 --- a/hw/rtl/fpu/VX_fpu_dpi.sv +++ b/hw/rtl/fpu/VX_fpu_dpi.sv @@ -31,6 +31,7 @@ module VX_fpu_dpi import VX_fpu_pkg::*; #( input wire [TAGW-1:0] tag_in, input wire [`INST_FPU_BITS-1:0] op_type, + input wire [`INST_MOD_BITS-1:0] op_mod, input wire [`INST_FMT_BITS-1:0] fmt, input wire [`INST_FRM_BITS-1:0] frm, @@ -51,7 +52,8 @@ module VX_fpu_dpi import VX_fpu_pkg::*; #( localparam FPU_DIVSQRT = 1; localparam FPU_CVT = 2; localparam FPU_NCP = 3; - localparam NUM_FPC = 4; + localparam FPU_EXP = 4; + localparam NUM_FPC = 5; localparam FPC_BITS = `LOG2UP(NUM_FPC); localparam RSP_DATAW = (NUM_LANES * `XLEN) + 1 + $bits(fflags_t) + TAGW; @@ -133,6 +135,7 @@ module VX_fpu_dpi import VX_fpu_pkg::*; #( `INST_FPU_I2F: begin core_select = FPU_CVT; is_itof = 1; end `INST_FPU_U2F: begin core_select = FPU_CVT; is_utof = 1; end `INST_FPU_F2F: begin core_select = FPU_CVT; is_f2f = 1; end + `INST_FPU_MISC: begin core_select = `INST_FPU_IS_EXP(op_type, op_mod) ? FPU_EXP : FPU_NCP; end default: begin core_select = FPU_NCP; end endcase end @@ -437,6 +440,45 @@ module VX_fpu_dpi import VX_fpu_pkg::*; #( end endgenerate + generate + begin : fexp + + reg [NUM_LANES-1:0][`XLEN-1:0] result_fexp_r; + reg [NUM_LANES-1:0][63:0] result_fexp; + fflags_t [NUM_LANES-1:0] fflags_fexp; + + wire fexp_valid = (valid_in && core_select == FPU_EXP); + wire fexp_ready = per_core_ready_out[FPU_EXP] || ~per_core_valid_out[FPU_EXP]; + wire fexp_fire = fexp_valid && fexp_ready; + + always @(*) begin + for (integer i = 0; i < NUM_LANES; ++i) begin + dpi_fexp(fexp_fire, int'(dst_fmt), operands[0][i], result_fexp[i], fflags_fexp[i]); + result_fexp_r[i] = result_fexp[i][`XLEN-1:0]; + end + end + + fflags_t fflags_merged; + `FPU_MERGE_FFLAGS(fflags_merged, fflags_fexp, lane_mask, NUM_LANES); + + VX_shift_register #( + .DATAW (1 + TAGW + NUM_LANES * `XLEN + $bits(fflags_t)), + .DEPTH (`LATENCY_FEXP), + .RESETW (1) + ) shift_reg ( + .clk (clk), + .reset (reset), + .enable (fexp_ready), + .data_in ({fexp_valid, tag_in, result_fexp_r, fflags_merged}), + .data_out ({per_core_valid_out[FPU_EXP], per_core_tag_out[FPU_EXP], per_core_result[FPU_EXP], per_core_fflags[FPU_EXP]}) + ); + + assign per_core_has_fflags[FPU_EXP] = 1; + assign per_core_ready_in[FPU_EXP] = fexp_ready; + + end + endgenerate + /////////////////////////////////////////////////////////////////////////// assign per_core_ready_in[FPU_DIVSQRT] = is_div ? div_ready_in : sqrt_ready_in; diff --git a/hw/rtl/fpu/VX_fpu_dsp.sv b/hw/rtl/fpu/VX_fpu_dsp.sv index cac648d3..766998e0 100644 --- a/hw/rtl/fpu/VX_fpu_dsp.sv +++ b/hw/rtl/fpu/VX_fpu_dsp.sv @@ -31,6 +31,7 @@ module VX_fpu_dsp import VX_fpu_pkg::*; #( input wire [TAGW-1:0] tag_in, input wire [`INST_FPU_BITS-1:0] op_type, + input wire [`INST_MOD_BITS-1:0] op_mod, input wire [`INST_FMT_BITS-1:0] fmt, input wire [`INST_FRM_BITS-1:0] frm, @@ -51,7 +52,8 @@ module VX_fpu_dsp import VX_fpu_pkg::*; #( localparam FPU_DIVSQRT = 1; localparam FPU_CVT = 2; localparam FPU_NCP = 3; - localparam NUM_FPC = 4; + localparam FPU_EXP = 4; + localparam NUM_FPC = 5; localparam FPC_BITS = `LOG2UP(NUM_FPC); localparam RSP_DATAW = (NUM_LANES * 32) + 1 + $bits(fflags_t) + TAGW; @@ -98,6 +100,7 @@ module VX_fpu_dsp import VX_fpu_pkg::*; #( `INST_FPU_F2U: begin core_select = FPU_CVT; end `INST_FPU_I2F: begin core_select = FPU_CVT; is_itof = 1; is_signed = 1; end `INST_FPU_U2F: begin core_select = FPU_CVT; is_itof = 1; end + `INST_FPU_MISC: begin core_select = `INST_FPU_IS_EXP(op_type, op_mod) ? FPU_EXP : FPU_NCP; end default: begin core_select = FPU_NCP; end endcase end @@ -107,6 +110,7 @@ module VX_fpu_dsp import VX_fpu_pkg::*; #( `RESET_RELAY (sqrt_reset, reset); `RESET_RELAY (cvt_reset, reset); `RESET_RELAY (ncp_reset, reset); + `RESET_RELAY (exp_reset, reset); wire [NUM_LANES-1:0][31:0] dataa_s; wire [NUM_LANES-1:0][31:0] datab_s; @@ -243,6 +247,25 @@ module VX_fpu_dsp import VX_fpu_pkg::*; #( .ready_out (per_core_ready_out[FPU_NCP]) ); + VX_fpu_exp #( + .NUM_LANES (NUM_LANES), + .TAGW (TAGW) + ) fpu_exp ( + .clk (clk), + .reset (exp_reset), + .valid_in (valid_in && (core_select == FPU_EXP)), + .ready_in (per_core_ready_in[FPU_EXP]), + .lane_mask (lane_mask), + .tag_in (tag_in), + .dataa (dataa_s), + .has_fflags (per_core_has_fflags[FPU_EXP]), + .fflags (per_core_fflags[FPU_EXP]), + .result (per_core_result[FPU_EXP]), + .tag_out (per_core_tag_out[FPU_EXP]), + .valid_out (per_core_valid_out[FPU_EXP]), + .ready_out (per_core_ready_out[FPU_EXP]) + ); + /////////////////////////////////////////////////////////////////////////// assign per_core_ready_in[FPU_DIVSQRT] = is_div ? div_ready_in : sqrt_ready_in; diff --git a/hw/rtl/fpu/VX_fpu_exp.sv b/hw/rtl/fpu/VX_fpu_exp.sv new file mode 100644 index 00000000..1ba68b3c --- /dev/null +++ b/hw/rtl/fpu/VX_fpu_exp.sv @@ -0,0 +1,92 @@ +// Copyright © 2019-2023 +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +`include "VX_fpu_define.vh" +`ifdef SV_DPI +`include "float_dpi.vh" +`else +`ERROR(("VX_fpu_exp requires SV_DPI; replace dpi_fexp with synthesizable exp RTL for synthesis")) +`endif + +module VX_fpu_exp import VX_fpu_pkg::*; #( + parameter NUM_LANES = 1, + parameter TAGW = 1 +) ( + input wire clk, + input wire reset, + + output wire ready_in, + input wire valid_in, + + input wire [NUM_LANES-1:0] lane_mask, + + input wire [TAGW-1:0] tag_in, + + input wire [NUM_LANES-1:0][31:0] dataa, + output wire [NUM_LANES-1:0][31:0] result, + + output wire has_fflags, + output wire [`FP_FLAGS_BITS-1:0] fflags, + + output wire [TAGW-1:0] tag_out, + + input wire ready_out, + output wire valid_out +); + wire stall = ~ready_out && valid_out; + wire enable = ~stall; + + fflags_t [NUM_LANES-1:0] per_lane_fflags; + wire [NUM_LANES-1:0] lane_mask_out; + + VX_shift_register #( + .DATAW (1 + NUM_LANES + TAGW), + .DEPTH (`LATENCY_FEXP), + .RESETW (1) + ) shift_reg ( + .clk (clk), + .reset (reset), + .enable (enable), + .data_in ({valid_in, lane_mask, tag_in}), + .data_out ({valid_out, lane_mask_out, tag_out}) + ); + + assign ready_in = enable; + + for (genvar i = 0; i < NUM_LANES; ++i) begin + reg [63:0] r; + `UNUSED_VAR (r) + + fflags_t f; + + always @(*) begin + dpi_fexp(enable && valid_in, int'(0), {32'hffffffff, dataa[i]}, r, f); + end + + VX_shift_register #( + .DATAW (32 + $bits(fflags_t)), + .DEPTH (`LATENCY_FEXP) + ) shift_req_dpi ( + .clk (clk), + `UNUSED_PIN (reset), + .enable (enable), + .data_in ({r[31:0], f}), + .data_out ({result[i], per_lane_fflags[i]}) + ); + end + + assign has_fflags = 1; + + `FPU_MERGE_FFLAGS(fflags, per_lane_fflags, lane_mask_out, NUM_LANES); + +endmodule diff --git a/hw/rtl/fpu/VX_fpu_fpnew.sv b/hw/rtl/fpu/VX_fpu_fpnew.sv index 93cd6cac..f8ae6a12 100644 --- a/hw/rtl/fpu/VX_fpu_fpnew.sv +++ b/hw/rtl/fpu/VX_fpu_fpnew.sv @@ -34,6 +34,7 @@ module VX_fpu_fpnew input wire [TAGW-1:0] tag_in, input wire [`INST_FPU_BITS-1:0] op_type, + input wire [`INST_MOD_BITS-1:0] op_mod, input wire [`INST_FMT_BITS-1:0] fmt, input wire [`INST_FRM_BITS-1:0] frm, @@ -104,6 +105,7 @@ module VX_fpu_fpnew reg fpu_has_fflags, fpu_has_fflags_out; fpnew_pkg::fp_format_e fpu_src_fmt, fpu_dst_fmt; fpnew_pkg::int_format_e fpu_int_fmt; + wire is_fexp = `INST_FPU_IS_EXP(op_type, op_mod); `UNUSED_VAR (fmt) @@ -183,7 +185,6 @@ module VX_fpu_fpnew end `ifdef XLEN_64 - `UNUSED_VAR (lane_mask) for (genvar i = 0; i < NUM_LANES; ++i) begin wire [(TAGW+1)-1:0] fpu_tag; wire fpu_valid_out_uq; @@ -210,7 +211,7 @@ module VX_fpu_fpnew .int_fmt_i (fpu_int_fmt), `UNUSED_PIN (vectorial_op_i), `UNUSED_PIN (simd_mask_i), - .tag_i ({fpu_tag_in, fpu_has_fflags}), + .tag_i ({fpu_tag_in, fpu_has_fflags}), .in_valid_i (fpu_valid_in), .in_ready_o (fpu_ready_in_uq), .flush_i (reset), @@ -248,8 +249,8 @@ module VX_fpu_fpnew .int_fmt_i (fpu_int_fmt), .vectorial_op_i (1'b1), .simd_mask_i (lane_mask), - .tag_i ({fpu_tag_in, fpu_has_fflags}), - .in_valid_i (fpu_valid_in), + .tag_i ({fpu_tag_in, fpu_has_fflags}), + .in_valid_i (fpu_valid_in), .in_ready_o (fpu_ready_in), .flush_i (reset), .result_o (fpu_result), @@ -261,10 +262,70 @@ module VX_fpu_fpnew ); `endif - assign fpu_valid_in = valid_in; - assign ready_in = fpu_ready_in; + wire exp_ready_in; + wire exp_valid_out; + wire [NUM_LANES-1:0][31:0] exp_dataa; + wire [NUM_LANES-1:0][31:0] exp_result_s; + wire [NUM_LANES-1:0][`XLEN-1:0] exp_result; + wire exp_has_fflags; + fflags_t exp_fflags; + wire [TAGW-1:0] exp_tag_out; + wire exp_ready_out; + + for (genvar i = 0; i < NUM_LANES; ++i) begin + assign exp_dataa[i] = dataa[i][31:0]; + `ifdef FPU_RV64F + assign exp_result[i] = {32'hffffffff, exp_result_s[i]}; + `else + assign exp_result[i] = exp_result_s[i]; + `endif + end + + VX_fpu_exp #( + .NUM_LANES (NUM_LANES), + .TAGW (TAGW) + ) fpu_exp ( + .clk (clk), + .reset (reset), + .valid_in (valid_in && is_fexp), + .ready_in (exp_ready_in), + .lane_mask (lane_mask), + .tag_in (tag_in), + .dataa (exp_dataa), + .has_fflags (exp_has_fflags), + .fflags (exp_fflags), + .result (exp_result_s), + .tag_out (exp_tag_out), + .valid_out (exp_valid_out), + .ready_out (exp_ready_out) + ); + + assign fpu_valid_in = valid_in && !is_fexp; + assign ready_in = is_fexp ? exp_ready_in : fpu_ready_in; assign fpu_tag_in = tag_in; + wire [RSP_DATAW-1:0] exp_rsp_data; + wire exp_rsp_valid; + wire exp_rsp_ready; + wire [RSP_DATAW-1:0] fpu_rsp_data; + wire fpu_rsp_valid; + wire fpu_rsp_ready; + + VX_elastic_buffer #( + .DATAW (RSP_DATAW), + .SIZE (`OUT_REG_TO_EB_SIZE(OUT_REG)), + .OUT_REG (`OUT_REG_TO_EB_REG(OUT_REG)) + ) exp_rsp_buf ( + .clk (clk), + .reset (reset), + .valid_in (exp_valid_out), + .ready_in (exp_ready_out), + .data_in ({exp_result, exp_has_fflags, exp_fflags, exp_tag_out}), + .data_out (exp_rsp_data), + .valid_out (exp_rsp_valid), + .ready_out (exp_rsp_ready) + ); + VX_elastic_buffer #( .DATAW (RSP_DATAW), .SIZE (`OUT_REG_TO_EB_SIZE(OUT_REG)), @@ -275,9 +336,26 @@ module VX_fpu_fpnew .valid_in (fpu_valid_out), .ready_in (fpu_ready_out), .data_in ({fpu_result, fpu_has_fflags_out, fpu_status, fpu_tag_out}), + .data_out (fpu_rsp_data), + .valid_out (fpu_rsp_valid), + .ready_out (fpu_rsp_ready) + ); + + VX_stream_arb #( + .NUM_INPUTS (2), + .DATAW (RSP_DATAW), + .ARBITER ("R"), + .OUT_REG (0) + ) rsp_arb ( + .clk (clk), + .reset (reset), + .valid_in ({exp_rsp_valid, fpu_rsp_valid}), + .ready_in ({exp_rsp_ready, fpu_rsp_ready}), + .data_in ({exp_rsp_data, fpu_rsp_data}), .data_out ({result, has_fflags, fflags, tag_out}), .valid_out (valid_out), - .ready_out (ready_out) + .ready_out (ready_out), + `UNUSED_PIN (sel_out) ); endmodule diff --git a/kernel/include/VX_config.h b/kernel/include/VX_config.h index b2c28f52..ef145825 100644 --- a/kernel/include/VX_config.h +++ b/kernel/include/VX_config.h @@ -402,6 +402,11 @@ #endif #endif +// FEXP Latency +#ifndef LATENCY_FEXP +#define LATENCY_FEXP 8 +#endif + // FCVT Latency #ifndef LATENCY_FCVT #define LATENCY_FCVT 5