mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
104 lines
3.8 KiB
Systemverilog
104 lines
3.8 KiB
Systemverilog
|
|
///////////////////////////////////////////
|
|
// 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
|