From abe1ff906eb9d7ba7bcc67a2b4171d94a2930569 Mon Sep 17 00:00:00 2001 From: cturek Date: Thu, 21 Jul 2022 20:45:08 +0000 Subject: [PATCH] Renamed variables, moved output handling to postprocessor, added remainder handling --- pipelined/srt/sqrttestgen | Bin 22792 -> 22792 bytes pipelined/srt/srt.sv | 100 +++++++++++++++++++++++++++++-------- pipelined/srt/testbench.sv | 10 ++-- 3 files changed, 85 insertions(+), 25 deletions(-) diff --git a/pipelined/srt/sqrttestgen b/pipelined/srt/sqrttestgen index 06615165395cb6abb37c9d60152d5fe70f15e11a..d2cb80d445718cfa8efc5daa24fefc6b5d462149 100755 GIT binary patch delta 695 zcmXxiO=uHA6ae6PsoR()?atZ;R#1#kNU;Y?6~!LxR$N>x6e;8qJj5P~^8llk64tG4?8ZfL&qtv#acVY(I2f8`~B(tn-8&JVB^% zLv8Hs>7 zZo0!)K%q3#VTtNPnpg^0EzqcJH-al(U&QYCp+v(e(*50h`-IMcWAT14@lJdYhTV_x zS%6{8wr4@O&)OwKzBjPkaU>cP3sJ|YK8;uPk)hllrHb?=Rafc)P0_QC=V$eJPOpa(G7U#@UhaWGd`dBa z?w9-@{Yv3#VQdkGFkP@FH8_nI?P>7bbvv)a aS)9o1k8M?W_#ksQW=gABWV&B6>6T65Z3JZi delta 715 zcmXw%L1+^}6o%(DjY&w8oduP8uw6xMwP1rvN=3~IUEPx+nj*a^9-sd^$XE8 z%=wj`)&Wn)BW^HXVD^~LF|RS7VgACLXWn2w%G_c;#N6rWN_gN9FZi6Wn_1}SLRsb{ z^A2Xo+~WrfGXG_^n13^mGXG@G=_^_{9bdfQR-KOf=zd4s9d#ea z7j{{~t$uuefO@(LB=rYD;!8@b2iTgYS<~4HTHbzxRyv>jG3NMPk2NOma_G8&7p1r!Mb&bjm`dZJDyX14^J@N+m zFrBzTKJZU#L3daux5$&!L!0~_X5`r6S5#%3vcyzEO0pb{541)N3?q2Z6pa0u{$5Y!oJbYc8NLkVjH(Ba?aU}L1h0y`7 diff --git a/pipelined/srt/srt.sv b/pipelined/srt/srt.sv index a7216b9f..7cbcd0da 100644 --- a/pipelined/srt/srt.sv +++ b/pipelined/srt/srt.sv @@ -35,33 +35,35 @@ module srt ( input logic Start, input logic Stall, // *** multiple pipe stages input logic Flush, // *** multiple pipe stages - // Floating Point Inputs - // later add exponents, signs, special cases + // Floating Point input logic XSign, YSign, input logic [`NE-1:0] XExp, YExp, input logic [`NF-1:0] SrcXFrac, SrcYFrac, + // Integer input logic [`XLEN-1:0] SrcA, SrcB, + // Customization input logic [1:0] Fmt, // Floats: 00 = 16 bit, 01 = 32 bit, 10 = 64 bit, 11 = 128 bit input logic W64, // 32-bit ints on XLEN=64 + // Selection input logic Signed, // Interpret integers as signed 2's complement input logic Int, // Choose integer inputs input logic Sqrt, // perform square root, not divide output logic rsign, done, - output logic [`DIVLEN-2:0] Rem, Quot, // *** later handle integers + output logic [`DIVLEN-1:0] Rem, Result, output logic [`NE-1:0] rExp, output logic [3:0] Flags ); - logic qp, qz, qn; // quotient is +1, 0, or -1 + logic qp, qz, qn; // result bits are +1, 0, or -1 logic [`NE-1:0] calcExp; logic calcSign; logic [`DIVLEN+3:0] X, Dpreproc, C, F, S, SM, AddIn; logic [`DIVLEN+3:0] WS, WSA, WSN, WC, WCA, WCN, D, Db, Dsel; - logic [$clog2(`XLEN+1)-1:0] intExp, dur, calcDur; + logic [$clog2(`XLEN+1)-1:0] zeroCntD, intExp, dur, calcDur; logic intSign; logic cin; - srtpreproc preproc(SrcA, SrcB, SrcXFrac, SrcYFrac, XExp, Fmt, W64, Signed, Int, Sqrt, X, Dpreproc, intExp, calcDur, intSign); + srtpreproc preproc(SrcA, SrcB, SrcXFrac, SrcYFrac, XExp, Fmt, W64, Signed, Int, Sqrt, X, Dpreproc, zeroCntD, intExp, calcDur, intSign); // Top Muxes and Registers // When start is asserted, the inputs are loaded into the divider. @@ -91,7 +93,7 @@ module srt ( // otfc2 #(`DIVLEN) otfc2(clk, Start, qp, qz, qn, Quot); // otherwise use sotfc creg sotfcC(clk, Start, Sqrt, C); - sotfc2 sotfc2(clk, Start, qp, qn, Sqrt, C, Quot, S, SM); + sotfc2 sotfc2(clk, Start, qp, qn, Sqrt, C, S, SM); fsel2 fsel(qp, qn, C, S, SM, F); // Adder input selection @@ -103,7 +105,7 @@ module srt ( expcalc expcalc(.XExp, .YExp, .calcExp, .Sqrt); - signcalc signcalc(.XSign, .YSign, .calcSign); + srtpostproc postproc(.WS, .WC, .X, .D, .S, .SM, .dur, .zeroCntD, .XSign, .YSign, .Signed, .Int, .Result, .Rem, .calcSign); endmodule //////////////// @@ -123,11 +125,11 @@ module srtpreproc ( input logic Int, // Choose integer inputs input logic Sqrt, // perform square root, not divide output logic [`DIVLEN+3:0] X, D, - output logic [$clog2(`XLEN+1)-1:0] intExp, dur, // Quotient integer exponent + output logic [$clog2(`XLEN+1)-1:0] zeroCntB, intExp, dur, // Quotient integer exponent output logic intSign // Quotient integer sign ); - logic [$clog2(`XLEN+1)-1:0] zeroCntA, zeroCntB; + logic [$clog2(`XLEN+1)-1:0] zeroCntA; logic [`XLEN-1:0] PosA, PosB; logic [`DIVLEN-1:0] ExtraA, ExtraB, PreprocA, PreprocB, PreprocX, PreprocY, DivX; logic [`NF+4:0] SqrtX; @@ -235,7 +237,7 @@ module otfc2 #(parameter N=66) ( input logic clk, input logic Start, input logic qp, qz, qn, - output logic [N-3:0] r + output logic [N-3:0] Result ); // The on-the-fly converter transfers the quotient // bits to the quotient as they come. @@ -261,7 +263,7 @@ module otfc2 #(parameter N=66) ( QMNext = {QMR, 1'b0}; end end - assign r = Q[N] ? Q[N-1:2] : Q[N-2:1]; + assign Result = Q[N] ? Q[N-1:2] : Q[N-2:1]; endmodule @@ -274,7 +276,6 @@ module sotfc2( input logic sp, sn, input logic Sqrt, input logic [`DIVLEN+3:0] C, - output logic [`DIVLEN-2:0] Sq, output logic [`DIVLEN+3:0] S, SM ); // The on-the-fly converter transfers the square root @@ -298,7 +299,6 @@ module sotfc2( SMNext = SM | (C & ~(C << 1)); end end - assign Sq = S[`DIVLEN] ? S[`DIVLEN-1:1] : S[`DIVLEN-2:0]; endmodule ////////////////////////// @@ -395,14 +395,74 @@ module expcalc( endmodule -////////////// -// signcalc // -////////////// -module signcalc( - input logic XSign, YSign, +module srtpostproc( + input logic [`DIVLEN+3:0] WS, WC, X, D, S, SM, + input logic [$clog2(`XLEN+1)-1:0] dur, zeroCntD, + input logic XSign, YSign, Signed, Int, + output logic [`DIVLEN-1:0] Result, Rem, output logic calcSign ); + logic [`DIVLEN+3:0] W, shiftRem, intRem, intS; + logic [`DIVLEN-1:0] floatRes, intRes; + logic WSign; + assign W = WS + WC; + assign WSign = W[`DIVLEN+3]; + // Remainder handling + always_comb begin + if (zeroCntD == ($clog2(`XLEN+1))'(`XLEN)) begin + intRem = X; + intS = -1; + end + else if (~Signed) begin + if (WSign) begin + intRem = W + D; + intS = SM; + end else begin + intRem = W; + intS = S; + end + end + else case ({YSign, XSign, WSign}) + 3'b000: begin + intRem = W; + intS = S; + end + 3'b001: begin + intRem = W + D; + intS = SM; + end + 3'b010: begin + intRem = W - D; + intS = ~S; + end + 3'b011: begin + intRem = W; + intS = ~SM; + end + 3'b100: begin + intRem = W; + intS = ~SM; + end + 3'b101: begin + intRem = W + D; + intS = ~SM + 1; + end + 3'b110: begin + intRem = W - D; + intS = S + 1; + end + 3'b111: begin + intRem = W; + intS = S; + end + endcase + end + assign floatRes = S[`DIVLEN] ? S[`DIVLEN:1] : S[`DIVLEN-1:0]; + assign intRes = intS[`DIVLEN] ? intS[`DIVLEN:1] : intS[`DIVLEN-1:0]; + assign Result = Int ? intRes : floatRes; assign calcSign = XSign ^ YSign; + assign shiftRem = intRem >>> dur; + assign Rem = shiftRem[`DIVLEN-1:0]; +endmodule -endmodule \ No newline at end of file diff --git a/pipelined/srt/testbench.sv b/pipelined/srt/testbench.sv index 7a4e1897..b72ffb42 100644 --- a/pipelined/srt/testbench.sv +++ b/pipelined/srt/testbench.sv @@ -49,7 +49,7 @@ module testbench; logic asign, bsign; logic [`NF-1:0] r; logic [`XLEN-1:0] rInt; - logic [`DIVLEN-2:0] Quot; + logic [`DIVLEN-1:0] Quot, Rem; // Test parameters parameter MEM_SIZE = 40000; @@ -72,7 +72,7 @@ module testbench; // Equip Int test or Sqrt test assign Int = 1'b0; - assign Sqrt = 1'b0; + assign Sqrt = 1'b1; // Divider srt srt(.clk, .Start(req), @@ -82,7 +82,7 @@ module testbench; .SrcXFrac(afrac), .SrcYFrac(bfrac), .SrcA(a), .SrcB(b), .Fmt(2'b00), .W64(1'b1), .Signed(1'b0), .Int, .Sqrt, - .Quot, .Rem(), .Flags(), .done); + .Result(Quot), .Rem, .Flags(), .done); // Counter // counter counter(clk, req, done); @@ -101,7 +101,7 @@ module testbench; begin testnum = 0; errors = 0; - $readmemh ("testvectors", Tests); + $readmemh ("sqrttestvectors", Tests); Vec = Tests[testnum]; a = Vec[`mema]; {asign, aExp, afrac} = a; @@ -117,7 +117,7 @@ module testbench; always @(posedge clk) begin r = Quot[(`DIVLEN - 2):(`DIVLEN - `NF - 1)]; - rInt = {1'b1, Quot}; + rInt = Quot; if (done) begin if (~Int & ~Sqrt) begin req <= #5 1;