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

View File

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