/////////////////////////////////////////// // packoutput.sv // // Written: David_Harris@hmc.edu // Modified: 5/11/24 // // Purpose: Pack the output of the FPU // // Documentation: RISC-V System on Chip Design // // A component of the CORE-V-WALLY configurable RISC-V project. // https://github.com/openhwgroup/cvw // // Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University // // SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 // // Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file // except in compliance with the License, or, at your option, the Apache License version 2.0. You // may obtain a copy of the License at // // https://solderpad.org/licenses/SHL-2.1/ // // Unless required by applicable law or agreed to in writing, any work 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. //////////////////////////////////////////////////////////////////////////////////////////////// module packoutput import cvw::*; #(parameter cvw_t P) ( input logic [P.FLEN-1:0] Unpacked, input logic [P.FMTBITS-1:0] Fmt, output logic [P.FLEN-1:0] Packed ); logic Sign; logic [P.NE1-1:0] Exp1; logic [P.NF1-1:0] Fract1; logic [P.NE2-1:0] Exp2; logic [P.NF2-1:0] Fract2; logic [P.H_NE-1:0] Exp3; logic [P.H_NF-1:0] Fract3; // Pack exponent and fraction, with NaN-boxing to full FLEN assign Sign = Unpacked[P.FLEN-1]; if (P.FPSIZES == 1) begin assign Packed = Unpacked; end else if (P.FPSIZES == 2) begin always_comb begin {Exp1, Fract1} = '0; // default if not used, to prevent latch case (Fmt) 1'b1: Packed = Unpacked; 1'b0: begin Exp1 = {Unpacked[P.FLEN-2], Unpacked[P.NF+P.NE1-2:P.NF]}; Fract1 = Unpacked[P.NF-1:P.NF-P.NF1]; Packed = {{(P.FLEN-P.LEN1){1'b1}}, Sign, Exp1, Fract1}; end endcase end end else if (P.FPSIZES == 3) begin always_comb begin {Exp1, Fract1, Exp2, Fract2} = '0; // default if not used, to prevent latch case (Fmt) P.FMT: Packed = Unpacked; P.FMT1: begin Exp1 = {Unpacked[P.FLEN-2], Unpacked[P.NF+P.NE1-2:P.NF]}; Fract1 = Unpacked[P.NF-1:P.NF-P.NF1]; Packed = {{(P.FLEN-P.LEN1){1'b1}}, Sign, Exp1, Fract1}; end P.FMT2: begin Exp2 = {Unpacked[P.FLEN-2], Unpacked[P.NF+P.NE2-2:P.NF]}; Fract2 = Unpacked[P.NF-1:P.NF-P.NF2]; Packed = {{(P.FLEN-P.LEN2){1'b1}}, Sign, Exp2, Fract2}; end default: Packed = 'x; endcase end end else if (P.FPSIZES == 4) begin always_comb begin {Exp1, Fract1, Exp2, Fract2, Exp3, Fract3} = '0; // default if not used, to prevent latch case (Fmt) 2'h3: Packed = Unpacked; // Quad 2'h1: begin // double Exp1 = {Unpacked[P.FLEN-2], Unpacked[P.NF+P.NE1-2:P.NF]}; Fract1 = Unpacked[P.NF-1:P.NF-P.NF1]; Packed = {{(P.FLEN-P.LEN1){1'b1}}, Sign, Exp1, Fract1}; end 2'h0: begin // float Exp2 = {Unpacked[P.FLEN-2], Unpacked[P.NF+P.NE2-2:P.NF]}; Fract2 = Unpacked[P.NF-1:P.NF-P.NF2]; Packed = {{(P.FLEN-P.LEN2){1'b1}}, Sign, Exp2, Fract2}; end 2'h2: begin // half Exp3 = {Unpacked[P.FLEN-2], Unpacked[P.NF+P.H_NE-2:P.NF]}; Fract3 = Unpacked[P.NF-1:P.NF-P.H_NF]; Packed = {{(P.FLEN-P.H_LEN){1'b1}}, Sign, Exp3, Fract3}; end endcase end end endmodule