radix-2 1 copy passes testfloat

This commit is contained in:
Katherine Parry 2022-08-06 22:54:05 +00:00
parent 8f1d8669b0
commit 8eeca3319c
8 changed files with 37 additions and 46 deletions

View File

@ -101,17 +101,18 @@
`define CORRSHIFTSZ ((`DIVRESLEN+`NF) > (3*`NF+8) ? (`DIVRESLEN+`NF) : (3*`NF+6)) `define CORRSHIFTSZ ((`DIVRESLEN+`NF) > (3*`NF+8) ? (`DIVRESLEN+`NF) : (3*`NF+6))
// division constants // division constants
`define RADIX 32'h4 `define RADIX 32'h2
`define DIVCOPIES 32'h4 `define DIVCOPIES 32'h1
`define DIVLEN ((`NF < `XLEN) ? (`XLEN) : (`NF + 3)) `define DIVLEN ((`NF < `XLEN) ? (`XLEN) : (`NF + 3))
`define DIVN (`NF < `XLEN ? `XLEN : `NF+1) // length of input // `define DIVN (`NF < `XLEN ? `XLEN : `NF+1) // length of input
`define DIVN (`NF < `XLEN ? `XLEN : `NF+3) // length of input
`define EXTRAFRACBITS ((`NF<(`XLEN)) ? (`XLEN - `NF) : 3) `define EXTRAFRACBITS ((`NF<(`XLEN)) ? (`XLEN - `NF) : 3)
`define EXTRAINTBITS ((`NF<(`XLEN)) ? 0 : (`NF - `XLEN + 3)) `define EXTRAINTBITS ((`NF<(`XLEN)) ? 0 : (`NF - `XLEN + 3))
`define DIVRESLEN ((`NF>`XLEN) ? `NF+4 : `XLEN) `define DIVRESLEN ((`NF>`XLEN) ? `NF+4 : `XLEN)
`define LOGR ((`RADIX==2) ? 32'h1 : 32'h2) `define LOGR ((`RADIX==2) ? 32'h1 : 32'h2)
// FPDUR = ceil(DIVRESLEN/(LOGR*DIVCOPIES)) // FPDUR = ceil(DIVRESLEN/(LOGR*DIVCOPIES))
// one interation is required for the integer bit for minimally redundent radix-4 // one interation is required for the integer bit for minimally redundent radix-4
`define FPDUR ((`DIVLEN+(`LOGR*`DIVCOPIES)-1)/(`LOGR*`DIVCOPIES)+(`RADIX/4)) `define FPDUR ((`DIVN+2+(`LOGR*`DIVCOPIES)-1)/(`LOGR*`DIVCOPIES)+(`RADIX/4))
`define DURLEN ($clog2(`FPDUR+1)) `define DURLEN ($clog2(`FPDUR+1))
`define QLEN (`FPDUR*`LOGR*`DIVCOPIES) `define QLEN (`FPDUR*`LOGR*`DIVCOPIES)
`define DIVb (`FPDUR*`LOGR*`DIVCOPIES)-1 `define DIVb (`FPDUR*`LOGR*`DIVCOPIES)-1

View File

@ -30,9 +30,9 @@ add wave -group {Divide} -noupdate /testbenchfp/divsqrt/srt/QNext
add wave -group {Divide} -noupdate /testbenchfp/divsqrt/srt/QMNext add wave -group {Divide} -noupdate /testbenchfp/divsqrt/srt/QMNext
add wave -group {Divide} -noupdate /testbenchfp/divsqrt/srt/* add wave -group {Divide} -noupdate /testbenchfp/divsqrt/srt/*
add wave -group {Divide} -group inter0 -noupdate /testbenchfp/divsqrt/srt/interations[0]/divinteration/* add wave -group {Divide} -group inter0 -noupdate /testbenchfp/divsqrt/srt/interations[0]/divinteration/*
# add wave -group {Divide} -group inter0 -noupdate /testbenchfp/divsqrt/srt/interations[0]/divinteration/otfc/otfc2/* add wave -group {Divide} -group inter0 -noupdate /testbenchfp/divsqrt/srt/interations[0]/divinteration/otfc/otfc2/*
# add wave -group {Divide} -group inter0 -noupdate /testbenchfp/divsqrt/srt/interations[0]/divinteration/qsel/qsel2/* add wave -group {Divide} -group inter0 -noupdate /testbenchfp/divsqrt/srt/interations[0]/divinteration/qsel/qsel2/*
add wave -group {Divide} -group inter0 -noupdate /testbenchfp/divsqrt/srt/interations[0]/divinteration/genblk1/qsel4/* # add wave -group {Divide} -group inter0 -noupdate /testbenchfp/divsqrt/srt/interations[0]/divinteration/genblk1/qsel4/*
add wave -group {Divide} -noupdate /testbenchfp/divsqrt/srtpreproc/* add wave -group {Divide} -noupdate /testbenchfp/divsqrt/srtpreproc/*
add wave -group {Divide} -noupdate /testbenchfp/divsqrt/srtpreproc/expcalc/* add wave -group {Divide} -noupdate /testbenchfp/divsqrt/srtpreproc/expcalc/*
add wave -group {Divide} -noupdate /testbenchfp/divsqrt/srtfsm/* add wave -group {Divide} -noupdate /testbenchfp/divsqrt/srtfsm/*

View File

@ -65,6 +65,6 @@ module divsqrt(
srtfsm srtfsm(.reset, .XsE, .SqrtE, .NextWSN, .NextWCN, .WS, .WC, .Dur, .DivBusy, .clk, .DivStart(DivStartE),.StallE, .StallM, .DivDone, .XZeroE, .YZeroE, .DivSE(DivSM), .XNaNE, .YNaNE, srtfsm srtfsm(.reset, .XsE, .SqrtE, .NextWSN, .NextWCN, .WS, .WC, .Dur, .DivBusy, .clk, .DivStart(DivStartE),.StallE, .StallM, .DivDone, .XZeroE, .YZeroE, .DivSE(DivSM), .XNaNE, .YNaNE,
.StickyWSA, .XInfE, .YInfE, .NegSticky(NegSticky), .EarlyTermShiftE(EarlyTermShiftM)); .StickyWSA, .XInfE, .YInfE, .NegSticky(NegSticky), .EarlyTermShiftE(EarlyTermShiftM));
srt srt(.clk, .Sqrt(SqrtM), .X,.Dpreproc, .NegSticky, .FirstWS(WS), .FirstWC(WC), .NextWSN, .NextWCN, .DivStart(DivStartE), .Xe(XeE), .Ye(YeE), .XZeroE, .YZeroE, srt srt(.clk, .SqrtE, .SqrtM, .X,.Dpreproc, .NegSticky, .FirstWS(WS), .FirstWC(WC), .NextWSN, .NextWCN, .DivStart(DivStartE), .Xe(XeE), .Ye(YeE), .XZeroE, .YZeroE,
.StickyWSA, .DivBusy, .Qm(QmM)); .StickyWSA, .DivBusy, .Qm(QmM));
endmodule endmodule

View File

@ -157,7 +157,7 @@ module flags(
// or when the positive res rounds up out of range // or when the positive res rounds up out of range
assign SigNaN = (XSNaN&~(IntToFp&CvtOp)) | (YSNaN&~CvtOp) | (ZSNaN&FmaOp); assign SigNaN = (XSNaN&~(IntToFp&CvtOp)) | (YSNaN&~CvtOp) | (ZSNaN&FmaOp);
assign FmaInvalid = ((XInf | YInf) & ZInf & (FmaPs ^ FmaAs) & ~NaNIn) | (XZero & YInf) | (YZero & XInf); assign FmaInvalid = ((XInf | YInf) & ZInf & (FmaPs ^ FmaAs) & ~NaNIn) | (XZero & YInf) | (YZero & XInf);
assign DivInvalid = ((XInf & YInf) | (XZero & YZero))&~Sqrt | (Xs&Sqrt); assign DivInvalid = ((XInf & YInf) | (XZero & YZero))&~Sqrt | (Xs&Sqrt&~NaNIn&~XZero);
assign Invalid = SigNaN | (FmaInvalid&FmaOp) | (DivInvalid&DivOp); assign Invalid = SigNaN | (FmaInvalid&FmaOp) | (DivInvalid&DivOp);

View File

@ -147,9 +147,9 @@ endmodule
module sotfc4( module sotfc4(
input logic [3:0] s, input logic [3:0] s,
input logic Sqrt, input logic Sqrt,
input logic [`DIVLEN+3:0] S, SM, input logic [`DIVb+3:0] S, SM,
input logic [`DIVLEN+3:0] C, input logic [`DIVb+3:0] C,
output logic [`DIVLEN+3:0] SNext, SMNext output logic [`DIVb+3:0] SNext, SMNext
); );
// The on-the-fly converter transfers the square root // The on-the-fly converter transfers the square root
// bits to the quotient as they come. // bits to the quotient as they come.

View File

@ -31,11 +31,11 @@
`include "wally-config.vh" `include "wally-config.vh"
module qsel2 ( // *** eventually just change to 4 bits module qsel2 ( // *** eventually just change to 4 bits
input logic [`DIVLEN+3:`DIVLEN] ps, pc, input logic [3:0] ps, pc,
output logic qp, qz//, qn output logic qp, qz//, qn
); );
logic [`DIVLEN+3:`DIVLEN] p, g; logic [3:0] p, g;
logic magnitude, sign, cout; logic magnitude, sign, cout;
// The quotient selection logic is presented for simplicity, not // The quotient selection logic is presented for simplicity, not
@ -46,9 +46,9 @@ module qsel2 ( // *** eventually just change to 4 bits
assign p = ps ^ pc; assign p = ps ^ pc;
assign g = ps & pc; assign g = ps & pc;
assign magnitude = ~(&p[`DIVLEN+2:`DIVLEN]); assign magnitude = ~(&p[2:0]);
assign cout = g[`DIVLEN+2] | (p[`DIVLEN+2] & (g[`DIVLEN+1] | p[`DIVLEN+1] & g[`DIVLEN])); assign cout = g[2] | (p[2] & (g[1] | p[1] & g[0]));
assign sign = p[`DIVLEN+3] ^ cout; assign sign = p[3] ^ cout;
/* assign #1 magnitude = ~((ps[54]^pc[54]) & (ps[53]^pc[53]) & /* assign #1 magnitude = ~((ps[54]^pc[54]) & (ps[53]^pc[53]) &
(ps[52]^pc[52])); (ps[52]^pc[52]));
assign #1 sign = (ps[55]^pc[55])^ assign #1 sign = (ps[55]^pc[55])^
@ -80,7 +80,7 @@ module fgen2 (
// Generate for both positive and negative bits // Generate for both positive and negative bits
assign FP = ~(SExt << 1) & CExt; assign FP = ~(SExt << 1) & CExt;
assign FN = (SMExt << 1) | (CExt & (~CExt << 2)); assign FN = (SMExt << 1) | (CExt & ~(CExt << 2));
assign FZ = '0; assign FZ = '0;
// Choose which adder input will be used // Choose which adder input will be used
@ -172,10 +172,10 @@ endmodule
//////////////////////////////////// ////////////////////////////////////
module fgen4 ( module fgen4 (
input logic [3:0] s, input logic [3:0] s,
input logic [`DIVLEN+3:0] C, S, SM, input logic [`DIVb+3:0] C, S, SM,
output logic [`DIVLEN+3:0] F output logic [`DIVb+3:0] F
); );
logic [`DIVLEN+3:0] F2, F1, F0, FN1, FN2; logic [`DIVb+3:0] F2, F1, F0, FN1, FN2;
// Generate for both positive and negative bits // Generate for both positive and negative bits
assign F2 = (~S << 2) & (C << 2); assign F2 = (~S << 2) & (C << 2);

View File

@ -36,7 +36,8 @@ module srt(
input logic DivBusy, input logic DivBusy,
input logic [`NE-1:0] Xe, Ye, input logic [`NE-1:0] Xe, Ye,
input logic XZeroE, YZeroE, input logic XZeroE, YZeroE,
input logic Sqrt, input logic SqrtE,
input logic SqrtM,
input logic [`DIVb:0] X, input logic [`DIVb:0] X,
input logic [`DIVN-2:0] Dpreproc, input logic [`DIVN-2:0] Dpreproc,
input logic NegSticky, input logic NegSticky,
@ -95,21 +96,14 @@ module srt(
end end
// mux2 #(`DIVb+4) wsmux(NextWSN, {{3{Sqrt}}, X}, DivStart, WSN); //*** modified for sqrt which doesnt work // mux2 #(`DIVb+4) wsmux(NextWSN, {3'b0, X}, DivStart, WSN);
// flopen #(`DIVb+4) wsflop(clk, DivStart|DivBusy, WSN, WS[0]); mux2 #(`DIVb+4) wsmux(NextWSN, {{3{SqrtE&~XZeroE}}, X}, DivStart, WSN);
// mux2 #(`DIVb+4) wcmux(NextWCN, '0, DivStart, WCN);
// flopen #(`DIVb+4) wcflop(clk, DivStart|DivBusy, WCN, WC[0]);
// flopen #(`DIVN-1) dflop(clk, DivStart, Dpreproc, D);
// mux2 #(`DIVb) Cmux(NextC, {Sqrt, {(`DIVb-1){1'b0}}}, DivStart, CMux);
// flop #(`DIVb) cflop(clk, CMux, C[0]);
mux2 #(`DIVb+4) wsmux(NextWSN, {3'b0, X}, DivStart, WSN);
flopen #(`DIVb+4) wsflop(clk, DivStart|DivBusy, WSN, WS[0]); flopen #(`DIVb+4) wsflop(clk, DivStart|DivBusy, WSN, WS[0]);
mux2 #(`DIVb+4) wcmux(NextWCN, '0, DivStart, WCN); mux2 #(`DIVb+4) wcmux(NextWCN, '0, DivStart, WCN);
flopen #(`DIVb+4) wcflop(clk, DivStart|DivBusy, WCN, WC[0]); flopen #(`DIVb+4) wcflop(clk, DivStart|DivBusy, WCN, WC[0]);
flopen #(`DIVN-1) dflop(clk, DivStart, Dpreproc, D); flopen #(`DIVN-1) dflop(clk, DivStart, Dpreproc, D);
mux2 #(`DIVb) Cmux({2'b11, C[`DIVCOPIES-1][`DIVb-1:2]}, {Sqrt, {(`DIVb-1){1'b0}}}, DivStart, CMux); mux2 #(`DIVb) Cmux(NextC, {1'b1, {(`DIVb-1){1'b0}}}, DivStart, CMux);
flop #(`DIVb) cflop(clk, CMux, C[0]); flopen #(`DIVb) cflop(clk, DivStart|DivBusy, CMux, C[0]);
// Divisor Selections // Divisor Selections
// - choose the negitive version of what's being selected // - choose the negitive version of what's being selected
@ -123,7 +117,7 @@ module srt(
genvar i; genvar i;
generate generate
for(i=0; $unsigned(i)<`DIVCOPIES; i++) begin : interations for(i=0; $unsigned(i)<`DIVCOPIES; i++) begin : interations
divinteration divinteration(.D, .DBar, .D2, .DBar2, .Sqrt, divinteration divinteration(.D, .DBar, .D2, .DBar2, .SqrtM,
.WS(WS[i]), .WC(WC[i]), .WSA(WSA[i]), .WCA(WCA[i]), .Q(Q[i]), .QM(QM[i]), .QNext(QNext[i]), .QMNext(QMNext[i]), .WS(WS[i]), .WC(WC[i]), .WSA(WSA[i]), .WCA(WCA[i]), .Q(Q[i]), .QM(QM[i]), .QNext(QNext[i]), .QMNext(QMNext[i]),
.C(C[i]), .S(S[i]), .SM(SM[i]), .SNext(SNext[i]), .SMNext(SMNext[i])); .C(C[i]), .S(S[i]), .SM(SM[i]), .SNext(SNext[i]), .SMNext(SMNext[i]));
if(i<(`DIVCOPIES-1)) begin if(i<(`DIVCOPIES-1)) begin
@ -151,11 +145,11 @@ module srt(
flopen #(`DIVb+1) QMreg(clk, DivBusy, QMMux, QM[0]); flopen #(`DIVb+1) QMreg(clk, DivBusy, QMMux, QM[0]);
flopr #(`DIVb+1) SMreg(clk, DivStart, SMNext[`DIVCOPIES-1], SM[0]); flopr #(`DIVb+1) SMreg(clk, DivStart, SMNext[`DIVCOPIES-1], SM[0]);
mux2 #(`DIVb+1) Smux(SNext[`DIVCOPIES-1], {Sqrt, {(`DIVb){1'b0}}}, DivStart, SMux); mux2 #(`DIVb+1) Smux(SNext[`DIVCOPIES-1], {SqrtM, {(`DIVb){1'b0}}}, DivStart, SMux);
flop #(`DIVb+1) Sreg(clk, SMux, S[0]); flop #(`DIVb+1) Sreg(clk, SMux, S[0]);
// division takes the result from the next cycle, which is shifted to the left one more time so the square root also needs to be shifted // division takes the result from the next cycle, which is shifted to the left one more time so the square root also needs to be shifted
always_comb always_comb
if(Sqrt) // sqrt ouputs in the range (1, .5] if(SqrtM) // sqrt ouputs in the range (1, .5]
if(NegSticky) Qm = {SM[0][`DIVb-1-(`RADIX/4):0], 1'b0}; if(NegSticky) Qm = {SM[0][`DIVb-1-(`RADIX/4):0], 1'b0};
else Qm = {S[0][`DIVb-1-(`RADIX/4):0], 1'b0}; else Qm = {S[0][`DIVb-1-(`RADIX/4):0], 1'b0};
else else
@ -186,7 +180,7 @@ module divinteration (
input logic [`DIVb:0] S, SM, input logic [`DIVb:0] S, SM,
input logic [`DIVb+3:0] WS, WC, input logic [`DIVb+3:0] WS, WC,
input logic [`DIVb-1:0] C, input logic [`DIVb-1:0] C,
input logic Sqrt, input logic SqrtM,
output logic [`DIVb:0] QNext, QMNext, output logic [`DIVb:0] QNext, QMNext,
output logic [`DIVb:0] SNext, SMNext, output logic [`DIVb:0] SNext, SMNext,
output logic [`DIVb+3:0] WSA, WCA output logic [`DIVb+3:0] WSA, WCA
@ -211,7 +205,7 @@ module divinteration (
qsel2 qsel2(WS[`DIVb+3:`DIVb], WC[`DIVb+3:`DIVb], qp, qz); qsel2 qsel2(WS[`DIVb+3:`DIVb], WC[`DIVb+3:`DIVb], qp, qz);
fgen2 fgen2(.sp(qp), .sz(qz), .C, .S, .SM, .F); fgen2 fgen2(.sp(qp), .sz(qz), .C, .S, .SM, .F);
end else begin end else begin
qsel4 qsel4(.D, .WS, .WC, .Sqrt, .q); qsel4 qsel4(.D, .WS, .WC, .Sqrt(SqrtM), .q);
// fgen4 fgen4(.s(q), .C, .S, .SM, .F); // fgen4 fgen4(.s(q), .C, .S, .SM, .F);
end end
@ -230,11 +224,11 @@ module divinteration (
end end
// Partial Product Generation // Partial Product Generation
// WSA, WCA = WS + WC - qD // WSA, WCA = WS + WC - qD
assign AddIn = Sqrt ? F : Dsel; assign AddIn = SqrtM ? F : Dsel;
if (`RADIX == 2) begin : csa if (`RADIX == 2) begin : csa
csa #(`DIVb+4) csa(WS, WC, AddIn, qp&~Sqrt, WSA, WCA); csa #(`DIVb+4) csa(WS, WC, AddIn, qp&~SqrtM, WSA, WCA);
end else begin end else begin
csa #(`DIVb+4) csa(WS, WC, AddIn, |q[3:2]&~Sqrt, WSA, WCA); csa #(`DIVb+4) csa(WS, WC, AddIn, |q[3:2]&~SqrtM, WSA, WCA);
end end
if (`RADIX == 2) begin : otfc if (`RADIX == 2) begin : otfc
@ -242,7 +236,7 @@ module divinteration (
sotfc2 sotfc2(.sp(qp), .sz(qz), .C, .S, .SM, .SNext, .SMNext); sotfc2 sotfc2(.sp(qp), .sz(qz), .C, .S, .SM, .SNext, .SMNext);
end else begin end else begin
otfc4 otfc4(.q, .Q, .QM, .QNext, .QMNext); otfc4 otfc4(.q, .Q, .QM, .QNext, .QMNext);
// sotfc4 sotfc4(.s(q), .Sqrt, .C, .S, .SM, .SNext, .SMNext); // sotfc4 sotfc4(.s(q), .SqrtM, .C, .S, .SM, .SNext, .SMNext);
end end
endmodule endmodule

View File

@ -85,10 +85,6 @@ module testbenchfp;
logic [`DURLEN-1:0] EarlyTermShift; logic [`DURLEN-1:0] EarlyTermShift;
logic DivStart, DivBusy; logic DivStart, DivBusy;
logic reset = 1'b0; logic reset = 1'b0;
logic [`DIVLEN-1:0] DivX;
logic [`DIVLEN-1:0] Dpreproc;
logic [`DIVLEN+3:0] NextWSN, WS;
logic [`DIVLEN+3:0] NextWCN, WC;
logic [$clog2(`NF+2)-1:0] XZeroCnt, YZeroCnt; logic [$clog2(`NF+2)-1:0] XZeroCnt, YZeroCnt;
logic [`DURLEN-1:0] Dur; logic [`DURLEN-1:0] Dur;