From 9d63aa683f7802a7fcb0589120f4f4450e24f4f9 Mon Sep 17 00:00:00 2001 From: David Harris Date: Sat, 2 Oct 2021 09:38:02 -0400 Subject: [PATCH] Moved muldiv result selection to M stage for performance --- wally-pipelined/src/muldiv/intdivrestoring.sv | 1 + wally-pipelined/src/muldiv/muldiv.sv | 55 +++++++++---------- 2 files changed, 26 insertions(+), 30 deletions(-) diff --git a/wally-pipelined/src/muldiv/intdivrestoring.sv b/wally-pipelined/src/muldiv/intdivrestoring.sv index 21e96c6e..ed78718c 100644 --- a/wally-pipelined/src/muldiv/intdivrestoring.sv +++ b/wally-pipelined/src/muldiv/intdivrestoring.sv @@ -59,6 +59,7 @@ module intdivrestoring ( assign DAbsB = ~Din; + // *** parameterize steps per cycle intdivrestoringstep step1(Win, XQin, DAbsB, W1, XQ1); intdivrestoringstep step2(W1, XQ1, DAbsB, W2, XQshift); diff --git a/wally-pipelined/src/muldiv/muldiv.sv b/wally-pipelined/src/muldiv/muldiv.sv index 43cfba80..03df97e7 100644 --- a/wally-pipelined/src/muldiv/muldiv.sv +++ b/wally-pipelined/src/muldiv/muldiv.sv @@ -31,7 +31,7 @@ module muldiv ( input logic [31:0] InstrD, // Execute Stage interface input logic [`XLEN-1:0] SrcAE, SrcBE, - input logic [2:0] Funct3E, + input logic [2:0] Funct3E, Funct3M, input logic MulDivE, W64E, // Writeback stage output logic [`XLEN-1:0] MulDivResultW, @@ -45,8 +45,8 @@ module muldiv ( generate if (`M_SUPPORTED) begin logic [`XLEN-1:0] MulDivResultE, MulDivResultM; - logic [`XLEN-1:0] PrelimResultE; - logic [`XLEN-1:0] QuotE, RemE; + logic [`XLEN-1:0] PrelimResultM; + logic [`XLEN-1:0] QuotM, RemM; logic [`XLEN*2-1:0] ProdE, ProdM; logic enable_q; @@ -57,7 +57,9 @@ module muldiv ( // logic gclk; logic startDivideE, busy; - logic signedDivide; + logic SignedDivideE; + logic W64M; + // Multiplier mul mul(.*); @@ -65,51 +67,44 @@ module muldiv ( // Divide - /*// *** replace this clock gater - always @(negedge clk) begin - enable_q <= ~StallM; - end - assign gclk = enable_q & clk; */ - // Handle sign extension for W-type instructions if (`XLEN == 64) begin // RV64 has W-type instructions - assign X = W64E ? {{32{SrcAE[31]&signedDivide}}, SrcAE[31:0]} : SrcAE; - assign D = W64E ? {{32{SrcBE[31]&signedDivide}}, SrcBE[31:0]} : SrcBE; + assign X = W64E ? {{32{SrcAE[31]&SignedDivideE}}, SrcAE[31:0]} : SrcAE; + assign D = W64E ? {{32{SrcBE[31]&SignedDivideE}}, SrcBE[31:0]} : SrcBE; end else begin // RV32 has no W-type instructions assign X = SrcAE; assign D = SrcBE; end - assign signedDivide = ~Funct3E[0]; // simplified from (Funct3E[2]&~Funct3E[1]&~Funct3E[0]) | (Funct3E[2]&Funct3E[1]&~Funct3E[0]); - //intdiv #(`XLEN) div (QuotE, RemE, DivDoneE, DivBusyE, div0error, N, D, gclk, reset, startDivideE, signedDivide); -// intdivrestoring div(.clk, .reset, .StallM, .signedDivide, .start(startDivideE), .X(X), .D(D), .busy(busy), .done(DivDoneE), .Q(QuotE), .REM(RemE)); - intdivrestoring div(.clk, .reset, .StallM, .signedDivide, .start(startDivideE), .X(X), .D(D), .busy(busy), .done(DivDoneE), .Q(QuotE), .REM(RemE)); + assign SignedDivideE = ~Funct3E[0]; // simplified from (Funct3E[2]&~Funct3E[1]&~Funct3E[0]) | (Funct3E[2]&Funct3E[1]&~Funct3E[0]); + //intdiv #(`XLEN) div (QuotE, RemE, DivDoneE, DivBusyE, div0error, N, D, gclk, reset, startDivideE, SignedDivideE); + intdivrestoring div(.clk, .reset, .StallM, .signedDivide(SignedDivideE), .start(startDivideE), .X(X), .D(D), .busy(busy), .done(DivDoneE), .Q(QuotM), .REM(RemM)); // Start a divide when a new division instruction is received and the divider isn't already busy or finishing - assign startDivideE = MulDivE & Funct3E[2] & ~busy & ~DivDoneE; + assign startDivideE = MulDivE & Funct3E[2] & ~busy & ~DivDoneE; // *** mabye DivDone should be M stage assign DivBusyE = startDivideE | busy; // Select result always_comb - case (Funct3E) - 3'b000: PrelimResultE = ProdE[`XLEN-1:0]; - 3'b001: PrelimResultE = ProdE[`XLEN*2-1:`XLEN]; - 3'b010: PrelimResultE = ProdE[`XLEN*2-1:`XLEN]; - 3'b011: PrelimResultE = ProdE[`XLEN*2-1:`XLEN]; - 3'b100: PrelimResultE = QuotE; - 3'b101: PrelimResultE = QuotE; - 3'b110: PrelimResultE = RemE; - 3'b111: PrelimResultE = RemE; - endcase // case (Funct3E) + case (Funct3M) + 3'b000: PrelimResultM = ProdM[`XLEN-1:0]; + 3'b001: PrelimResultM = ProdM[`XLEN*2-1:`XLEN]; + 3'b010: PrelimResultM = ProdM[`XLEN*2-1:`XLEN]; + 3'b011: PrelimResultM = ProdM[`XLEN*2-1:`XLEN]; + 3'b100: PrelimResultM = QuotM; + 3'b101: PrelimResultM = QuotM; + 3'b110: PrelimResultM = RemM; + 3'b111: PrelimResultM = RemM; + endcase // Handle sign extension for W-type instructions + flopenrc #(1) W64MReg(clk, reset, FlushM, ~StallM, W64E, W64M); if (`XLEN == 64) begin // RV64 has W-type instructions - assign MulDivResultE = W64E ? {{32{PrelimResultE[31]}}, PrelimResultE[31:0]} : PrelimResultE; + assign MulDivResultM = W64M ? {{32{PrelimResultM[31]}}, PrelimResultM[31:0]} : PrelimResultM; end else begin // RV32 has no W-type instructions - assign MulDivResultE = PrelimResultE; + assign MulDivResultM = PrelimResultM; end - flopenrc #(`XLEN) MulDivResultMReg(clk, reset, FlushM, ~StallM, MulDivResultE, MulDivResultM); // could let part of multiplication spill into Memory stage flopenrc #(`XLEN) MulDivResultWReg(clk, reset, FlushW, ~StallW, MulDivResultM, MulDivResultW); end else begin // no M instructions supported