2022-07-15 21:42:45 +00:00
|
|
|
///////////////////////////////////////////
|
2022-08-29 11:04:05 +00:00
|
|
|
// fdivsqrtiter.sv
|
2022-07-15 21:42:45 +00:00
|
|
|
//
|
|
|
|
// Written: David_Harris@hmc.edu, me@KatherineParry.com, cturek@hmc.edu
|
|
|
|
// Modified:13 January 2022
|
|
|
|
//
|
|
|
|
// Purpose: Combined Divide and Square Root Floating Point and Integer Unit
|
|
|
|
//
|
|
|
|
// 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"
|
|
|
|
|
2022-08-29 11:04:05 +00:00
|
|
|
module fdivsqrtiter(
|
2022-07-15 21:42:45 +00:00
|
|
|
input logic clk,
|
2022-12-02 19:30:49 +00:00
|
|
|
input logic IFDivStartE,
|
2022-11-16 18:13:27 +00:00
|
|
|
input logic FDivBusyE,
|
2022-07-15 21:42:45 +00:00
|
|
|
input logic [`NE-1:0] Xe, Ye,
|
|
|
|
input logic XZeroE, YZeroE,
|
2022-08-06 22:54:05 +00:00
|
|
|
input logic SqrtE,
|
2022-12-02 19:11:53 +00:00
|
|
|
// input logic SqrtM,
|
2022-11-06 23:09:09 +00:00
|
|
|
input logic OTFCSwap,
|
2022-09-14 17:26:56 +00:00
|
|
|
input logic [`DIVb+3:0] X,
|
2022-12-02 21:44:29 +00:00
|
|
|
input logic [`DIVb-1:0] DPreproc,
|
|
|
|
output logic [`DIVb-1:0] D,
|
|
|
|
output logic [`DIVb:0] FirstU, FirstUM,
|
2022-09-19 05:42:35 +00:00
|
|
|
output logic [`DIVb+1:0] FirstC,
|
2022-09-20 11:35:14 +00:00
|
|
|
output logic Firstun,
|
2022-12-02 21:44:29 +00:00
|
|
|
output logic [`DIVb+3:0] FirstWS, FirstWC
|
2022-07-15 21:42:45 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
/* verilator lint_off UNOPTFLAT */
|
2022-12-02 21:44:29 +00:00
|
|
|
logic [`DIVb+3:0] WSNext[`DIVCOPIES-1:0]; // Q4.b
|
|
|
|
logic [`DIVb+3:0] WCNext[`DIVCOPIES-1:0]; // Q4.b
|
|
|
|
logic [`DIVb+3:0] WS[`DIVCOPIES:0]; // Q4.b
|
|
|
|
logic [`DIVb+3:0] WC[`DIVCOPIES:0]; // Q4.b
|
|
|
|
logic [`DIVb:0] U[`DIVCOPIES:0]; // U1.b
|
|
|
|
logic [`DIVb:0] UM[`DIVCOPIES:0]; // U1.b
|
|
|
|
logic [`DIVb:0] UNext[`DIVCOPIES-1:0]; // U1.b
|
|
|
|
logic [`DIVb:0] UMNext[`DIVCOPIES-1:0]; // U1.b
|
|
|
|
logic [`DIVb+1:0] C[`DIVCOPIES:0]; // Q2.b
|
|
|
|
logic [`DIVb+1:0] initC; // Q2.b
|
|
|
|
logic [`DIVCOPIES-1:0] un;
|
2022-09-07 18:36:35 +00:00
|
|
|
|
2022-07-15 21:42:45 +00:00
|
|
|
/* verilator lint_on UNOPTFLAT */
|
2022-12-02 21:44:29 +00:00
|
|
|
logic [`DIVb+3:0] WSN, WCN; // Q4.b
|
|
|
|
logic [`DIVb+3:0] DBar, D2, DBar2; // Q4.b
|
2022-09-19 05:42:35 +00:00
|
|
|
logic [`DIVb+1:0] NextC;
|
|
|
|
logic [`DIVb+1:0] CMux;
|
2022-12-02 21:44:29 +00:00
|
|
|
logic [`DIVb:0] UMux, UMMux;
|
|
|
|
logic [`DIVb:0] initU, initUM;
|
2022-09-19 07:04:00 +00:00
|
|
|
|
2022-07-15 21:42:45 +00:00
|
|
|
|
|
|
|
// Top Muxes and Registers
|
|
|
|
// When start is asserted, the inputs are loaded into the divider.
|
2022-10-09 11:45:45 +00:00
|
|
|
// Otherwise, the divisor is retained and the residual and result
|
|
|
|
// are fed back for the next iteration.
|
2022-10-09 10:37:27 +00:00
|
|
|
|
|
|
|
// Residual WS/SC registers/initializaiton mux
|
2022-12-02 19:30:49 +00:00
|
|
|
mux2 #(`DIVb+4) wsmux(WS[`DIVCOPIES], X, IFDivStartE, WSN);
|
|
|
|
mux2 #(`DIVb+4) wcmux(WC[`DIVCOPIES], '0, IFDivStartE, WCN);
|
2022-12-02 21:44:29 +00:00
|
|
|
flopen #(`DIVb+4) wsreg(clk, FDivBusyE, WSN, WS[0]);
|
|
|
|
flopen #(`DIVb+4) wcreg(clk, FDivBusyE, WCN, WC[0]);
|
2022-10-09 10:37:27 +00:00
|
|
|
|
|
|
|
// UOTFC Result U and UM registers/initialization mux
|
|
|
|
// Initialize U to 1.0 and UM to 0 for square root; U to 0 and UM to -1 for division
|
|
|
|
assign initU = SqrtE ? {1'b1, {(`DIVb){1'b0}}} : 0;
|
|
|
|
assign initUM = SqrtE ? 0 : {1'b1, {(`DIVb){1'b0}}};
|
2022-12-02 21:44:29 +00:00
|
|
|
mux2 #(`DIVb+1) Umux(UNext[`DIVCOPIES-1], initU, IFDivStartE, UMux);
|
|
|
|
mux2 #(`DIVb+1) UMmux(UMNext[`DIVCOPIES-1], initUM, IFDivStartE, UMMux);
|
2022-12-02 19:30:49 +00:00
|
|
|
flopen #(`DIVb+1) UReg(clk, IFDivStartE|FDivBusyE, UMux, U[0]);
|
|
|
|
flopen #(`DIVb+1) UMReg(clk, IFDivStartE|FDivBusyE, UMMux, UM[0]);
|
2022-09-19 05:42:35 +00:00
|
|
|
|
2022-10-09 10:37:27 +00:00
|
|
|
// C register/initialization mux
|
2022-09-19 05:42:35 +00:00
|
|
|
// Initialize C to -1 for sqrt and -R for division
|
2022-10-09 10:37:27 +00:00
|
|
|
logic [1:0] initCUpper;
|
|
|
|
assign initCUpper = SqrtE ? 2'b11 : (`RADIX == 4) ? 2'b00 : 2'b10;
|
2022-09-19 05:42:35 +00:00
|
|
|
assign initC = {initCUpper, {`DIVb{1'b0}}};
|
2022-12-02 19:30:49 +00:00
|
|
|
mux2 #(`DIVb+2) Cmux(C[`DIVCOPIES], initC, IFDivStartE, CMux);
|
|
|
|
flopen #(`DIVb+2) cflop(clk, IFDivStartE|FDivBusyE, CMux, C[0]);
|
2022-07-15 21:42:45 +00:00
|
|
|
|
2022-10-09 10:37:27 +00:00
|
|
|
// Divisior register
|
2022-12-02 21:44:29 +00:00
|
|
|
flopen #(`DIVb) dflop(clk, IFDivStartE, DPreproc, D);
|
2022-10-09 10:37:27 +00:00
|
|
|
|
2022-07-15 21:42:45 +00:00
|
|
|
// Divisor Selections
|
2022-07-22 22:02:04 +00:00
|
|
|
// - choose the negitive version of what's being selected
|
|
|
|
// - D is only the fraction
|
2022-12-02 21:44:29 +00:00
|
|
|
assign DBar = {3'b111, 1'b0, ~D};
|
2022-07-15 21:42:45 +00:00
|
|
|
if(`RADIX == 4) begin : d2
|
2022-12-02 21:44:29 +00:00
|
|
|
assign DBar2 = {2'b11, 1'b0, ~D, 1'b1};
|
|
|
|
assign D2 = {2'b00, 1'b1, D, 1'b0};
|
2022-07-15 21:42:45 +00:00
|
|
|
end
|
|
|
|
|
2022-10-09 10:37:27 +00:00
|
|
|
// k=DIVCOPIES of the recurrence logic
|
2022-07-15 21:42:45 +00:00
|
|
|
genvar i;
|
|
|
|
generate
|
2022-11-06 23:32:38 +00:00
|
|
|
for(i=0; $unsigned(i)<`DIVCOPIES; i++) begin : iterations
|
2022-08-29 11:26:14 +00:00
|
|
|
if (`RADIX == 2) begin: stage
|
2022-12-02 19:11:53 +00:00
|
|
|
fdivsqrtstage2 fdivsqrtstage(.D, .DBar, .SqrtE, .OTFCSwap,
|
2022-11-06 23:32:38 +00:00
|
|
|
.WS(WS[i]), .WC(WC[i]), .WSNext(WSNext[i]), .WCNext(WCNext[i]),
|
2022-09-20 11:35:14 +00:00
|
|
|
.C(C[i]), .U(U[i]), .UM(UM[i]), .CNext(C[i+1]), .UNext(UNext[i]), .UMNext(UMNext[i]), .un(un[i]));
|
2022-08-29 11:26:14 +00:00
|
|
|
end else begin: stage
|
2022-09-01 23:57:57 +00:00
|
|
|
logic j1;
|
2022-09-16 02:15:48 +00:00
|
|
|
assign j1 = (i == 0 & ~C[0][`DIVb-1]);
|
2022-12-02 19:11:53 +00:00
|
|
|
fdivsqrtstage4 fdivsqrtstage(.D, .DBar, .D2, .DBar2, .SqrtE, .j1, .OTFCSwap,
|
2022-10-09 11:45:45 +00:00
|
|
|
.WS(WS[i]), .WC(WC[i]), .WSNext(WSNext[i]), .WCNext(WCNext[i]),
|
2022-09-20 11:35:14 +00:00
|
|
|
.C(C[i]), .U(U[i]), .UM(UM[i]), .CNext(C[i+1]), .UNext(UNext[i]), .UMNext(UMNext[i]), .un(un[i]));
|
2022-08-29 11:26:14 +00:00
|
|
|
end
|
2022-10-09 11:45:45 +00:00
|
|
|
assign WS[i+1] = WSNext[i];
|
|
|
|
assign WC[i+1] = WCNext[i];
|
2022-10-09 10:37:27 +00:00
|
|
|
assign U[i+1] = UNext[i];
|
|
|
|
assign UM[i+1] = UMNext[i];
|
2022-07-15 21:42:45 +00:00
|
|
|
end
|
|
|
|
endgenerate
|
|
|
|
|
2022-10-09 10:37:27 +00:00
|
|
|
// Send values from start of cycle for postprocessing
|
2022-07-15 21:42:45 +00:00
|
|
|
assign FirstWS = WS[0];
|
|
|
|
assign FirstWC = WC[0];
|
2022-11-06 23:32:38 +00:00
|
|
|
assign FirstU = U[0];
|
2022-09-19 07:43:27 +00:00
|
|
|
assign FirstUM = UM[0];
|
2022-11-06 23:32:38 +00:00
|
|
|
assign FirstC = C[0];
|
2022-09-20 11:35:14 +00:00
|
|
|
assign Firstun = un[0];
|
2022-07-15 21:42:45 +00:00
|
|
|
endmodule
|
|
|
|
|