From 7fc53226acbf740c0fc94ef7fbff450cace3922d Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Wed, 24 May 2023 15:01:35 -0500 Subject: [PATCH] MDU and hazard unit now also parameterized. Based on Lim's work. Again I want to clarify this their work. Not mine. I'm just doing this because the merge had an issue. --- src/hazard/hazard.sv | 2 - src/mdu/div.sv | 70 ++++++++++++++++----------------- src/mdu/mdu.sv | 34 ++++++++-------- src/mdu/mul.sv | 44 ++++++++++----------- src/wally/wallypipelinedcore.sv | 2 +- 5 files changed, 72 insertions(+), 80 deletions(-) diff --git a/src/hazard/hazard.sv b/src/hazard/hazard.sv index 51f2ccf40..8efa454d9 100644 --- a/src/hazard/hazard.sv +++ b/src/hazard/hazard.sv @@ -26,8 +26,6 @@ // and limitations under the License. //////////////////////////////////////////////////////////////////////////////////////////////// -`include "wally-config.vh" - module hazard ( // Detect hazards input logic BPWrongE, CSRWriteFenceM, RetM, TrapM, diff --git a/src/mdu/div.sv b/src/mdu/div.sv index 848760032..a05e88f6d 100644 --- a/src/mdu/div.sv +++ b/src/mdu/div.sv @@ -26,9 +26,7 @@ // and limitations under the License. //////////////////////////////////////////////////////////////////////////////////////////////// -`include "wally-config.vh" - -module div( +module div import cvw::*; #(parameter cvw_t P) ( input logic clk, input logic reset, input logic StallM, @@ -36,26 +34,26 @@ module div( input logic IntDivE, // integer division/remainder instruction of any type input logic DivSignedE, // signed division input logic W64E, // W-type instructions (divw, divuw, remw, remuw) - input logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE,// Forwarding mux outputs for Source A and B + input logic [P.XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE,// Forwarding mux outputs for Source A and B output logic DivBusyE, // Divide is busy - stall pipeline - output logic [`XLEN-1:0] QuotM, RemM // Quotient and remainder outputs + output logic [P.XLEN-1:0] QuotM, RemM // Quotient and remainder outputs ); - localparam STEPBITS = $clog2(`XLEN/`IDIV_BITSPERCYCLE); // Number of steps + localparam STEPBITS = $clog2(P.XLEN/P.IDIV_BITSPERCYCLE); // Number of steps typedef enum logic [1:0] {IDLE, BUSY, DONE} statetype; // division FSM state statetype state; - logic [`XLEN-1:0] W[`IDIV_BITSPERCYCLE:0]; // Residual for each of k steps - logic [`XLEN-1:0] XQ[`IDIV_BITSPERCYCLE:0]; // dividend/quotient for each of k steps - logic [`XLEN-1:0] WNext, XQNext; // initialized W and XQ going into registers - logic [`XLEN-1:0] DinE, XinE; // divisor & dividend, possibly truncated to 32 bits - logic [`XLEN-1:0] DnE; // DnE = ~DinE - logic [`XLEN-1:0] DAbsBE; // absolute value of D - logic [`XLEN-1:0] DAbsB; // registered absolute value of D, constant during division - logic [`XLEN-1:0] XnE; // DXnE = ~XinE - logic [`XLEN-1:0] XInitE; // |X|, or original X for divide by 0 - logic [`XLEN-1:0] WnM, XQnM; // negated residual W and quotient XQ for postprocessing sign correction + logic [P.XLEN-1:0] W[P.IDIV_BITSPERCYCLE:0]; // Residual for each of k steps + logic [P.XLEN-1:0] XQ[P.IDIV_BITSPERCYCLE:0]; // dividend/quotient for each of k steps + logic [P.XLEN-1:0] WNext, XQNext; // initialized W and XQ going into registers + logic [P.XLEN-1:0] DinE, XinE; // divisor & dividend, possibly truncated to 32 bits + logic [P.XLEN-1:0] DnE; // DnE = ~DinE + logic [P.XLEN-1:0] DAbsBE; // absolute value of D + logic [P.XLEN-1:0] DAbsB; // registered absolute value of D, constant during division + logic [P.XLEN-1:0] XnE; // DXnE = ~XinE + logic [P.XLEN-1:0] XInitE; // |X|, or original X for divide by 0 + logic [P.XLEN-1:0] WnM, XQnM; // negated residual W and quotient XQ for postprocessing sign correction logic [STEPBITS:0] step; // division step logic Div0E, Div0M; // divide by 0 logic DivStartE; // start integer division @@ -71,42 +69,42 @@ module div( assign DivBusyE = (state == BUSY) | DivStartE; // Handle sign extension for W-type instructions - if (`XLEN == 64) begin:rv64 // RV64 has W-type instructions - mux2 #(`XLEN) xinmux(ForwardedSrcAE, {ForwardedSrcAE[31:0], 32'b0}, W64E, XinE); - mux2 #(`XLEN) dinmux(ForwardedSrcBE, {{32{ForwardedSrcBE[31]&DivSignedE}}, ForwardedSrcBE[31:0]}, W64E, DinE); + if (P.XLEN == 64) begin:rv64 // RV64 has W-type instructions + mux2 #(P.XLEN) xinmux(ForwardedSrcAE, {ForwardedSrcAE[31:0], 32'b0}, W64E, XinE); + mux2 #(P.XLEN) dinmux(ForwardedSrcBE, {{32{ForwardedSrcBE[31]&DivSignedE}}, ForwardedSrcBE[31:0]}, W64E, DinE); end else begin // RV32 has no W-type instructions assign XinE = ForwardedSrcAE; assign DinE = ForwardedSrcBE; end // Extract sign bits and check fo division by zero - assign SignDE = DivSignedE & DinE[`XLEN-1]; - assign SignXE = DivSignedE & XinE[`XLEN-1]; + assign SignDE = DivSignedE & DinE[P.XLEN-1]; + assign SignXE = DivSignedE & XinE[P.XLEN-1]; assign NegQE = SignDE ^ SignXE; assign Div0E = (DinE == 0); // Take absolute value for signed operations, and negate D to handle subtraction in divider stages - neg #(`XLEN) negd(DinE, DnE); - mux2 #(`XLEN) dabsmux(DnE, DinE, SignDE, DAbsBE); // take absolute value for signed operations, and negate for subtraction setp - neg #(`XLEN) negx(XinE, XnE); - mux3 #(`XLEN) xabsmux(XinE, XnE, ForwardedSrcAE, {Div0E, SignXE}, XInitE); // take absolute value for signed operations, or keep original value for divide by 0 + neg #(P.XLEN) negd(DinE, DnE); + mux2 #(P.XLEN) dabsmux(DnE, DinE, SignDE, DAbsBE); // take absolute value for signed operations, and negate for subtraction setp + neg #(P.XLEN) negx(XinE, XnE); + mux3 #(P.XLEN) xabsmux(XinE, XnE, ForwardedSrcAE, {Div0E, SignXE}, XInitE); // take absolute value for signed operations, or keep original value for divide by 0 ////////////////////////////// // Division Iterations (effectively stalled execute stage, no suffix) ////////////////////////////// // initialization multiplexers on first cycle of operation - mux2 #(`XLEN) wmux(W[`IDIV_BITSPERCYCLE], {`XLEN{1'b0}}, DivStartE, WNext); - mux2 #(`XLEN) xmux(XQ[`IDIV_BITSPERCYCLE], XInitE, DivStartE, XQNext); + mux2 #(P.XLEN) wmux(W[P.IDIV_BITSPERCYCLE], {P.XLEN{1'b0}}, DivStartE, WNext); + mux2 #(P.XLEN) xmux(XQ[P.IDIV_BITSPERCYCLE], XInitE, DivStartE, XQNext); // registers before division steps - flopen #(`XLEN) wreg(clk, DivBusyE, WNext, W[0]); - flopen #(`XLEN) xreg(clk, DivBusyE, XQNext, XQ[0]); - flopen #(`XLEN) dabsreg(clk, DivStartE, DAbsBE, DAbsB); + flopen #(P.XLEN) wreg(clk, DivBusyE, WNext, W[0]); + flopen #(P.XLEN) xreg(clk, DivBusyE, XQNext, XQ[0]); + flopen #(P.XLEN) dabsreg(clk, DivStartE, DAbsBE, DAbsB); // one copy of divstep for each bit produced per cycle genvar i; - for (i=0; i<`IDIV_BITSPERCYCLE; i = i+1) + for (i=0; i