mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
moved unsused division code again
This commit is contained in:
parent
ccc97d6fee
commit
b67792086c
@ -1 +1 @@
|
||||
Subproject commit 307c77b26e070ae85ffea665ad9b642b40e33c86
|
||||
Subproject commit be67c99bd461742aa1c100bcc0732657faae2230
|
@ -1,74 +0,0 @@
|
||||
///////////////////////////////////////////
|
||||
//
|
||||
// Written: James Stine
|
||||
// Modified: 8/1/2018
|
||||
//
|
||||
// Purpose: Floating point divider/square root top unit (Goldschmidt)
|
||||
//
|
||||
// A component of the Wally configurable RISC-V project.
|
||||
//
|
||||
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
|
||||
//
|
||||
// MIT LICENSE
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
// software and associated documentation files (the "Software"), to deal in the Software
|
||||
// without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
||||
// to whom the Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all copies or
|
||||
// substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
|
||||
// OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
module convert_inputs(
|
||||
input [63:0] op1, // 1st input operand (A)
|
||||
input [63:0] op2, // 2nd input operand (B)
|
||||
input [2:0] op_type, // Function opcode
|
||||
input P, // Result Precision (0 for double, 1 for single)
|
||||
|
||||
output [63:0] Float1, // Converted 1st input operand
|
||||
output [63:0] Float2 // Converted 2nd input operand
|
||||
);
|
||||
|
||||
wire conv_SP; // Convert from SP to DP
|
||||
wire Zexp1; // One if the exponent of op1 is zero
|
||||
wire Zexp2; // One if the exponent of op2 is zero
|
||||
wire Oexp1; // One if the exponent of op1 is all ones
|
||||
wire Oexp2; // One if the exponent of op2 is all ones
|
||||
|
||||
// Convert from single precision to double precision if (op_type is 11X
|
||||
// and P is 0) or (op_type is not 11X and P is one).
|
||||
assign conv_SP = ~P;
|
||||
|
||||
// Test if the input exponent is zero, because if it is then the
|
||||
// exponent of the converted number should be zero.
|
||||
assign Zexp1 = ~(|op1[30:23]);
|
||||
assign Zexp2 = ~(|op2[30:23]);
|
||||
assign Oexp1 = (&op1[30:23]);
|
||||
assign Oexp2 = (&op2[30:23]);
|
||||
|
||||
// Conditionally convert op1. Lower 29 bits are zero for single precision.
|
||||
assign Float1[62:29] = conv_SP ? {op1[30], {3{(~op1[30]&~Zexp1)|Oexp1}}, op1[29:0]}
|
||||
: op1[62:29];
|
||||
assign Float1[28:0] = op1[28:0] & {29{~conv_SP}};
|
||||
|
||||
// Conditionally convert op2. Lower 29 bits are zero for single precision.
|
||||
assign Float2[62:29] = conv_SP ? {op2[30], {3{(~op2[30]&~Zexp2)|Oexp2}}, op2[29:0]}
|
||||
: op2[62:29];
|
||||
assign Float2[28:0] = op2[28:0] & {29{~conv_SP}};
|
||||
|
||||
// Set the sign of Float1 based on its original sign and if the operation
|
||||
// is negation (op_type = 101) or absolute value (op_type = 100)
|
||||
|
||||
assign Float1[63] = conv_SP ? op1[31] : op1[63];
|
||||
assign Float2[63] = conv_SP ? op2[31] : op2[63];
|
||||
|
||||
endmodule // convert_inputs
|
||||
|
@ -1,47 +0,0 @@
|
||||
// This module takes as inputs two operands (op1 and op2)
|
||||
// and the result precision (P). Based on the operation and precision,
|
||||
// it conditionally converts single precision values to double
|
||||
// precision values and modifies the sign of op1.
|
||||
// The converted operands are Float1 and Float2.
|
||||
module convert_inputs_div (
|
||||
|
||||
input logic [63:0] op1, // 1st input operand (A)
|
||||
input logic [63:0] op2, // 2nd input operand (B)
|
||||
input logic P, // Result Precision (0 for double, 1 for single)
|
||||
input logic op_type, // Operation
|
||||
|
||||
output logic [63:0] Float1, // Converted 1st input operand
|
||||
output logic [63:0] Float2b // Converted 2nd input operand
|
||||
);
|
||||
|
||||
logic [63:0] Float2;
|
||||
logic Zexp1; // One if the exponent of op1 is zero
|
||||
logic Zexp2; // One if the exponent of op2 is zero
|
||||
logic Oexp1; // One if the exponent of op1 is all ones
|
||||
logic Oexp2; // One if the exponent of op2 is all ones
|
||||
|
||||
// Test if the input exponent is zero, because if it is then the
|
||||
// exponent of the converted number should be zero.
|
||||
assign Zexp1 = ~(|op1[30:23]);
|
||||
assign Zexp2 = ~(|op2[30:23]);
|
||||
assign Oexp1 = (&op1[30:23]);
|
||||
assign Oexp2 = (&op2[30:23]);
|
||||
|
||||
// Conditionally convert op1. Lower 29 bits are zero for single precision.
|
||||
assign Float1[62:29] = P ? {op1[30], {3{(~op1[30]&~Zexp1)|Oexp1}}, op1[29:0]}
|
||||
: op1[62:29];
|
||||
assign Float1[28:0] = op1[28:0] & {29{~P}};
|
||||
|
||||
// Conditionally convert op2. Lower 29 bits are zero for single precision.
|
||||
assign Float2[62:29] = P ? {op2[30], {3{(~op2[30]&~Zexp2)|Oexp2}}, op2[29:0]}
|
||||
: op2[62:29];
|
||||
assign Float2[28:0] = op2[28:0] & {29{~P}};
|
||||
|
||||
// Set the sign of Float1 based on its original sign
|
||||
assign Float1[63] = P ? op1[31] : op1[63];
|
||||
assign Float2[63] = P ? op2[31] : op2[63];
|
||||
|
||||
// For sqrt, assign Float2 same as Float1 for simplicity
|
||||
assign Float2b = op_type ? Float1 : Float2;
|
||||
|
||||
endmodule // convert_inputs
|
@ -1,126 +0,0 @@
|
||||
///////////////////////////////////////////
|
||||
//
|
||||
// Written: James Stine
|
||||
// Modified: 9/28/2021
|
||||
//
|
||||
// Purpose: Main convergence routine for floating point divider/square root unit (Goldschmidt)
|
||||
//
|
||||
// A component of the Wally configurable RISC-V project.
|
||||
//
|
||||
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
|
||||
//
|
||||
// MIT LICENSE
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
// software and associated documentation files (the "Software"), to deal in the Software
|
||||
// without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
||||
// to whom the Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all copies or
|
||||
// substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
|
||||
// OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
module divconv (
|
||||
input logic [52:0] d, n,
|
||||
input logic [2:0] sel_muxa, sel_muxb,
|
||||
input logic sel_muxr,
|
||||
input logic load_rega, load_regb, load_regc, load_regd,
|
||||
input logic load_regr, load_regs,
|
||||
input logic P,
|
||||
input logic op_type,
|
||||
input logic exp_odd,
|
||||
input logic reset,
|
||||
input logic clk,
|
||||
|
||||
output logic [59:0] q1, qp1, qm1,
|
||||
output logic [59:0] q0, qp0, qm0,
|
||||
output logic [59:0] rega_out, regb_out, regc_out, regd_out,
|
||||
output logic [119:0] regr_out
|
||||
);
|
||||
|
||||
logic [59:0] muxa_out, muxb_out;
|
||||
logic [10:0] ia_div, ia_sqrt;
|
||||
logic [59:0] ia_out;
|
||||
logic [119:0] mul_out;
|
||||
logic [59:0] q_out1, qm_out1, qp_out1;
|
||||
logic [59:0] q_out0, qm_out0, qp_out0;
|
||||
logic [59:0] mcand, mplier, mcand_q;
|
||||
logic [59:0] twocmp_out;
|
||||
logic [60:0] three;
|
||||
logic [119:0] constant, constant2;
|
||||
logic [59:0] q_const, qp_const, qm_const;
|
||||
logic [59:0] d2, n2;
|
||||
logic muxr_out;
|
||||
logic cout1, cout2, cout3, cout4, cout5, cout6, cout7;
|
||||
|
||||
// Check if exponent is odd for sqrt
|
||||
// If exp_odd=1 and sqrt, then M/2 and use ia_addr=0 as IA
|
||||
assign d2 = (exp_odd&op_type) ? {1'b0, d, 6'h0} : {d, 7'h0};
|
||||
assign n2 = op_type ? d2 : {n, 7'h0};
|
||||
|
||||
// IA div/sqrt
|
||||
sbtm_div ia1 (d[52:41], ia_div);
|
||||
sbtm_sqrt ia2 (d2[59:48], ia_sqrt);
|
||||
assign ia_out = op_type ? {ia_sqrt, {49{1'b0}}} : {ia_div, {49{1'b0}}};
|
||||
|
||||
// Choose IA or iteration
|
||||
mux6 #(60) mx1 (d2, ia_out, rega_out, regc_out, regd_out, regb_out, sel_muxb, muxb_out);
|
||||
mux5 #(60) mx2 (regc_out, n2, ia_out, regb_out, regd_out, sel_muxa, muxa_out);
|
||||
|
||||
// Deal with remainder if [0.5, 1) instead of [1, 2)
|
||||
mux2 #(120) mx3a ({~n, {67{1'b1}}}, {{1'b1}, ~n, {66{1'b1}}}, q1[59], constant2);
|
||||
// Select Mcand, Remainder/Q''
|
||||
mux2 #(120) mx3 (120'h0, constant2, sel_muxr, constant);
|
||||
// Select mcand - remainder should always choose q1 [1,2) because
|
||||
// adjustment of N in the from XX.FFFFFFF
|
||||
mux2 #(60) mx4 (q0, q1, q1[59], mcand_q);
|
||||
mux2 #(60) mx5 (muxb_out, mcand_q, sel_muxr&op_type, mplier);
|
||||
mux2 #(60) mx6 (muxa_out, mcand_q, sel_muxr, mcand);
|
||||
// Q*D - N (reversed but changed in rounder.v to account for sign reversal)
|
||||
// Add ulp for subtraction in remainder
|
||||
mux2 #(1) mx7 (1'b0, 1'b1, sel_muxr, muxr_out);
|
||||
|
||||
// Constant for Q''
|
||||
mux2 #(60) mx8 ({60'h0000_0000_0000_020}, {60'h0000_0040_0000_000}, P, q_const);
|
||||
mux2 #(60) mx9 ({60'h0000_0000_0000_0A0}, {60'h0000_0140_0000_000}, P, qp_const);
|
||||
mux2 #(60) mxA ({60'hFFFF_FFFF_FFFF_F9F}, {60'hFFFF_FF3F_FFFF_FFF}, P, qm_const);
|
||||
|
||||
// CPA (from CSA)/Remainder addition/subtraction
|
||||
assign {cout1, mul_out} = (mcand*mplier) + constant + {119'b0, muxr_out};
|
||||
|
||||
// Assuming [1,2) - q1
|
||||
assign {cout2, q_out1} = regb_out + q_const;
|
||||
assign {cout3, qp_out1} = regb_out + qp_const;
|
||||
assign {cout4, qm_out1} = regb_out + qm_const + 1'b1;
|
||||
// Assuming [0.5,1) - q0
|
||||
assign {cout5, q_out0} = {regb_out[58:0], 1'b0} + q_const;
|
||||
assign {cout6, qp_out0} = {regb_out[58:0], 1'b0} + qp_const;
|
||||
assign {cout7, qm_out0} = {regb_out[58:0], 1'b0} + qm_const + 1'b1;
|
||||
|
||||
// One's complement instead of two's complement (for hw efficiency)
|
||||
assign three = {~mul_out[118], mul_out[118], ~mul_out[117:59]};
|
||||
mux2 #(60) mxTC (~mul_out[118:59], three[60:1], op_type, twocmp_out);
|
||||
|
||||
// regs
|
||||
flopenr #(60) regc (clk, reset, load_regc, twocmp_out, regc_out);
|
||||
flopenr #(60) regb (clk, reset, load_regb, mul_out[118:59], regb_out);
|
||||
flopenr #(60) rega (clk, reset, load_rega, mul_out[118:59], rega_out);
|
||||
flopenr #(60) regd (clk, reset, load_regd, mul_out[118:59], regd_out);
|
||||
flopenr #(120) regr (clk, reset, load_regr, mul_out, regr_out);
|
||||
// Assuming [1,2)
|
||||
flopenr #(60) rege (clk, reset, load_regs, {q_out1[59:35], (q_out1[34:6] & {29{~P}}), 6'h0}, q1);
|
||||
flopenr #(60) regf (clk, reset, load_regs, {qm_out1[59:35], (qm_out1[34:6] & {29{~P}}), 6'h0}, qm1);
|
||||
flopenr #(60) regg (clk, reset, load_regs, {qp_out1[59:35], (qp_out1[34:6] & {29{~P}}), 6'h0}, qp1);
|
||||
// Assuming [0,1)
|
||||
flopenr #(60) regh (clk, reset, load_regs, {q_out0[59:35], (q_out0[34:6] & {29{~P}}), 6'h0}, q0);
|
||||
flopenr #(60) regj (clk, reset, load_regs, {qm_out0[59:35], (qm_out0[34:6] & {29{~P}}), 6'h0}, qm0);
|
||||
flopenr #(60) regk (clk, reset, load_regs, {qp_out0[59:35], (qp_out0[34:6] & {29{~P}}), 6'h0}, qp0);
|
||||
|
||||
endmodule // divconv
|
@ -1,198 +0,0 @@
|
||||
///////////////////////////////////////////
|
||||
//
|
||||
// Written: James Stine
|
||||
// Modified: 8/1/2018
|
||||
//
|
||||
// Purpose: Convergence unit for pipelined floating point divider/square root top unit (Goldschmidt)
|
||||
//
|
||||
// A component of the Wally configurable RISC-V project.
|
||||
//
|
||||
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
|
||||
//
|
||||
// MIT LICENSE
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
// software and associated documentation files (the "Software"), to deal in the Software
|
||||
// without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
||||
// to whom the Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all copies or
|
||||
// substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
|
||||
// OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
`include "wally-config.vh"
|
||||
|
||||
module divconv_pipe (q1, qm1, qp1, q0, qm0, qp0, rega_out, regb_out, regc_out, regd_out,
|
||||
regr_out, d, n, sel_muxa, sel_muxb, sel_muxr, reset, clk,
|
||||
load_rega, load_regb, load_regc, load_regd, load_regr, load_regs, load_regp,
|
||||
P, op_type, exp_odd);
|
||||
|
||||
input logic [52:0] d, n;
|
||||
input logic [2:0] sel_muxa, sel_muxb;
|
||||
input logic sel_muxr;
|
||||
input logic load_rega, load_regb, load_regc, load_regd;
|
||||
input logic load_regr, load_regs;
|
||||
input logic load_regp;
|
||||
input logic P;
|
||||
input logic op_type;
|
||||
input logic exp_odd;
|
||||
input logic reset;
|
||||
input logic clk;
|
||||
|
||||
output logic [59:0] q1, qp1, qm1;
|
||||
output logic [59:0] q0, qp0, qm0;
|
||||
output logic [59:0] rega_out, regb_out, regc_out, regd_out;
|
||||
output logic [119:0] regr_out;
|
||||
|
||||
supply1 vdd;
|
||||
supply0 vss;
|
||||
|
||||
logic [59:0] muxa_out, muxb_out;
|
||||
logic muxr_out;
|
||||
logic [10:0] ia_div, ia_sqrt;
|
||||
logic [59:0] ia_out;
|
||||
logic [119:0] mul_out;
|
||||
logic [59:0] q_out1, qm_out1, qp_out1;
|
||||
logic [59:0] q_out0, qm_out0, qp_out0;
|
||||
logic [59:0] mcand, mplier, mcand_q;
|
||||
logic [59:0] twocmp_out;
|
||||
logic [60:0] three;
|
||||
logic [119:0] Carry, Carry2;
|
||||
logic [119:0] Sum, Sum2;
|
||||
logic [119:0] constant, constant2;
|
||||
logic [59:0] q_const, qp_const, qm_const;
|
||||
logic [59:0] d2, n2;
|
||||
logic [11:0] d3;
|
||||
|
||||
// Check if exponent is odd for sqrt
|
||||
// If exp_odd=1 and sqrt, then M/2 and use ia_addr=0 as IA
|
||||
assign d2 = (exp_odd&op_type) ? {vss, d, 6'h0} : {d, 7'h0};
|
||||
assign n2 = op_type ? d2 : {n, 7'h0};
|
||||
|
||||
// IA div/sqrt
|
||||
sbtm_div ia1 (d[52:41], ia_div);
|
||||
sbtm_sqrt ia2 (d2[59:48], ia_sqrt);
|
||||
assign ia_out = op_type ? {ia_sqrt, {49{1'b0}}} : {ia_div, {49{1'b0}}};
|
||||
|
||||
// Choose IA or iteration
|
||||
mux6 #(60) mx1 (d2, ia_out, rega_out, regc_out, regd_out, regb_out, sel_muxb, muxb_out);
|
||||
mux5 #(60) mx2 (regc_out, n2, ia_out, regb_out, regd_out, sel_muxa, muxa_out);
|
||||
|
||||
// Deal with remainder if [0.5, 1) instead of [1, 2)
|
||||
mux2 #(120) mx3a ({~n, {67{1'b1}}}, {{1'b1}, ~n, {66{1'b1}}}, q1[59], constant2);
|
||||
// Select Mcand, Remainder/Q''
|
||||
mux2 #(120) mx3 (120'h0, constant2, sel_muxr, constant);
|
||||
// Select mcand - remainder should always choose q1 [1,2) because
|
||||
// adjustment of N in the from XX.FFFFFFF
|
||||
mux2 #(60) mx4 (q0, q1, q1[59], mcand_q);
|
||||
mux2 #(60) mx5 (muxb_out, mcand_q, sel_muxr&op_type, mplier);
|
||||
mux2 #(60) mx6 (muxa_out, mcand_q, sel_muxr, mcand);
|
||||
// R4 Booth TDM multiplier (carry/save)
|
||||
redundantmul #(60) bigmul(.a(mcand), .b(mplier), .out0(Sum), .out1(Carry));
|
||||
// Q*D - N (reversed but changed in rounder.v to account for sign reversal)
|
||||
csa #(120) csa1 (Sum, Carry, constant, 1'b0, Sum2, Carry2);
|
||||
// Add ulp for subtraction in remainder
|
||||
mux2 #(1) mx7 (1'b0, 1'b1, sel_muxr, muxr_out);
|
||||
|
||||
// Constant for Q''
|
||||
mux2 #(60) mx8 ({60'h0000_0000_0000_020}, {60'h0000_0040_0000_000}, P, q_const);
|
||||
mux2 #(60) mx9 ({60'h0000_0000_0000_0A0}, {60'h0000_0140_0000_000}, P, qp_const);
|
||||
mux2 #(60) mxA ({60'hFFFF_FFFF_FFFF_F9F}, {60'hFFFF_FF3F_FFFF_FFF}, P, qm_const);
|
||||
|
||||
logic [119:0] Sum_pipe;
|
||||
logic [119:0] Carry_pipe;
|
||||
logic muxr_pipe;
|
||||
logic rega_pipe;
|
||||
logic regb_pipe;
|
||||
logic regc_pipe;
|
||||
logic regd_pipe;
|
||||
logic regs_pipe;
|
||||
logic regs_pipe2;
|
||||
logic regr_pipe;
|
||||
logic P_pipe;
|
||||
logic op_type_pipe;
|
||||
logic [59:0] q_const_pipe;
|
||||
logic [59:0] qm_const_pipe;
|
||||
logic [59:0] qp_const_pipe;
|
||||
logic [59:0] q_const_pipe2;
|
||||
logic [59:0] qm_const_pipe2;
|
||||
logic [59:0] qp_const_pipe2;
|
||||
|
||||
// Stage 1
|
||||
flopenr #(120) regp1 (clk, reset, load_regp, Sum2, Sum_pipe);
|
||||
flopenr #(120) regp2 (clk, reset, load_regp, Carry2, Carry_pipe);
|
||||
flopenr #(1) regp3 (clk, reset, load_regp, muxr_out, muxr_pipe);
|
||||
|
||||
flopenr #(1) regp4 (clk, reset, load_regp, load_rega, rega_pipe);
|
||||
flopenr #(1) regp5 (clk, reset, load_regp, load_regb, regb_pipe);
|
||||
flopenr #(1) regp6 (clk, reset, load_regp, load_regc, regc_pipe);
|
||||
flopenr #(1) regp7 (clk, reset, load_regp, load_regd, regd_pipe);
|
||||
flopenr #(1) regp8 (clk, reset, load_regp, load_regs, regs_pipe);
|
||||
flopenr #(1) regp9 (clk, reset, load_regp, load_regr, regr_pipe);
|
||||
flopenr #(1) regpA (clk, reset, load_regp, P, P_pipe);
|
||||
flopenr #(1) regpB (clk, reset, load_regp, op_type, op_type_pipe);
|
||||
flopenr #(60) regpC (clk, reset, load_regp, q_const, q_const_pipe);
|
||||
flopenr #(60) regpD (clk, reset, load_regp, qp_const, qp_const_pipe);
|
||||
flopenr #(60) regpE (clk, reset, load_regp, qm_const, qm_const_pipe);
|
||||
|
||||
// CPA (from CSA)/Remainder addition/subtraction
|
||||
assign mul_out = Sum_pipe + Carry_pipe + {119'h0, muxr_pipe};
|
||||
// One's complement instead of two's complement (for hw efficiency)
|
||||
assign three = {~mul_out[118] , mul_out[118], ~mul_out[117:59]};
|
||||
mux2 #(60) mxTC (~mul_out[118:59], three[60:1], op_type_pipe, twocmp_out);
|
||||
|
||||
// Stage 2
|
||||
flopenr #(60) regc (clk, reset, regc_pipe, twocmp_out, regc_out);
|
||||
flopenr #(60) regb (clk, reset, regb_pipe, mul_out[118:59], regb_out);
|
||||
flopenr #(60) rega (clk, reset, rega_pipe, mul_out[118:59], rega_out);
|
||||
flopenr #(60) regd (clk, reset, regd_pipe, mul_out[118:59], regd_out);
|
||||
flopenr #(120) regr (clk, reset, regr_pipe, mul_out, regr_out);
|
||||
flopenr #(1) regl (clk, reset, regs_pipe, regs_pipe, regs_pipe2);
|
||||
flopenr #(60) regm (clk, reset, regs_pipe, q_const_pipe, q_const_pipe2);
|
||||
flopenr #(60) regn (clk, reset, regs_pipe, qp_const_pipe, qp_const_pipe2);
|
||||
flopenr #(60) rego (clk, reset, regs_pipe, qm_const_pipe, qm_const_pipe2);
|
||||
|
||||
// Assuming [1,2) - q1
|
||||
assign q_out1 = regb_out + q_const;
|
||||
assign qp_out1 = regb_out + qp_const;
|
||||
assign qm_out1 = regb_out + qm_const + 1'b1;
|
||||
// Assuming [0.5,1) - q0
|
||||
assign q_out0 = {regb_out[58:0], 1'b0} + q_const;
|
||||
assign qp_out0 = {regb_out[58:0], 1'b0} + qp_const;
|
||||
assign qm_out0 = {regb_out[58:0], 1'b0} + qm_const + 1'b1;
|
||||
|
||||
// Stage 3
|
||||
// Assuming [1,2)
|
||||
flopenr #(60) rege (clk, reset, regs_pipe2, {q_out1[59:35], (q_out1[34:6] & {29{~P_pipe}}), 6'h0}, q1);
|
||||
flopenr #(60) regf (clk, reset, regs_pipe2, {qm_out1[59:35], (qm_out1[34:6] & {29{~P_pipe}}), 6'h0}, qm1);
|
||||
flopenr #(60) regg (clk, reset, regs_pipe2, {qp_out1[59:35], (qp_out1[34:6] & {29{~P_pipe}}), 6'h0}, qp1);
|
||||
// Assuming [0,1)
|
||||
flopenr #(60) regh (clk, reset, regs_pipe2, {q_out0[59:35], (q_out0[34:6] & {29{~P_pipe}}), 6'h0}, q0);
|
||||
flopenr #(60) regj (clk, reset, regs_pipe2, {qm_out0[59:35], (qm_out0[34:6] & {29{~P_pipe}}), 6'h0}, qm0);
|
||||
flopenr #(60) regk (clk, reset, regs_pipe2, {qp_out0[59:35], (qp_out0[34:6] & {29{~P_pipe}}), 6'h0}, qp0);
|
||||
|
||||
endmodule // divconv
|
||||
|
||||
// *** rewrote behaviorally dh 5 Jan 2021 for speed
|
||||
// module csa #(parameter WIDTH=8) (
|
||||
// input logic [WIDTH-1:0] a, b, c,
|
||||
// output logic [WIDTH-1:0] sum, carry);
|
||||
|
||||
// assign sum = a ^ b ^ c;
|
||||
// assign carry = (a & (b | c)) | (b & c);
|
||||
// /*
|
||||
// logic [WIDTH:0] carry_temp;
|
||||
// genvar i;
|
||||
// for (i=0;i<WIDTH;i=i+1) begin : genbit
|
||||
// fa fa_inst (a[i], b[i], c[i], sum[i], carry_temp[i+1]);
|
||||
// end
|
||||
// assign carry = {carry_temp[WIDTH-1:1], 1'b0};
|
||||
// */
|
||||
// endmodule // csa
|
@ -1,82 +0,0 @@
|
||||
// Exception logic for the floating point adder. Note: We may
|
||||
// actually want to move to where the result is computed.
|
||||
module exception_div (
|
||||
|
||||
input logic [63:0] A, // 1st input operand (op1)
|
||||
input logic [63:0] B, // 2nd input operand (op2)
|
||||
input logic op_type, // Determine operation
|
||||
output logic [2:0] Ztype, // Indicates type of result (Z)
|
||||
output logic Invalid // Invalid operation exception
|
||||
);
|
||||
|
||||
logic AzeroM; // '1' if the mantissa of A is zero
|
||||
logic BzeroM; // '1' if the mantissa of B is zero
|
||||
logic AzeroE; // '1' if the exponent of A is zero
|
||||
logic BzeroE; // '1' if the exponent of B is zero
|
||||
logic AonesE; // '1' if the exponent of A is all ones
|
||||
logic BonesE; // '1' if the exponent of B is all ones
|
||||
logic AInf; // '1' if A is infinite
|
||||
logic BInf; // '1' if B is infinite
|
||||
logic AZero; // '1' if A is 0
|
||||
logic BZero; // '1' if B is 0
|
||||
logic ANaN; // '1' if A is a not-a-number
|
||||
logic BNaN; // '1' if B is a not-a-number
|
||||
logic ASNaN; // '1' if A is a signalling not-a-number
|
||||
logic BSNaN; // '1' if B is a signalling not-a-number
|
||||
logic ZSNaN; // '1' if result Z is a quiet NaN
|
||||
logic ZInf; // '1' if result Z is an infnity
|
||||
logic Zero; // '1' if result is zero
|
||||
logic NegSqrt; // '1' if sqrt and operand is negative
|
||||
|
||||
//***take this module out and add more registers or just recalculate it all
|
||||
// Determine if mantissas are all zeros
|
||||
assign AzeroM = (A[51:0] == 52'h0);
|
||||
assign BzeroM = (B[51:0] == 52'h0);
|
||||
|
||||
// Determine if exponents are all ones or all zeros
|
||||
assign AonesE = A[62]&A[61]&A[60]&A[59]&A[58]&A[57]&A[56]&A[55]&A[54]&A[53]&A[52];
|
||||
assign BonesE = B[62]&B[61]&B[60]&B[59]&B[58]&B[57]&B[56]&B[55]&B[54]&B[53]&B[52];
|
||||
assign AzeroE = ~(A[62]|A[61]|A[60]|A[59]|A[58]|A[57]|A[56]|A[55]|A[54]|A[53]|A[52]);
|
||||
assign BzeroE = ~(B[62]|B[61]|B[60]|B[59]|B[58]|B[57]|B[56]|B[55]|B[54]|B[53]|B[52]);
|
||||
|
||||
// Determine special cases. Note: Zero is not really a special case.
|
||||
assign AInf = AonesE & AzeroM;
|
||||
assign BInf = BonesE & BzeroM;
|
||||
assign ANaN = AonesE & ~AzeroM;
|
||||
assign BNaN = BonesE & ~BzeroM;
|
||||
assign ASNaN = ANaN & A[50];
|
||||
assign BSNaN = ANaN & A[50];
|
||||
assign AZero = AzeroE & AzeroM;
|
||||
assign BZero = BzeroE & BzeroE;
|
||||
|
||||
// Is NaN if operand is negative and its a sqrt
|
||||
assign NegSqrt = (A[63] & op_type & ~AZero);
|
||||
|
||||
// An "Invalid Operation" exception occurs if (A or B is a signalling NaN)
|
||||
// or (A and B are both Infinite)
|
||||
assign Invalid = ASNaN | BSNaN | (((AInf & BInf) | (AZero & BZero))&~op_type) |
|
||||
NegSqrt;
|
||||
|
||||
// The result is a quiet NaN if (an "Invalid Operation" exception occurs)
|
||||
// or (A is a NaN) or (B is a NaN).
|
||||
assign ZSNaN = Invalid | ANaN | BNaN;
|
||||
|
||||
// The result is zero
|
||||
assign Zero = (AZero | BInf)&~op_type | AZero&op_type;
|
||||
|
||||
// The result is +Inf if ((A is Inf) or (B is 0)) and (the
|
||||
// result is not a quiet NaN).
|
||||
assign ZInf = (AInf | BZero)&~ZSNaN&~op_type | AInf&op_type&~ZSNaN;
|
||||
|
||||
// Set the type of the result as follows:
|
||||
// Ztype Result
|
||||
// 000 Normal
|
||||
// 010 Infinity
|
||||
// 011 Zero
|
||||
// 110 Div by 0
|
||||
// 111 SNaN
|
||||
assign Ztype[2] = (ZSNaN);
|
||||
assign Ztype[1] = (ZSNaN) | (Zero) | (ZInf);
|
||||
assign Ztype[0] = (ZSNaN) | (Zero);
|
||||
|
||||
endmodule // exception
|
@ -1,132 +0,0 @@
|
||||
///////////////////////////////////////////
|
||||
//
|
||||
// Written: James Stine
|
||||
// Modified: 8/1/2018
|
||||
//
|
||||
// Purpose: Floating point divider/square root top unit (Goldschmidt)
|
||||
//
|
||||
// A component of the Wally configurable RISC-V project.
|
||||
//
|
||||
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
|
||||
//
|
||||
// MIT LICENSE
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
// software and associated documentation files (the "Software"), to deal in the Software
|
||||
// without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
||||
// to whom the Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all copies or
|
||||
// substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
|
||||
// OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// `timescale 1ps/1ps
|
||||
module fpdiv (
|
||||
input logic clk,
|
||||
input logic reset,
|
||||
input logic start,
|
||||
input logic [63:0] op1,
|
||||
input logic [63:0] op2,
|
||||
input logic [1:0] rm,
|
||||
input logic op_type,
|
||||
input logic P,
|
||||
input logic OvEn,
|
||||
input logic UnEn,
|
||||
input logic XNaNQ,
|
||||
input logic YNaNQ,
|
||||
input logic XZeroQ,
|
||||
input logic YZeroQ,
|
||||
input logic XInfQ,
|
||||
input logic YInfQ,
|
||||
|
||||
output logic done,
|
||||
output logic FDivBusyE,
|
||||
output logic [63:0] AS_Result,
|
||||
output logic [4:0] Flags);
|
||||
|
||||
logic [63:0] Float1;
|
||||
logic [63:0] Float2;
|
||||
|
||||
logic [12:0] exp1, exp2, expF;
|
||||
logic [12:0] exp_diff, bias;
|
||||
logic [13:0] exp_sqrt;
|
||||
logic [63:0] Result;
|
||||
logic [52:0] mantissaA;
|
||||
logic [52:0] mantissaB;
|
||||
|
||||
logic [2:0] sel_inv;
|
||||
logic Invalid;
|
||||
logic [4:0] FlagsIn;
|
||||
logic signResult;
|
||||
|
||||
logic [59:0] q1, qm1, qp1, q0, qm0, qp0;
|
||||
logic [59:0] rega_out, regb_out, regc_out, regd_out;
|
||||
logic [119:0] regr_out;
|
||||
logic [2:0] sel_muxa, sel_muxb;
|
||||
logic sel_muxr;
|
||||
logic load_rega, load_regb, load_regc, load_regd, load_regr;
|
||||
|
||||
logic load_regs;
|
||||
logic exp_cout1, exp_cout2;
|
||||
logic exp_odd, open;
|
||||
|
||||
// op_type : fdiv=0, fsqrt=1
|
||||
assign Float1 = op1;
|
||||
assign Float2 = op_type ? op1 : op2;
|
||||
|
||||
// Exception detection
|
||||
exception_div exc1 (.A(Float1), .B(Float2), .op_type, .Ztype(sel_inv), .Invalid);
|
||||
|
||||
// Determine Sign/Mantissa
|
||||
assign signResult = (Float1[63]^Float2[63]);
|
||||
assign mantissaA = {1'b1, Float1[51:0]};
|
||||
assign mantissaB = {1'b1, Float2[51:0]};
|
||||
// Perform Exponent Subtraction - expA - expB + Bias
|
||||
assign exp1 = {2'b0, Float1[62:52]};
|
||||
assign exp2 = {2'b0, Float2[62:52]};
|
||||
assign bias = {3'h0, 10'h3FF};
|
||||
// Divide exponent
|
||||
assign {exp_cout1, open, exp_diff} = {2'b0, exp1} - {2'b0, exp2} + {2'b0, bias};
|
||||
|
||||
// Sqrt exponent (check if exponent is odd)
|
||||
assign exp_odd = Float1[52] ? 1'b0 : 1'b1;
|
||||
assign {exp_cout2, exp_sqrt} = {1'b0, exp1} + {4'h0, 10'h3ff} + {13'b0, exp_odd};
|
||||
// Choose correct exponent
|
||||
assign expF = op_type ? exp_sqrt[13:1] : exp_diff;
|
||||
|
||||
// Main Goldschmidt/Division Routine
|
||||
divconv goldy (.q1, .qm1, .qp1, .q0, .qm0, .qp0, .rega_out, .regb_out, .regc_out, .regd_out,
|
||||
.regr_out, .d(mantissaB), .n(mantissaA), .sel_muxa, .sel_muxb, .sel_muxr,
|
||||
.reset, .clk, .load_rega, .load_regb, .load_regc, .load_regd,
|
||||
.load_regr, .load_regs, .P, .op_type, .exp_odd);
|
||||
|
||||
// FSM : control divider
|
||||
fsm_fpdiv control (.clk, .reset, .start, .op_type,
|
||||
.done, .load_rega, .load_regb, .load_regc, .load_regd,
|
||||
.load_regr, .load_regs, .sel_muxa, .sel_muxb, .sel_muxr,
|
||||
.divBusy(FDivBusyE));
|
||||
|
||||
// Round the mantissa to a 52-bit value, with the leading one
|
||||
// removed. The rounding units also handles special cases and
|
||||
// set the exception flags.
|
||||
rounder_div round1 (.rm, .P, .OvEn, .UnEn, .exp_diff(expF),
|
||||
.sel_inv, .Invalid, .SignR(signResult),
|
||||
.Float1(op1), .Float2(op2),
|
||||
.XNaNQ, .YNaNQ, .XZeroQ, .YZeroQ,
|
||||
.XInfQ, .YInfQ, .op_type,
|
||||
.q1, .qm1, .qp1, .q0, .qm0, .qp0, .regr_out,
|
||||
.Result, .Flags(FlagsIn));
|
||||
|
||||
// Store the final result and the exception flags in registers.
|
||||
flopenr #(64) rega (clk, reset, done, Result, AS_Result);
|
||||
flopenr #(5) regc (clk, reset, done, FlagsIn, Flags);
|
||||
|
||||
endmodule // fpadd
|
||||
|
@ -1,170 +0,0 @@
|
||||
///////////////////////////////////////////
|
||||
//
|
||||
// Written: James Stine
|
||||
// Modified: 8/1/2018
|
||||
//
|
||||
// Purpose: Floating point divider/square root top unit pipelined version (Goldschmidt)
|
||||
//
|
||||
// A component of the Wally configurable RISC-V project.
|
||||
//
|
||||
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
|
||||
//
|
||||
// MIT LICENSE
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
// software and associated documentation files (the "Software"), to deal in the Software
|
||||
// without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
||||
// to whom the Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all copies or
|
||||
// substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
|
||||
// OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
module fpdiv_pipe (
|
||||
input logic clk,
|
||||
input logic reset,
|
||||
input logic start,
|
||||
input logic [63:0] op1,
|
||||
input logic [63:0] op2,
|
||||
input logic [1:0] rm,
|
||||
input logic op_type,
|
||||
input logic P,
|
||||
input logic OvEn,
|
||||
input logic UnEn,
|
||||
input logic XNaNQ,
|
||||
input logic YNaNQ,
|
||||
input logic XZeroQ,
|
||||
input logic YZeroQ,
|
||||
input logic XInfQ,
|
||||
input logic YInfQ,
|
||||
|
||||
output logic done,
|
||||
output logic FDivBusyE,
|
||||
output logic load_preload,
|
||||
output logic [63:0] AS_Result,
|
||||
output logic [4:0] Flags);
|
||||
|
||||
supply1 vdd;
|
||||
supply0 vss;
|
||||
|
||||
logic [63:0] Float1;
|
||||
logic [63:0] Float2;
|
||||
logic [63:0] IntValue;
|
||||
|
||||
logic [12:0] exp1, exp2, expF;
|
||||
logic [14:0] exp_pre_diff;
|
||||
logic [12:0] exp_diff, bias;
|
||||
logic [13:0] exp_sqrt;
|
||||
|
||||
logic [63:0] Result;
|
||||
logic [52:0] mantissaA;
|
||||
logic [52:0] mantissaB;
|
||||
|
||||
logic [2:0] sel_inv;
|
||||
logic Invalid;
|
||||
logic [4:0] FlagsIn;
|
||||
logic exp_gt63;
|
||||
logic Sticky_out;
|
||||
logic signResult, sign_corr;
|
||||
logic corr_sign;
|
||||
logic zeroB;
|
||||
logic convert;
|
||||
logic swap;
|
||||
logic sub;
|
||||
|
||||
logic [59:0] q1, qm1, qp1, q0, qm0, qp0;
|
||||
logic [59:0] rega_out, regb_out, regc_out, regd_out;
|
||||
logic [119:0] regr_out;
|
||||
logic [2:0] sel_muxa, sel_muxb;
|
||||
logic sel_muxr;
|
||||
logic load_rega, load_regb, load_regc, load_regd, load_regr;
|
||||
logic load_regp, load_regs;
|
||||
|
||||
logic exp_odd, exp_odd1;
|
||||
logic start1;
|
||||
logic P1;
|
||||
logic op_type1;
|
||||
logic [12:0] expF1;
|
||||
logic [52:0] mantissaA1;
|
||||
logic [52:0] mantissaB1;
|
||||
logic [2:0] sel_inv1;
|
||||
logic signResult1;
|
||||
logic Invalid1;
|
||||
|
||||
// op_type : fdiv=0, fsqrt=1
|
||||
assign Float1 = op1;
|
||||
assign Float2 = op_type ? op1 : op2;
|
||||
|
||||
// Exception detection
|
||||
exception_div exc1 (.A(Float1), .B(Float2), .op_type, .Ztype(sel_inv), .Invalid);
|
||||
|
||||
// Determine Sign/Mantissa
|
||||
assign signResult = ((Float1[63]^Float2[63])&~op_type);
|
||||
assign mantissaA = {vdd, Float1[51:0]};
|
||||
assign mantissaB = {vdd, Float2[51:0]};
|
||||
|
||||
// Perform Exponent Subtraction - expA - expB + Bias
|
||||
assign exp1 = {2'b0, Float1[62:52]};
|
||||
assign exp2 = {2'b0, Float2[62:52]};
|
||||
// bias : DP = 2^{11-1}-1 = 1023
|
||||
assign bias = {3'h0, 10'h3FF};
|
||||
// Divide exponent
|
||||
assign exp_pre_diff = {2'b0, exp1} - {2'b0, exp2} + {2'b0, bias};
|
||||
assign exp_diff = exp_pre_diff[12:0];
|
||||
|
||||
// Sqrt exponent (check if exponent is odd)
|
||||
assign exp_odd = Float1[52] ? 1'b0 : 1'b1;
|
||||
assign exp_sqrt = {1'b0, exp1} + {4'h0, 10'h3ff} + {13'b0, exp_odd};
|
||||
// Choose correct exponent
|
||||
assign expF = op_type ? exp_sqrt[13:1] : exp_diff;
|
||||
|
||||
flopenr #(1) rega (clk, reset, 1'b1, exp_odd, exp_odd1);
|
||||
flopenr #(1) regb (clk, reset, 1'b1, P, P1);
|
||||
flopenr #(1) regc (clk, reset, 1'b1, op_type, op_type1);
|
||||
flopenr #(13) regd (clk, reset, 1'b1, expF, expF1);
|
||||
flopenr #(53) rege (clk, reset, 1'b1, mantissaA, mantissaA1);
|
||||
flopenr #(53) regf (clk, reset, 1'b1, mantissaB, mantissaB1);
|
||||
flopenr #(1) regg (clk, reset, 1'b1, start, start1);
|
||||
flopenr #(3) regh (clk, reset, 1'b1, sel_inv, sel_inv1);
|
||||
flopenr #(1) regj (clk, reset, 1'b1, signResult, signResult1);
|
||||
flopenr #(1) regk (clk, reset, 1'b1, Invalid, Invalid1);
|
||||
|
||||
// Main Goldschmidt/Division Routine
|
||||
divconv_pipe goldy (.q1, .qm1, .qp1, .q0, .qm0, .qp0,
|
||||
.rega_out, .regb_out, .regc_out, .regd_out,
|
||||
.regr_out, .d(mantissaB1), .n(mantissaA1),
|
||||
.sel_muxa, .sel_muxb, .sel_muxr, .reset, .clk,
|
||||
.load_rega, .load_regb, .load_regc, .load_regd,
|
||||
.load_regr, .load_regs, .load_regp,
|
||||
.P(P), .op_type(op_type1), .exp_odd(exp_odd1));
|
||||
|
||||
// FSM : control divider
|
||||
fsm_fpdiv_pipe control (.clk, .reset, .start(start), .op_type(op_type1), .P(P),
|
||||
.done, .load_rega, .load_regb, .load_regc, .load_regd,
|
||||
.load_regr, .load_regs, .load_regp, .load_preload,
|
||||
.sel_muxa, .sel_muxb, .sel_muxr, .divBusy(FDivBusyE));
|
||||
|
||||
// Round the mantissa to a 52-bit value, with the leading one
|
||||
// removed. The rounding units also handles special cases and
|
||||
// set the exception flags.
|
||||
rounder_div round1 (.rm, .P(P), .OvEn(1'b0), .UnEn(1'b0), .exp_diff(expF1),
|
||||
.sel_inv(sel_inv1), .Invalid(Invalid1), .SignR(signResult1),
|
||||
.Float1(op1), .Float2(op2),
|
||||
.XNaNQ, .YNaNQ, .XZeroQ, .YZeroQ,
|
||||
.XInfQ, .YInfQ, .op_type(op_type1),
|
||||
.q1, .qm1, .qp1, .q0, .qm0, .qp0, .regr_out,
|
||||
.Result, .Flags(FlagsIn));
|
||||
|
||||
// Store the final result and the exception flags in registers.
|
||||
flopenr #(64) regl (clk, reset, done, Result, AS_Result);
|
||||
flopenr #(5) regn (clk, reset, done, FlagsIn, Flags);
|
||||
|
||||
endmodule // fpdiv_pipe
|
||||
|
@ -1,74 +0,0 @@
|
||||
///////////////////////////////////////////
|
||||
//
|
||||
// Written: David Harris
|
||||
// Modified: 11 September 2021
|
||||
//
|
||||
// Purpose: Recurrence-based SRT Division and Square Root
|
||||
//
|
||||
// A component of the Wally configurable RISC-V project.
|
||||
//
|
||||
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
|
||||
//
|
||||
// MIT LICENSE
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
// software and associated documentation files (the "Software"), to deal in the Software
|
||||
// without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
||||
// to whom the Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all copies or
|
||||
// substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
|
||||
// OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
`include "wally-config.vh"
|
||||
|
||||
module fpudivsqrtrecur (
|
||||
input logic clk,
|
||||
input logic reset,
|
||||
input logic FlushM, // flush the memory stage
|
||||
input logic StallM, // stall memory stage
|
||||
input logic FDivSqrtStart, // start a computation
|
||||
input logic FmtE, // precision 1 = double 0 = single
|
||||
input logic FDivE, FSqrtE,
|
||||
input logic [2:0] FrmM, // rounding mode 000 = rount to nearest, ties to even 001 = round twords zero 010 = round down 011 = round up 100 = round to nearest, ties to max magnitude
|
||||
input logic XSgnE, YSgnE, // input signs - execute stage
|
||||
input logic [`NE-1:0] XExpE, YExpE, // input exponents - execute stage
|
||||
input logic [`NF:0] XManE, YManE, // input mantissa - execute stage
|
||||
input logic XDenormE, YDenormE, // is denorm
|
||||
input logic XZeroE, YZeroE, // is zero - execute stage
|
||||
input logic XNaNE, YNaNE, // is NaN
|
||||
input logic XSNaNE, YSNaNE, // is signaling NaN
|
||||
input logic XInfE, YInfE, ZInfE, // is infinity
|
||||
input logic [10:0] BiasE, // bias (max exponent/2) ***parameterize in unpacking unit
|
||||
output logic FDviSqrtBusy, FDivSqrtDone, //currently occpied, or done with operation
|
||||
output logic [`FLEN-1:0] FDivSqrtResM, // result
|
||||
output logic [4:0] FDivSqrtFlgM // flags
|
||||
);
|
||||
|
||||
logic FDivSqrtResSgn;
|
||||
logic [`FLEN-1:0] FDivSqrtRecurRes;
|
||||
|
||||
// Radix-2 SRT Division and Square Root
|
||||
|
||||
// Special Cases
|
||||
// *** shift to handle denorms in hardware
|
||||
|
||||
assign FDivSqrtResSgn = FDivE & (XSgnE ^ YSgnE); // Sign is negative for division if inputs have opposite signs
|
||||
|
||||
always_comb begin
|
||||
if (FSqrtE & XSgnE | FDivE & XZeroE & YZeroE | XNaNE | FDivE & YNaNE) FDivSqrtResM = 0; // ***replace with NAN; // *** which one
|
||||
else if (FDivE & YZeroE | XInfE) FDivSqrtResM = {FDivSqrtResSgn, (`NE)'(1), (`NF)'(0)}; // infinity
|
||||
else if (FDivE & YInfE) FDivSqrtResM = {FDivSqrtResSgn, (`NE)'(0), (`NF)'(0)}; // zero
|
||||
else FDivSqrtResM = FDivSqrtRecurRes;
|
||||
end
|
||||
|
||||
// *** handle early termination in the special cases
|
||||
// *** handle signaling NANs
|
||||
endmodule
|
@ -1,105 +0,0 @@
|
||||
///////////////////////////////////////////
|
||||
//
|
||||
// Written: David Harris
|
||||
// Modified: 11 September 2021
|
||||
//
|
||||
// Purpose: Recurrence-based SRT Division and Square Root
|
||||
//
|
||||
// A component of the Wally configurable RISC-V project.
|
||||
//
|
||||
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
|
||||
//
|
||||
// MIT LICENSE
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
// software and associated documentation files (the "Software"), to deal in the Software
|
||||
// without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
||||
// to whom the Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all copies or
|
||||
// substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
|
||||
// OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
`include "wally-config.vh"
|
||||
|
||||
// Bit counts:
|
||||
// Inputs are originally normalized floating point numbers with NF fractional bits and a leading 1 integer bit
|
||||
// x is right shifted by up to 2 to be in the range of 1/4 <= x < 1/2 for divide, 1/4 <= x < 1 for sqrt
|
||||
// Hence, x now has NF+2 fractional bits and 0 integer bits
|
||||
// d is right shifted by 1 to be in the range of 1/2 <= d < 1. It thus has NF+1 fractional bits and 0 integer bits
|
||||
// q is eventually in the range of 1/4 < q < 1 and hence needs NF+2 bits to keep NF bits when normalized, plus some*** more bits for rounding
|
||||
// The partial
|
||||
|
||||
/*
|
||||
module fpudivsqrtrecurcore (
|
||||
input logic clk,
|
||||
input logic reset,
|
||||
input logic start, // start a computation
|
||||
input logic busy, // computation running
|
||||
input logic fmt, // precision 1 = double 0 = single
|
||||
input logic [`NF+1:0] x, // in range 1/4 <= x < 1/2 for divide, 1/4 <=x < 1 for sqrt
|
||||
input logic [`NF+1:0] din, // in range 1/2 <= d < 1 for divide
|
||||
input logic FDiv, FSqrt, // *** not yet used
|
||||
output logic [`FLEN-1:0] FDivSqrtRecurRes // result
|
||||
);
|
||||
|
||||
assign FDivSqrtRecurRes = 0;
|
||||
|
||||
logic [***] d, ws, wsout, wsnext, wc, wcout, wcnext;
|
||||
logic [1:0] q; // 00 = 0, 01 = 1, 10 = -1
|
||||
|
||||
// Radix-2 SRT Division
|
||||
|
||||
// registers for divisor and partial remainder
|
||||
flopen #(NF+1) dreg(clk, start, din, d);
|
||||
mux2 #(NF+1) wsmux(wsout, x, start, wsnext);
|
||||
flopen #(NF+1) wsreg(clk, busy, wsnext, ws);
|
||||
mux2 #(NF+1) wcmux(wcout, 0, start, wcnext);
|
||||
flopen #(NF+1) wcreg(clk, busy, wcnext, wc);
|
||||
|
||||
// quotient selection
|
||||
qsel qsel(ws[***4bits], wc[***], q);
|
||||
|
||||
// partial remainder update
|
||||
always_comb begin // select -d * q to add to partial remainder
|
||||
if (q[1]) dq = d;
|
||||
else if (q[0]) dq = ~d;
|
||||
else dq = 0;
|
||||
end
|
||||
csa #(***) csa(ws, wc, dq, q[1], wsout, wcout);
|
||||
|
||||
|
||||
endmodule
|
||||
*/
|
||||
|
||||
/*
|
||||
module csa #(parameter N=4) (
|
||||
input logic [N-1:0] sin, cin, ain,
|
||||
input logic carry,
|
||||
output logic [N-1:0] sum, cout
|
||||
);
|
||||
|
||||
logic [N-1:0] c;
|
||||
|
||||
assign c = {cin[N-2:0], carry}; // shift carries left and inject optional 1 into lsb
|
||||
assign sum = sin ^ ain ^ c;
|
||||
assign cout = sin & ain | sin & c | ain & c;
|
||||
endmodule
|
||||
*/
|
||||
|
||||
module qsel( // radix 2 SRT division quotient selection
|
||||
input logic [3:0] wc, ws,
|
||||
output logic [1:0] q
|
||||
);
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
|
@ -1,537 +0,0 @@
|
||||
///////////////////////////////////////////
|
||||
//
|
||||
// Written: James Stine
|
||||
// Modified: 9/28/2021
|
||||
//
|
||||
// Purpose: FSM for floating point divider/square root unit (Goldschmidt)
|
||||
//
|
||||
// A component of the Wally configurable RISC-V project.
|
||||
//
|
||||
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
|
||||
//
|
||||
// MIT LICENSE
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
// software and associated documentation files (the "Software"), to deal in the Software
|
||||
// without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
||||
// to whom the Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all copies or
|
||||
// substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
|
||||
// OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
module fsm_fpdiv (
|
||||
input logic clk,
|
||||
input logic reset,
|
||||
input logic start,
|
||||
input logic op_type,
|
||||
output logic done,
|
||||
output logic load_rega,
|
||||
output logic load_regb,
|
||||
output logic load_regc,
|
||||
output logic load_regd,
|
||||
output logic load_regr,
|
||||
output logic load_regs,
|
||||
output logic [2:0] sel_muxa,
|
||||
output logic [2:0] sel_muxb,
|
||||
output logic sel_muxr,
|
||||
output logic divBusy
|
||||
);
|
||||
|
||||
typedef enum logic [4:0] {S0, S1, S2, S3, S4, S5, S6, S7, S8, S9,
|
||||
S10, S11, S12, S13, S14, S15, S16, S17, S18, S19,
|
||||
S20, S21, S22, S23, S24, S25, S26, S27, S28, S29,
|
||||
S30} statetype;
|
||||
|
||||
statetype current_state, next_state;
|
||||
|
||||
always @(posedge clk)
|
||||
begin
|
||||
if (reset == 1'b1)
|
||||
current_state = S0;
|
||||
else
|
||||
current_state = next_state;
|
||||
end
|
||||
|
||||
always_comb
|
||||
begin
|
||||
case(current_state)
|
||||
S0: // iteration 0
|
||||
begin
|
||||
if (start==1'b0)
|
||||
begin
|
||||
done = 1'b0;
|
||||
divBusy = 1'b0;
|
||||
load_rega = 1'b0;
|
||||
load_regb = 1'b0;
|
||||
load_regc = 1'b0;
|
||||
load_regd = 1'b0;
|
||||
load_regr = 1'b0;
|
||||
load_regs = 1'b0;
|
||||
sel_muxa = 3'b000;
|
||||
sel_muxb = 3'b000;
|
||||
sel_muxr = 1'b0;
|
||||
next_state = S0;
|
||||
end
|
||||
else if (start==1'b1 & op_type==1'b0)
|
||||
begin
|
||||
done = 1'b0;
|
||||
divBusy = 1'b1;
|
||||
load_rega = 1'b0;
|
||||
load_regb = 1'b1;
|
||||
load_regc = 1'b0;
|
||||
load_regd = 1'b0;
|
||||
load_regr = 1'b0;
|
||||
load_regs = 1'b0;
|
||||
sel_muxa = 3'b001;
|
||||
sel_muxb = 3'b001;
|
||||
sel_muxr = 1'b0;
|
||||
next_state = S1;
|
||||
end // if (start==1'b1 & op_type==1'b0)
|
||||
else if (start==1'b1 & op_type==1'b1)
|
||||
begin
|
||||
done = 1'b0;
|
||||
divBusy = 1'b1;
|
||||
load_rega = 1'b0;
|
||||
load_regb = 1'b1;
|
||||
load_regc = 1'b0;
|
||||
load_regd = 1'b0;
|
||||
load_regr = 1'b0;
|
||||
load_regs = 1'b0;
|
||||
sel_muxa = 3'b010;
|
||||
sel_muxb = 3'b000;
|
||||
sel_muxr = 1'b0;
|
||||
next_state = S13;
|
||||
end
|
||||
else
|
||||
begin
|
||||
done = 1'b0;
|
||||
divBusy = 1'b0;
|
||||
load_rega = 1'b0;
|
||||
load_regb = 1'b0;
|
||||
load_regc = 1'b0;
|
||||
load_regd = 1'b0;
|
||||
load_regr = 1'b0;
|
||||
load_regs = 1'b0;
|
||||
sel_muxa = 3'b000;
|
||||
sel_muxb = 3'b000;
|
||||
sel_muxr = 1'b0;
|
||||
next_state = S0;
|
||||
end
|
||||
end // case: S0
|
||||
S1:
|
||||
begin
|
||||
done = 1'b0;
|
||||
divBusy = 1'b1;
|
||||
load_rega = 1'b1;
|
||||
load_regb = 1'b0;
|
||||
load_regc = 1'b1;
|
||||
load_regd = 1'b0;
|
||||
load_regr = 1'b0;
|
||||
load_regs = 1'b0;
|
||||
sel_muxa = 3'b010;
|
||||
sel_muxb = 3'b000;
|
||||
sel_muxr = 1'b0;
|
||||
next_state = S2;
|
||||
end
|
||||
S2: // iteration 1
|
||||
begin
|
||||
done = 1'b0;
|
||||
divBusy = 1'b1;
|
||||
load_rega = 1'b0;
|
||||
load_regb = 1'b1;
|
||||
load_regc = 1'b0;
|
||||
load_regd = 1'b0;
|
||||
load_regr = 1'b0;
|
||||
load_regs = 1'b0;
|
||||
sel_muxa = 3'b011;
|
||||
sel_muxb = 3'b011;
|
||||
sel_muxr = 1'b0;
|
||||
next_state = S3;
|
||||
end
|
||||
S3:
|
||||
begin
|
||||
done = 1'b0;
|
||||
divBusy = 1'b1;
|
||||
load_rega = 1'b1;
|
||||
load_regb = 1'b0;
|
||||
load_regc = 1'b1;
|
||||
load_regd = 1'b0;
|
||||
load_regr = 1'b0;
|
||||
load_regs = 1'b0;
|
||||
sel_muxa = 3'b000;
|
||||
sel_muxb = 3'b010;
|
||||
sel_muxr = 1'b0;
|
||||
next_state = S4;
|
||||
end
|
||||
S4: // iteration 2
|
||||
begin
|
||||
done = 1'b0;
|
||||
divBusy = 1'b1;
|
||||
load_rega = 1'b0;
|
||||
load_regb = 1'b1;
|
||||
load_regc = 1'b0;
|
||||
load_regd = 1'b0;
|
||||
load_regr = 1'b0;
|
||||
load_regs = 1'b0;
|
||||
sel_muxa = 3'b011;
|
||||
sel_muxb = 3'b011;
|
||||
sel_muxr = 1'b0;
|
||||
next_state = S5;
|
||||
end
|
||||
S5:
|
||||
begin
|
||||
done = 1'b0;
|
||||
divBusy = 1'b1;
|
||||
load_rega = 1'b1;
|
||||
load_regb = 1'b0;
|
||||
load_regc = 1'b1;
|
||||
load_regd = 1'b0;
|
||||
load_regr = 1'b0;
|
||||
load_regs = 1'b0;
|
||||
sel_muxa = 3'b000;
|
||||
sel_muxb = 3'b010;
|
||||
sel_muxr = 1'b0; // add
|
||||
next_state = S6;
|
||||
end
|
||||
S6: // iteration 3
|
||||
begin
|
||||
done = 1'b0;
|
||||
divBusy = 1'b1;
|
||||
load_rega = 1'b0;
|
||||
load_regb = 1'b1;
|
||||
load_regc = 1'b0;
|
||||
load_regd = 1'b0;
|
||||
load_regr = 1'b0;
|
||||
load_regs = 1'b0;
|
||||
sel_muxa = 3'b011;
|
||||
sel_muxb = 3'b011;
|
||||
sel_muxr = 1'b0;
|
||||
next_state = S8;
|
||||
end
|
||||
S7:
|
||||
begin
|
||||
done = 1'b0;
|
||||
divBusy = 1'b1;
|
||||
load_rega = 1'b1;
|
||||
load_regb = 1'b0;
|
||||
load_regc = 1'b1;
|
||||
load_regd = 1'b0;
|
||||
load_regr = 1'b0;
|
||||
load_regs = 1'b0;
|
||||
sel_muxa = 3'b000;
|
||||
sel_muxb = 3'b010;
|
||||
sel_muxr = 1'b0;
|
||||
next_state = S8;
|
||||
end // case: S7
|
||||
S8: // q,qm,qp
|
||||
begin
|
||||
done = 1'b0;
|
||||
divBusy = 1'b1;
|
||||
load_rega = 1'b0;
|
||||
load_regb = 1'b0;
|
||||
load_regc = 1'b0;
|
||||
load_regd = 1'b0;
|
||||
load_regr = 1'b0;
|
||||
load_regs = 1'b1;
|
||||
sel_muxa = 3'b000;
|
||||
sel_muxb = 3'b000;
|
||||
sel_muxr = 1'b0;
|
||||
next_state = S9;
|
||||
end
|
||||
S9: // rem
|
||||
begin
|
||||
done = 1'b0;
|
||||
divBusy = 1'b1;
|
||||
load_rega = 1'b0;
|
||||
load_regb = 1'b0;
|
||||
load_regc = 1'b0;
|
||||
load_regd = 1'b0;
|
||||
load_regr = 1'b1;
|
||||
load_regs = 1'b0;
|
||||
sel_muxa = 3'b000;
|
||||
sel_muxb = 3'b000;
|
||||
sel_muxr = 1'b1;
|
||||
next_state = S10;
|
||||
end
|
||||
S10: // done
|
||||
begin
|
||||
done = 1'b1;
|
||||
divBusy = 1'b0;
|
||||
load_rega = 1'b0;
|
||||
load_regb = 1'b0;
|
||||
load_regc = 1'b0;
|
||||
load_regd = 1'b0;
|
||||
load_regr = 1'b0;
|
||||
load_regs = 1'b0;
|
||||
sel_muxa = 3'b000;
|
||||
sel_muxb = 3'b000;
|
||||
sel_muxr = 1'b0;
|
||||
next_state = S11;
|
||||
end // case: S10
|
||||
S11: // done
|
||||
begin
|
||||
done = 1'b0;
|
||||
divBusy = 1'b0;
|
||||
load_rega = 1'b0;
|
||||
load_regb = 1'b0;
|
||||
load_regc = 1'b0;
|
||||
load_regd = 1'b0;
|
||||
load_regr = 1'b0;
|
||||
load_regs = 1'b0;
|
||||
sel_muxa = 3'b000;
|
||||
sel_muxb = 3'b000;
|
||||
sel_muxr = 1'b0;
|
||||
next_state = S0;
|
||||
end
|
||||
S13: // start of sqrt path
|
||||
begin
|
||||
done = 1'b0;
|
||||
divBusy = 1'b1;
|
||||
load_rega = 1'b0;
|
||||
load_regb = 1'b0;
|
||||
load_regc = 1'b0;
|
||||
load_regd = 1'b1;
|
||||
load_regr = 1'b0;
|
||||
load_regs = 1'b0;
|
||||
sel_muxa = 3'b010;
|
||||
sel_muxb = 3'b001;
|
||||
sel_muxr = 1'b0;
|
||||
next_state = S14;
|
||||
end
|
||||
S14:
|
||||
begin
|
||||
done = 1'b0;
|
||||
divBusy = 1'b1;
|
||||
load_rega = 1'b1;
|
||||
load_regb = 1'b0;
|
||||
load_regc = 1'b1;
|
||||
load_regd = 1'b0;
|
||||
load_regr = 1'b0;
|
||||
load_regs = 1'b0;
|
||||
sel_muxa = 3'b001;
|
||||
sel_muxb = 3'b100;
|
||||
sel_muxr = 1'b0;
|
||||
next_state = S15;
|
||||
end
|
||||
S15: // iteration 1
|
||||
begin
|
||||
done = 1'b0;
|
||||
divBusy = 1'b1;
|
||||
load_rega = 1'b0;
|
||||
load_regb = 1'b1;
|
||||
load_regc = 1'b0;
|
||||
load_regd = 1'b0;
|
||||
load_regr = 1'b0;
|
||||
load_regs = 1'b0;
|
||||
sel_muxa = 3'b011;
|
||||
sel_muxb = 3'b011;
|
||||
sel_muxr = 1'b0;
|
||||
next_state = S16;
|
||||
end
|
||||
S16:
|
||||
begin
|
||||
done = 1'b0;
|
||||
divBusy = 1'b1;
|
||||
load_rega = 1'b0;
|
||||
load_regb = 1'b0;
|
||||
load_regc = 1'b0;
|
||||
load_regd = 1'b1;
|
||||
load_regr = 1'b0;
|
||||
load_regs = 1'b0;
|
||||
sel_muxa = 3'b000;
|
||||
sel_muxb = 3'b011;
|
||||
sel_muxr = 1'b0;
|
||||
next_state = S17;
|
||||
end
|
||||
S17:
|
||||
begin
|
||||
done = 1'b0;
|
||||
divBusy = 1'b1;
|
||||
load_rega = 1'b1;
|
||||
load_regb = 1'b0;
|
||||
load_regc = 1'b1;
|
||||
load_regd = 1'b0;
|
||||
load_regr = 1'b0;
|
||||
load_regs = 1'b0;
|
||||
sel_muxa = 3'b100;
|
||||
sel_muxb = 3'b010;
|
||||
sel_muxr = 1'b0;
|
||||
next_state = S18;
|
||||
end
|
||||
S18: // iteration 2
|
||||
begin
|
||||
done = 1'b0;
|
||||
divBusy = 1'b1;
|
||||
load_rega = 1'b0;
|
||||
load_regb = 1'b1;
|
||||
load_regc = 1'b0;
|
||||
load_regd = 1'b0;
|
||||
load_regr = 1'b0;
|
||||
load_regs = 1'b0;
|
||||
sel_muxa = 3'b011;
|
||||
sel_muxb = 3'b011;
|
||||
sel_muxr = 1'b0;
|
||||
next_state = S19;
|
||||
end
|
||||
S19:
|
||||
begin
|
||||
done = 1'b0;
|
||||
divBusy = 1'b1;
|
||||
load_rega = 1'b0;
|
||||
load_regb = 1'b0;
|
||||
load_regc = 1'b0;
|
||||
load_regd = 1'b1;
|
||||
load_regr = 1'b0;
|
||||
load_regs = 1'b0;
|
||||
sel_muxa = 3'b000;
|
||||
sel_muxb = 3'b011;
|
||||
sel_muxr = 1'b0;
|
||||
next_state = S20;
|
||||
end
|
||||
S20:
|
||||
begin
|
||||
done = 1'b0;
|
||||
divBusy = 1'b1;
|
||||
load_rega = 1'b1;
|
||||
load_regb = 1'b0;
|
||||
load_regc = 1'b1;
|
||||
load_regd = 1'b0;
|
||||
load_regr = 1'b0;
|
||||
load_regs = 1'b0;
|
||||
sel_muxa = 3'b100;
|
||||
sel_muxb = 3'b010;
|
||||
sel_muxr = 1'b0;
|
||||
next_state = S21;
|
||||
end
|
||||
S21: // iteration 3
|
||||
begin
|
||||
done = 1'b0;
|
||||
divBusy = 1'b1;
|
||||
load_rega = 1'b0;
|
||||
load_regb = 1'b1;
|
||||
load_regc = 1'b0;
|
||||
load_regd = 1'b0;
|
||||
load_regr = 1'b0;
|
||||
load_regs = 1'b0;
|
||||
sel_muxa = 3'b011;
|
||||
sel_muxb = 3'b011;
|
||||
sel_muxr = 1'b0;
|
||||
next_state = S22;
|
||||
end
|
||||
S22:
|
||||
begin
|
||||
done = 1'b0;
|
||||
divBusy = 1'b1;
|
||||
load_rega = 1'b0;
|
||||
load_regb = 1'b0;
|
||||
load_regc = 1'b0;
|
||||
load_regd = 1'b1;
|
||||
load_regr = 1'b0;
|
||||
load_regs = 1'b0;
|
||||
sel_muxa = 3'b000;
|
||||
sel_muxb = 3'b011;
|
||||
sel_muxr = 1'b0;
|
||||
next_state = S23;
|
||||
end
|
||||
S23:
|
||||
begin
|
||||
done = 1'b0;
|
||||
divBusy = 1'b1;
|
||||
load_rega = 1'b1;
|
||||
load_regb = 1'b0;
|
||||
load_regc = 1'b1;
|
||||
load_regd = 1'b0;
|
||||
load_regr = 1'b0;
|
||||
load_regs = 1'b0;
|
||||
sel_muxa = 3'b100;
|
||||
sel_muxb = 3'b010;
|
||||
sel_muxr = 1'b0;
|
||||
next_state = S24;
|
||||
end
|
||||
S24: // q,qm,qp
|
||||
begin
|
||||
done = 1'b0;
|
||||
divBusy = 1'b1;
|
||||
load_rega = 1'b0;
|
||||
load_regb = 1'b0;
|
||||
load_regc = 1'b0;
|
||||
load_regd = 1'b0;
|
||||
load_regr = 1'b0;
|
||||
load_regs = 1'b1;
|
||||
sel_muxa = 3'b000;
|
||||
sel_muxb = 3'b000;
|
||||
sel_muxr = 1'b0;
|
||||
next_state = S25;
|
||||
end
|
||||
S25: // rem
|
||||
begin
|
||||
done = 1'b0;
|
||||
divBusy = 1'b1;
|
||||
load_rega = 1'b0;
|
||||
load_regb = 1'b0;
|
||||
load_regc = 1'b0;
|
||||
load_regd = 1'b0;
|
||||
load_regr = 1'b1;
|
||||
load_regs = 1'b0;
|
||||
sel_muxa = 3'b011;
|
||||
sel_muxb = 3'b110;
|
||||
sel_muxr = 1'b1;
|
||||
next_state = S26;
|
||||
end
|
||||
S26: // done
|
||||
begin
|
||||
done = 1'b1;
|
||||
divBusy = 1'b0;
|
||||
load_rega = 1'b0;
|
||||
load_regb = 1'b0;
|
||||
load_regc = 1'b0;
|
||||
load_regd = 1'b0;
|
||||
load_regr = 1'b0;
|
||||
load_regs = 1'b0;
|
||||
sel_muxa = 3'b000;
|
||||
sel_muxb = 3'b000;
|
||||
sel_muxr = 1'b0;
|
||||
next_state = S27;
|
||||
end // case: S26
|
||||
S27: // done
|
||||
begin
|
||||
done = 1'b0;
|
||||
divBusy = 1'b0;
|
||||
load_rega = 1'b0;
|
||||
load_regb = 1'b0;
|
||||
load_regc = 1'b0;
|
||||
load_regd = 1'b0;
|
||||
load_regr = 1'b0;
|
||||
load_regs = 1'b0;
|
||||
sel_muxa = 3'b000;
|
||||
sel_muxb = 3'b000;
|
||||
sel_muxr = 1'b0;
|
||||
next_state = S0;
|
||||
end
|
||||
default:
|
||||
begin
|
||||
done = 1'b0;
|
||||
divBusy = 1'b0;
|
||||
load_rega = 1'b0;
|
||||
load_regb = 1'b0;
|
||||
load_regc = 1'b0;
|
||||
load_regd = 1'b0;
|
||||
load_regr = 1'b0;
|
||||
load_regs = 1'b0;
|
||||
sel_muxa = 3'b000;
|
||||
sel_muxb = 3'b000;
|
||||
sel_muxr = 1'b0;
|
||||
next_state = S0;
|
||||
end
|
||||
endcase // case(current_state)
|
||||
end // always @ (current_state or X)
|
||||
|
||||
endmodule // fsm
|
File diff suppressed because it is too large
Load Diff
@ -1,171 +0,0 @@
|
||||
// module lz2 (P, V, B0, B1);
|
||||
|
||||
// input B0;
|
||||
// input B1;
|
||||
|
||||
// output P;
|
||||
// output V;
|
||||
|
||||
// assign V = B0 | B1;
|
||||
// assign P = B0 & ~B1;
|
||||
|
||||
// endmodule // lz2
|
||||
|
||||
// Note: This module is not made out of two lz2's - why not? (MJS)
|
||||
|
||||
// module lz4 (ZP, ZV, B0, B1, V0, V1);
|
||||
|
||||
// input B0;
|
||||
// input B1;
|
||||
// input V0;
|
||||
// input V1;
|
||||
|
||||
// output [1:0] ZP;
|
||||
// output ZV;
|
||||
|
||||
// assign ZP[0] = V0 ? B0 : B1;
|
||||
// assign ZP[1] = ~V0;
|
||||
// assign ZV = V0 | V1;
|
||||
|
||||
// endmodule // lz4
|
||||
|
||||
// // Note: This module is not made out of two lz4's - why not? (MJS)
|
||||
|
||||
// module lz8 (ZP, ZV, B);
|
||||
|
||||
// input [7:0] B;
|
||||
|
||||
// wire s1p0;
|
||||
// wire s1v0;
|
||||
// wire s1p1;
|
||||
// wire s1v1;
|
||||
// wire s2p0;
|
||||
// wire s2v0;
|
||||
// wire s2p1;
|
||||
// wire s2v1;
|
||||
// wire [1:0] ZPa;
|
||||
// wire [1:0] ZPb;
|
||||
// wire ZVa;
|
||||
// wire ZVb;
|
||||
|
||||
// output [2:0] ZP;
|
||||
// output ZV;
|
||||
|
||||
// lz2 l1(s1p0, s1v0, B[2], B[3]);
|
||||
// lz2 l2(s1p1, s1v1, B[0], B[1]);
|
||||
// lz4 l3(ZPa, ZVa, s1p0, s1p1, s1v0, s1v1);
|
||||
|
||||
// lz2 l4(s2p0, s2v0, B[6], B[7]);
|
||||
// lz2 l5(s2p1, s2v1, B[4], B[5]);
|
||||
// lz4 l6(ZPb, ZVb, s2p0, s2p1, s2v0, s2v1);
|
||||
|
||||
// assign ZP[1:0] = ZVb ? ZPb : ZPa;
|
||||
// assign ZP[2] = ~ZVb;
|
||||
// assign ZV = ZVa | ZVb;
|
||||
|
||||
// endmodule // lz8
|
||||
|
||||
// module lz16 (ZP, ZV, B);
|
||||
|
||||
// input [15:0] B;
|
||||
|
||||
// wire [2:0] ZPa;
|
||||
// wire [2:0] ZPb;
|
||||
// wire ZVa;
|
||||
// wire ZVb;
|
||||
|
||||
// output [3:0] ZP;
|
||||
// output ZV;
|
||||
|
||||
// lz8 l1(ZPa, ZVa, B[7:0]);
|
||||
// lz8 l2(ZPb, ZVb, B[15:8]);
|
||||
|
||||
// assign ZP[2:0] = ZVb ? ZPb : ZPa;
|
||||
// assign ZP[3] = ~ZVb;
|
||||
// assign ZV = ZVa | ZVb;
|
||||
|
||||
// endmodule // lz16
|
||||
|
||||
// module lz32 (ZP, ZV, B);
|
||||
|
||||
// input [31:0] B;
|
||||
|
||||
// wire [3:0] ZPa;
|
||||
// wire [3:0] ZPb;
|
||||
// wire ZVa;
|
||||
// wire ZVb;
|
||||
|
||||
// output [4:0] ZP;
|
||||
// output ZV;
|
||||
|
||||
// lz16 l1(ZPa, ZVa, B[15:0]);
|
||||
// lz16 l2(ZPb, ZVb, B[31:16]);
|
||||
|
||||
// assign ZP[3:0] = ZVb ? ZPb : ZPa;
|
||||
// assign ZP[4] = ~ZVb;
|
||||
// assign ZV = ZVa | ZVb;
|
||||
|
||||
// endmodule // lz32
|
||||
|
||||
// // This module returns the number of leading zeros ZP in the 64-bit
|
||||
// // number B. If there are no ones in B, then ZP and ZV are both 0.
|
||||
|
||||
// module lz64 (ZP, ZV, B);
|
||||
|
||||
// input [63:0] B;
|
||||
|
||||
// wire [4:0] ZPa;
|
||||
// wire [4:0] ZPb;
|
||||
// wire ZVa;
|
||||
// wire ZVb;
|
||||
|
||||
// output [5:0] ZP;
|
||||
// output ZV;
|
||||
|
||||
// lz32 l1(ZPa, ZVa, B[31:0]);
|
||||
// lz32 l2(ZPb, ZVb, B[63:32]);
|
||||
|
||||
// assign ZV = ZVa | ZVb;
|
||||
// assign ZP[4:0] = (ZVb ? ZPb : ZPa) & {5{ZV}};
|
||||
// assign ZP[5] = ~ZVb & ZV;
|
||||
|
||||
// endmodule // lz64
|
||||
|
||||
// This module returns the number of leading zeros ZP in the 52-bit
|
||||
// number B. If there are no ones in B, then ZP and ZV are both 0.
|
||||
|
||||
module lz52 (ZP, ZV, B);
|
||||
|
||||
input [51:0] B;
|
||||
|
||||
wire [4:0] ZP_32;
|
||||
wire [3:0] ZP_16;
|
||||
wire [1:0] ZP_4;
|
||||
wire ZV_32;
|
||||
wire ZV_16;
|
||||
wire ZV_4;
|
||||
|
||||
wire ZP_2_1;
|
||||
wire ZP_2_2;
|
||||
wire ZV_2_1;
|
||||
wire ZV_2_2;
|
||||
|
||||
output [5:0] ZP;
|
||||
output ZV;
|
||||
|
||||
lz32 l1 (ZP_32, ZV_32, B[51:20]);
|
||||
lz16 l2 (ZP_16, ZV_16, B[19:4]);
|
||||
|
||||
lz2 l3_1 (ZP_2_1, ZV_2_1, B[3], B[2]);
|
||||
lz2 l3_2 (ZP_2_2, ZV_2_2, B[1], B[0]);
|
||||
lz4 l3_final (ZP_4, ZV_4, ZP_2_1, ZP_2_2, ZV_2_1, ZV_2_2);
|
||||
|
||||
assign ZV = ZV_32 | ZV_16 | ZV_4;
|
||||
assign ZP[5] = ~ZV_32;
|
||||
assign ZP[4] = ZV_32 ? ZP_32[4] : ~ZV_16;
|
||||
assign ZP[3:2] = ZV_32 ? ZP_32[3:2] : (ZV_16 ? ZP_16[3:2] : 2'b0);
|
||||
assign ZP[1:0] = ZV_32 ? ZP_32[1:0] : (ZV_16 ? ZP_16[1:0] : ZP_4);
|
||||
|
||||
endmodule // lz52
|
||||
|
||||
|
@ -1,58 +0,0 @@
|
||||
///////////////////////////////////////////
|
||||
// redundantmul.sv
|
||||
//
|
||||
// Written: David_Harris@hmc.edu and ssanghai@hm.edu 10/11/2021
|
||||
// Modified:
|
||||
//
|
||||
// Purpose: multiplier with output in redundant carry-sum form
|
||||
// This can be faster than a mutiplier that requires a final adder to obtain the nonredundant answer.
|
||||
// The module has several implementations controlled by the DESIGN_COMPILER flag.
|
||||
// When DESIGN_COMPILER = 1, use the Synopsys DesignWare DW02_multp block. This will give highest quality results
|
||||
// but doesn't work in simulation or when using different tools
|
||||
// When DESIGN_COMPILER = 2, use the Wally mult_cs block with Radix 2 Booth encoding and a Wallace Tree
|
||||
// This simulates and synthesizes, but quality of results ae lower than DesignWare
|
||||
// Otherwise, just use a nonredundant multiplier and set one word to 0. This is best for FPGAs, which have
|
||||
// block multipliers, and also simulates fastest.
|
||||
//
|
||||
// A component of the Wally configurable RISC-V project.
|
||||
//
|
||||
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
|
||||
//
|
||||
// MIT LICENSE
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
// software and associated documentation files (the "Software"), to deal in the Software
|
||||
// without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
||||
// to whom the Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all copies or
|
||||
// substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
|
||||
// OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
`include "wally-config.vh"
|
||||
|
||||
module redundantmul #(parameter WIDTH =8)(
|
||||
input logic [WIDTH-1:0] a,b,
|
||||
output logic [2*WIDTH-1:0] out0, out1);
|
||||
|
||||
if (`DESIGN_COMPILER == 1) begin:mul
|
||||
logic [2*WIDTH-1+2:0] tmp_out0;
|
||||
logic [2*WIDTH-1+2:0] tmp_out1;
|
||||
|
||||
DW02_multp #(WIDTH, WIDTH, 2*WIDTH+2) mul(.a, .b, .tc(1'b0), .out0(tmp_out0), .out1(tmp_out1));
|
||||
assign out0 = tmp_out0[2*WIDTH-1:0];
|
||||
assign out1 = tmp_out1[2*WIDTH-1:0];
|
||||
end else begin:mul // force a nonredunant multipler. This will simulate properly and also is appropriate for FPGAs.
|
||||
assign out0 = a * b;
|
||||
assign out1 = 0;
|
||||
end
|
||||
endmodule
|
||||
|
||||
|
@ -1,259 +0,0 @@
|
||||
// The rounder takes as input logics a 64-bit value to be rounded, A, the
|
||||
// exponent of the value to be rounded, the sign of the final result, Sign,
|
||||
// the precision of the results, P, and the two-bit rounding mode, rm.
|
||||
// It produces a rounded 52-bit result, Z, the exponent of the rounded
|
||||
// result, Z_exp, and a flag that indicates if the result was rounded,
|
||||
// Inexact. The rounding mode has the following values.
|
||||
// rm Modee
|
||||
// 00 round-to-nearest-even
|
||||
// 01 round-toward-zero
|
||||
// 10 round-toward-plus infinity
|
||||
// 11 round-toward-minus infinity
|
||||
// The rounding algorithm determines if '1' should be added to the
|
||||
// truncated signficant result, based on three significant bits
|
||||
// (least (L), round (R) and sticky (S)), the rounding mode (rm)
|
||||
// and the sign of the final result (Sign). Visually, L and R appear as
|
||||
// xxxxxL,Rxxxxxxx
|
||||
// where , denotes the rounding boundary. S is the logical OR of all the
|
||||
// bits to the right of R.
|
||||
|
||||
module rounder (
|
||||
input logic [2:0] rm,
|
||||
input logic P,
|
||||
input logic OvEn,
|
||||
input logic UnEn,
|
||||
input logic exp_valid,
|
||||
input logic [3:0] sel_inv,
|
||||
input logic Invalid,
|
||||
input logic DenormIn,
|
||||
input logic Asign,
|
||||
input logic [10:0] Aexp,
|
||||
input logic [5:0] norm_shift,
|
||||
input logic [63:0] A,
|
||||
input logic [10:0] exponent_postsum,
|
||||
input logic A_Norm,
|
||||
input logic B_Norm,
|
||||
input logic [11:0] exp_A_unmodified,
|
||||
input logic [11:0] exp_B_unmodified,
|
||||
input logic normal_overflow,
|
||||
input logic normal_underflow,
|
||||
input logic swap,
|
||||
input logic [2:0] op_type,
|
||||
input logic [63:0] sum,
|
||||
|
||||
output logic [63:0] Result,
|
||||
output logic DenormIO,
|
||||
output logic [4:0] Flags
|
||||
);
|
||||
|
||||
wire Rsign;
|
||||
wire Sticky_out;
|
||||
wire [51:0] ShiftMant;
|
||||
wire [63:0] ShiftMant_64;
|
||||
wire [10:0] Rexp;
|
||||
wire [10:0] Rexp_denorm;
|
||||
wire [11:0] Texp; //Parallelized for denorm exponent
|
||||
wire [11:0] Texp_addone; //results
|
||||
wire [11:0] Texp_subone;
|
||||
wire [51:0] Rmant;
|
||||
wire [51:0] Tmant;
|
||||
wire Rzero;
|
||||
wire VSS = 1'b0;
|
||||
wire VDD = 1'b1;
|
||||
wire [51:0] B; // Value used to add the "ones"
|
||||
wire [11:0] B_12_overflow; // Value used to add one to exponent
|
||||
wire [11:0] B_12_underflow; // Value used to subtract one from exponent
|
||||
wire S_SP; // Single precision sticky bit
|
||||
wire S_DP; // Double precision sticky bit
|
||||
wire S; // Actual sticky bit
|
||||
wire R; // Round bit
|
||||
wire L; // Least significant bit
|
||||
wire add_one; // '1' if one should be added
|
||||
wire UnFlow_SP, UnFlow_DP, UnderFlow;
|
||||
wire OvFlow_SP, OvFlow_DP, OverFlow;
|
||||
wire Inexact;
|
||||
wire Round_zero;
|
||||
wire Infinite;
|
||||
wire VeryLarge;
|
||||
wire Largest;
|
||||
wire Adj_exp;
|
||||
wire Valid;
|
||||
wire NaN;
|
||||
wire Cout;
|
||||
wire Cout_overflow;
|
||||
wire Texp_l7z;
|
||||
wire Texp_l7o;
|
||||
|
||||
// Determine the sticky bits for double and single precision
|
||||
assign S_DP= A[9]|A[8]|A[7]|A[6]|A[5]|A[4]|A[3]|A[2]|A[1]|A[0];
|
||||
assign S_SP = S_DP |A[38]|A[37]|A[36]|A[35]|A[34]|A[33]|A[32]|A[31]|A[30]|
|
||||
A[29]|A[28]|A[27]|A[26]|A[25]|A[24]|A[23]|A[22]|A[21]|A[20]|
|
||||
A[19]|A[18]|A[17]|A[16]|A[15]|A[14]|A[13]|A[12]|A[11]|A[10];
|
||||
|
||||
// Set the least (L), round (R), and sticky (S) bits based on
|
||||
// the precision.
|
||||
assign {L, R, S} = P ? {A[40],A[39],S_SP} : {A[11],A[10],S_DP};
|
||||
|
||||
// Add one if ((the rounding mode is round-to-nearest) and (R is one) and
|
||||
// (S or L is one)) or ((the rounding mode is towards plus or minus
|
||||
// infinity (rm[1] = 1)) and (the sign and rm[0] are the same) and
|
||||
// (R or S is one)).
|
||||
|
||||
assign add_one = ~rm[2] & ((~rm[1]&~rm[0]&R&(L|S)) | (rm[1]&(Asign^~rm[0])&(R|S))) | (rm[2] & R);
|
||||
|
||||
// Add one using a 52-bit adder. The one is added to the LSB B[0] for
|
||||
// double precision or to B[29] for single precision.
|
||||
// This could be simplified by using a specialized adder.
|
||||
// The current adder is actually 64-bits. The leading one
|
||||
// for normalized results in not included in the addition.
|
||||
assign B = {{22{VSS}}, add_one&P, {28{VSS}}, add_one&~P};
|
||||
assign B_12_overflow = {8'h0, 3'b0, normal_overflow};
|
||||
assign B_12_underflow = {8'h0, 3'b0, normal_underflow};
|
||||
|
||||
cla52 add1(Tmant, Cout, A[62:11], B); //***adder
|
||||
|
||||
cla12 add1_exp(Texp_addone, Cout_overflow, Texp, B_12_overflow); //***adder
|
||||
|
||||
cla_sub12 sub1_exp(Texp_subone, Texp, B_12_underflow); //***adder
|
||||
|
||||
// Now that rounding is done, we compute the final exponent
|
||||
// and test for special cases.
|
||||
|
||||
// Compute the value of the exponent by subtracting the shift
|
||||
// value from the previous exponent and then adding 2 + cout.
|
||||
// If needed this could be optimized to used a specialized
|
||||
// adder.
|
||||
|
||||
assign Texp = DenormIn ? ({1'b0, exponent_postsum}) : ({VSS, Aexp} - {{6{VSS}}, norm_shift} +{{10{VSS}}, VDD, Cout});
|
||||
|
||||
// Overflow only occurs for double precision, if Texp[10] to Texp[0] are
|
||||
// all ones. To encourage sharing with single precision overflow detection,
|
||||
// the lower 7 bits are tested separately.
|
||||
assign Texp_l7o = Texp[6]&Texp[5]&Texp[4]&Texp[3]&Texp[2]&Texp[1]&Texp[0];
|
||||
assign OvFlow_DP = Texp[10]&Texp[9]&Texp[8]&Texp[7]&Texp_l7o;
|
||||
|
||||
// Overflow occurs for single precision if (Texp[10] is one) and
|
||||
// ((Texp[9] or Texp[8] or Texp[7]) is one) or (Texp[6] to Texp[0]
|
||||
// are all ones.
|
||||
assign OvFlow_SP = Texp[10]&(Texp[9]|Texp[8]|Texp[7]|Texp_l7o);
|
||||
|
||||
// Underflow occurs for double precision if (Texp[11] is one) or Texp[10] to
|
||||
// Texp[0] are all zeros.
|
||||
assign Texp_l7z = ~Texp[6]&~Texp[5]&~Texp[4]&~Texp[3]&~Texp[2]&~Texp[1]&~Texp[0];
|
||||
assign UnFlow_DP = Texp[11] | ~Texp[10]&~Texp[9]&~Texp[8]&~Texp[7]&Texp_l7z;
|
||||
|
||||
// Underflow occurs for single precision if (Texp[10] is zero) and
|
||||
// (Texp[9] or Texp[8] or Texp[7]) is zero.
|
||||
assign UnFlow_SP = (~Texp[10]&(~Texp[9]|~Texp[8]|~Texp[7]|Texp_l7z));
|
||||
|
||||
// Set the overflow and underflow flags. They should not be set if
|
||||
// the input logic was infinite or NaN or the output logic of the adder is zero.
|
||||
// 00 = Valid
|
||||
// 10 = NaN
|
||||
assign Valid = (~sel_inv[2]&~sel_inv[1]&~sel_inv[0]);
|
||||
assign NaN = ~sel_inv[2]&~sel_inv[1]& sel_inv[0];
|
||||
assign UnderFlow = ((P & UnFlow_SP | UnFlow_DP)&Valid&exp_valid) |
|
||||
(~Aexp[10]&Aexp[9]&Aexp[8]&Aexp[7]&~Aexp[6]
|
||||
&~Aexp[5]&~Aexp[4]&~Aexp[3]&~Aexp[2]
|
||||
&~Aexp[1]&~Aexp[0]&sel_inv[3]);
|
||||
assign OverFlow = (P & OvFlow_SP | OvFlow_DP)&Valid&~UnderFlow&exp_valid;
|
||||
|
||||
// The DenormIO is set if underflow has occurred or if their was a
|
||||
// denormalized input logic.
|
||||
assign DenormIO = DenormIn | UnderFlow;
|
||||
|
||||
// The final result is Inexact if any rounding occurred ((i.e., R or S
|
||||
// is one), or (if the result overflows ) or (if the result underflows and the
|
||||
// underflow trap is not enabled)) and (value of the result was not previous set
|
||||
// by an exception case).
|
||||
assign Inexact = (R|S|OverFlow|(UnderFlow&~UnEn))&Valid;
|
||||
|
||||
// Set the IEEE Exception Flags: Inexact, Underflow, Overflow, Div_By_0,
|
||||
// Invlalid.
|
||||
assign Flags = {UnderFlow, VSS, OverFlow, Invalid, Inexact};
|
||||
|
||||
// Determine the final result.
|
||||
|
||||
// The sign of the final result is one if the result is not zero and
|
||||
// the sign of A is one, or if the result is zero and the the rounding
|
||||
// mode is round-to-minus infinity. The final result is zero, if exp_valid
|
||||
// is zero. If underflow occurs, then the result is set to zero.
|
||||
//
|
||||
// For Zero (goes equally for subtraction although
|
||||
// signs may alter operands sign):
|
||||
// -0 + -0 = -0 (always)
|
||||
// +0 + +0 = +0 (always)
|
||||
// -0 + +0 = +0 (for RN, RZ, RU)
|
||||
// -0 + +0 = -0 (for RD)
|
||||
assign Rzero = ~exp_valid | UnderFlow;
|
||||
assign Rsign = DenormIn ?
|
||||
( ~(op_type[1] | op_type[0]) ?
|
||||
( (sum[63] & (A_Norm | B_Norm) & (exp_A_unmodified[11] ^ exp_B_unmodified[11])) ?
|
||||
~Asign : Asign)
|
||||
: ( ((A_Norm ^ B_Norm) & (exp_A_unmodified[11] ~^ exp_B_unmodified[11])) ?
|
||||
(normal_underflow ? ~Asign : Asign) : Asign)
|
||||
)
|
||||
: ( ((Asign&exp_valid |
|
||||
(sel_inv[2]&~sel_inv[1]&sel_inv[0]&rm[1]&rm[0] |
|
||||
sel_inv[2]&sel_inv[1]&~sel_inv[0] |
|
||||
~exp_valid&rm[1]&rm[0]&~sel_inv[2] |
|
||||
UnderFlow&rm[1]&rm[0])) & ~sel_inv[3]) |
|
||||
(Asign & sel_inv[3]) );
|
||||
|
||||
// The exponent of the final result is zero if the final result is
|
||||
// zero or a denorm, all ones if the final result is NaN or Infinite
|
||||
// or overflow occurred and the magnitude of the number is
|
||||
// not rounded toward from zero, and all ones with an LSB of zero
|
||||
// if overflow occurred and the magnitude of the number is
|
||||
// rounded toward zero. If the result is single precision,
|
||||
// Texp[7] shoud be inverted. When the Overflow trap is enabled (OvEn = 1)
|
||||
// and overflow occurs and the operation is not conversion, bits 10 and 9 are
|
||||
// inverted for double precision, and bits 7 and 6 are inverted for single precision.
|
||||
assign Round_zero = ~rm[1]&rm[0] | ~Asign&rm[0] | Asign&rm[1]&~rm[0];
|
||||
assign VeryLarge = OverFlow & ~OvEn;
|
||||
assign Infinite = (VeryLarge & ~Round_zero) | (~sel_inv[2] & sel_inv[1]);
|
||||
assign Largest = VeryLarge & Round_zero;
|
||||
assign Adj_exp = OverFlow & OvEn;
|
||||
assign Rexp[10:1] = ({10{~Valid}} |
|
||||
{Texp[10]&~Adj_exp, Texp[9]&~Adj_exp, Texp[8],
|
||||
(Texp[7]^P)&~(Adj_exp&P), Texp[6]&~(Adj_exp&P), Texp[5:1]} |
|
||||
{10{VeryLarge}})&{10{~Rzero | NaN}};
|
||||
assign Rexp[0] = ({~Valid} | Texp[0] | Infinite)&(~Rzero | NaN)&~Largest;
|
||||
|
||||
// The denormalized rounded exponent uses the overflow/underflow values
|
||||
// computed in the fpadd component to round the exponent up or down
|
||||
// Depending on the operation and the signs of the orignal operands,
|
||||
// underflow may or may not be needed to round.
|
||||
assign Rexp_denorm = DenormIn ?
|
||||
((~op_type[1] & op_type[0]) ?
|
||||
( ((A_Norm != B_Norm) & (exp_A_unmodified[11] == exp_B_unmodified[11])) ?
|
||||
( (normal_overflow == normal_underflow) ? Texp[10:0] : (normal_overflow ? Texp_addone[10:0] : Texp_subone[10:0]) )
|
||||
: ( normal_overflow ? Texp_addone[10:0] : Texp[10:0] ) )
|
||||
: ( ((A_Norm != B_Norm) & (exp_A_unmodified[11] != exp_B_unmodified[11])) ?
|
||||
( (normal_overflow == normal_underflow) ? Texp[10:0] : (normal_overflow ? Texp_addone[10:0] : Texp_subone[10:0]) )
|
||||
: ( normal_overflow ? Texp_addone[10:0] : Texp[10:0] ) )
|
||||
) :
|
||||
Rexp; //KEP used to be all of exp_A_unmodified
|
||||
|
||||
// If the result is zero or infinity, the mantissa is all zeros.
|
||||
// If the result is NaN, the mantissa is 10...0
|
||||
// If the result the largest floating point number, the mantissa
|
||||
// is all ones. Otherwise, the mantissa is not changed.
|
||||
// If operation is denormalized, take the mantissa directly from
|
||||
// its normalized value.
|
||||
assign Rmant[51] = Largest | NaN | (Tmant[51]&~Infinite&~Rzero);
|
||||
assign Rmant[50:0] = {51{Largest}} | (Tmant[50:0]&{51{~Infinite&Valid&~Rzero}});
|
||||
|
||||
assign ShiftMant = A[51:0];
|
||||
|
||||
// For single precision, the 8 least significant bits of the exponent
|
||||
// and 23 most significant bits of the mantissa contain bits used
|
||||
// for the final result. A double precision result is returned if
|
||||
// overflow has occurred, the overflow trap is enabled, and a conversion
|
||||
// is being performed.
|
||||
|
||||
assign Result = DenormIn ? {Rsign, Rexp_denorm, ShiftMant} : (P ? {{32{1'b1}}, Rsign, Rexp[7:0], Rmant[51:29]}
|
||||
: {Rsign, Rexp, Rmant});
|
||||
|
||||
endmodule // rounder
|
||||
|
@ -1,212 +0,0 @@
|
||||
///////////////////////////////////////////
|
||||
//
|
||||
// Written: James Stine
|
||||
// Modified: 8/1/2018
|
||||
//
|
||||
// Purpose: Floating point divider/square root rounder unit (Goldschmidt)
|
||||
//
|
||||
// A component of the Wally configurable RISC-V project.
|
||||
//
|
||||
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
|
||||
//
|
||||
// MIT LICENSE
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
// software and associated documentation files (the "Software"), to deal in the Software
|
||||
// without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
||||
// to whom the Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all copies or
|
||||
// substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
|
||||
// OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
module rounder_div (
|
||||
input logic [1:0] rm,
|
||||
input logic P,
|
||||
input logic OvEn,
|
||||
input logic UnEn,
|
||||
input logic [12:0] exp_diff,
|
||||
input logic [2:0] sel_inv,
|
||||
input logic Invalid,
|
||||
input logic SignR,
|
||||
input logic [63:0] Float1,
|
||||
input logic [63:0] Float2,
|
||||
input logic XNaNQ,
|
||||
input logic YNaNQ,
|
||||
input logic XZeroQ,
|
||||
input logic YZeroQ,
|
||||
input logic XInfQ,
|
||||
input logic YInfQ,
|
||||
input logic op_type,
|
||||
input logic [59:0] q1,
|
||||
input logic [59:0] qm1,
|
||||
input logic [59:0] qp1,
|
||||
input logic [59:0] q0,
|
||||
input logic [59:0] qm0,
|
||||
input logic [59:0] qp0,
|
||||
input logic [119:0] regr_out,
|
||||
|
||||
output logic [63:0] Result,
|
||||
output logic [4:0] Flags
|
||||
);
|
||||
|
||||
logic Rsign;
|
||||
logic [10:0] Rexp;
|
||||
logic [12:0] Texp;
|
||||
logic [51:0] Rmant;
|
||||
logic [59:0] Tmant;
|
||||
logic [51:0] Smant;
|
||||
logic Rzero;
|
||||
logic Gdp, Gsp, G;
|
||||
logic UnFlow_SP, UnFlow_DP, UnderFlow;
|
||||
logic OvFlow_SP, OvFlow_DP, OverFlow;
|
||||
logic Inexact;
|
||||
logic Round_zero;
|
||||
logic Infinite;
|
||||
logic VeryLarge;
|
||||
logic Largest;
|
||||
logic Div0;
|
||||
logic Adj_exp;
|
||||
logic Valid;
|
||||
logic NaN;
|
||||
logic Texp_l7z;
|
||||
logic Texp_l7o;
|
||||
logic OvCon;
|
||||
logic zero_rem;
|
||||
logic [1:0] mux_mant;
|
||||
logic sign_rem;
|
||||
logic [59:0] q, qm, qp;
|
||||
logic exp_ovf;
|
||||
|
||||
logic [50:0] NaN_out;
|
||||
logic NaN_Sign_out;
|
||||
logic Sign_out;
|
||||
|
||||
// Remainder = 0?
|
||||
assign zero_rem = ~(|regr_out);
|
||||
// Remainder Sign
|
||||
assign sign_rem = ~regr_out[119];
|
||||
// choose correct Guard bit [1,2) or [0,1)
|
||||
assign Gdp = q1[59] ? q1[6] : q0[6];
|
||||
assign Gsp = q1[59] ? q1[35] : q0[35];
|
||||
assign G = P ? Gsp : Gdp;
|
||||
// Selection of Rounding (from logic/switching)
|
||||
assign mux_mant[1] = (SignR&rm[1]&rm[0]&G) | (!SignR&rm[1]&!rm[0]&G) |
|
||||
(!rm[1]&!rm[0]&G&!sign_rem) |
|
||||
(SignR&rm[1]&rm[0]&!zero_rem&!sign_rem) |
|
||||
(!SignR&rm[1]&!rm[0]&!zero_rem&!sign_rem);
|
||||
assign mux_mant[0] = (!SignR&rm[0]&!G&!zero_rem&sign_rem) |
|
||||
(!rm[1]&rm[0]&!G&!zero_rem&sign_rem) |
|
||||
(SignR&rm[1]&!rm[0]&!G&!zero_rem&sign_rem);
|
||||
|
||||
// Which Q?
|
||||
mux2 #(60) mx1 (q0, q1, q1[59], q);
|
||||
mux2 #(60) mx2 (qm0, qm1, q1[59], qm);
|
||||
mux2 #(60) mx3 (qp0, qp1, q1[59], qp);
|
||||
// Choose Q, Q+1, Q-1
|
||||
mux3 #(60) mx4 (q, qm, qp, mux_mant, Tmant);
|
||||
assign Smant = Tmant[58:7];
|
||||
// Compute the value of the exponent
|
||||
// exponent is modified if we choose:
|
||||
// 1.) we choose any qm0, qp0, q0 (since we shift mant)
|
||||
// 2.) we choose qp and we overflow (for RU)
|
||||
assign exp_ovf = |{qp[58:36], (qp[35:7] & {29{~P}})};
|
||||
assign Texp = exp_diff - {{12{1'b0}}, ~q1[59]} + {{12{1'b0}}, mux_mant[1]&qp1[59]&~exp_ovf};
|
||||
|
||||
// Overflow only occurs for double precision, if Texp[10] to Texp[0] are
|
||||
// all ones. To encourage sharing with single precision overflow detection,
|
||||
// the lower 7 bits are tested separately.
|
||||
assign Texp_l7o = Texp[6]&Texp[5]&Texp[4]&Texp[3]&Texp[2]&Texp[1]&Texp[0];
|
||||
assign OvFlow_DP = (~Texp[12]&Texp[11]) | (Texp[10]&Texp[9]&Texp[8]&Texp[7]&Texp_l7o);
|
||||
|
||||
// Overflow occurs for single precision if (Texp[10] is one) and
|
||||
// ((Texp[9] or Texp[8] or Texp[7]) is one) or (Texp[6] to Texp[0]
|
||||
// are all ones.
|
||||
assign OvFlow_SP = Texp[10]&(Texp[9]|Texp[8]|Texp[7]|Texp_l7o);
|
||||
|
||||
// Underflow occurs for double precision if (Texp[11]/Texp[10] is one) or
|
||||
// Texp[10] to Texp[0] are all zeros.
|
||||
assign Texp_l7z = ~Texp[6]&~Texp[5]&~Texp[4]&~Texp[3]&~Texp[2]&~Texp[1]&~Texp[0];
|
||||
assign UnFlow_DP = (Texp[12]&Texp[11]) | ~Texp[11]&~Texp[10]&~Texp[9]&~Texp[8]&~Texp[7]&Texp_l7z;
|
||||
|
||||
// Underflow occurs for single precision if (Texp[10] is zero) and
|
||||
// (Texp[9] or Texp[8] or Texp[7]) is zero.
|
||||
assign UnFlow_SP = ~Texp[10]&(~Texp[9]|~Texp[8]|~Texp[7]|Texp_l7z);
|
||||
|
||||
// Set the overflow and underflow flags. They should not be set if
|
||||
// the input was infinite or NaN or the output of the adder is zero.
|
||||
// 00 = Valid
|
||||
// 10 = NaN
|
||||
assign Valid = ~sel_inv[2]&~sel_inv[1]&~sel_inv[0];
|
||||
assign NaN = sel_inv[2]&sel_inv[1]&sel_inv[0];
|
||||
assign UnderFlow = (P & UnFlow_SP | UnFlow_DP) & Valid;
|
||||
assign OverFlow = (P & OvFlow_SP | OvFlow_DP) & Valid;
|
||||
assign Div0 = YZeroQ&~XZeroQ&~op_type&~NaN;
|
||||
|
||||
// The final result is Inexact if any rounding occurred ((i.e., R or S
|
||||
// is one), or (if the result overflows ) or (if the result underflows and the
|
||||
// underflow trap is not enabled)) and (value of the result was not previous set
|
||||
// by an exception case).
|
||||
assign Inexact = (G|~zero_rem|OverFlow|(UnderFlow&~UnEn))&Valid;
|
||||
|
||||
// Set the IEEE Exception Flags: Inexact, Underflow, Overflow, Div_By_0,
|
||||
// Invlalid.
|
||||
assign Flags = {Inexact, UnderFlow, OverFlow, Div0, Invalid};
|
||||
|
||||
// Determine sign
|
||||
assign Rzero = UnderFlow | (~sel_inv[2]&sel_inv[1]&sel_inv[0]);
|
||||
assign Rsign = SignR;
|
||||
|
||||
// The exponent of the final result is zero if the final result is
|
||||
// zero or a denorm, all ones if the final result is NaN or Infinite
|
||||
// or overflow occurred and the magnitude of the number is
|
||||
// not rounded toward from zero, and all ones with an LSB of zero
|
||||
// if overflow occurred and the magnitude of the number is
|
||||
// rounded toward zero. If the result is single precision,
|
||||
// Texp[7] shoud be inverted. When the Overflow trap is enabled (OvEn = 1)
|
||||
// and overflow occurs and the operation is not conversion, bits 10 and 9 are
|
||||
// inverted for double precision, and bits 7 and 6 are inverted for single precision.
|
||||
assign Round_zero = ~rm[1]&rm[0] | ~SignR&rm[0] | SignR&rm[1]&~rm[0];
|
||||
assign VeryLarge = OverFlow & ~OvEn;
|
||||
assign Infinite = (VeryLarge & ~Round_zero) | sel_inv[1];
|
||||
assign Largest = VeryLarge & Round_zero;
|
||||
assign Adj_exp = OverFlow & OvEn;
|
||||
assign Rexp[10:1] = ({10{~Valid}} |
|
||||
{Texp[10]&~Adj_exp, Texp[9]&~Adj_exp, Texp[8],
|
||||
(Texp[7]^P)&~(Adj_exp&P), Texp[6]&~(Adj_exp&P), Texp[5:1]} |
|
||||
{10{VeryLarge}})&{10{~Rzero | NaN}};
|
||||
assign Rexp[0] = ({~Valid} | Texp[0] | Infinite)&(~Rzero | NaN)&~Largest;
|
||||
|
||||
// If the result is zero or infinity, the mantissa is all zeros.
|
||||
// If the result is NaN, the mantissa is 10...0
|
||||
// If the result the largest floating point number, the mantissa
|
||||
// is all ones. Otherwise, the mantissa is not changed.
|
||||
assign NaN_out = ~XNaNQ&YNaNQ ? Float2[50:0] : Float1[50:0];
|
||||
assign NaN_Sign_out = ~XNaNQ&YNaNQ ? Float2[63] : Float1[63];
|
||||
assign Sign_out = (XZeroQ&YZeroQ | XInfQ&YInfQ)&~op_type | Rsign&~XNaNQ&~YNaNQ |
|
||||
NaN_Sign_out&(XNaNQ|YNaNQ);
|
||||
// FIXME (jes) - Imperas gives sNaN a Sign=0 where x86 gives Sign=1
|
||||
// | Float1[63]&op_type; (logic to fix this but removed for now)
|
||||
|
||||
assign Rmant[51] = Largest | NaN | (Smant[51]&~Infinite&~Rzero);
|
||||
assign Rmant[50:0] = ({51{Largest}} | (Smant[50:0]&{51{~Infinite&Valid&~Rzero}}) |
|
||||
(NaN_out&{51{NaN}}))&({51{~(op_type&Float1[63]&~XZeroQ)}});
|
||||
|
||||
// For single precision, the 8 least significant bits of the exponent
|
||||
// and 23 most significant bits of the mantissa contain bits used
|
||||
// for the final result. A double precision result is returned if
|
||||
// overflow has occurred, the overflow trap is enabled, and a conversion
|
||||
// is being performed.
|
||||
assign OvCon = OverFlow & OvEn;
|
||||
assign Result = (P&~OvCon) ? { {32{1'b1}}, Sign_out, Rexp[7:0], Rmant[51:29]}
|
||||
: {Sign_out, Rexp, Rmant};
|
||||
|
||||
endmodule // rounder
|
||||
|
@ -1,170 +0,0 @@
|
||||
///////////////////////////////////////////
|
||||
//
|
||||
// Written: James Stine
|
||||
// Modified: 8/1/2018
|
||||
//
|
||||
// Purpose: Bipartite Lookup
|
||||
//
|
||||
// A component of the Wally configurable RISC-V project.
|
||||
//
|
||||
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
|
||||
//
|
||||
// MIT LICENSE
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
// software and associated documentation files (the "Software"), to deal in the Software
|
||||
// without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
||||
// to whom the Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all copies or
|
||||
// substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
|
||||
// OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
module sbtm_a0 (input logic [6:0] a,
|
||||
output logic [12:0] y);
|
||||
|
||||
always_comb
|
||||
case(a)
|
||||
7'b0000000: y = 13'b1111111100010;
|
||||
7'b0000001: y = 13'b1111110100011;
|
||||
7'b0000010: y = 13'b1111101100101;
|
||||
7'b0000011: y = 13'b1111100101000;
|
||||
7'b0000100: y = 13'b1111011101100;
|
||||
7'b0000101: y = 13'b1111010110000;
|
||||
7'b0000110: y = 13'b1111001110110;
|
||||
7'b0000111: y = 13'b1111000111100;
|
||||
7'b0001000: y = 13'b1111000000100;
|
||||
7'b0001001: y = 13'b1110111001100;
|
||||
7'b0001010: y = 13'b1110110010101;
|
||||
7'b0001011: y = 13'b1110101011110;
|
||||
7'b0001100: y = 13'b1110100101001;
|
||||
7'b0001101: y = 13'b1110011110100;
|
||||
7'b0001110: y = 13'b1110011000000;
|
||||
7'b0001111: y = 13'b1110010001101;
|
||||
7'b0010000: y = 13'b1110001011010;
|
||||
7'b0010001: y = 13'b1110000101000;
|
||||
7'b0010010: y = 13'b1101111110111;
|
||||
7'b0010011: y = 13'b1101111000110;
|
||||
7'b0010100: y = 13'b1101110010111;
|
||||
7'b0010101: y = 13'b1101101100111;
|
||||
7'b0010110: y = 13'b1101100111001;
|
||||
7'b0010111: y = 13'b1101100001011;
|
||||
7'b0011000: y = 13'b1101011011101;
|
||||
7'b0011001: y = 13'b1101010110001;
|
||||
7'b0011010: y = 13'b1101010000100;
|
||||
7'b0011011: y = 13'b1101001011001;
|
||||
7'b0011100: y = 13'b1101000101110;
|
||||
7'b0011101: y = 13'b1101000000011;
|
||||
7'b0011110: y = 13'b1100111011001;
|
||||
7'b0011111: y = 13'b1100110101111;
|
||||
7'b0100000: y = 13'b1100110000110;
|
||||
7'b0100001: y = 13'b1100101011110;
|
||||
7'b0100010: y = 13'b1100100110110;
|
||||
7'b0100011: y = 13'b1100100001111;
|
||||
7'b0100100: y = 13'b1100011101000;
|
||||
7'b0100101: y = 13'b1100011000001;
|
||||
7'b0100110: y = 13'b1100010011011;
|
||||
7'b0100111: y = 13'b1100001110101;
|
||||
7'b0101000: y = 13'b1100001010000;
|
||||
7'b0101001: y = 13'b1100000101011;
|
||||
7'b0101010: y = 13'b1100000000111;
|
||||
7'b0101011: y = 13'b1011111100011;
|
||||
7'b0101100: y = 13'b1011111000000;
|
||||
7'b0101101: y = 13'b1011110011101;
|
||||
7'b0101110: y = 13'b1011101111010;
|
||||
7'b0101111: y = 13'b1011101011000;
|
||||
7'b0110000: y = 13'b1011100110110;
|
||||
7'b0110001: y = 13'b1011100010101;
|
||||
7'b0110010: y = 13'b1011011110011;
|
||||
7'b0110011: y = 13'b1011011010011;
|
||||
7'b0110100: y = 13'b1011010110010;
|
||||
7'b0110101: y = 13'b1011010010010;
|
||||
7'b0110110: y = 13'b1011001110011;
|
||||
7'b0110111: y = 13'b1011001010011;
|
||||
7'b0111000: y = 13'b1011000110100;
|
||||
7'b0111001: y = 13'b1011000010110;
|
||||
7'b0111010: y = 13'b1010111110111;
|
||||
7'b0111011: y = 13'b1010111011001;
|
||||
7'b0111100: y = 13'b1010110111100;
|
||||
7'b0111101: y = 13'b1010110011110;
|
||||
7'b0111110: y = 13'b1010110000001;
|
||||
7'b0111111: y = 13'b1010101100100;
|
||||
7'b1000000: y = 13'b1010101001000;
|
||||
7'b1000001: y = 13'b1010100101100;
|
||||
7'b1000010: y = 13'b1010100010000;
|
||||
7'b1000011: y = 13'b1010011110100;
|
||||
7'b1000100: y = 13'b1010011011001;
|
||||
7'b1000101: y = 13'b1010010111110;
|
||||
7'b1000110: y = 13'b1010010100011;
|
||||
7'b1000111: y = 13'b1010010001001;
|
||||
7'b1001000: y = 13'b1010001101111;
|
||||
7'b1001001: y = 13'b1010001010101;
|
||||
7'b1001010: y = 13'b1010000111011;
|
||||
7'b1001011: y = 13'b1010000100001;
|
||||
7'b1001100: y = 13'b1010000001000;
|
||||
7'b1001101: y = 13'b1001111101111;
|
||||
7'b1001110: y = 13'b1001111010111;
|
||||
7'b1001111: y = 13'b1001110111110;
|
||||
7'b1010000: y = 13'b1001110100110;
|
||||
7'b1010001: y = 13'b1001110001110;
|
||||
7'b1010010: y = 13'b1001101110110;
|
||||
7'b1010011: y = 13'b1001101011111;
|
||||
7'b1010100: y = 13'b1001101000111;
|
||||
7'b1010101: y = 13'b1001100110000;
|
||||
7'b1010110: y = 13'b1001100011001;
|
||||
7'b1010111: y = 13'b1001100000010;
|
||||
7'b1011000: y = 13'b1001011101100;
|
||||
7'b1011001: y = 13'b1001011010110;
|
||||
7'b1011010: y = 13'b1001011000000;
|
||||
7'b1011011: y = 13'b1001010101010;
|
||||
7'b1011100: y = 13'b1001010010100;
|
||||
7'b1011101: y = 13'b1001001111111;
|
||||
7'b1011110: y = 13'b1001001101001;
|
||||
7'b1011111: y = 13'b1001001010100;
|
||||
7'b1100000: y = 13'b1001000111111;
|
||||
7'b1100001: y = 13'b1001000101011;
|
||||
7'b1100010: y = 13'b1001000010110;
|
||||
7'b1100011: y = 13'b1001000000010;
|
||||
7'b1100100: y = 13'b1000111101110;
|
||||
7'b1100101: y = 13'b1000111011010;
|
||||
7'b1100110: y = 13'b1000111000110;
|
||||
7'b1100111: y = 13'b1000110110010;
|
||||
7'b1101000: y = 13'b1000110011111;
|
||||
7'b1101001: y = 13'b1000110001011;
|
||||
7'b1101010: y = 13'b1000101111000;
|
||||
7'b1101011: y = 13'b1000101100101;
|
||||
7'b1101100: y = 13'b1000101010010;
|
||||
7'b1101101: y = 13'b1000101000000;
|
||||
7'b1101110: y = 13'b1000100101101;
|
||||
7'b1101111: y = 13'b1000100011011;
|
||||
7'b1110000: y = 13'b1000100001001;
|
||||
7'b1110001: y = 13'b1000011110110;
|
||||
7'b1110010: y = 13'b1000011100101;
|
||||
7'b1110011: y = 13'b1000011010011;
|
||||
7'b1110100: y = 13'b1000011000001;
|
||||
7'b1110101: y = 13'b1000010110000;
|
||||
7'b1110110: y = 13'b1000010011110;
|
||||
7'b1110111: y = 13'b1000010001101;
|
||||
7'b1111000: y = 13'b1000001111100;
|
||||
7'b1111001: y = 13'b1000001101011;
|
||||
7'b1111010: y = 13'b1000001011010;
|
||||
7'b1111011: y = 13'b1000001001010;
|
||||
7'b1111100: y = 13'b1000000111001;
|
||||
7'b1111101: y = 13'b1000000101001;
|
||||
7'b1111110: y = 13'b1000000011001;
|
||||
7'b1111111: y = 13'b1000000001001;
|
||||
default: y = 13'bxxxxxxxxxxxxx;
|
||||
endcase // case (a)
|
||||
|
||||
endmodule // sbtm_a0
|
||||
|
||||
|
||||
|
||||
|
@ -1,170 +0,0 @@
|
||||
///////////////////////////////////////////
|
||||
//
|
||||
// Written: James Stine
|
||||
// Modified: 8/1/2018
|
||||
//
|
||||
// Purpose: Bipartite Lookup
|
||||
//
|
||||
// A component of the Wally configurable RISC-V project.
|
||||
//
|
||||
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
|
||||
//
|
||||
// MIT LICENSE
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
// software and associated documentation files (the "Software"), to deal in the Software
|
||||
// without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
||||
// to whom the Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all copies or
|
||||
// substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
|
||||
// OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
module sbtm_a1 (input logic [6:0] a,
|
||||
output logic [4:0] y);
|
||||
|
||||
always_comb
|
||||
case(a)
|
||||
7'b0000000: y = 5'b11100;
|
||||
7'b0000001: y = 5'b11000;
|
||||
7'b0000010: y = 5'b10100;
|
||||
7'b0000011: y = 5'b10000;
|
||||
7'b0000100: y = 5'b01101;
|
||||
7'b0000101: y = 5'b01001;
|
||||
7'b0000110: y = 5'b00101;
|
||||
7'b0000111: y = 5'b00001;
|
||||
7'b0001000: y = 5'b11001;
|
||||
7'b0001001: y = 5'b10101;
|
||||
7'b0001010: y = 5'b10010;
|
||||
7'b0001011: y = 5'b01111;
|
||||
7'b0001100: y = 5'b01011;
|
||||
7'b0001101: y = 5'b01000;
|
||||
7'b0001110: y = 5'b00101;
|
||||
7'b0001111: y = 5'b00001;
|
||||
7'b0010000: y = 5'b10110;
|
||||
7'b0010001: y = 5'b10011;
|
||||
7'b0010010: y = 5'b10000;
|
||||
7'b0010011: y = 5'b01101;
|
||||
7'b0010100: y = 5'b01010;
|
||||
7'b0010101: y = 5'b00111;
|
||||
7'b0010110: y = 5'b00100;
|
||||
7'b0010111: y = 5'b00001;
|
||||
7'b0011000: y = 5'b10100;
|
||||
7'b0011001: y = 5'b10001;
|
||||
7'b0011010: y = 5'b01110;
|
||||
7'b0011011: y = 5'b01100;
|
||||
7'b0011100: y = 5'b01001;
|
||||
7'b0011101: y = 5'b00110;
|
||||
7'b0011110: y = 5'b00100;
|
||||
7'b0011111: y = 5'b00001;
|
||||
7'b0100000: y = 5'b10010;
|
||||
7'b0100001: y = 5'b01111;
|
||||
7'b0100010: y = 5'b01101;
|
||||
7'b0100011: y = 5'b01010;
|
||||
7'b0100100: y = 5'b01000;
|
||||
7'b0100101: y = 5'b00110;
|
||||
7'b0100110: y = 5'b00011;
|
||||
7'b0100111: y = 5'b00001;
|
||||
7'b0101000: y = 5'b10000;
|
||||
7'b0101001: y = 5'b01110;
|
||||
7'b0101010: y = 5'b01100;
|
||||
7'b0101011: y = 5'b01001;
|
||||
7'b0101100: y = 5'b00111;
|
||||
7'b0101101: y = 5'b00101;
|
||||
7'b0101110: y = 5'b00011;
|
||||
7'b0101111: y = 5'b00001;
|
||||
7'b0110000: y = 5'b01111;
|
||||
7'b0110001: y = 5'b01101;
|
||||
7'b0110010: y = 5'b01011;
|
||||
7'b0110011: y = 5'b01001;
|
||||
7'b0110100: y = 5'b00111;
|
||||
7'b0110101: y = 5'b00101;
|
||||
7'b0110110: y = 5'b00011;
|
||||
7'b0110111: y = 5'b00001;
|
||||
7'b0111000: y = 5'b01101;
|
||||
7'b0111001: y = 5'b01100;
|
||||
7'b0111010: y = 5'b01010;
|
||||
7'b0111011: y = 5'b01000;
|
||||
7'b0111100: y = 5'b00110;
|
||||
7'b0111101: y = 5'b00100;
|
||||
7'b0111110: y = 5'b00010;
|
||||
7'b0111111: y = 5'b00000;
|
||||
7'b1000000: y = 5'b01100;
|
||||
7'b1000001: y = 5'b01011;
|
||||
7'b1000010: y = 5'b01001;
|
||||
7'b1000011: y = 5'b00111;
|
||||
7'b1000100: y = 5'b00101;
|
||||
7'b1000101: y = 5'b00100;
|
||||
7'b1000110: y = 5'b00010;
|
||||
7'b1000111: y = 5'b00000;
|
||||
7'b1001000: y = 5'b01011;
|
||||
7'b1001001: y = 5'b01010;
|
||||
7'b1001010: y = 5'b01000;
|
||||
7'b1001011: y = 5'b00111;
|
||||
7'b1001100: y = 5'b00101;
|
||||
7'b1001101: y = 5'b00011;
|
||||
7'b1001110: y = 5'b00010;
|
||||
7'b1001111: y = 5'b00000;
|
||||
7'b1010000: y = 5'b01010;
|
||||
7'b1010001: y = 5'b01001;
|
||||
7'b1010010: y = 5'b01000;
|
||||
7'b1010011: y = 5'b00110;
|
||||
7'b1010100: y = 5'b00101;
|
||||
7'b1010101: y = 5'b00011;
|
||||
7'b1010110: y = 5'b00010;
|
||||
7'b1010111: y = 5'b00000;
|
||||
7'b1011000: y = 5'b01010;
|
||||
7'b1011001: y = 5'b01000;
|
||||
7'b1011010: y = 5'b00111;
|
||||
7'b1011011: y = 5'b00110;
|
||||
7'b1011100: y = 5'b00100;
|
||||
7'b1011101: y = 5'b00011;
|
||||
7'b1011110: y = 5'b00010;
|
||||
7'b1011111: y = 5'b00000;
|
||||
7'b1100000: y = 5'b01001;
|
||||
7'b1100001: y = 5'b01000;
|
||||
7'b1100010: y = 5'b00110;
|
||||
7'b1100011: y = 5'b00101;
|
||||
7'b1100100: y = 5'b00100;
|
||||
7'b1100101: y = 5'b00011;
|
||||
7'b1100110: y = 5'b00001;
|
||||
7'b1100111: y = 5'b00000;
|
||||
7'b1101000: y = 5'b01000;
|
||||
7'b1101001: y = 5'b00111;
|
||||
7'b1101010: y = 5'b00110;
|
||||
7'b1101011: y = 5'b00101;
|
||||
7'b1101100: y = 5'b00100;
|
||||
7'b1101101: y = 5'b00010;
|
||||
7'b1101110: y = 5'b00001;
|
||||
7'b1101111: y = 5'b00000;
|
||||
7'b1110000: y = 5'b01000;
|
||||
7'b1110001: y = 5'b00111;
|
||||
7'b1110010: y = 5'b00110;
|
||||
7'b1110011: y = 5'b00100;
|
||||
7'b1110100: y = 5'b00011;
|
||||
7'b1110101: y = 5'b00010;
|
||||
7'b1110110: y = 5'b00001;
|
||||
7'b1110111: y = 5'b00000;
|
||||
7'b1111000: y = 5'b00111;
|
||||
7'b1111001: y = 5'b00110;
|
||||
7'b1111010: y = 5'b00101;
|
||||
7'b1111011: y = 5'b00100;
|
||||
7'b1111100: y = 5'b00011;
|
||||
7'b1111101: y = 5'b00010;
|
||||
7'b1111110: y = 5'b00001;
|
||||
7'b1111111: y = 5'b00000;
|
||||
default: y = 5'bxxxxx;
|
||||
endcase // case (a)
|
||||
|
||||
endmodule // sbtm_a0
|
||||
|
||||
|
||||
|
||||
|
@ -1,234 +0,0 @@
|
||||
///////////////////////////////////////////
|
||||
//
|
||||
// Written: James Stine
|
||||
// Modified: 8/1/2018
|
||||
//
|
||||
// Purpose: Bipartite Lookup
|
||||
//
|
||||
// A component of the Wally configurable RISC-V project.
|
||||
//
|
||||
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
|
||||
//
|
||||
// MIT LICENSE
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
// software and associated documentation files (the "Software"), to deal in the Software
|
||||
// without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
||||
// to whom the Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all copies or
|
||||
// substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
|
||||
// OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
module sbtm_a2 (input logic [7:0] a,
|
||||
output logic [13:0] y);
|
||||
|
||||
always_comb
|
||||
case(a)
|
||||
8'b01000000: y = 14'b10110100010111;
|
||||
8'b01000001: y = 14'b10110010111111;
|
||||
8'b01000010: y = 14'b10110001101000;
|
||||
8'b01000011: y = 14'b10110000010011;
|
||||
8'b01000100: y = 14'b10101111000001;
|
||||
8'b01000101: y = 14'b10101101110000;
|
||||
8'b01000110: y = 14'b10101100100001;
|
||||
8'b01000111: y = 14'b10101011010011;
|
||||
8'b01001000: y = 14'b10101010000111;
|
||||
8'b01001001: y = 14'b10101000111101;
|
||||
8'b01001010: y = 14'b10100111110100;
|
||||
8'b01001011: y = 14'b10100110101101;
|
||||
8'b01001100: y = 14'b10100101100111;
|
||||
8'b01001101: y = 14'b10100100100010;
|
||||
8'b01001110: y = 14'b10100011011111;
|
||||
8'b01001111: y = 14'b10100010011101;
|
||||
8'b01010000: y = 14'b10100001011100;
|
||||
8'b01010001: y = 14'b10100000011100;
|
||||
8'b01010010: y = 14'b10011111011110;
|
||||
8'b01010011: y = 14'b10011110100001;
|
||||
8'b01010100: y = 14'b10011101100100;
|
||||
8'b01010101: y = 14'b10011100101001;
|
||||
8'b01010110: y = 14'b10011011101111;
|
||||
8'b01010111: y = 14'b10011010110110;
|
||||
8'b01011000: y = 14'b10011001111110;
|
||||
8'b01011001: y = 14'b10011001000110;
|
||||
8'b01011010: y = 14'b10011000010000;
|
||||
8'b01011011: y = 14'b10010111011011;
|
||||
8'b01011100: y = 14'b10010110100110;
|
||||
8'b01011101: y = 14'b10010101110011;
|
||||
8'b01011110: y = 14'b10010101000000;
|
||||
8'b01011111: y = 14'b10010100001110;
|
||||
8'b01100000: y = 14'b10010011011100;
|
||||
8'b01100001: y = 14'b10010010101100;
|
||||
8'b01100010: y = 14'b10010001111100;
|
||||
8'b01100011: y = 14'b10010001001101;
|
||||
8'b01100100: y = 14'b10010000011111;
|
||||
8'b01100101: y = 14'b10001111110001;
|
||||
8'b01100110: y = 14'b10001111000100;
|
||||
8'b01100111: y = 14'b10001110011000;
|
||||
8'b01101000: y = 14'b10001101101100;
|
||||
8'b01101001: y = 14'b10001101000001;
|
||||
8'b01101010: y = 14'b10001100010110;
|
||||
8'b01101011: y = 14'b10001011101100;
|
||||
8'b01101100: y = 14'b10001011000011;
|
||||
8'b01101101: y = 14'b10001010011010;
|
||||
8'b01101110: y = 14'b10001001110010;
|
||||
8'b01101111: y = 14'b10001001001010;
|
||||
8'b01110000: y = 14'b10001000100011;
|
||||
8'b01110001: y = 14'b10000111111101;
|
||||
8'b01110010: y = 14'b10000111010111;
|
||||
8'b01110011: y = 14'b10000110110001;
|
||||
8'b01110100: y = 14'b10000110001100;
|
||||
8'b01110101: y = 14'b10000101100111;
|
||||
8'b01110110: y = 14'b10000101000011;
|
||||
8'b01110111: y = 14'b10000100011111;
|
||||
8'b01111000: y = 14'b10000011111100;
|
||||
8'b01111001: y = 14'b10000011011001;
|
||||
8'b01111010: y = 14'b10000010110111;
|
||||
8'b01111011: y = 14'b10000010010101;
|
||||
8'b01111100: y = 14'b10000001110011;
|
||||
8'b01111101: y = 14'b10000001010010;
|
||||
8'b01111110: y = 14'b10000000110001;
|
||||
8'b01111111: y = 14'b10000000010001;
|
||||
8'b10000000: y = 14'b01111111110001;
|
||||
8'b10000001: y = 14'b01111111010001;
|
||||
8'b10000010: y = 14'b01111110110010;
|
||||
8'b10000011: y = 14'b01111110010011;
|
||||
8'b10000100: y = 14'b01111101110101;
|
||||
8'b10000101: y = 14'b01111101010110;
|
||||
8'b10000110: y = 14'b01111100111001;
|
||||
8'b10000111: y = 14'b01111100011011;
|
||||
8'b10001000: y = 14'b01111011111110;
|
||||
8'b10001001: y = 14'b01111011100001;
|
||||
8'b10001010: y = 14'b01111011000100;
|
||||
8'b10001011: y = 14'b01111010101000;
|
||||
8'b10001100: y = 14'b01111010001100;
|
||||
8'b10001101: y = 14'b01111001110000;
|
||||
8'b10001110: y = 14'b01111001010101;
|
||||
8'b10001111: y = 14'b01111000111010;
|
||||
8'b10010000: y = 14'b01111000011111;
|
||||
8'b10010001: y = 14'b01111000000100;
|
||||
8'b10010010: y = 14'b01110111101010;
|
||||
8'b10010011: y = 14'b01110111010000;
|
||||
8'b10010100: y = 14'b01110110110110;
|
||||
8'b10010101: y = 14'b01110110011101;
|
||||
8'b10010110: y = 14'b01110110000100;
|
||||
8'b10010111: y = 14'b01110101101011;
|
||||
8'b10011000: y = 14'b01110101010010;
|
||||
8'b10011001: y = 14'b01110100111001;
|
||||
8'b10011010: y = 14'b01110100100001;
|
||||
8'b10011011: y = 14'b01110100001001;
|
||||
8'b10011100: y = 14'b01110011110001;
|
||||
8'b10011101: y = 14'b01110011011010;
|
||||
8'b10011110: y = 14'b01110011000010;
|
||||
8'b10011111: y = 14'b01110010101011;
|
||||
8'b10100000: y = 14'b01110010010100;
|
||||
8'b10100001: y = 14'b01110001111110;
|
||||
8'b10100010: y = 14'b01110001100111;
|
||||
8'b10100011: y = 14'b01110001010001;
|
||||
8'b10100100: y = 14'b01110000111011;
|
||||
8'b10100101: y = 14'b01110000100101;
|
||||
8'b10100110: y = 14'b01110000001111;
|
||||
8'b10100111: y = 14'b01101111111010;
|
||||
8'b10101000: y = 14'b01101111100101;
|
||||
8'b10101001: y = 14'b01101111010000;
|
||||
8'b10101010: y = 14'b01101110111011;
|
||||
8'b10101011: y = 14'b01101110100110;
|
||||
8'b10101100: y = 14'b01101110010001;
|
||||
8'b10101101: y = 14'b01101101111101;
|
||||
8'b10101110: y = 14'b01101101101001;
|
||||
8'b10101111: y = 14'b01101101010101;
|
||||
8'b10110000: y = 14'b01101101000001;
|
||||
8'b10110001: y = 14'b01101100101101;
|
||||
8'b10110010: y = 14'b01101100011010;
|
||||
8'b10110011: y = 14'b01101100000110;
|
||||
8'b10110100: y = 14'b01101011110011;
|
||||
8'b10110101: y = 14'b01101011100000;
|
||||
8'b10110110: y = 14'b01101011001101;
|
||||
8'b10110111: y = 14'b01101010111010;
|
||||
8'b10111000: y = 14'b01101010101000;
|
||||
8'b10111001: y = 14'b01101010010101;
|
||||
8'b10111010: y = 14'b01101010000011;
|
||||
8'b10111011: y = 14'b01101001110001;
|
||||
8'b10111100: y = 14'b01101001011111;
|
||||
8'b10111101: y = 14'b01101001001101;
|
||||
8'b10111110: y = 14'b01101000111100;
|
||||
8'b10111111: y = 14'b01101000101010;
|
||||
8'b11000000: y = 14'b01101000011001;
|
||||
8'b11000001: y = 14'b01101000000111;
|
||||
8'b11000010: y = 14'b01100111110110;
|
||||
8'b11000011: y = 14'b01100111100101;
|
||||
8'b11000100: y = 14'b01100111010100;
|
||||
8'b11000101: y = 14'b01100111000011;
|
||||
8'b11000110: y = 14'b01100110110011;
|
||||
8'b11000111: y = 14'b01100110100010;
|
||||
8'b11001000: y = 14'b01100110010010;
|
||||
8'b11001001: y = 14'b01100110000010;
|
||||
8'b11001010: y = 14'b01100101110010;
|
||||
8'b11001011: y = 14'b01100101100001;
|
||||
8'b11001100: y = 14'b01100101010010;
|
||||
8'b11001101: y = 14'b01100101000010;
|
||||
8'b11001110: y = 14'b01100100110010;
|
||||
8'b11001111: y = 14'b01100100100011;
|
||||
8'b11010000: y = 14'b01100100010011;
|
||||
8'b11010001: y = 14'b01100100000100;
|
||||
8'b11010010: y = 14'b01100011110101;
|
||||
8'b11010011: y = 14'b01100011100101;
|
||||
8'b11010100: y = 14'b01100011010110;
|
||||
8'b11010101: y = 14'b01100011000111;
|
||||
8'b11010110: y = 14'b01100010111001;
|
||||
8'b11010111: y = 14'b01100010101010;
|
||||
8'b11011000: y = 14'b01100010011011;
|
||||
8'b11011001: y = 14'b01100010001101;
|
||||
8'b11011010: y = 14'b01100001111110;
|
||||
8'b11011011: y = 14'b01100001110000;
|
||||
8'b11011100: y = 14'b01100001100010;
|
||||
8'b11011101: y = 14'b01100001010100;
|
||||
8'b11011110: y = 14'b01100001000110;
|
||||
8'b11011111: y = 14'b01100000111000;
|
||||
8'b11100000: y = 14'b01100000101010;
|
||||
8'b11100001: y = 14'b01100000011100;
|
||||
8'b11100010: y = 14'b01100000001111;
|
||||
8'b11100011: y = 14'b01100000000001;
|
||||
8'b11100100: y = 14'b01011111110100;
|
||||
8'b11100101: y = 14'b01011111100110;
|
||||
8'b11100110: y = 14'b01011111011001;
|
||||
8'b11100111: y = 14'b01011111001100;
|
||||
8'b11101000: y = 14'b01011110111111;
|
||||
8'b11101001: y = 14'b01011110110010;
|
||||
8'b11101010: y = 14'b01011110100101;
|
||||
8'b11101011: y = 14'b01011110011000;
|
||||
8'b11101100: y = 14'b01011110001011;
|
||||
8'b11101101: y = 14'b01011101111110;
|
||||
8'b11101110: y = 14'b01011101110010;
|
||||
8'b11101111: y = 14'b01011101100101;
|
||||
8'b11110000: y = 14'b01011101011001;
|
||||
8'b11110001: y = 14'b01011101001100;
|
||||
8'b11110010: y = 14'b01011101000000;
|
||||
8'b11110011: y = 14'b01011100110100;
|
||||
8'b11110100: y = 14'b01011100101000;
|
||||
8'b11110101: y = 14'b01011100011100;
|
||||
8'b11110110: y = 14'b01011100010000;
|
||||
8'b11110111: y = 14'b01011100000100;
|
||||
8'b11111000: y = 14'b01011011111000;
|
||||
8'b11111001: y = 14'b01011011101100;
|
||||
8'b11111010: y = 14'b01011011100000;
|
||||
8'b11111011: y = 14'b01011011010101;
|
||||
8'b11111100: y = 14'b01011011001001;
|
||||
8'b11111101: y = 14'b01011010111101;
|
||||
8'b11111110: y = 14'b01011010110010;
|
||||
8'b11111111: y = 14'b01011010100111;
|
||||
default: y = 14'bxxxxxxxxxxxxxx;
|
||||
endcase // case (a)
|
||||
|
||||
endmodule // sbtm_a0
|
||||
|
||||
|
||||
|
||||
|
@ -1,230 +0,0 @@
|
||||
///////////////////////////////////////////
|
||||
//
|
||||
// Written: James Stine
|
||||
// Modified: 8/1/2018
|
||||
//
|
||||
// Purpose: Bipartite Lookup
|
||||
//
|
||||
// A component of the Wally configurable RISC-V project.
|
||||
//
|
||||
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
|
||||
//
|
||||
// MIT LICENSE
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
// software and associated documentation files (the "Software"), to deal in the Software
|
||||
// without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
||||
// to whom the Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all copies or
|
||||
// substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
|
||||
// OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
module sbtm_a3 (input logic [7:0] a,
|
||||
output logic [5:0] y);
|
||||
|
||||
always_comb
|
||||
case(a)
|
||||
8'b01000000: y = 6'b100110;
|
||||
8'b01000001: y = 6'b100001;
|
||||
8'b01000010: y = 6'b011100;
|
||||
8'b01000011: y = 6'b010111;
|
||||
8'b01000100: y = 6'b010010;
|
||||
8'b01000101: y = 6'b001100;
|
||||
8'b01000110: y = 6'b000111;
|
||||
8'b01000111: y = 6'b000010;
|
||||
8'b01001000: y = 6'b100000;
|
||||
8'b01001001: y = 6'b011100;
|
||||
8'b01001010: y = 6'b011000;
|
||||
8'b01001011: y = 6'b010011;
|
||||
8'b01001100: y = 6'b001111;
|
||||
8'b01001101: y = 6'b001010;
|
||||
8'b01001110: y = 6'b000110;
|
||||
8'b01001111: y = 6'b000010;
|
||||
8'b01010000: y = 6'b011100;
|
||||
8'b01010001: y = 6'b011000;
|
||||
8'b01010010: y = 6'b010100;
|
||||
8'b01010011: y = 6'b010000;
|
||||
8'b01010100: y = 6'b001101;
|
||||
8'b01010101: y = 6'b001001;
|
||||
8'b01010110: y = 6'b000101;
|
||||
8'b01010111: y = 6'b000001;
|
||||
8'b01011000: y = 6'b011000;
|
||||
8'b01011001: y = 6'b010101;
|
||||
8'b01011010: y = 6'b010010;
|
||||
8'b01011011: y = 6'b001110;
|
||||
8'b01011100: y = 6'b001011;
|
||||
8'b01011101: y = 6'b001000;
|
||||
8'b01011110: y = 6'b000100;
|
||||
8'b01011111: y = 6'b000001;
|
||||
8'b01100000: y = 6'b010101;
|
||||
8'b01100001: y = 6'b010010;
|
||||
8'b01100010: y = 6'b001111;
|
||||
8'b01100011: y = 6'b001101;
|
||||
8'b01100100: y = 6'b001010;
|
||||
8'b01100101: y = 6'b000111;
|
||||
8'b01100110: y = 6'b000100;
|
||||
8'b01100111: y = 6'b000001;
|
||||
8'b01101000: y = 6'b010011;
|
||||
8'b01101001: y = 6'b010000;
|
||||
8'b01101010: y = 6'b001110;
|
||||
8'b01101011: y = 6'b001011;
|
||||
8'b01101100: y = 6'b001001;
|
||||
8'b01101101: y = 6'b000110;
|
||||
8'b01101110: y = 6'b000011;
|
||||
8'b01101111: y = 6'b000001;
|
||||
8'b01110000: y = 6'b010001;
|
||||
8'b01110001: y = 6'b001111;
|
||||
8'b01110010: y = 6'b001100;
|
||||
8'b01110011: y = 6'b001010;
|
||||
8'b01110100: y = 6'b001000;
|
||||
8'b01110101: y = 6'b000101;
|
||||
8'b01110110: y = 6'b000011;
|
||||
8'b01110111: y = 6'b000001;
|
||||
8'b01111000: y = 6'b001111;
|
||||
8'b01111001: y = 6'b001101;
|
||||
8'b01111010: y = 6'b001011;
|
||||
8'b01111011: y = 6'b001001;
|
||||
8'b01111100: y = 6'b000111;
|
||||
8'b01111101: y = 6'b000101;
|
||||
8'b01111110: y = 6'b000011;
|
||||
8'b01111111: y = 6'b000001;
|
||||
8'b10000000: y = 6'b001110;
|
||||
8'b10000001: y = 6'b001100;
|
||||
8'b10000010: y = 6'b001010;
|
||||
8'b10000011: y = 6'b001000;
|
||||
8'b10000100: y = 6'b000110;
|
||||
8'b10000101: y = 6'b000100;
|
||||
8'b10000110: y = 6'b000010;
|
||||
8'b10000111: y = 6'b000000;
|
||||
8'b10001000: y = 6'b001101;
|
||||
8'b10001001: y = 6'b001011;
|
||||
8'b10001010: y = 6'b001001;
|
||||
8'b10001011: y = 6'b000111;
|
||||
8'b10001100: y = 6'b000110;
|
||||
8'b10001101: y = 6'b000100;
|
||||
8'b10001110: y = 6'b000010;
|
||||
8'b10001111: y = 6'b000000;
|
||||
8'b10010000: y = 6'b001100;
|
||||
8'b10010001: y = 6'b001010;
|
||||
8'b10010010: y = 6'b001000;
|
||||
8'b10010011: y = 6'b000111;
|
||||
8'b10010100: y = 6'b000101;
|
||||
8'b10010101: y = 6'b000100;
|
||||
8'b10010110: y = 6'b000010;
|
||||
8'b10010111: y = 6'b000000;
|
||||
8'b10011000: y = 6'b001011;
|
||||
8'b10011001: y = 6'b001001;
|
||||
8'b10011010: y = 6'b001000;
|
||||
8'b10011011: y = 6'b000110;
|
||||
8'b10011100: y = 6'b000101;
|
||||
8'b10011101: y = 6'b000011;
|
||||
8'b10011110: y = 6'b000010;
|
||||
8'b10011111: y = 6'b000000;
|
||||
8'b10100000: y = 6'b001010;
|
||||
8'b10100001: y = 6'b001000;
|
||||
8'b10100010: y = 6'b000111;
|
||||
8'b10100011: y = 6'b000110;
|
||||
8'b10100100: y = 6'b000100;
|
||||
8'b10100101: y = 6'b000011;
|
||||
8'b10100110: y = 6'b000010;
|
||||
8'b10100111: y = 6'b000000;
|
||||
8'b10101000: y = 6'b001001;
|
||||
8'b10101001: y = 6'b001000;
|
||||
8'b10101010: y = 6'b000111;
|
||||
8'b10101011: y = 6'b000101;
|
||||
8'b10101100: y = 6'b000100;
|
||||
8'b10101101: y = 6'b000011;
|
||||
8'b10101110: y = 6'b000001;
|
||||
8'b10101111: y = 6'b000000;
|
||||
8'b10110000: y = 6'b001000;
|
||||
8'b10110001: y = 6'b000111;
|
||||
8'b10110010: y = 6'b000110;
|
||||
8'b10110011: y = 6'b000101;
|
||||
8'b10110100: y = 6'b000100;
|
||||
8'b10110101: y = 6'b000010;
|
||||
8'b10110110: y = 6'b000001;
|
||||
8'b10110111: y = 6'b000000;
|
||||
8'b10111000: y = 6'b001000;
|
||||
8'b10111001: y = 6'b000111;
|
||||
8'b10111010: y = 6'b000110;
|
||||
8'b10111011: y = 6'b000101;
|
||||
8'b10111100: y = 6'b000011;
|
||||
8'b10111101: y = 6'b000010;
|
||||
8'b10111110: y = 6'b000001;
|
||||
8'b10111111: y = 6'b000000;
|
||||
8'b11000000: y = 6'b000111;
|
||||
8'b11000001: y = 6'b000110;
|
||||
8'b11000010: y = 6'b000101;
|
||||
8'b11000011: y = 6'b000100;
|
||||
8'b11000100: y = 6'b000011;
|
||||
8'b11000101: y = 6'b000010;
|
||||
8'b11000110: y = 6'b000001;
|
||||
8'b11000111: y = 6'b000000;
|
||||
8'b11001000: y = 6'b000111;
|
||||
8'b11001001: y = 6'b000110;
|
||||
8'b11001010: y = 6'b000101;
|
||||
8'b11001011: y = 6'b000100;
|
||||
8'b11001100: y = 6'b000011;
|
||||
8'b11001101: y = 6'b000010;
|
||||
8'b11001110: y = 6'b000001;
|
||||
8'b11001111: y = 6'b000000;
|
||||
8'b11010000: y = 6'b000111;
|
||||
8'b11010001: y = 6'b000110;
|
||||
8'b11010010: y = 6'b000101;
|
||||
8'b11010011: y = 6'b000100;
|
||||
8'b11010100: y = 6'b000011;
|
||||
8'b11010101: y = 6'b000010;
|
||||
8'b11010110: y = 6'b000001;
|
||||
8'b11010111: y = 6'b000000;
|
||||
8'b11011000: y = 6'b000110;
|
||||
8'b11011001: y = 6'b000101;
|
||||
8'b11011010: y = 6'b000100;
|
||||
8'b11011011: y = 6'b000011;
|
||||
8'b11011100: y = 6'b000011;
|
||||
8'b11011101: y = 6'b000010;
|
||||
8'b11011110: y = 6'b000001;
|
||||
8'b11011111: y = 6'b000000;
|
||||
8'b11100000: y = 6'b000110;
|
||||
8'b11100001: y = 6'b000101;
|
||||
8'b11100010: y = 6'b000100;
|
||||
8'b11100011: y = 6'b000011;
|
||||
8'b11100100: y = 6'b000010;
|
||||
8'b11100101: y = 6'b000010;
|
||||
8'b11100110: y = 6'b000001;
|
||||
8'b11100111: y = 6'b000000;
|
||||
8'b11101000: y = 6'b000101;
|
||||
8'b11101001: y = 6'b000101;
|
||||
8'b11101010: y = 6'b000100;
|
||||
8'b11101011: y = 6'b000011;
|
||||
8'b11101100: y = 6'b000010;
|
||||
8'b11101101: y = 6'b000001;
|
||||
8'b11101110: y = 6'b000001;
|
||||
8'b11101111: y = 6'b000000;
|
||||
8'b11110000: y = 6'b000101;
|
||||
8'b11110001: y = 6'b000100;
|
||||
8'b11110010: y = 6'b000100;
|
||||
8'b11110011: y = 6'b000011;
|
||||
8'b11110100: y = 6'b000010;
|
||||
8'b11110101: y = 6'b000001;
|
||||
8'b11110110: y = 6'b000001;
|
||||
8'b11110111: y = 6'b000000;
|
||||
8'b11111000: y = 6'b000101;
|
||||
8'b11111001: y = 6'b000100;
|
||||
8'b11111010: y = 6'b000011;
|
||||
8'b11111011: y = 6'b000011;
|
||||
8'b11111100: y = 6'b000010;
|
||||
8'b11111101: y = 6'b000001;
|
||||
8'b11111110: y = 6'b000001;
|
||||
8'b11111111: y = 6'b000000;
|
||||
default: y = 6'bxxxxxx;
|
||||
endcase // case (a)
|
||||
|
||||
endmodule // sbtm_a0
|
@ -1,62 +0,0 @@
|
||||
///////////////////////////////////////////
|
||||
//
|
||||
// Written: James Stine
|
||||
// Modified: 8/1/2018
|
||||
//
|
||||
// Purpose: Bipartite Lookup for divide portion of fpdivsqrt
|
||||
//
|
||||
// A component of the Wally configurable RISC-V project.
|
||||
//
|
||||
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
|
||||
//
|
||||
// MIT LICENSE
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
// software and associated documentation files (the "Software"), to deal in the Software
|
||||
// without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
||||
// to whom the Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all copies or
|
||||
// substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
|
||||
// OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
module sbtm_div (input logic [11:0] a, output logic [10:0] ia_out);
|
||||
|
||||
// bit partitions
|
||||
logic [3:0] x0;
|
||||
logic [2:0] x1;
|
||||
logic [3:0] x2;
|
||||
logic [2:0] x2_1cmp;
|
||||
// mem outputs
|
||||
logic [12:0] y0;
|
||||
logic [4:0] y1;
|
||||
// input to CPA
|
||||
logic [14:0] op1;
|
||||
logic [14:0] op2;
|
||||
logic [14:0] p;
|
||||
logic cout;
|
||||
|
||||
assign x0 = a[10:7];
|
||||
assign x1 = a[6:4];
|
||||
assign x2 = a[3:0];
|
||||
|
||||
sbtm_a0 mem1 ({x0, x1}, y0);
|
||||
// 1s cmp per sbtm/stam
|
||||
assign x2_1cmp = x2[3] ? ~x2[2:0] : x2[2:0];
|
||||
sbtm_a1 mem2 ({x0, x2_1cmp}, y1);
|
||||
assign op1 = {1'b0, y0, 1'b0};
|
||||
// 1s cmp per sbtm/stam
|
||||
assign op2 = x2[3] ? {1'b1, {8{1'b1}}, ~y1, 1'b1} :
|
||||
{1'b0, 8'b0, y1, 1'b1};
|
||||
// CPA
|
||||
assign {cout, p} = op1 + op2;
|
||||
assign ia_out = p[14:4];
|
||||
|
||||
endmodule // sbtm
|
@ -1,68 +0,0 @@
|
||||
///////////////////////////////////////////
|
||||
//
|
||||
// Written: James Stine
|
||||
// Modified: 8/1/2018
|
||||
//
|
||||
// Purpose: Bipartite Lookup for sqrt part of fpdivsqrt
|
||||
//
|
||||
// A component of the Wally configurable RISC-V project.
|
||||
//
|
||||
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
|
||||
//
|
||||
// MIT LICENSE
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
// software and associated documentation files (the "Software"), to deal in the Software
|
||||
// without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
||||
// to whom the Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all copies or
|
||||
// substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
|
||||
// OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
module sbtm_sqrt (input logic [11:0] a, output logic [10:0] y);
|
||||
|
||||
// bit partitions
|
||||
logic [4:0] x0;
|
||||
logic [2:0] x1;
|
||||
logic [3:0] x2;
|
||||
logic [2:0] x2_1cmp;
|
||||
// mem outputs
|
||||
logic [13:0] y0;
|
||||
logic [5:0] y1;
|
||||
// input to CPA
|
||||
logic [14:0] op1;
|
||||
logic [14:0] op2;
|
||||
logic [14:0] p;
|
||||
logic cout;
|
||||
|
||||
assign x0 = a[11:7];
|
||||
assign x1 = a[6:4];
|
||||
assign x2 = a[3:0];
|
||||
|
||||
sbtm_a2 mem1 ({x0, x1}, y0);
|
||||
assign op1 = {y0, 1'b0};
|
||||
|
||||
// 1s cmp per sbtm/stam
|
||||
assign x2_1cmp = x2[3] ? ~x2[2:0] : x2[2:0];
|
||||
sbtm_a3 mem2 ({x0, x2_1cmp}, y1);
|
||||
// 1s cmp per sbtm/stam
|
||||
assign op2 = x2[3] ? {{8{1'b1}}, ~y1, 1'b1} :
|
||||
{8'b0, y1, 1'b1};
|
||||
|
||||
// CPA
|
||||
assign {cout, p} = op1 + op2;
|
||||
assign y = p[14:4];
|
||||
|
||||
endmodule // sbtm2
|
||||
|
||||
|
||||
|
||||
|
@ -1,164 +0,0 @@
|
||||
|
||||
// MJS - This module implements a 57-bit 2-to-1 multiplexor, which is
|
||||
// used in the barrel shifter for significand alignment.
|
||||
|
||||
module mux21x57 (Z, A, B, Sel);
|
||||
|
||||
input [56:0] A;
|
||||
input [56:0] B;
|
||||
input Sel;
|
||||
|
||||
output [56:0] Z;
|
||||
|
||||
assign Z = Sel ? B : A;
|
||||
|
||||
endmodule // mux21x57
|
||||
|
||||
// MJS - This module implements a 64-bit 2-to-1 multiplexor, which is
|
||||
// used in the barrel shifter for significand normalization.
|
||||
|
||||
module mux21x64 (Z, A, B, Sel);
|
||||
|
||||
input [63:0] A;
|
||||
input [63:0] B;
|
||||
input Sel;
|
||||
|
||||
output [63:0] Z;
|
||||
|
||||
assign Z = Sel ? B : A;
|
||||
|
||||
endmodule // mux21x64
|
||||
|
||||
// The implementation of the barrel shifter was modified to use
|
||||
// fewer gates. It is now implemented using six 64-bit 2-to-1 muxes. The
|
||||
// barrel shifter takes a 64-bit input A and shifts it left by up to
|
||||
// 63-bits, as specified by Shift, to produce a 63-bit output Z.
|
||||
// Bits to the right are filled with zeros.
|
||||
// The 64 bit shift is implemented using 6 stages of shifts of 32
|
||||
// 16, 8, 4, 2, and 1 bit shifts.
|
||||
|
||||
module barrel_shifter_l64 (Z, A, Shift);
|
||||
|
||||
input [63:0] A;
|
||||
input [5:0] Shift;
|
||||
|
||||
wire [63:0] stage1;
|
||||
wire [63:0] stage2;
|
||||
wire [63:0] stage3;
|
||||
wire [63:0] stage4;
|
||||
wire [63:0] stage5;
|
||||
wire [31:0] thirtytwozeros = 32'h0;
|
||||
wire [15:0] sixteenzeros = 16'h0;
|
||||
wire [ 7:0] eightzeros = 8'h0;
|
||||
wire [ 3:0] fourzeros = 4'h0;
|
||||
wire [ 1:0] twozeros = 2'b00;
|
||||
wire onezero = 1'b0;
|
||||
|
||||
output [63:0] Z;
|
||||
|
||||
mux21x64 mx01(stage1, A, {A[31:0], thirtytwozeros}, Shift[5]);
|
||||
mux21x64 mx02(stage2, stage1, {stage1[47:0], sixteenzeros}, Shift[4]);
|
||||
mux21x64 mx03(stage3, stage2, {stage2[55:0], eightzeros}, Shift[3]);
|
||||
mux21x64 mx04(stage4, stage3, {stage3[59:0], fourzeros}, Shift[2]);
|
||||
mux21x64 mx05(stage5, stage4, {stage4[61:0], twozeros}, Shift[1]);
|
||||
mux21x64 mx06(Z , stage5, {stage5[62:0], onezero}, Shift[0]);
|
||||
|
||||
endmodule // barrel_shifter_l63
|
||||
|
||||
// The implementation of the barrel shifter was modified to use
|
||||
// fewer gates. It is now implemented using six 57-bit 2-to-1 muxes. The
|
||||
// barrel shifter takes a 57-bit input A and right shifts it by up to
|
||||
// 63-bits, as specified by Shift, to produce a 57-bit output Z.
|
||||
// It also computes a Sticky bit, which is set to
|
||||
// one if any of the bits that were shifted out was one.
|
||||
// Bits shifted into the left are filled with zeros.
|
||||
// The 63 bit shift is implemented using 6 stages of shifts of 32
|
||||
// 16, 8, 4, 2, and 1 bits.
|
||||
|
||||
module barrel_shifter_r57 (Z, Sticky, A, Shift);
|
||||
|
||||
input [56:0] A;
|
||||
input [5:0] Shift;
|
||||
|
||||
output Sticky;
|
||||
output [56:0] Z;
|
||||
|
||||
wire [56:0] stage1;
|
||||
wire [56:0] stage2;
|
||||
wire [56:0] stage3;
|
||||
wire [56:0] stage4;
|
||||
wire [56:0] stage5;
|
||||
wire [62:0] sixtythreezeros = 63'h0;
|
||||
wire [31:0] thirtytwozeros = 32'h0;
|
||||
wire [15:0] sixteenzeros = 16'h0;
|
||||
wire [ 7:0] eightzeros = 8'h0;
|
||||
wire [ 3:0] fourzeros = 4'h0;
|
||||
wire [ 1:0] twozeros = 2'b00;
|
||||
wire onezero = 1'b0;
|
||||
wire [62:0] S;
|
||||
|
||||
// Shift operations
|
||||
mux21x57 mx01(stage1, A, {thirtytwozeros, A[56:32]}, Shift[5]);
|
||||
mux21x57 mx02(stage2, stage1, {sixteenzeros, stage1[56:16]}, Shift[4]);
|
||||
mux21x57 mx03(stage3, stage2, {eightzeros, stage2[56:8]}, Shift[3]);
|
||||
mux21x57 mx04(stage4, stage3, {fourzeros, stage3[56:4]}, Shift[2]);
|
||||
mux21x57 mx05(stage5, stage4, {twozeros, stage4[56:2]}, Shift[1]);
|
||||
mux21x57 mx06(Z , stage5, {onezero, stage5[56:1]}, Shift[0]);
|
||||
|
||||
// Sticky bit calculation. The Sticky bit is set to one if any of the
|
||||
// bits that were shifter out were one
|
||||
|
||||
assign S[31:0] = {32{Shift[5]}} & A[31:0];
|
||||
assign S[47:32] = {16{Shift[4]}} & stage1[15:0];
|
||||
assign S[55:48] = { 8{Shift[3]}} & stage2[7:0];
|
||||
assign S[59:56] = { 4{Shift[2]}} & stage3[3:0];
|
||||
assign S[61:60] = { 2{Shift[1]}} & stage4[1:0];
|
||||
assign S[62] = Shift[0] & stage5[0];
|
||||
assign Sticky = (S != sixtythreezeros);
|
||||
|
||||
endmodule // barrel_shifter_r57
|
||||
|
||||
/*
|
||||
module barrel_shifter_r64 (Z, Sticky, A, Shift);
|
||||
|
||||
input [63:0] A;
|
||||
input [5:0] Shift;
|
||||
|
||||
output Sticky;
|
||||
output [63:0] Z;
|
||||
|
||||
wire [63:0] stage1;
|
||||
wire [63:0] stage2;
|
||||
wire [63:0] stage3;
|
||||
wire [63:0] stage4;
|
||||
wire [63:0] stage5;
|
||||
wire [62:0] sixtythreezeros = 63'h0;
|
||||
wire [31:0] thirtytwozeros = 32'h0;
|
||||
wire [15:0] sixteenzeros = 16'h0;
|
||||
wire [ 7:0] eightzeros = 8'h0;
|
||||
wire [ 3:0] fourzeros = 4'h0;
|
||||
wire [ 1:0] twozeros = 2'b00;
|
||||
wire onezero = 1'b0;
|
||||
wire [62:0] S;
|
||||
|
||||
// Shift operations
|
||||
mux21x64 mx01(stage1, A, {thirtytwozeros, A[63:32]}, Shift[5]);
|
||||
mux21x64 mx02(stage2, stage1, {sixteenzeros, stage1[63:16]}, Shift[4]);
|
||||
mux21x64 mx03(stage3, stage2, {eightzeros, stage2[63:8]}, Shift[3]);
|
||||
mux21x64 mx04(stage4, stage3, {fourzeros, stage3[63:4]}, Shift[2]);
|
||||
mux21x64 mx05(stage5, stage4, {twozeros, stage4[63:2]}, Shift[1]);
|
||||
mux21x64 mx06(Z , stage5, {onezero, stage5[63:1]}, Shift[0]);
|
||||
|
||||
// Sticky bit calculation. The Sticky bit is set to one if any of the
|
||||
// bits that were shifter out were one
|
||||
|
||||
assign S[31:0] = {32{Shift[5]}} & A[31:0];
|
||||
assign S[47:32] = {16{Shift[4]}} & stage1[15:0];
|
||||
assign S[55:48] = { 8{Shift[3]}} & stage2[7:0];
|
||||
assign S[59:56] = { 4{Shift[2]}} & stage3[3:0];
|
||||
assign S[61:60] = { 2{Shift[1]}} & stage4[1:0];
|
||||
assign S[62] = Shift[0] & stage5[0];
|
||||
assign Sticky = (S != sixtythreezeros);
|
||||
|
||||
endmodule // barrel_shifter_r64
|
||||
*/
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,2 +0,0 @@
|
||||
vsim -do "do srt-radix4.do"
|
||||
|
@ -1 +0,0 @@
|
||||
vsim -c -do "do srt-radix4.do"
|
@ -1,31 +0,0 @@
|
||||
# srt.do
|
||||
#
|
||||
# David_Harris@hmc.edu 19 October 2021
|
||||
|
||||
# Use this wally-pipelined.do file to run this example.
|
||||
# Either bring up ModelSim and type the following at the "ModelSim>" prompt:
|
||||
# do wally-pipelined.do
|
||||
# or, to run from a shell, type the following at the shell prompt:
|
||||
# vsim -do wally-pipelined.do -c
|
||||
# (omit the "-c" to see the GUI while running from the shell)
|
||||
|
||||
onbreak {resume}
|
||||
|
||||
# create library
|
||||
if [file exists work] {
|
||||
vdel -all
|
||||
}
|
||||
vlib work
|
||||
|
||||
vlog +incdir+../config/rv64gc +incdir+../config/shared srt-radix4.sv testbench-radix4.sv ../src/generic/flop/flop*.sv ../src/generic/mux.sv ../src/generic/lzc.sv
|
||||
vopt +acc work.testbenchradix4 -o workopt
|
||||
vsim workopt
|
||||
|
||||
-- display input and output signals as hexidecimal values
|
||||
add wave /testbenchradix4/*
|
||||
add wave /testbenchradix4/srtradix4/*
|
||||
add wave /testbenchradix4/srtradix4/qsel4/*
|
||||
add wave /testbenchradix4/srtradix4/otfc4/*
|
||||
|
||||
-- Run the Simulation
|
||||
run -all
|
@ -1,122 +0,0 @@
|
||||
|
||||
`include "wally-config.vh"
|
||||
`define DIVLEN ((`NF<`XLEN) ? `XLEN : `NF)
|
||||
|
||||
///////////
|
||||
// clock //
|
||||
///////////
|
||||
module clock(clk);
|
||||
output clk;
|
||||
|
||||
// Internal clk signal
|
||||
logic clk;
|
||||
|
||||
endmodule
|
||||
|
||||
//////////
|
||||
// testbench //
|
||||
//////////
|
||||
module testbenchradix4;
|
||||
logic clk;
|
||||
logic req;
|
||||
logic DivDone;
|
||||
logic [63:0] a, b;
|
||||
logic [51:0] afrac, bfrac;
|
||||
logic [10:0] aExp, bExp;
|
||||
logic asign, bsign;
|
||||
logic [51:0] r, rOTFC;
|
||||
logic [`DIVLEN-1:0] Quot, QuotOTFC;
|
||||
logic [54:0] rp, rm; // positive quotient digits
|
||||
|
||||
// Test parameters
|
||||
parameter MEM_SIZE = 40000;
|
||||
parameter MEM_WIDTH = 64+64+64;
|
||||
|
||||
`define memr 63:0
|
||||
`define memb 127:64
|
||||
`define mema 191:128
|
||||
|
||||
// Test logicisters
|
||||
logic [MEM_WIDTH-1:0] Tests [0:MEM_SIZE]; // Space for input file
|
||||
logic [MEM_WIDTH-1:0] Vec; // Verilog doesn't allow direct access to a
|
||||
// bit field of an array
|
||||
logic [63:0] correctr, nextr, diffn, diffp;
|
||||
logic [10:0] DivExp;
|
||||
logic DivSgn;
|
||||
integer testnum, errors;
|
||||
|
||||
// Divider
|
||||
srtradix4 srtradix4(.clk, .DivStart(req),
|
||||
.XExpE(aExp), .YExpE(bExp), .DivExp,
|
||||
.XSgnE(asign), .YSgnE(bsign), .DivSgn,
|
||||
.XFrac(afrac), .YFrac(bfrac),
|
||||
.SrcA('0), .SrcB('0),
|
||||
.W64(1'b0), .Signed(1'b0), .Int(1'b0), .Sqrt(1'b0), .DivDone,
|
||||
.Quot, .Rem());
|
||||
|
||||
// Counter
|
||||
|
||||
|
||||
initial
|
||||
forever
|
||||
begin
|
||||
clk = 1; #17;
|
||||
clk = 0; #17;
|
||||
end
|
||||
|
||||
|
||||
// Read test vectors from disk
|
||||
initial
|
||||
begin
|
||||
testnum = 0;
|
||||
errors = 0;
|
||||
$readmemh ("testvectors", Tests);
|
||||
Vec = Tests[testnum];
|
||||
a = Vec[`mema];
|
||||
{asign, aExp, afrac} = a;
|
||||
b = Vec[`memb];
|
||||
{bsign, bExp, bfrac} = b;
|
||||
nextr = Vec[`memr];
|
||||
r = Quot[`DIVLEN-1:`DIVLEN - 52];
|
||||
req <= 1;
|
||||
end
|
||||
|
||||
// Apply directed test vectors read from file.
|
||||
|
||||
always @(posedge clk)
|
||||
begin
|
||||
r = Quot[`DIVLEN-1:`DIVLEN - 52];
|
||||
if (DivDone) begin
|
||||
req <= 1;
|
||||
diffp = correctr[51:0] - r;
|
||||
diffn = r - correctr[51:0];
|
||||
if ((DivSgn !== correctr[63]) | (DivExp !== correctr[62:52]) | ($signed(diffn) > 1) | ($signed(diffp) > 1) | (diffn === 64'bx) | (diffp === 64'bx)) // check if accurate to 1 ulp
|
||||
begin
|
||||
errors = errors+1;
|
||||
$display("result was %h_%h, should be %h %h %h\n", DivExp, r, correctr, diffn, diffp);
|
||||
$display("failed\n");
|
||||
$stop;
|
||||
end
|
||||
if (afrac === 52'hxxxxxxxxxxxxx)
|
||||
begin
|
||||
$display("%d Tests completed successfully", testnum);
|
||||
$stop;
|
||||
end
|
||||
end
|
||||
if (req)
|
||||
begin
|
||||
req <= 0;
|
||||
correctr = nextr;
|
||||
testnum = testnum+1;
|
||||
Vec = Tests[testnum];
|
||||
$display("a = %h b = %h",a,b);
|
||||
a = Vec[`mema];
|
||||
{asign, aExp, afrac} = a;
|
||||
b = Vec[`memb];
|
||||
{bsign, bExp, bfrac} = b;
|
||||
nextr = Vec[`memr];
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
Loading…
Reference in New Issue
Block a user