Renamed variables, moved output handling to postprocessor, added remainder handling

This commit is contained in:
cturek 2022-07-21 20:45:08 +00:00
parent a17361870f
commit abe1ff906e
3 changed files with 85 additions and 25 deletions

Binary file not shown.

View File

@ -35,33 +35,35 @@ module srt (
input logic Start, input logic Start,
input logic Stall, // *** multiple pipe stages input logic Stall, // *** multiple pipe stages
input logic Flush, // *** multiple pipe stages input logic Flush, // *** multiple pipe stages
// Floating Point Inputs // Floating Point
// later add exponents, signs, special cases
input logic XSign, YSign, input logic XSign, YSign,
input logic [`NE-1:0] XExp, YExp, input logic [`NE-1:0] XExp, YExp,
input logic [`NF-1:0] SrcXFrac, SrcYFrac, input logic [`NF-1:0] SrcXFrac, SrcYFrac,
// Integer
input logic [`XLEN-1:0] SrcA, SrcB, 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 [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 input logic W64, // 32-bit ints on XLEN=64
// Selection
input logic Signed, // Interpret integers as signed 2's complement input logic Signed, // Interpret integers as signed 2's complement
input logic Int, // Choose integer inputs input logic Int, // Choose integer inputs
input logic Sqrt, // perform square root, not divide input logic Sqrt, // perform square root, not divide
output logic rsign, done, 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 [`NE-1:0] rExp,
output logic [3:0] Flags 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 [`NE-1:0] calcExp;
logic calcSign; logic calcSign;
logic [`DIVLEN+3:0] X, Dpreproc, C, F, S, SM, AddIn; 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 [`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 intSign;
logic cin; 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 // Top Muxes and Registers
// When start is asserted, the inputs are loaded into the divider. // 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); // otfc2 #(`DIVLEN) otfc2(clk, Start, qp, qz, qn, Quot);
// otherwise use sotfc // otherwise use sotfc
creg sotfcC(clk, Start, Sqrt, C); 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); fsel2 fsel(qp, qn, C, S, SM, F);
// Adder input selection // Adder input selection
@ -103,7 +105,7 @@ module srt (
expcalc expcalc(.XExp, .YExp, .calcExp, .Sqrt); 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 endmodule
//////////////// ////////////////
@ -123,11 +125,11 @@ module srtpreproc (
input logic Int, // Choose integer inputs input logic Int, // Choose integer inputs
input logic Sqrt, // perform square root, not divide input logic Sqrt, // perform square root, not divide
output logic [`DIVLEN+3:0] X, D, 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 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 [`XLEN-1:0] PosA, PosB;
logic [`DIVLEN-1:0] ExtraA, ExtraB, PreprocA, PreprocB, PreprocX, PreprocY, DivX; logic [`DIVLEN-1:0] ExtraA, ExtraB, PreprocA, PreprocB, PreprocX, PreprocY, DivX;
logic [`NF+4:0] SqrtX; logic [`NF+4:0] SqrtX;
@ -235,7 +237,7 @@ module otfc2 #(parameter N=66) (
input logic clk, input logic clk,
input logic Start, input logic Start,
input logic qp, qz, qn, 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 // The on-the-fly converter transfers the quotient
// bits to the quotient as they come. // bits to the quotient as they come.
@ -261,7 +263,7 @@ module otfc2 #(parameter N=66) (
QMNext = {QMR, 1'b0}; QMNext = {QMR, 1'b0};
end end
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 endmodule
@ -274,7 +276,6 @@ module sotfc2(
input logic sp, sn, input logic sp, sn,
input logic Sqrt, input logic Sqrt,
input logic [`DIVLEN+3:0] C, input logic [`DIVLEN+3:0] C,
output logic [`DIVLEN-2:0] Sq,
output logic [`DIVLEN+3:0] S, SM output logic [`DIVLEN+3:0] S, SM
); );
// The on-the-fly converter transfers the square root // The on-the-fly converter transfers the square root
@ -298,7 +299,6 @@ module sotfc2(
SMNext = SM | (C & ~(C << 1)); SMNext = SM | (C & ~(C << 1));
end end
end end
assign Sq = S[`DIVLEN] ? S[`DIVLEN-1:1] : S[`DIVLEN-2:0];
endmodule endmodule
////////////////////////// //////////////////////////
@ -395,14 +395,74 @@ module expcalc(
endmodule endmodule
////////////// module srtpostproc(
// signcalc // input logic [`DIVLEN+3:0] WS, WC, X, D, S, SM,
////////////// input logic [$clog2(`XLEN+1)-1:0] dur, zeroCntD,
module signcalc( input logic XSign, YSign, Signed, Int,
input logic XSign, YSign, output logic [`DIVLEN-1:0] Result, Rem,
output logic calcSign 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 calcSign = XSign ^ YSign;
assign shiftRem = intRem >>> dur;
assign Rem = shiftRem[`DIVLEN-1:0];
endmodule endmodule

View File

@ -49,7 +49,7 @@ module testbench;
logic asign, bsign; logic asign, bsign;
logic [`NF-1:0] r; logic [`NF-1:0] r;
logic [`XLEN-1:0] rInt; logic [`XLEN-1:0] rInt;
logic [`DIVLEN-2:0] Quot; logic [`DIVLEN-1:0] Quot, Rem;
// Test parameters // Test parameters
parameter MEM_SIZE = 40000; parameter MEM_SIZE = 40000;
@ -72,7 +72,7 @@ module testbench;
// Equip Int test or Sqrt test // Equip Int test or Sqrt test
assign Int = 1'b0; assign Int = 1'b0;
assign Sqrt = 1'b0; assign Sqrt = 1'b1;
// Divider // Divider
srt srt(.clk, .Start(req), srt srt(.clk, .Start(req),
@ -82,7 +82,7 @@ module testbench;
.SrcXFrac(afrac), .SrcYFrac(bfrac), .SrcXFrac(afrac), .SrcYFrac(bfrac),
.SrcA(a), .SrcB(b), .Fmt(2'b00), .SrcA(a), .SrcB(b), .Fmt(2'b00),
.W64(1'b1), .Signed(1'b0), .Int, .Sqrt, .W64(1'b1), .Signed(1'b0), .Int, .Sqrt,
.Quot, .Rem(), .Flags(), .done); .Result(Quot), .Rem, .Flags(), .done);
// Counter // Counter
// counter counter(clk, req, done); // counter counter(clk, req, done);
@ -101,7 +101,7 @@ module testbench;
begin begin
testnum = 0; testnum = 0;
errors = 0; errors = 0;
$readmemh ("testvectors", Tests); $readmemh ("sqrttestvectors", Tests);
Vec = Tests[testnum]; Vec = Tests[testnum];
a = Vec[`mema]; a = Vec[`mema];
{asign, aExp, afrac} = a; {asign, aExp, afrac} = a;
@ -117,7 +117,7 @@ module testbench;
always @(posedge clk) begin always @(posedge clk) begin
r = Quot[(`DIVLEN - 2):(`DIVLEN - `NF - 1)]; r = Quot[(`DIVLEN - 2):(`DIVLEN - `NF - 1)];
rInt = {1'b1, Quot}; rInt = Quot;
if (done) begin if (done) begin
if (~Int & ~Sqrt) begin if (~Int & ~Sqrt) begin
req <= #5 1; req <= #5 1;