mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
Renamed variables, moved output handling to postprocessor, added remainder handling
This commit is contained in:
parent
a17361870f
commit
abe1ff906e
Binary file not shown.
@ -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
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user