Vortex 2.0 changes:
+ Microarchitecture optimizations + 64-bit support + Xilinx FPGA support + LLVM-16 support + Refactoring and quality control fixes minor update minor update minor update minor update minor update minor update cleanup cleanup cache bindings and memory perf refactory minor update minor update hw unit tests fixes minor update minor update minor update minor update minor update minor udpate minor update minor update minor update minor update minor update minor update minor update minor updates minor updates minor update minor update minor update minor update minor update minor update minor updates minor updates minor updates minor updates minor update minor update
This commit is contained in:
79
hw/rtl/fpu/VX_fpu_rounding.sv
Normal file
79
hw/rtl/fpu/VX_fpu_rounding.sv
Normal file
@@ -0,0 +1,79 @@
|
||||
// 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 FPU_DSP
|
||||
|
||||
/// Modified port of rouding module from fpnew Libray
|
||||
/// reference: https://github.com/pulp-platform/fpnew
|
||||
|
||||
module VX_fpu_rounding #(
|
||||
parameter DAT_WIDTH = 2 // Width of the abolute value, without sign bit
|
||||
) (
|
||||
// inputs
|
||||
input wire [DAT_WIDTH-1:0] abs_value_i, // absolute value without sign
|
||||
input wire sign_i,
|
||||
// rounding information
|
||||
input wire [1:0] round_sticky_bits_i, // round and sticky bits {RS}
|
||||
input wire [2:0] rnd_mode_i,
|
||||
input wire effective_subtraction_i, // sign of inputs affects rounding of zeroes
|
||||
// outputs
|
||||
output wire [DAT_WIDTH-1:0] abs_rounded_o, // absolute value without sign
|
||||
output wire sign_o,
|
||||
output wire exact_zero_o // output is an exact zero
|
||||
);
|
||||
|
||||
reg round_up; // Rounding decision
|
||||
|
||||
// Take the rounding decision according to RISC-V spec
|
||||
// RoundMode | Mnemonic | Meaning
|
||||
// :--------:|:--------:|:-------
|
||||
// 000 | RNE | Round to Nearest, ties to Even
|
||||
// 001 | RTZ | Round towards Zero
|
||||
// 010 | RDN | Round Down (towards -\infty)
|
||||
// 011 | RUP | Round Up (towards \infty)
|
||||
// 100 | RMM | Round to Nearest, ties to Max Magnitude
|
||||
// others | | *invalid*
|
||||
|
||||
always @(*) begin
|
||||
case (rnd_mode_i)
|
||||
`INST_FRM_RNE: // Decide accoring to round/sticky bits
|
||||
case (round_sticky_bits_i)
|
||||
2'b00,
|
||||
2'b01: round_up = 1'b0; // < ulp/2 away, round down
|
||||
2'b10: round_up = abs_value_i[0]; // = ulp/2 away, round towards even result
|
||||
2'b11: round_up = 1'b1; // > ulp/2 away, round up
|
||||
default: round_up = 1'bx;
|
||||
endcase
|
||||
`INST_FRM_RTZ: round_up = 1'b0; // always round down
|
||||
`INST_FRM_RDN: round_up = (| round_sticky_bits_i) & sign_i; // to 0 if +, away if -
|
||||
`INST_FRM_RUP: round_up = (| round_sticky_bits_i) & ~sign_i; // to 0 if -, away if +
|
||||
`INST_FRM_RMM: round_up = round_sticky_bits_i[1]; // round down if < ulp/2 away, else up
|
||||
default: round_up = 1'bx; // propagate x
|
||||
endcase
|
||||
end
|
||||
|
||||
// Perform the rounding, exponent change and overflow to inf happens automagically
|
||||
assign abs_rounded_o = abs_value_i + DAT_WIDTH'(round_up);
|
||||
|
||||
// True zero result is a zero result without dirty round/sticky bits
|
||||
assign exact_zero_o = (abs_value_i == 0) && (round_sticky_bits_i == 0);
|
||||
|
||||
// In case of effective subtraction (thus signs of addition operands must have differed) and a
|
||||
// true zero result, the result sign is '-' in case of RDN and '+' for other modes.
|
||||
assign sign_o = (exact_zero_o && effective_subtraction_i) ? (rnd_mode_i == `INST_FRM_RDN)
|
||||
: sign_i;
|
||||
|
||||
endmodule
|
||||
`endif
|
||||
Reference in New Issue
Block a user