moved unsused division code again

This commit is contained in:
Katherine Parry 2022-07-07 16:41:26 -07:00
parent b7e590ebb0
commit 905b7ffc84
29 changed files with 1 additions and 6902 deletions

@ -1 +1 @@
Subproject commit 307c77b26e070ae85ffea665ad9b642b40e33c86
Subproject commit be67c99bd461742aa1c100bcc0732657faae2230

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -1,2 +0,0 @@
vsim -do "do srt-radix4.do"

View File

@ -1 +0,0 @@
vsim -c -do "do srt-radix4.do"

View File

@ -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

View File

@ -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