mirror of
https://github.com/openhwgroup/cvw.git
synced 2025-04-23 13:27:16 -04:00
Fixed all tap/space issue in RTL.
This commit is contained in:
parent
b5a58502d0
commit
46b1bca4fc
68 changed files with 1561 additions and 1577 deletions
|
@ -31,53 +31,53 @@ module fctrl (
|
|||
input logic clk,
|
||||
input logic reset,
|
||||
// input control signals
|
||||
input logic StallE, StallM, StallW, // stall signals
|
||||
input logic FlushE, FlushM, FlushW, // flush signals
|
||||
input logic IntDivE, // is inteteger division
|
||||
input logic [2:0] FRM_REGW, // rounding mode from CSR
|
||||
input logic [1:0] STATUS_FS, // is FPU enabled?
|
||||
input logic FDivBusyE, // is the divider busy
|
||||
// intruction
|
||||
input logic [31:0] InstrD, // the full instruction
|
||||
input logic [6:0] Funct7D, // bits 31:25 of instruction - may contain percision
|
||||
input logic [6:0] OpD, // bits 6:0 of instruction
|
||||
input logic [4:0] Rs2D, // bits 24:20 of instruction
|
||||
input logic [2:0] Funct3D, Funct3E, // bits 14:12 of instruction - may contain rounding mode
|
||||
// input mux selections
|
||||
output logic XEnD, YEnD, ZEnD, // enable inputs
|
||||
output logic XEnE, YEnE, ZEnE, // enable inputs
|
||||
// opperation mux selections
|
||||
output logic FCvtIntE, FCvtIntW, // convert to integer opperation
|
||||
output logic [2:0] FrmM, // FP rounding mode
|
||||
output logic [`FMTBITS-1:0] FmtE, FmtM, // FP format
|
||||
output logic [2:0] OpCtrlE, OpCtrlM, // Select which opperation to do in each component
|
||||
output logic FpLoadStoreM, // FP load or store instruction
|
||||
output logic [1:0] PostProcSelE, PostProcSelM, // select result in the post processing unit
|
||||
output logic [1:0] FResSelE, FResSelM, FResSelW, // Select one of the results that finish in the memory stage
|
||||
input logic StallE, StallM, StallW, // stall signals
|
||||
input logic FlushE, FlushM, FlushW, // flush signals
|
||||
input logic IntDivE, // is inteteger division
|
||||
input logic [2:0] FRM_REGW, // rounding mode from CSR
|
||||
input logic [1:0] STATUS_FS, // is FPU enabled?
|
||||
input logic FDivBusyE, // is the divider busy
|
||||
// intruction
|
||||
input logic [31:0] InstrD, // the full instruction
|
||||
input logic [6:0] Funct7D, // bits 31:25 of instruction - may contain percision
|
||||
input logic [6:0] OpD, // bits 6:0 of instruction
|
||||
input logic [4:0] Rs2D, // bits 24:20 of instruction
|
||||
input logic [2:0] Funct3D, Funct3E, // bits 14:12 of instruction - may contain rounding mode
|
||||
// input mux selections
|
||||
output logic XEnD, YEnD, ZEnD, // enable inputs
|
||||
output logic XEnE, YEnE, ZEnE, // enable inputs
|
||||
// opperation mux selections
|
||||
output logic FCvtIntE, FCvtIntW, // convert to integer opperation
|
||||
output logic [2:0] FrmM, // FP rounding mode
|
||||
output logic [`FMTBITS-1:0] FmtE, FmtM, // FP format
|
||||
output logic [2:0] OpCtrlE, OpCtrlM, // Select which opperation to do in each component
|
||||
output logic FpLoadStoreM, // FP load or store instruction
|
||||
output logic [1:0] PostProcSelE, PostProcSelM, // select result in the post processing unit
|
||||
output logic [1:0] FResSelE, FResSelM, FResSelW, // Select one of the results that finish in the memory stage
|
||||
// register control signals
|
||||
output logic FRegWriteE, FRegWriteM, FRegWriteW, // FP register write enable
|
||||
output logic FWriteIntE, FWriteIntM, // Write to integer register
|
||||
output logic [4:0] Adr1D, Adr2D, Adr3D, // adresses of each input
|
||||
output logic [4:0] Adr1E, Adr2E, Adr3E, // adresses of each input
|
||||
output logic FRegWriteE, FRegWriteM, FRegWriteW, // FP register write enable
|
||||
output logic FWriteIntE, FWriteIntM, // Write to integer register
|
||||
output logic [4:0] Adr1D, Adr2D, Adr3D, // adresses of each input
|
||||
output logic [4:0] Adr1E, Adr2E, Adr3E, // adresses of each input
|
||||
// other control signals
|
||||
output logic IllegalFPUInstrD, // Is the instruction an illegal fpu instruction
|
||||
output logic FDivStartE, IDivStartE // Start division or squareroot
|
||||
output logic FDivStartE, IDivStartE // Start division or squareroot
|
||||
);
|
||||
|
||||
`define FCTRLW 12
|
||||
|
||||
logic [`FCTRLW-1:0] ControlsD; // control signals
|
||||
logic FRegWriteD; // FP register write enable
|
||||
logic FDivStartD; // start division/sqrt
|
||||
logic FWriteIntD; // integer register write enable
|
||||
logic [2:0] OpCtrlD; // Select which opperation to do in each component
|
||||
logic [1:0] PostProcSelD; // select result in the post processing unit
|
||||
logic [1:0] FResSelD; // Select one of the results that finish in the memory stage
|
||||
logic [2:0] FrmD, FrmE; // FP rounding mode
|
||||
logic [`FMTBITS-1:0] FmtD; // FP format
|
||||
logic [1:0] Fmt; // format - before possible reduction
|
||||
logic SupportedFmt; // is the format supported
|
||||
logic FCvtIntD, FCvtIntM; // convert to integer opperation
|
||||
logic [`FCTRLW-1:0] ControlsD; // control signals
|
||||
logic FRegWriteD; // FP register write enable
|
||||
logic FDivStartD; // start division/sqrt
|
||||
logic FWriteIntD; // integer register write enable
|
||||
logic [2:0] OpCtrlD; // Select which opperation to do in each component
|
||||
logic [1:0] PostProcSelD; // select result in the post processing unit
|
||||
logic [1:0] FResSelD; // Select one of the results that finish in the memory stage
|
||||
logic [2:0] FrmD, FrmE; // FP rounding mode
|
||||
logic [`FMTBITS-1:0] FmtD; // FP format
|
||||
logic [1:0] Fmt; // format - before possible reduction
|
||||
logic SupportedFmt; // is the format supported
|
||||
logic FCvtIntD, FCvtIntM; // convert to integer opperation
|
||||
|
||||
// FPU Instruction Decoder
|
||||
assign Fmt = Funct7D[1:0];
|
||||
|
|
|
@ -30,20 +30,20 @@
|
|||
`include "wally-config.vh"
|
||||
|
||||
module fcvt (
|
||||
input logic Xs, // input's sign
|
||||
input logic [`NE-1:0] Xe, // input's exponent
|
||||
input logic [`NF:0] Xm, // input's fraction
|
||||
input logic [`XLEN-1:0] Int, // integer input - from IEU
|
||||
input logic [2:0] OpCtrl, // choose which opperation (look below for values)
|
||||
input logic ToInt, // is fp->int (since it's writting to the integer register)
|
||||
input logic XZero, // is the input zero
|
||||
input logic [`FMTBITS-1:0] Fmt, // the input's precision (11=quad 01=double 00=single 10=half)
|
||||
output logic [`NE:0] Ce, // the calculated expoent
|
||||
output logic [`LOGCVTLEN-1:0] ShiftAmt, // how much to shift by
|
||||
input logic Xs, // input's sign
|
||||
input logic [`NE-1:0] Xe, // input's exponent
|
||||
input logic [`NF:0] Xm, // input's fraction
|
||||
input logic [`XLEN-1:0] Int, // integer input - from IEU
|
||||
input logic [2:0] OpCtrl, // choose which opperation (look below for values)
|
||||
input logic ToInt, // is fp->int (since it's writting to the integer register)
|
||||
input logic XZero, // is the input zero
|
||||
input logic [`FMTBITS-1:0] Fmt, // the input's precision (11=quad 01=double 00=single 10=half)
|
||||
output logic [`NE:0] Ce, // the calculated expoent
|
||||
output logic [`LOGCVTLEN-1:0] ShiftAmt, // how much to shift by
|
||||
output logic ResSubnormUf,// does the result underflow or is subnormal
|
||||
output logic Cs, // the result's sign
|
||||
output logic IntZero, // is the integer zero?
|
||||
output logic [`CVTLEN-1:0] LzcIn // input to the Leading Zero Counter (priority encoder)
|
||||
output logic Cs, // the result's sign
|
||||
output logic IntZero, // is the integer zero?
|
||||
output logic [`CVTLEN-1:0] LzcIn // input to the Leading Zero Counter (priority encoder)
|
||||
);
|
||||
|
||||
// OpCtrls:
|
||||
|
@ -60,7 +60,7 @@ module fcvt (
|
|||
logic [`XLEN-1:0] PosInt; // the positive integer input
|
||||
logic [`XLEN-1:0] TrimInt; // integer trimmed to the correct size
|
||||
logic [`NE-2:0] NewBias; // the bias of the final result
|
||||
logic [`NE-1:0] OldExp; // the old exponent
|
||||
logic [`NE-1:0] OldExp; // the old exponent
|
||||
logic Signed; // is the opperation with a signed integer?
|
||||
logic Int64; // is the integer 64 bits?
|
||||
logic IntToFp; // is the opperation an int->fp conversion?
|
||||
|
|
|
@ -29,49 +29,49 @@
|
|||
`include "wally-config.vh"
|
||||
|
||||
module fdivsqrt(
|
||||
input logic clk,
|
||||
input logic reset,
|
||||
input logic clk,
|
||||
input logic reset,
|
||||
input logic [`FMTBITS-1:0] FmtE,
|
||||
input logic XsE,
|
||||
input logic [`NF:0] XmE, YmE,
|
||||
input logic [`NE-1:0] XeE, YeE,
|
||||
input logic XInfE, YInfE,
|
||||
input logic XZeroE, YZeroE,
|
||||
input logic XNaNE, YNaNE,
|
||||
input logic FDivStartE, IDivStartE,
|
||||
input logic StallM,
|
||||
input logic FlushE,
|
||||
input logic SqrtE, SqrtM,
|
||||
input logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, // these are the src outputs before the mux choosing between them and PCE to put in srcA/B
|
||||
input logic [2:0] Funct3E, Funct3M,
|
||||
input logic IntDivE, W64E,
|
||||
output logic DivStickyM,
|
||||
output logic FDivBusyE, IFDivStartE, FDivDoneE,
|
||||
output logic [`NE+1:0] QeM,
|
||||
output logic [`DIVb:0] QmM,
|
||||
output logic [`XLEN-1:0] FIntDivResultM
|
||||
input logic XsE,
|
||||
input logic [`NF:0] XmE, YmE,
|
||||
input logic [`NE-1:0] XeE, YeE,
|
||||
input logic XInfE, YInfE,
|
||||
input logic XZeroE, YZeroE,
|
||||
input logic XNaNE, YNaNE,
|
||||
input logic FDivStartE, IDivStartE,
|
||||
input logic StallM,
|
||||
input logic FlushE,
|
||||
input logic SqrtE, SqrtM,
|
||||
input logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, // these are the src outputs before the mux choosing between them and PCE to put in srcA/B
|
||||
input logic [2:0] Funct3E, Funct3M,
|
||||
input logic IntDivE, W64E,
|
||||
output logic DivStickyM,
|
||||
output logic FDivBusyE, IFDivStartE, FDivDoneE,
|
||||
output logic [`NE+1:0] QeM,
|
||||
output logic [`DIVb:0] QmM,
|
||||
output logic [`XLEN-1:0] FIntDivResultM
|
||||
);
|
||||
|
||||
// Floating-point division and square root module, with optional integer division and remainder
|
||||
// Computes X/Y, sqrt(X), A/B, or A%B
|
||||
|
||||
logic [`DIVb+3:0] WS, WC; // Partial remainder components
|
||||
logic [`DIVb+3:0] X; // Iterator Initial Value (from dividend)
|
||||
logic [`DIVb-1:0] DPreproc, D; // Iterator Divisor
|
||||
logic [`DIVb:0] FirstU, FirstUM; // Intermediate result values
|
||||
logic [`DIVb+1:0] FirstC; // Step tracker
|
||||
logic Firstun; // Quotient selection
|
||||
logic WZeroE; // Early termination flag
|
||||
logic SpecialCaseM; // Divide by zero, square root of negative, etc.
|
||||
logic DivStartE; // Enable signal for flops during stall
|
||||
|
||||
// Integer div/rem signals
|
||||
logic BZeroM; // Denominator is zero
|
||||
logic IntDivM; // Integer operation
|
||||
logic [`DIVBLEN:0] nE, nM, mM; // Shift amounts
|
||||
logic NegQuotM, ALTBM, AsM, W64M; // Special handling for postprocessor
|
||||
logic [`XLEN-1:0] AM; // Original Numerator for postprocessor
|
||||
logic ISpecialCaseE; // Integer div/remainder special cases
|
||||
logic [`DIVb+3:0] WS, WC; // Partial remainder components
|
||||
logic [`DIVb+3:0] X; // Iterator Initial Value (from dividend)
|
||||
logic [`DIVb-1:0] DPreproc, D; // Iterator Divisor
|
||||
logic [`DIVb:0] FirstU, FirstUM; // Intermediate result values
|
||||
logic [`DIVb+1:0] FirstC; // Step tracker
|
||||
logic Firstun; // Quotient selection
|
||||
logic WZeroE; // Early termination flag
|
||||
logic SpecialCaseM; // Divide by zero, square root of negative, etc.
|
||||
logic DivStartE; // Enable signal for flops during stall
|
||||
|
||||
// Integer div/rem signals
|
||||
logic BZeroM; // Denominator is zero
|
||||
logic IntDivM; // Integer operation
|
||||
logic [`DIVBLEN:0] nE, nM, mM; // Shift amounts
|
||||
logic NegQuotM, ALTBM, AsM, W64M; // Special handling for postprocessor
|
||||
logic [`XLEN-1:0] AM; // Original Numerator for postprocessor
|
||||
logic ISpecialCaseE; // Integer div/remainder special cases
|
||||
|
||||
fdivsqrtpreproc fdivsqrtpreproc( // Preprocessor
|
||||
.clk, .IFDivStartE, .Xm(XmE), .Ym(YmE), .Xe(XeE), .Ye(YeE),
|
||||
|
@ -100,4 +100,4 @@ module fdivsqrt(
|
|||
// Int-specific
|
||||
.nM, .mM, .ALTBM, .AsM, .BZeroM, .NegQuotM, .W64M, .RemOpM(Funct3M[1]), .AM,
|
||||
.FIntDivResultM);
|
||||
endmodule
|
||||
endmodule
|
||||
|
|
|
@ -37,7 +37,7 @@ module fdivsqrtpostproc(
|
|||
input logic [`DIVb+1:0] FirstC,
|
||||
input logic SqrtE,
|
||||
input logic Firstun, SqrtM, SpecialCaseM, NegQuotM,
|
||||
input logic [`XLEN-1:0] AM,
|
||||
input logic [`XLEN-1:0] AM,
|
||||
input logic RemOpM, ALTBM, BZeroM, AsM, W64M,
|
||||
input logic [`DIVBLEN:0] nM, mM,
|
||||
output logic [`DIVb:0] QmM,
|
||||
|
@ -46,11 +46,11 @@ module fdivsqrtpostproc(
|
|||
output logic [`XLEN-1:0] FIntDivResultM
|
||||
);
|
||||
|
||||
logic [`DIVb+3:0] W, Sum, DM;
|
||||
logic [`DIVb:0] PreQmM;
|
||||
logic NegStickyM;
|
||||
logic weq0E, WZeroM;
|
||||
logic [`XLEN-1:0] IntDivResultM;
|
||||
logic [`DIVb+3:0] W, Sum, DM;
|
||||
logic [`DIVb:0] PreQmM;
|
||||
logic NegStickyM;
|
||||
logic weq0E, WZeroM;
|
||||
logic [`XLEN-1:0] IntDivResultM;
|
||||
|
||||
//////////////////////////
|
||||
// Execute Stage: Detect early termination for an exact result
|
||||
|
@ -134,4 +134,4 @@ module fdivsqrtpostproc(
|
|||
end else
|
||||
assign FIntDivResultM = IntDivResultM[`XLEN-1:0];
|
||||
end
|
||||
endmodule
|
||||
endmodule
|
||||
|
|
|
@ -29,35 +29,35 @@
|
|||
`include "wally-config.vh"
|
||||
|
||||
module fdivsqrtpreproc (
|
||||
input logic clk,
|
||||
input logic IFDivStartE,
|
||||
input logic [`NF:0] Xm, Ym,
|
||||
input logic [`NE-1:0] Xe, Ye,
|
||||
input logic clk,
|
||||
input logic IFDivStartE,
|
||||
input logic [`NF:0] Xm, Ym,
|
||||
input logic [`NE-1:0] Xe, Ye,
|
||||
input logic [`FMTBITS-1:0] Fmt,
|
||||
input logic Sqrt,
|
||||
input logic XZeroE,
|
||||
input logic [2:0] Funct3E,
|
||||
output logic [`NE+1:0] QeM,
|
||||
output logic [`DIVb+3:0] X,
|
||||
output logic [`DIVb-1:0] DPreproc,
|
||||
input logic Sqrt,
|
||||
input logic XZeroE,
|
||||
input logic [2:0] Funct3E,
|
||||
output logic [`NE+1:0] QeM,
|
||||
output logic [`DIVb+3:0] X,
|
||||
output logic [`DIVb-1:0] DPreproc,
|
||||
// Int-specific
|
||||
input logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, // *** these are the src outputs before the mux choosing between them and PCE to put in srcA/B
|
||||
input logic IntDivE, W64E,
|
||||
output logic ISpecialCaseE,
|
||||
output logic [`DIVBLEN:0] nE, nM, mM,
|
||||
output logic NegQuotM, ALTBM, IntDivM, W64M,
|
||||
output logic AsM, BZeroM,
|
||||
output logic [`XLEN-1:0] AM
|
||||
input logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, // *** these are the src outputs before the mux choosing between them and PCE to put in srcA/B
|
||||
input logic IntDivE, W64E,
|
||||
output logic ISpecialCaseE,
|
||||
output logic [`DIVBLEN:0] nE, nM, mM,
|
||||
output logic NegQuotM, ALTBM, IntDivM, W64M,
|
||||
output logic AsM, BZeroM,
|
||||
output logic [`XLEN-1:0] AM
|
||||
);
|
||||
|
||||
logic [`DIVb-1:0] XPreproc;
|
||||
logic [`DIVb:0] PreSqrtX;
|
||||
logic [`DIVb+3:0] DivX, DivXShifted, SqrtX, PreShiftX; // Variations of dividend, to be muxed
|
||||
logic [`NE+1:0] QeE; // Quotient Exponent (FP only)
|
||||
logic [`DIVb-1:0] IFNormLenX, IFNormLenD; // Correctly-sized inputs for iterator
|
||||
logic [`DIVBLEN:0] mE, ell; // Leading zeros of inputs
|
||||
logic NumerZeroE; // Numerator is zero (X or A)
|
||||
logic AZeroE, BZeroE; // A or B is Zero for integer division
|
||||
logic [`DIVb-1:0] XPreproc;
|
||||
logic [`DIVb:0] PreSqrtX;
|
||||
logic [`DIVb+3:0] DivX, DivXShifted, SqrtX, PreShiftX; // Variations of dividend, to be muxed
|
||||
logic [`NE+1:0] QeE; // Quotient Exponent (FP only)
|
||||
logic [`DIVb-1:0] IFNormLenX, IFNormLenD; // Correctly-sized inputs for iterator
|
||||
logic [`DIVBLEN:0] mE, ell; // Leading zeros of inputs
|
||||
logic NumerZeroE; // Numerator is zero (X or A)
|
||||
logic AZeroE, BZeroE; // A or B is Zero for integer division
|
||||
|
||||
if (`IDIV_ON_FPU) begin:intpreproc // Int Supported
|
||||
logic signedDiv, NegQuotE;
|
||||
|
|
|
@ -45,11 +45,11 @@ module fdivsqrtqsel2 (
|
|||
assign g = ps & pc;
|
||||
|
||||
assign magnitude = ~((ps[2]^pc[2]) & (ps[1]^pc[1]) &
|
||||
(ps[0]^pc[0]));
|
||||
(ps[0]^pc[0]));
|
||||
assign sign = (ps[3]^pc[3])^
|
||||
(ps[2] & pc[2] | ((ps[2]^pc[2]) &
|
||||
(ps[1]&pc[1] | ((ps[1]^pc[1]) &
|
||||
(ps[0]&pc[0])))));
|
||||
(ps[1]&pc[1] | ((ps[1]^pc[1]) &
|
||||
(ps[0]&pc[0])))));
|
||||
|
||||
// Produce digit = +1, 0, or -1
|
||||
assign up = magnitude & ~sign;
|
||||
|
|
|
@ -32,21 +32,21 @@ module fdivsqrtqsel4 (
|
|||
input logic [2:0] Dmsbs,
|
||||
input logic [4:0] Smsbs,
|
||||
input logic [7:0] WSmsbs, WCmsbs,
|
||||
input logic Sqrt, j1,
|
||||
input logic Sqrt, j1,
|
||||
output logic [3:0] udigit
|
||||
);
|
||||
logic [6:0] Wmsbs;
|
||||
logic [7:0] PreWmsbs;
|
||||
logic [2:0] A;
|
||||
logic [6:0] Wmsbs;
|
||||
logic [7:0] PreWmsbs;
|
||||
logic [2:0] A;
|
||||
|
||||
assign PreWmsbs = WCmsbs + WSmsbs;
|
||||
assign Wmsbs = PreWmsbs[7:1];
|
||||
// D = 0001.xxx...
|
||||
// Dmsbs = | |
|
||||
assign PreWmsbs = WCmsbs + WSmsbs;
|
||||
assign Wmsbs = PreWmsbs[7:1];
|
||||
// D = 0001.xxx...
|
||||
// Dmsbs = | |
|
||||
// W = xxxx.xxx...
|
||||
// Wmsbs = | |
|
||||
// Wmsbs = | |
|
||||
|
||||
logic [3:0] USel4[1023:0];
|
||||
logic [3:0] USel4[1023:0];
|
||||
|
||||
// Prepopulate selection table; this is constant at compile time
|
||||
always_comb begin
|
||||
|
@ -109,5 +109,5 @@ module fdivsqrtqsel4 (
|
|||
end else A = Dmsbs;
|
||||
|
||||
// Select quotient digit from lookup table based on A and W
|
||||
assign udigit = USel4[{A,Wmsbs}];
|
||||
assign udigit = USel4[{A,Wmsbs}];
|
||||
endmodule
|
||||
|
|
|
@ -32,19 +32,19 @@ module fdivsqrtqsel4cmp (
|
|||
input logic [2:0] Dmsbs,
|
||||
input logic [4:0] Smsbs,
|
||||
input logic [7:0] WSmsbs, WCmsbs,
|
||||
input logic SqrtE, j1,
|
||||
input logic SqrtE, j1,
|
||||
output logic [3:0] udigit
|
||||
);
|
||||
logic [6:0] Wmsbs;
|
||||
logic [7:0] PreWmsbs;
|
||||
logic [2:0] A;
|
||||
logic [6:0] Wmsbs;
|
||||
logic [7:0] PreWmsbs;
|
||||
logic [2:0] A;
|
||||
|
||||
assign PreWmsbs = WCmsbs + WSmsbs;
|
||||
assign Wmsbs = PreWmsbs[7:1];
|
||||
// D = 0001.xxx...
|
||||
// Dmsbs = | |
|
||||
assign PreWmsbs = WCmsbs + WSmsbs;
|
||||
assign Wmsbs = PreWmsbs[7:1];
|
||||
// D = 0001.xxx...
|
||||
// Dmsbs = | |
|
||||
// W = xxxx.xxx...
|
||||
// Wmsbs = | |
|
||||
// Wmsbs = | |
|
||||
|
||||
logic [6:0] mk2, mk1, mk0, mkm1;
|
||||
logic [6:0] mks2[7:0], mks1[7:0];
|
||||
|
@ -87,5 +87,5 @@ module fdivsqrtqsel4cmp (
|
|||
else if ($signed(Wmsbs) >= $signed(mk1)) udigit = 4'b0100; // choose 1
|
||||
else if ($signed(Wmsbs) >= $signed(mk0)) udigit = 4'b0000; // choose 0
|
||||
else if ($signed(Wmsbs) >= $signed(mkm1)) udigit = 4'b0010; // choose -1
|
||||
else udigit = 4'b0001; // choose -2
|
||||
else udigit = 4'b0001; // choose -2
|
||||
endmodule
|
||||
|
|
|
@ -31,32 +31,32 @@
|
|||
/* verilator lint_off UNOPTFLAT */
|
||||
module fdivsqrtstage2 (
|
||||
input logic [`DIVb-1:0] D,
|
||||
input logic [`DIVb+3:0] DBar,
|
||||
input logic [`DIVb:0] U, UM,
|
||||
input logic [`DIVb+3:0] WS, WC,
|
||||
input logic [`DIVb+3:0] DBar,
|
||||
input logic [`DIVb:0] U, UM,
|
||||
input logic [`DIVb+3:0] WS, WC,
|
||||
input logic [`DIVb+1:0] C,
|
||||
input logic SqrtE,
|
||||
output logic un,
|
||||
input logic SqrtE,
|
||||
output logic un,
|
||||
output logic [`DIVb+1:0] CNext,
|
||||
output logic [`DIVb:0] UNext, UMNext,
|
||||
output logic [`DIVb+3:0] WSNext, WCNext
|
||||
output logic [`DIVb:0] UNext, UMNext,
|
||||
output logic [`DIVb+3:0] WSNext, WCNext
|
||||
);
|
||||
/* verilator lint_on UNOPTFLAT */
|
||||
|
||||
logic [`DIVb+3:0] Dsel;
|
||||
logic up, uz;
|
||||
logic [`DIVb+3:0] F;
|
||||
logic [`DIVb+3:0] AddIn;
|
||||
logic [`DIVb+3:0] WSA, WCA;
|
||||
logic [`DIVb+3:0] Dsel;
|
||||
logic up, uz;
|
||||
logic [`DIVb+3:0] F;
|
||||
logic [`DIVb+3:0] AddIn;
|
||||
logic [`DIVb+3:0] WSA, WCA;
|
||||
|
||||
// Qmient Selection logic
|
||||
// Given partial remainder, select digit of +1, 0, or -1 (up, uz, un)
|
||||
// q encoding:
|
||||
// 1000 = +2
|
||||
// 0100 = +1
|
||||
// 0000 = 0
|
||||
// 0010 = -1
|
||||
// 0001 = -2
|
||||
// 1000 = +2
|
||||
// 0100 = +1
|
||||
// 0000 = 0
|
||||
// 0010 = -1
|
||||
// 0001 = -2
|
||||
fdivsqrtqsel2 qsel2(WS[`DIVb+3:`DIVb], WC[`DIVb+3:`DIVb], up, uz, un);
|
||||
|
||||
// Sqrt F generation. Extend C, U, UM to Q4.k
|
||||
|
|
|
@ -30,34 +30,34 @@
|
|||
|
||||
module fdivsqrtstage4 (
|
||||
input logic [`DIVb-1:0] D,
|
||||
input logic [`DIVb+3:0] DBar, D2, DBar2,
|
||||
input logic [`DIVb:0] U, UM,
|
||||
input logic [`DIVb+3:0] WS, WC,
|
||||
input logic [`DIVb+3:0] DBar, D2, DBar2,
|
||||
input logic [`DIVb:0] U,UM,
|
||||
input logic [`DIVb+3:0] WS, WC,
|
||||
input logic [`DIVb+1:0] C,
|
||||
input logic SqrtE, j1,
|
||||
input logic SqrtE, j1,
|
||||
output logic [`DIVb+1:0] CNext,
|
||||
output logic un,
|
||||
output logic [`DIVb:0] UNext, UMNext,
|
||||
output logic [`DIVb+3:0] WSNext, WCNext
|
||||
output logic un,
|
||||
output logic [`DIVb:0] UNext, UMNext,
|
||||
output logic [`DIVb+3:0] WSNext, WCNext
|
||||
);
|
||||
|
||||
logic [`DIVb+3:0] Dsel;
|
||||
logic [3:0] udigit;
|
||||
logic [`DIVb+3:0] F;
|
||||
logic [`DIVb+3:0] AddIn;
|
||||
logic [4:0] Smsbs;
|
||||
logic [2:0] Dmsbs;
|
||||
logic [7:0] WCmsbs, WSmsbs;
|
||||
logic CarryIn;
|
||||
logic [`DIVb+3:0] WSA, WCA;
|
||||
logic [`DIVb+3:0] Dsel;
|
||||
logic [3:0] udigit;
|
||||
logic [`DIVb+3:0] F;
|
||||
logic [`DIVb+3:0] AddIn;
|
||||
logic [4:0] Smsbs;
|
||||
logic [2:0] Dmsbs;
|
||||
logic [7:0] WCmsbs, WSmsbs;
|
||||
logic CarryIn;
|
||||
logic [`DIVb+3:0] WSA, WCA;
|
||||
|
||||
// Digit Selection logic
|
||||
// u encoding:
|
||||
// 1000 = +2
|
||||
// 0100 = +1
|
||||
// 0000 = 0
|
||||
// 0010 = -1
|
||||
// 0001 = -2
|
||||
// 1000 = +2
|
||||
// 0100 = +1
|
||||
// 0000 = 0
|
||||
// 0010 = -1
|
||||
// 0001 = -2
|
||||
assign Smsbs = U[`DIVb:`DIVb-4];
|
||||
assign Dmsbs = D[`DIVb-1:`DIVb-3];
|
||||
assign WCmsbs = WC[`DIVb+3:`DIVb-4];
|
||||
|
|
|
@ -32,12 +32,12 @@
|
|||
module fmalza #(WIDTH) (
|
||||
input logic [WIDTH-1:0] A, // addend
|
||||
input logic [2*`NF+1:0] Pm, // product
|
||||
input logic Cin, // carry in
|
||||
input logic Cin, // carry in
|
||||
input logic sub, // subtraction
|
||||
output logic [$clog2(WIDTH+1)-1:0] SCnt // normalization shift count for the positive result
|
||||
);
|
||||
|
||||
logic [WIDTH:0] F; // most significant bit of F indicates leading digit
|
||||
logic [WIDTH:0] F; // most significant bit of F indicates leading digit
|
||||
logic [WIDTH-1:0] B; // zero-extended product with same size as aligned A
|
||||
logic [WIDTH-1:0] P, G, K; // propagate, generate, kill for each column
|
||||
logic [WIDTH-1:0] Pp1, Gm1, Km1; // propagate shifted right by 1, generate/kill shifted left 1
|
||||
|
|
222
src/fpu/fpu.sv
222
src/fpu/fpu.sv
|
@ -29,40 +29,40 @@
|
|||
`include "wally-config.vh"
|
||||
|
||||
module fpu (
|
||||
input logic clk,
|
||||
input logic reset,
|
||||
input logic clk,
|
||||
input logic reset,
|
||||
// Hazards
|
||||
input logic StallE, StallM, StallW, // stall signals (from HZU)
|
||||
input logic FlushE, FlushM, FlushW, // flush signals (from HZU)
|
||||
output logic FPUStallD, // Stall the decode stage (To HZU)
|
||||
output logic FDivBusyE, // Is the divide/sqrt unit busy (stall execute stage) (to HZU)
|
||||
// CSRs
|
||||
input logic [1:0] STATUS_FS, // Is floating-point enabled? (From privileged unit)
|
||||
input logic [2:0] FRM_REGW, // Rounding mode (from CSR)
|
||||
// Decode stage
|
||||
input logic [31:0] InstrD, // instruction (from IFU)
|
||||
// Execute stage
|
||||
input logic [2:0] Funct3E, // Funct fields of instruction specify type of operations
|
||||
input logic IntDivE, W64E, // Integer division on FPU
|
||||
input logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, // Integer input for convert, move, and int div (from IEU)
|
||||
input logic [4:0] RdE, // which FP register to write to (from IEU)
|
||||
output logic FWriteIntE, // integer register write enable (to IEU)
|
||||
output logic FCvtIntE, // Convert to int (to IEU)
|
||||
// Memory stage
|
||||
input logic [2:0] Funct3M, // Funct fields of instruction specify type of operations
|
||||
input logic [4:0] RdM, // which FP register to write to (from IEU)
|
||||
output logic FRegWriteM, // FP register write enable (to privileged unit)
|
||||
output logic FpLoadStoreM, // Fp load instruction? (to LSU)
|
||||
output logic [`FLEN-1:0] FWriteDataM, // Data to be written to memory (to LSU)
|
||||
output logic [`XLEN-1:0] FIntResM, // data to be written to integer register (to IEU)
|
||||
output logic IllegalFPUInstrD, // Is the instruction an illegal fpu instruction (to IFU)
|
||||
output logic [4:0] SetFflagsM, // FPU flags (to privileged unit)
|
||||
// Writeback stage
|
||||
input logic [4:0] RdW, // which FP register to write to (from IEU)
|
||||
input logic [`FLEN-1:0] ReadDataW, // Read data (from LSU)
|
||||
output logic [`XLEN-1:0] FCvtIntResW, // convert result to to be written to integer register (to IEU)
|
||||
output logic FCvtIntW, // select FCvtIntRes (to IEU)
|
||||
output logic [`XLEN-1:0] FIntDivResultW // Result from integer division (to IEU)
|
||||
input logic StallE, StallM, StallW, // stall signals (from HZU)
|
||||
input logic FlushE, FlushM, FlushW, // flush signals (from HZU)
|
||||
output logic FPUStallD, // Stall the decode stage (To HZU)
|
||||
output logic FDivBusyE, // Is the divide/sqrt unit busy (stall execute stage) (to HZU)
|
||||
// CSRs
|
||||
input logic [1:0] STATUS_FS, // Is floating-point enabled? (From privileged unit)
|
||||
input logic [2:0] FRM_REGW, // Rounding mode (from CSR)
|
||||
// Decode stage
|
||||
input logic [31:0] InstrD, // instruction (from IFU)
|
||||
// Execute stage
|
||||
input logic [2:0] Funct3E, // Funct fields of instruction specify type of operations
|
||||
input logic IntDivE, W64E, // Integer division on FPU
|
||||
input logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, // Integer input for convert, move, and int div (from IEU)
|
||||
input logic [4:0] RdE, // which FP register to write to (from IEU)
|
||||
output logic FWriteIntE, // integer register write enable (to IEU)
|
||||
output logic FCvtIntE, // Convert to int (to IEU)
|
||||
// Memory stage
|
||||
input logic [2:0] Funct3M, // Funct fields of instruction specify type of operations
|
||||
input logic [4:0] RdM, // which FP register to write to (from IEU)
|
||||
output logic FRegWriteM, // FP register write enable (to privileged unit)
|
||||
output logic FpLoadStoreM, // Fp load instruction? (to LSU)
|
||||
output logic [`FLEN-1:0] FWriteDataM, // Data to be written to memory (to LSU)
|
||||
output logic [`XLEN-1:0] FIntResM, // data to be written to integer register (to IEU)
|
||||
output logic IllegalFPUInstrD, // Is the instruction an illegal fpu instruction (to IFU)
|
||||
output logic [4:0] SetFflagsM, // FPU flags (to privileged unit)
|
||||
// Writeback stage
|
||||
input logic [4:0] RdW, // which FP register to write to (from IEU)
|
||||
input logic [`FLEN-1:0] ReadDataW, // Read data (from LSU)
|
||||
output logic [`XLEN-1:0] FCvtIntResW, // convert result to to be written to integer register (to IEU)
|
||||
output logic FCvtIntW, // select FCvtIntRes (to IEU)
|
||||
output logic [`XLEN-1:0] FIntDivResultW // Result from integer division (to IEU)
|
||||
);
|
||||
|
||||
// RISC-V FPU specifics:
|
||||
|
@ -70,97 +70,97 @@ module fpu (
|
|||
// - RISC-V detects underflow after rounding
|
||||
|
||||
// control signals
|
||||
logic FRegWriteW; // FP register write enable
|
||||
logic [2:0] FrmM; // FP rounding mode
|
||||
logic [`FMTBITS-1:0] FmtE, FmtM; // FP precision 0-single 1-double
|
||||
logic FDivStartE, IDivStartE; // Start division or squareroot
|
||||
logic FWriteIntM; // Write to integer register
|
||||
logic [1:0] ForwardXE, ForwardYE, ForwardZE; // forwarding mux control signals
|
||||
logic [2:0] OpCtrlE, OpCtrlM; // Select which opperation to do in each component
|
||||
logic [1:0] FResSelE, FResSelM, FResSelW; // Select one of the results that finish in the memory stage
|
||||
logic [1:0] PostProcSelE, PostProcSelM; // select result in the post processing unit
|
||||
logic [4:0] Adr1D, Adr2D, Adr3D; // register adresses of each input
|
||||
logic [4:0] Adr1E, Adr2E, Adr3E; // register adresses of each input
|
||||
logic XEnD, YEnD, ZEnD; // X, Y, Z inputs used for current operation
|
||||
logic XEnE, YEnE, ZEnE; // X, Y, Z inputs used for current operation
|
||||
logic FRegWriteE; // Write floating-point register
|
||||
logic FRegWriteW; // FP register write enable
|
||||
logic [2:0] FrmM; // FP rounding mode
|
||||
logic [`FMTBITS-1:0] FmtE, FmtM; // FP precision 0-single 1-double
|
||||
logic FDivStartE, IDivStartE; // Start division or squareroot
|
||||
logic FWriteIntM; // Write to integer register
|
||||
logic [1:0] ForwardXE, ForwardYE, ForwardZE; // forwarding mux control signals
|
||||
logic [2:0] OpCtrlE, OpCtrlM; // Select which opperation to do in each component
|
||||
logic [1:0] FResSelE, FResSelM, FResSelW; // Select one of the results that finish in the memory stage
|
||||
logic [1:0] PostProcSelE, PostProcSelM; // select result in the post processing unit
|
||||
logic [4:0] Adr1D, Adr2D, Adr3D; // register adresses of each input
|
||||
logic [4:0] Adr1E, Adr2E, Adr3E; // register adresses of each input
|
||||
logic XEnD, YEnD, ZEnD; // X, Y, Z inputs used for current operation
|
||||
logic XEnE, YEnE, ZEnE; // X, Y, Z inputs used for current operation
|
||||
logic FRegWriteE; // Write floating-point register
|
||||
|
||||
// regfile signals
|
||||
logic [`FLEN-1:0] FRD1D, FRD2D, FRD3D; // Read Data from FP register - decode stage
|
||||
logic [`FLEN-1:0] FRD1E, FRD2E, FRD3E; // Read Data from FP register - execute stage
|
||||
logic [`FLEN-1:0] XE; // Input 1 to the various units (after forwarding)
|
||||
logic [`XLEN-1:0] IntSrcXE; // Input 1 to the various units (after forwarding)
|
||||
logic [`FLEN-1:0] PreYE, YE; // Input 2 to the various units (after forwarding)
|
||||
logic [`FLEN-1:0] PreZE, ZE; // Input 3 to the various units (after forwarding)
|
||||
logic [`FLEN-1:0] FRD1D, FRD2D, FRD3D; // Read Data from FP register - decode stage
|
||||
logic [`FLEN-1:0] FRD1E, FRD2E, FRD3E; // Read Data from FP register - execute stage
|
||||
logic [`FLEN-1:0] XE; // Input 1 to the various units (after forwarding)
|
||||
logic [`XLEN-1:0] IntSrcXE; // Input 1 to the various units (after forwarding)
|
||||
logic [`FLEN-1:0] PreYE, YE; // Input 2 to the various units (after forwarding)
|
||||
logic [`FLEN-1:0] PreZE, ZE; // Input 3 to the various units (after forwarding)
|
||||
|
||||
// unpacking signals
|
||||
logic XsE, YsE, ZsE; // input's sign - execute stage
|
||||
logic XsM, YsM; // input's sign - memory stage
|
||||
logic [`NE-1:0] XeE, YeE, ZeE; // input's exponent - execute stage
|
||||
logic [`NE-1:0] ZeM; // input's exponent - memory stage
|
||||
logic [`NF:0] XmE, YmE, ZmE; // input's significand - execute stage
|
||||
logic [`NF:0] XmM, YmM, ZmM; // input's significand - memory stage
|
||||
logic XNaNE, YNaNE, ZNaNE; // is the input a NaN - execute stage
|
||||
logic XNaNM, YNaNM, ZNaNM; // is the input a NaN - memory stage
|
||||
logic XSNaNE, YSNaNE, ZSNaNE; // is the input a signaling NaN - execute stage
|
||||
logic XSNaNM, YSNaNM, ZSNaNM; // is the input a signaling NaN - memory stage
|
||||
logic XSubnormE; // is the input subnormal
|
||||
logic XZeroE, YZeroE, ZZeroE; // is the input zero - execute stage
|
||||
logic XZeroM, YZeroM; // is the input zero - memory stage
|
||||
logic XInfE, YInfE, ZInfE; // is the input infinity - execute stage
|
||||
logic XInfM, YInfM, ZInfM; // is the input infinity - memory stage
|
||||
logic XExpMaxE; // is the exponent all ones (max value)
|
||||
logic [`FLEN-1:0] XPostBoxE; // X after fixing bad NaN box. Needed for 1-input operations
|
||||
logic XsE, YsE, ZsE; // input's sign - execute stage
|
||||
logic XsM, YsM; // input's sign - memory stage
|
||||
logic [`NE-1:0] XeE, YeE, ZeE; // input's exponent - execute stage
|
||||
logic [`NE-1:0] ZeM; // input's exponent - memory stage
|
||||
logic [`NF:0] XmE, YmE, ZmE; // input's significand - execute stage
|
||||
logic [`NF:0] XmM, YmM, ZmM; // input's significand - memory stage
|
||||
logic XNaNE, YNaNE, ZNaNE; // is the input a NaN - execute stage
|
||||
logic XNaNM, YNaNM, ZNaNM; // is the input a NaN - memory stage
|
||||
logic XSNaNE, YSNaNE, ZSNaNE; // is the input a signaling NaN - execute stage
|
||||
logic XSNaNM, YSNaNM, ZSNaNM; // is the input a signaling NaN - memory stage
|
||||
logic XSubnormE; // is the input subnormal
|
||||
logic XZeroE, YZeroE, ZZeroE; // is the input zero - execute stage
|
||||
logic XZeroM, YZeroM; // is the input zero - memory stage
|
||||
logic XInfE, YInfE, ZInfE; // is the input infinity - execute stage
|
||||
logic XInfM, YInfM, ZInfM; // is the input infinity - memory stage
|
||||
logic XExpMaxE; // is the exponent all ones (max value)
|
||||
logic [`FLEN-1:0] XPostBoxE; // X after fixing bad NaN box. Needed for 1-input operations
|
||||
|
||||
// Fma Signals
|
||||
logic FmaAddSubE; // Multiply by 1.0 when adding or subtracting
|
||||
logic [1:0] FmaZSelE; // Select Z = Y when adding or subtracting, 0 when multiplying
|
||||
logic [3*`NF+3:0] SmE, SmM; // Sum significand
|
||||
logic FmaAStickyE, FmaAStickyM; // FMA addend sticky bit output
|
||||
logic [`NE+1:0] SeE,SeM; // Sum exponent
|
||||
logic InvAE, InvAM; // Invert addend
|
||||
logic AsE, AsM; // Addend sign
|
||||
logic PsE, PsM; // Product sign
|
||||
logic SsE, SsM; // Sum sign
|
||||
logic [$clog2(3*`NF+5)-1:0] SCntE, SCntM; // LZA sum leading zero count
|
||||
logic FmaAddSubE; // Multiply by 1.0 when adding or subtracting
|
||||
logic [1:0] FmaZSelE; // Select Z = Y when adding or subtracting, 0 when multiplying
|
||||
logic [3*`NF+3:0] SmE, SmM; // Sum significand
|
||||
logic FmaAStickyE, FmaAStickyM; // FMA addend sticky bit output
|
||||
logic [`NE+1:0] SeE,SeM; // Sum exponent
|
||||
logic InvAE, InvAM; // Invert addend
|
||||
logic AsE, AsM; // Addend sign
|
||||
logic PsE, PsM; // Product sign
|
||||
logic SsE, SsM; // Sum sign
|
||||
logic [$clog2(3*`NF+5)-1:0] SCntE, SCntM; // LZA sum leading zero count
|
||||
|
||||
// Cvt Signals
|
||||
logic [`NE:0] CeE, CeM; // convert intermediate expoent
|
||||
logic [`LOGCVTLEN-1:0] CvtShiftAmtE, CvtShiftAmtM; // how much to shift by
|
||||
logic CvtResSubnormUfE, CvtResSubnormUfM; // does the result underflow or is subnormal
|
||||
logic CsE, CsM; // convert result sign
|
||||
logic IntZeroE, IntZeroM; // is the integer zero?
|
||||
logic [`CVTLEN-1:0] CvtLzcInE, CvtLzcInM; // input to the Leading Zero Counter (priority encoder)
|
||||
logic [`XLEN-1:0] FCvtIntResM; // fcvt integer result (for IEU)
|
||||
logic [`NE:0] CeE, CeM; // convert intermediate expoent
|
||||
logic [`LOGCVTLEN-1:0] CvtShiftAmtE, CvtShiftAmtM; // how much to shift by
|
||||
logic CvtResSubnormUfE, CvtResSubnormUfM; // does the result underflow or is subnormal
|
||||
logic CsE, CsM; // convert result sign
|
||||
logic IntZeroE, IntZeroM; // is the integer zero?
|
||||
logic [`CVTLEN-1:0] CvtLzcInE, CvtLzcInM; // input to the Leading Zero Counter (priority encoder)
|
||||
logic [`XLEN-1:0] FCvtIntResM; // fcvt integer result (for IEU)
|
||||
|
||||
// divide signals
|
||||
logic [`DIVb:0] QmM; // fdivsqrt signifcand
|
||||
logic [`NE+1:0] QeM; // fdivsqrt exponent
|
||||
logic DivStickyM; // fdivsqrt sticky bit
|
||||
logic FDivDoneE, IFDivStartE; // fdivsqrt control signals
|
||||
logic [`XLEN-1:0] FIntDivResultM; // fdivsqrt integer division result (for IEU)
|
||||
logic [`DIVb:0] QmM; // fdivsqrt signifcand
|
||||
logic [`NE+1:0] QeM; // fdivsqrt exponent
|
||||
logic DivStickyM; // fdivsqrt sticky bit
|
||||
logic FDivDoneE, IFDivStartE; // fdivsqrt control signals
|
||||
logic [`XLEN-1:0] FIntDivResultM; // fdivsqrt integer division result (for IEU)
|
||||
|
||||
// result and flag signals
|
||||
logic [`XLEN-1:0] ClassResE; // classify result
|
||||
logic [`FLEN-1:0] CmpFpResE; // compare result to FPU (min/max)
|
||||
logic [`XLEN-1:0] CmpIntResE; // compare result to IEU (eq/lt/le)
|
||||
logic CmpNVE; // compare invalid flag (Not Valid)
|
||||
logic [`FLEN-1:0] SgnResE; // sign injection result
|
||||
logic [`XLEN-1:0] FIntResE; // FPU to IEU E-stage result (classify, compare, move)
|
||||
logic [`FLEN-1:0] PostProcResM; // Postprocessor output
|
||||
logic [4:0] PostProcFlgM; // Postprocessor flags
|
||||
logic PreNVE, PreNVM; // selected flag that is ready in the memory stage
|
||||
logic [`FLEN-1:0] FpResM, FpResW; // FPU preliminary result
|
||||
logic [`FLEN-1:0] PreFpResE, PreFpResM; // selected result that is ready in the memory stage
|
||||
logic [`FLEN-1:0] FResultW; // final FP result being written to the FP register
|
||||
logic [`XLEN-1:0] ClassResE; // classify result
|
||||
logic [`FLEN-1:0] CmpFpResE; // compare result to FPU (min/max)
|
||||
logic [`XLEN-1:0] CmpIntResE; // compare result to IEU (eq/lt/le)
|
||||
logic CmpNVE; // compare invalid flag (Not Valid)
|
||||
logic [`FLEN-1:0] SgnResE; // sign injection result
|
||||
logic [`XLEN-1:0] FIntResE; // FPU to IEU E-stage result (classify, compare, move)
|
||||
logic [`FLEN-1:0] PostProcResM; // Postprocessor output
|
||||
logic [4:0] PostProcFlgM; // Postprocessor flags
|
||||
logic PreNVE, PreNVM; // selected flag that is ready in the memory stage
|
||||
logic [`FLEN-1:0] FpResM, FpResW; // FPU preliminary result
|
||||
logic [`FLEN-1:0] PreFpResE, PreFpResM; // selected result that is ready in the memory stage
|
||||
logic [`FLEN-1:0] FResultW; // final FP result being written to the FP register
|
||||
|
||||
// other signals
|
||||
logic [`FLEN-1:0] AlignedSrcAE; // align SrcA from IEU to the floating point format for fmv
|
||||
logic [`FLEN-1:0] BoxedZeroE; // Zero value for Z for multiplication, with NaN boxing if needed
|
||||
logic [`FLEN-1:0] BoxedOneE; // One value for Z for multiplication, with NaN boxing if needed
|
||||
logic StallUnpackedM; // Stall unpacker outputs during multicycle fdivsqrt
|
||||
logic [`FLEN-1:0] SgnExtXE; // Sign-extended X input for move to integer
|
||||
logic mvsgn; // sign bit for extending move
|
||||
logic [`FLEN-1:0] AlignedSrcAE; // align SrcA from IEU to the floating point format for fmv
|
||||
logic [`FLEN-1:0] BoxedZeroE; // Zero value for Z for multiplication, with NaN boxing if needed
|
||||
logic [`FLEN-1:0] BoxedOneE; // One value for Z for multiplication, with NaN boxing if needed
|
||||
logic StallUnpackedM; // Stall unpacker outputs during multicycle fdivsqrt
|
||||
logic [`FLEN-1:0] SgnExtXE; // Sign-extended X input for move to integer
|
||||
logic mvsgn; // sign bit for extending move
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Decode Stage: fctrl decoder, read register file
|
||||
|
@ -180,7 +180,7 @@ module fpu (
|
|||
fregfile fregfile (.clk, .reset, .we4(FRegWriteW),
|
||||
.a1(InstrD[19:15]), .a2(InstrD[24:20]), .a3(InstrD[31:27]),
|
||||
.a4(RdW), .wd4(FResultW),
|
||||
.rd1(FRD1D), .rd2(FRD2D), .rd3(FRD3D));
|
||||
.rd1(FRD1D), .rd2(FRD2D), .rd3(FRD3D));
|
||||
|
||||
// D/E pipeline registers
|
||||
flopenrc #(`FLEN) DEReg1(clk, reset, FlushE, ~StallE, FRD1D, FRD1E);
|
||||
|
|
|
@ -29,8 +29,8 @@
|
|||
`include "wally-config.vh"
|
||||
|
||||
module fregfile (
|
||||
input logic clk, reset,
|
||||
input logic we4, // write enable
|
||||
input logic clk, reset,
|
||||
input logic we4, // write enable
|
||||
input logic [4:0] a1, a2, a3, a4, // adresses
|
||||
input logic [`FLEN-1:0] wd4, // write data
|
||||
output logic [`FLEN-1:0] rd1, rd2, rd3 // read data
|
||||
|
@ -46,7 +46,7 @@ module fregfile (
|
|||
|
||||
always_ff @(negedge clk) // or posedge reset)
|
||||
if (reset) for(i=0; i<32; i++) rf[i] <= 0;
|
||||
else if (we4) rf[a4] <= wd4;
|
||||
else if (we4) rf[a4] <= wd4;
|
||||
|
||||
assign #2 rd1 = rf[a1];
|
||||
assign #2 rd2 = rf[a2];
|
||||
|
|
|
@ -29,43 +29,43 @@
|
|||
`include "wally-config.vh"
|
||||
|
||||
module fsgninj (
|
||||
input logic Xs, Ys, // X and Y sign bits
|
||||
input logic [`FLEN-1:0] X, // X
|
||||
input logic [`FMTBITS-1:0] Fmt, // format
|
||||
input logic [1:0] OpCtrl, // operation control
|
||||
output logic [`FLEN-1:0] SgnRes // result
|
||||
input logic Xs, Ys, // X and Y sign bits
|
||||
input logic [`FLEN-1:0] X, // X
|
||||
input logic [`FMTBITS-1:0] Fmt, // format
|
||||
input logic [1:0] OpCtrl, // operation control
|
||||
output logic [`FLEN-1:0] SgnRes // result
|
||||
);
|
||||
|
||||
logic ResSgn; // result sign
|
||||
logic ResSgn; // result sign
|
||||
|
||||
// OpCtrl:
|
||||
// 00 - fsgnj - directly copy over sign value of Y
|
||||
// 01 - fsgnjn - negate sign value of Y
|
||||
// 10 - fsgnjx - XOR sign values of X and Y
|
||||
|
||||
// calculate the result's sign
|
||||
assign ResSgn = (OpCtrl[1] ? Xs : OpCtrl[0]) ^ Ys;
|
||||
|
||||
// format final result based on precision
|
||||
// - uses NaN-blocking format
|
||||
// - if there are any unsused bits the most significant bits are filled with 1s
|
||||
|
||||
// OpCtrl:
|
||||
// 00 - fsgnj - directly copy over sign value of Y
|
||||
// 01 - fsgnjn - negate sign value of Y
|
||||
// 10 - fsgnjx - XOR sign values of X and Y
|
||||
|
||||
// calculate the result's sign
|
||||
assign ResSgn = (OpCtrl[1] ? Xs : OpCtrl[0]) ^ Ys;
|
||||
|
||||
// format final result based on precision
|
||||
// - uses NaN-blocking format
|
||||
// - if there are any unsused bits the most significant bits are filled with 1s
|
||||
|
||||
if (`FPSIZES == 1)
|
||||
assign SgnRes = {ResSgn, X[`FLEN-2:0]};
|
||||
assign SgnRes = {ResSgn, X[`FLEN-2:0]};
|
||||
else if (`FPSIZES == 2)
|
||||
assign SgnRes = {~Fmt|ResSgn, X[`FLEN-2:`LEN1], Fmt ? X[`LEN1-1] : ResSgn, X[`LEN1-2:0]};
|
||||
assign SgnRes = {~Fmt|ResSgn, X[`FLEN-2:`LEN1], Fmt ? X[`LEN1-1] : ResSgn, X[`LEN1-2:0]};
|
||||
else if (`FPSIZES == 3) begin
|
||||
logic [2:0] SgnBits;
|
||||
logic [2:0] SgnBits;
|
||||
always_comb
|
||||
case (Fmt)
|
||||
`FMT: SgnBits = {ResSgn, X[`LEN1-1], X[`LEN2-1]};
|
||||
`FMT1: SgnBits = {1'b1, ResSgn, X[`LEN2-1]};
|
||||
`FMT1: SgnBits = {1'b1, ResSgn, X[`LEN2-1]};
|
||||
`FMT2: SgnBits = {2'b11, ResSgn};
|
||||
default: SgnBits = {3{1'bx}};
|
||||
endcase
|
||||
assign SgnRes = {SgnBits[2], X[`FLEN-2:`LEN1], SgnBits[1], X[`LEN1-2:`LEN2], SgnBits[0], X[`LEN2-2:0]};
|
||||
end else if (`FPSIZES == 4) begin
|
||||
logic [3:0] SgnBits;
|
||||
assign SgnRes = {SgnBits[2], X[`FLEN-2:`LEN1], SgnBits[1], X[`LEN1-2:`LEN2], SgnBits[0], X[`LEN2-2:0]};
|
||||
end else if (`FPSIZES == 4) begin
|
||||
logic [3:0] SgnBits;
|
||||
always_comb
|
||||
case (Fmt)
|
||||
`Q_FMT: SgnBits = {ResSgn, X[`D_LEN-1], X[`S_LEN-1], X[`H_LEN-1]};
|
||||
|
@ -73,7 +73,7 @@ module fsgninj (
|
|||
`S_FMT: SgnBits = {2'b11, ResSgn, X[`H_LEN-1]};
|
||||
`H_FMT: SgnBits = {3'b111, ResSgn};
|
||||
endcase
|
||||
assign SgnRes = {SgnBits[3], X[`Q_LEN-2:`D_LEN], SgnBits[2], X[`D_LEN-2:`S_LEN], SgnBits[1], X[`S_LEN-2:`H_LEN], SgnBits[0], X[`H_LEN-2:0]};
|
||||
end
|
||||
assign SgnRes = {SgnBits[3], X[`Q_LEN-2:`D_LEN], SgnBits[2], X[`D_LEN-2:`S_LEN], SgnBits[1], X[`S_LEN-2:`H_LEN], SgnBits[0], X[`H_LEN-2:0]};
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
|
@ -30,13 +30,13 @@
|
|||
`include "wally-config.vh"
|
||||
|
||||
module arrs(
|
||||
input logic clk,
|
||||
input logic areset,
|
||||
input logic clk,
|
||||
input logic areset,
|
||||
output logic reset
|
||||
);
|
||||
|
||||
logic metaStable;
|
||||
logic resetB;
|
||||
logic metaStable;
|
||||
logic resetB;
|
||||
|
||||
always_ff @(posedge clk , posedge areset) begin
|
||||
if (areset) begin
|
||||
|
|
|
@ -27,9 +27,9 @@
|
|||
`include "wally-config.vh"
|
||||
|
||||
module clockgater (
|
||||
input logic E,
|
||||
input logic SE,
|
||||
input logic CLK,
|
||||
input logic E,
|
||||
input logic SE,
|
||||
input logic CLK,
|
||||
output logic ECLK
|
||||
);
|
||||
|
||||
|
@ -39,10 +39,10 @@ module clockgater (
|
|||
// VERY IMPORTANT.
|
||||
// This part functionally models a clock gater, but does not necessarily meet the timing constrains a real standard cell would.
|
||||
// Do not use this in synthesis!
|
||||
logic enable_q;
|
||||
logic enable_q;
|
||||
always_latch begin
|
||||
if(~CLK) begin
|
||||
enable_q <= E | SE;
|
||||
enable_q <= E | SE;
|
||||
end
|
||||
end
|
||||
assign ECLK = enable_q & CLK;
|
||||
|
|
|
@ -49,39 +49,39 @@ module ram1p1rwbe #(parameter DEPTH=64, WIDTH=44) (
|
|||
// ***************************************************************************
|
||||
// TRUE SRAM macro
|
||||
// ***************************************************************************
|
||||
if ((`USE_SRAM == 1) & (WIDTH == 128) & (DEPTH == 64)) begin // Cache data subarray
|
||||
if ((`USE_SRAM == 1) & (WIDTH == 128) & (DEPTH == 64)) begin // Cache data subarray
|
||||
genvar index;
|
||||
// 64 x 128-bit SRAM
|
||||
logic [WIDTH-1:0] BitWriteMask;
|
||||
for (index=0; index < WIDTH; index++)
|
||||
assign BitWriteMask[index] = bwe[index/8];
|
||||
// 64 x 128-bit SRAM
|
||||
logic [WIDTH-1:0] BitWriteMask;
|
||||
for (index=0; index < WIDTH; index++)
|
||||
assign BitWriteMask[index] = bwe[index/8];
|
||||
ram1p1rwbe_64x128 sram1A (.CLK(clk), .CEB(~ce), .WEB(~we),
|
||||
.A(addr), .D(din),
|
||||
.BWEB(~BitWriteMask), .Q(dout));
|
||||
.A(addr), .D(din),
|
||||
.BWEB(~BitWriteMask), .Q(dout));
|
||||
|
||||
end else if ((`USE_SRAM == 1) & (WIDTH == 44) & (DEPTH == 64)) begin // RV64 cache tag
|
||||
genvar index;
|
||||
// 64 x 44-bit SRAM
|
||||
logic [WIDTH-1:0] BitWriteMask;
|
||||
for (index=0; index < WIDTH; index++)
|
||||
assign BitWriteMask[index] = bwe[index/8];
|
||||
ram1p1rwbe_64x44 sram1B (.CLK(clk), .CEB(~ce), .WEB(~we),
|
||||
.A(addr), .D(din),
|
||||
.BWEB(~BitWriteMask), .Q(dout));
|
||||
genvar index;
|
||||
// 64 x 44-bit SRAM
|
||||
logic [WIDTH-1:0] BitWriteMask;
|
||||
for (index=0; index < WIDTH; index++)
|
||||
assign BitWriteMask[index] = bwe[index/8];
|
||||
ram1p1rwbe_64x44 sram1B (.CLK(clk), .CEB(~ce), .WEB(~we),
|
||||
.A(addr), .D(din),
|
||||
.BWEB(~BitWriteMask), .Q(dout));
|
||||
|
||||
end else if ((`USE_SRAM == 1) & (WIDTH == 22) & (DEPTH == 64)) begin // RV32 cache tag
|
||||
genvar index;
|
||||
// 64 x 22-bit SRAM
|
||||
logic [WIDTH-1:0] BitWriteMask;
|
||||
for (index=0; index < WIDTH; index++)
|
||||
assign BitWriteMask[index] = bwe[index/8];
|
||||
ram1p1rwbe_64x22 sram1B (.CLK(clk), .CEB(~ce), .WEB(~we),
|
||||
.A(addr), .D(din),
|
||||
.BWEB(~BitWriteMask), .Q(dout));
|
||||
genvar index;
|
||||
// 64 x 22-bit SRAM
|
||||
logic [WIDTH-1:0] BitWriteMask;
|
||||
for (index=0; index < WIDTH; index++)
|
||||
assign BitWriteMask[index] = bwe[index/8];
|
||||
ram1p1rwbe_64x22 sram1B (.CLK(clk), .CEB(~ce), .WEB(~we),
|
||||
.A(addr), .D(din),
|
||||
.BWEB(~BitWriteMask), .Q(dout));
|
||||
|
||||
// ***************************************************************************
|
||||
// READ first SRAM model
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
// READ first SRAM model
|
||||
// ***************************************************************************
|
||||
end else begin: ram
|
||||
integer i;
|
||||
|
||||
|
@ -91,19 +91,18 @@ module ram1p1rwbe #(parameter DEPTH=64, WIDTH=44) (
|
|||
assign dout = RAM[addrd];
|
||||
|
||||
/* // Read
|
||||
always_ff @(posedge clk)
|
||||
if(ce) dout <= #1 mem[addr]; */
|
||||
|
||||
always_ff @(posedge clk)
|
||||
if(ce) dout <= #1 mem[addr]; */
|
||||
|
||||
// Write divided into part for bytes and part for extra msbs
|
||||
// Questa sim version 2022.3_2 does not allow multiple drivers for RAM when using always_ff.
|
||||
// Therefore these always blocks use the older always @(posedge clk)
|
||||
// Questa sim version 2022.3_2 does not allow multiple drivers for RAM when using always_ff.
|
||||
// Therefore these always blocks use the older always @(posedge clk)
|
||||
if(WIDTH >= 8)
|
||||
always @(posedge clk)
|
||||
if (ce & we)
|
||||
for(i = 0; i < WIDTH/8; i++)
|
||||
if(bwe[i]) RAM[addr][i*8 +: 8] <= #1 din[i*8 +: 8];
|
||||
|
||||
|
||||
if (WIDTH%8 != 0) // handle msbs if width not a multiple of 8
|
||||
always @(posedge clk)
|
||||
if (ce & we & bwe[WIDTH/8])
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
module ram1p1rwbe_64x128(
|
||||
input logic CLK,
|
||||
input logic CEB,
|
||||
input logic CEB,
|
||||
input logic WEB,
|
||||
input logic [5:0] A,
|
||||
input logic [127:0] D,
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
module ram1p1rwbe_64x22(
|
||||
input logic CLK,
|
||||
input logic CEB,
|
||||
input logic CEB,
|
||||
input logic WEB,
|
||||
input logic [5:0] A,
|
||||
input logic [21:0] D,
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
module ram1p1rwbe_64x44(
|
||||
input logic CLK,
|
||||
input logic CEB,
|
||||
input logic CEB,
|
||||
input logic WEB,
|
||||
input logic [5:0] A,
|
||||
input logic [43:0] D,
|
||||
|
|
|
@ -44,96 +44,94 @@ module ram2p1r1wbe #(parameter DEPTH=1024, WIDTH=68) (
|
|||
output logic [WIDTH-1:0] rd1
|
||||
);
|
||||
|
||||
logic [WIDTH-1:0] mem[DEPTH-1:0];
|
||||
localparam SRAMWIDTH = 32;
|
||||
localparam SRAMNUMSETS = SRAMWIDTH/WIDTH;
|
||||
logic [WIDTH-1:0] mem[DEPTH-1:0];
|
||||
localparam SRAMWIDTH = 32;
|
||||
localparam SRAMNUMSETS = SRAMWIDTH/WIDTH;
|
||||
|
||||
// ***************************************************************************
|
||||
// TRUE Smem macro
|
||||
// ***************************************************************************
|
||||
|
||||
if ((`USE_SRAM == 1) & (WIDTH == 68) & (DEPTH == 1024)) begin
|
||||
|
||||
ram2p1r1wbe_1024x68 memory1(.CLKA(clk), .CLKB(clk),
|
||||
.CEBA(~ce1), .CEBB(~ce2),
|
||||
.WEBA('0), .WEBB(~we2),
|
||||
.AA(ra1), .AB(wa2),
|
||||
.DA('0),
|
||||
.DB(wd2),
|
||||
.BWEBA('0), .BWEBB('1),
|
||||
.QA(rd1),
|
||||
.QB());
|
||||
if ((`USE_SRAM == 1) & (WIDTH == 68) & (DEPTH == 1024)) begin
|
||||
|
||||
ram2p1r1wbe_1024x68 memory1(.CLKA(clk), .CLKB(clk),
|
||||
.CEBA(~ce1), .CEBB(~ce2),
|
||||
.WEBA('0), .WEBB(~we2),
|
||||
.AA(ra1), .AB(wa2),
|
||||
.DA('0),
|
||||
.DB(wd2),
|
||||
.BWEBA('0), .BWEBB('1),
|
||||
.QA(rd1),
|
||||
.QB());
|
||||
|
||||
end else if ((`USE_SRAM == 1) & (WIDTH == 36) & (DEPTH == 1024)) begin
|
||||
|
||||
ram2p1r1wbe_1024x36 memory1(.CLKA(clk), .CLKB(clk),
|
||||
.CEBA(~ce1), .CEBB(~ce2),
|
||||
.WEBA('0), .WEBB(~we2),
|
||||
.AA(ra1), .AB(wa2),
|
||||
.DA('0),
|
||||
.DB(wd2),
|
||||
.BWEBA('0), .BWEBB('1),
|
||||
.QA(rd1),
|
||||
.QB());
|
||||
end else if ((`USE_SRAM == 1) & (WIDTH == 36) & (DEPTH == 1024)) begin
|
||||
|
||||
ram2p1r1wbe_1024x36 memory1(.CLKA(clk), .CLKB(clk),
|
||||
.CEBA(~ce1), .CEBB(~ce2),
|
||||
.WEBA('0), .WEBB(~we2),
|
||||
.AA(ra1), .AB(wa2),
|
||||
.DA('0),
|
||||
.DB(wd2),
|
||||
.BWEBA('0), .BWEBB('1),
|
||||
.QA(rd1),
|
||||
.QB());
|
||||
|
||||
end else if ((`USE_SRAM == 1) & (WIDTH == 2) & (DEPTH == 1024)) begin
|
||||
end else if ((`USE_SRAM == 1) & (WIDTH == 2) & (DEPTH == 1024)) begin
|
||||
|
||||
logic [SRAMWIDTH-1:0] SRAMReadData;
|
||||
logic [SRAMWIDTH-1:0] SRAMWriteData;
|
||||
logic [SRAMWIDTH-1:0] RD1Sets[SRAMNUMSETS-1:0];
|
||||
logic [SRAMNUMSETS-1:0] SRAMBitMaskPre;
|
||||
logic [SRAMWIDTH-1:0] SRAMBitMask;
|
||||
logic [$clog2(DEPTH)-1:0] RA1Q;
|
||||
|
||||
|
||||
onehotdecoder #($clog2(SRAMNUMSETS)) oh1(wa2[$clog2(SRAMNUMSETS)-1:0], SRAMBitMaskPre);
|
||||
genvar index;
|
||||
for (index = 0; index < SRAMNUMSETS; index++) begin:readdatalinesetsmux
|
||||
assign RD1Sets[index] = SRAMReadData[(index*WIDTH)+WIDTH-1 : (index*WIDTH)];
|
||||
assign SRAMWriteData[index*2+1:index*2] = wd2;
|
||||
assign SRAMBitMask[index*2+1:index*2] = {2{SRAMBitMaskPre[index]}};
|
||||
end
|
||||
flopen #($clog2(DEPTH)) mem_reg1 (clk, ce1, ra1, RA1Q);
|
||||
assign rd1 = RD1Sets[RA1Q[$clog2(SRAMWIDTH)-1:0]];
|
||||
ram2p1r1wbe_64x32 memory2(.CLKA(clk), .CLKB(clk),
|
||||
.CEBA(~ce1), .CEBB(~ce2),
|
||||
.WEBA('0), .WEBB(~we2),
|
||||
.AA(ra1[$clog2(DEPTH)-1:$clog2(SRAMNUMSETS)]),
|
||||
.AB(wa2[$clog2(DEPTH)-1:$clog2(SRAMNUMSETS)]),
|
||||
.DA('0),
|
||||
.DB(SRAMWriteData),
|
||||
.BWEBA('0), .BWEBB(SRAMBitMask),
|
||||
.QA(SRAMReadData),
|
||||
.QB());
|
||||
logic [SRAMWIDTH-1:0] SRAMReadData;
|
||||
logic [SRAMWIDTH-1:0] SRAMWriteData;
|
||||
logic [SRAMWIDTH-1:0] RD1Sets[SRAMNUMSETS-1:0];
|
||||
logic [SRAMNUMSETS-1:0] SRAMBitMaskPre;
|
||||
logic [SRAMWIDTH-1:0] SRAMBitMask;
|
||||
logic [$clog2(DEPTH)-1:0] RA1Q;
|
||||
|
||||
onehotdecoder #($clog2(SRAMNUMSETS)) oh1(wa2[$clog2(SRAMNUMSETS)-1:0], SRAMBitMaskPre);
|
||||
genvar index;
|
||||
for (index = 0; index < SRAMNUMSETS; index++) begin:readdatalinesetsmux
|
||||
assign RD1Sets[index] = SRAMReadData[(index*WIDTH)+WIDTH-1 : (index*WIDTH)];
|
||||
assign SRAMWriteData[index*2+1:index*2] = wd2;
|
||||
assign SRAMBitMask[index*2+1:index*2] = {2{SRAMBitMaskPre[index]}};
|
||||
end
|
||||
flopen #($clog2(DEPTH)) mem_reg1 (clk, ce1, ra1, RA1Q);
|
||||
assign rd1 = RD1Sets[RA1Q[$clog2(SRAMWIDTH)-1:0]];
|
||||
ram2p1r1wbe_64x32 memory2(.CLKA(clk), .CLKB(clk),
|
||||
.CEBA(~ce1), .CEBB(~ce2),
|
||||
.WEBA('0), .WEBB(~we2),
|
||||
.AA(ra1[$clog2(DEPTH)-1:$clog2(SRAMNUMSETS)]),
|
||||
.AB(wa2[$clog2(DEPTH)-1:$clog2(SRAMNUMSETS)]),
|
||||
.DA('0),
|
||||
.DB(SRAMWriteData),
|
||||
.BWEBA('0), .BWEBB(SRAMBitMask),
|
||||
.QA(SRAMReadData),
|
||||
.QB());
|
||||
|
||||
end else begin
|
||||
|
||||
// ***************************************************************************
|
||||
// READ first SRAM model
|
||||
// ***************************************************************************
|
||||
integer i;
|
||||
|
||||
end else begin
|
||||
|
||||
// ***************************************************************************
|
||||
// READ first SRAM model
|
||||
// ***************************************************************************
|
||||
integer i;
|
||||
|
||||
// Read
|
||||
logic [$clog2(DEPTH)-1:0] ra1d;
|
||||
flopen #($clog2(DEPTH)) adrreg(clk, ce1, ra1, ra1d);
|
||||
assign rd1 = mem[ra1d];
|
||||
|
||||
/* // Read
|
||||
always_ff @(posedge clk)
|
||||
if(ce1) rd1 <= #1 mem[ra1]; */
|
||||
|
||||
// Write divided into part for bytes and part for extra msbs
|
||||
if(WIDTH >= 8)
|
||||
always @(posedge clk)
|
||||
if (ce2 & we2)
|
||||
for(i = 0; i < WIDTH/8; i++)
|
||||
if(bwe2[i]) mem[wa2][i*8 +: 8] <= #1 wd2[i*8 +: 8];
|
||||
|
||||
if (WIDTH%8 != 0) // handle msbs if width not a multiple of 8
|
||||
always @(posedge clk)
|
||||
if (ce2 & we2 & bwe2[WIDTH/8])
|
||||
mem[wa2][WIDTH-1:WIDTH-WIDTH%8] <= #1 wd2[WIDTH-1:WIDTH-WIDTH%8];
|
||||
|
||||
/* // Read
|
||||
always_ff @(posedge clk)
|
||||
if(ce1) rd1 <= #1 mem[ra1]; */
|
||||
|
||||
// Write divided into part for bytes and part for extra msbs
|
||||
if(WIDTH >= 8)
|
||||
always @(posedge clk)
|
||||
if (ce2 & we2)
|
||||
for(i = 0; i < WIDTH/8; i++)
|
||||
if(bwe2[i]) mem[wa2][i*8 +: 8] <= #1 wd2[i*8 +: 8];
|
||||
|
||||
if (WIDTH%8 != 0) // handle msbs if width not a multiple of 8
|
||||
always @(posedge clk)
|
||||
if (ce2 & we2 & bwe2[WIDTH/8])
|
||||
mem[wa2][WIDTH-1:WIDTH-WIDTH%8] <= #1 wd2[WIDTH-1:WIDTH-WIDTH%8];
|
||||
end
|
||||
|
||||
|
||||
endmodule
|
||||
|
|
|
@ -27,8 +27,8 @@
|
|||
module ram2p1r1wbe_1024x36(
|
||||
input logic CLKA,
|
||||
input logic CLKB,
|
||||
input logic CEBA,
|
||||
input logic CEBB,
|
||||
input logic CEBA,
|
||||
input logic CEBB,
|
||||
input logic WEBA,
|
||||
input logic WEBB,
|
||||
input logic [9:0] AA,
|
||||
|
@ -43,12 +43,12 @@ module ram2p1r1wbe_1024x36(
|
|||
|
||||
// replace "generic1024x36RAM" with "TSDN..1024X36.." module from your memory vendor
|
||||
//generic1024x36RAM sramIP (.CLKA, .CLKB, .CEBA, .CEBB, .WEBA, .WEBB,
|
||||
// .AA, .AB, .DA, .DB, .BWEBA, .BWEBB, .QA, .QB);
|
||||
// .AA, .AB, .DA, .DB, .BWEBA, .BWEBB, .QA, .QB);
|
||||
// use part of a larger RAM to avoid generating more flavors of RAM
|
||||
logic [67:0] QAfull, QBfull;
|
||||
TSDN28HPCPA1024X68M4MW sramIP(.CLKA, .CLKB, .CEBA, .CEBB, .WEBA, .WEBB,
|
||||
.AA, .AB, .DA({32'b0, DA[35:0]}), .DB({32'b0, DB[35:0]}),
|
||||
.BWEBA({32'b0, BWEBA[35:0]}), .BWEBB({32'b0, BWEBB[35:0]}), .QA(QAfull), .QB(QBfull));
|
||||
.AA, .AB, .DA({32'b0, DA[35:0]}), .DB({32'b0, DB[35:0]}),
|
||||
.BWEBA({32'b0, BWEBA[35:0]}), .BWEBB({32'b0, BWEBB[35:0]}), .QA(QAfull), .QB(QBfull));
|
||||
assign QA = QAfull[35:0];
|
||||
assign QB = QBfull[35:0];
|
||||
|
||||
|
|
|
@ -27,8 +27,8 @@
|
|||
module ram2p1r1wbe_1024x68(
|
||||
input logic CLKA,
|
||||
input logic CLKB,
|
||||
input logic CEBA,
|
||||
input logic CEBB,
|
||||
input logic CEBA,
|
||||
input logic CEBB,
|
||||
input logic WEBA,
|
||||
input logic WEBB,
|
||||
input logic [9:0] AA,
|
||||
|
@ -43,8 +43,8 @@ module ram2p1r1wbe_1024x68(
|
|||
|
||||
// replace "generic1024x68RAM" with "TSDN..1024X68.." module from your memory vendor
|
||||
//generic1024x68RAM sramIP (.CLKA, .CLKB, .CEBA, .CEBB, .WEBA, .WEBB,
|
||||
// .AA, .AB, .DA, .DB, .BWEBA, .BWEBB, .QA, .QB);
|
||||
// .AA, .AB, .DA, .DB, .BWEBA, .BWEBB, .QA, .QB);
|
||||
TSDN28HPCPA1024X68M4MW sramIP(.CLKA, .CLKB, .CEBA, .CEBB, .WEBA, .WEBB,
|
||||
.AA, .AB, .DA, .DB, .BWEBA, .BWEBB, .QA, .QB);
|
||||
.AA, .AB, .DA, .DB, .BWEBA, .BWEBB, .QA, .QB);
|
||||
|
||||
endmodule
|
||||
|
|
|
@ -27,8 +27,8 @@
|
|||
module ram2p1r1wbe_128x64(
|
||||
input logic CLKA,
|
||||
input logic CLKB,
|
||||
input logic CEBA,
|
||||
input logic CEBB,
|
||||
input logic CEBA,
|
||||
input logic CEBB,
|
||||
input logic WEBA,
|
||||
input logic WEBB,
|
||||
input logic [6:0] AA,
|
||||
|
@ -43,8 +43,8 @@ module ram2p1r1wbe_128x64(
|
|||
|
||||
// replace "generic128x64RAM" with "TSDN..128X64.." module from your memory vendor
|
||||
TSDN28HPCPA128X64M4FW sramIP (.CLKA, .CLKB, .CEBA, .CEBB, .WEBA, .WEBB,
|
||||
.AA, .AB, .DA, .DB, .BWEBA, .BWEBB, .QA, .QB);
|
||||
.AA, .AB, .DA, .DB, .BWEBA, .BWEBB, .QA, .QB);
|
||||
// generic128x64RAM sramIP (.CLKA, .CLKB, .CEBA, .CEBB, .WEBA, .WEBB,
|
||||
// .AA, .AB, .DA, .DB, .BWEBA, .BWEBB, .QA, .QB);
|
||||
// .AA, .AB, .DA, .DB, .BWEBA, .BWEBB, .QA, .QB);
|
||||
|
||||
endmodule
|
||||
|
|
|
@ -27,8 +27,8 @@
|
|||
module ram2p1r1wbe_2048x64(
|
||||
input logic CLKA,
|
||||
input logic CLKB,
|
||||
input logic CEBA,
|
||||
input logic CEBB,
|
||||
input logic CEBA,
|
||||
input logic CEBB,
|
||||
input logic WEBA,
|
||||
input logic WEBB,
|
||||
input logic [8:0] AA,
|
||||
|
@ -43,8 +43,8 @@ module ram2p1r1wbe_2048x64(
|
|||
|
||||
// replace "generic2048x64RAM" with "TSDN..2048X64.." module from your memory vendor
|
||||
TSDN28HPCPA2048X64MMFW sramIP (.CLKA, .CLKB, .CEBA, .CEBB, .WEBA, .WEBB,
|
||||
.AA, .AB, .DA, .DB, .BWEBA, .BWEBB, .QA, .QB);
|
||||
.AA, .AB, .DA, .DB, .BWEBA, .BWEBB, .QA, .QB);
|
||||
// generic2048x64RAM sramIP (.CLKA, .CLKB, .CEBA, .CEBB, .WEBA, .WEBB,
|
||||
// .AA, .AB, .DA, .DB, .BWEBA, .BWEBB, .QA, .QB);
|
||||
// .AA, .AB, .DA, .DB, .BWEBA, .BWEBB, .QA, .QB);
|
||||
|
||||
endmodule
|
||||
|
|
|
@ -27,8 +27,8 @@
|
|||
module ram2p1r1wbe_64x32(
|
||||
input logic CLKA,
|
||||
input logic CLKB,
|
||||
input logic CEBA,
|
||||
input logic CEBB,
|
||||
input logic CEBA,
|
||||
input logic CEBB,
|
||||
input logic WEBA,
|
||||
input logic WEBB,
|
||||
input logic [5:0] AA,
|
||||
|
@ -43,7 +43,7 @@ module ram2p1r1wbe_64x32(
|
|||
|
||||
// replace "generic64x32RAM" with "TSDN..64X32.." module from your memory vendor
|
||||
//generic64x32RAM sramIP (.CLKA, .CLKB, .CEBA, .CEBB, .WEBA, .WEBB,
|
||||
// .AA, .AB, .DA, .DB, .BWEBA, .BWEBB, .QA, .QB);
|
||||
// .AA, .AB, .DA, .DB, .BWEBA, .BWEBB, .QA, .QB);
|
||||
TSDN28HPCPA64X32M4MW sramIP(.CLKA, .CLKB, .CEBA, .CEBB, .WEBA, .WEBB,
|
||||
.AA, .AB, .DA, .DB, .BWEBA, .BWEBB, .QA, .QB);
|
||||
.AA, .AB, .DA, .DB, .BWEBA, .BWEBB, .QA, .QB);
|
||||
endmodule
|
||||
|
|
|
@ -28,8 +28,8 @@
|
|||
`include "wally-config.vh"
|
||||
|
||||
module rom1p1r #(parameter ADDR_WIDTH = 8,
|
||||
parameter DATA_WIDTH = 32,
|
||||
parameter PRELOAD_ENABLED = 0)
|
||||
parameter DATA_WIDTH = 32,
|
||||
parameter PRELOAD_ENABLED = 0)
|
||||
(input logic clk,
|
||||
input logic ce,
|
||||
input logic [ADDR_WIDTH-1:0] addr,
|
||||
|
@ -37,7 +37,7 @@ module rom1p1r #(parameter ADDR_WIDTH = 8,
|
|||
);
|
||||
|
||||
// Core Memory
|
||||
logic [DATA_WIDTH-1:0] ROM [(2**ADDR_WIDTH)-1:0];
|
||||
logic [DATA_WIDTH-1:0] ROM [(2**ADDR_WIDTH)-1:0];
|
||||
/* if ((`USE_SRAM == 1) & (ADDR_WDITH == 7) & (DATA_WIDTH == 64)) begin
|
||||
rom1p1r_128x64 rom1 (.CLK(clk), .CEB(~ce), .A(addr[6:0]), .Q(dout));
|
||||
|
||||
|
@ -46,55 +46,55 @@ module rom1p1r #(parameter ADDR_WIDTH = 8,
|
|||
|
||||
end else begin */
|
||||
always @ (posedge clk) begin
|
||||
if(ce) dout <= ROM[addr];
|
||||
if(ce) dout <= ROM[addr];
|
||||
end
|
||||
|
||||
// for FPGA, initialize with zero-stage bootloader
|
||||
if(PRELOAD_ENABLED)
|
||||
initial begin
|
||||
ROM[0] = 64'h9581819300002197;
|
||||
ROM[1] = 64'h4281420141014081;
|
||||
ROM[2] = 64'h4481440143814301;
|
||||
ROM[3] = 64'h4681460145814501;
|
||||
ROM[4] = 64'h4881480147814701;
|
||||
ROM[5] = 64'h4a814a0149814901;
|
||||
ROM[6] = 64'h4c814c014b814b01;
|
||||
ROM[7] = 64'h4e814e014d814d01;
|
||||
ROM[8] = 64'h0110011b4f814f01;
|
||||
ROM[9] = 64'h059b45011161016e;
|
||||
ROM[10] = 64'h0004063705fe0010;
|
||||
ROM[11] = 64'h05a000ef8006061b;
|
||||
ROM[12] = 64'h0ff003930000100f;
|
||||
ROM[13] = 64'h4e952e3110060e37;
|
||||
ROM[14] = 64'hc602829b0053f2b7;
|
||||
ROM[15] = 64'h2023fe02dfe312fd;
|
||||
ROM[16] = 64'h829b0053f2b7007e;
|
||||
ROM[17] = 64'hfe02dfe312fdc602;
|
||||
ROM[18] = 64'h4de31efd000e2023;
|
||||
ROM[19] = 64'h059bf1402573fdd0;
|
||||
ROM[20] = 64'h0000061705e20870;
|
||||
ROM[21] = 64'h0010029b01260613;
|
||||
ROM[22] = 64'h11010002806702fe;
|
||||
ROM[23] = 64'h84b2842ae426e822;
|
||||
ROM[24] = 64'h892ee04aec064511;
|
||||
ROM[25] = 64'h06e000ef07e000ef;
|
||||
ROM[26] = 64'h979334fd02905563;
|
||||
ROM[27] = 64'h07930177d4930204;
|
||||
ROM[28] = 64'h4089093394be2004;
|
||||
ROM[29] = 64'h04138522008905b3;
|
||||
ROM[30] = 64'h19e3014000ef2004;
|
||||
ROM[31] = 64'h64a2644260e2fe94;
|
||||
ROM[32] = 64'h6749808261056902;
|
||||
ROM[33] = 64'hdfed8b8510472783;
|
||||
ROM[34] = 64'h2423479110a73823;
|
||||
ROM[35] = 64'h10472783674910f7;
|
||||
ROM[36] = 64'h20058693ffed8b89;
|
||||
ROM[37] = 64'h05a1118737836749;
|
||||
ROM[38] = 64'hfed59be3fef5bc23;
|
||||
ROM[39] = 64'h1047278367498082;
|
||||
ROM[40] = 64'h47858082dfed8b85;
|
||||
ROM[41] = 64'h40a7853b4015551b;
|
||||
ROM[42] = 64'h808210a7a02367c9;
|
||||
ROM[0] = 64'h9581819300002197;
|
||||
ROM[1] = 64'h4281420141014081;
|
||||
ROM[2] = 64'h4481440143814301;
|
||||
ROM[3] = 64'h4681460145814501;
|
||||
ROM[4] = 64'h4881480147814701;
|
||||
ROM[5] = 64'h4a814a0149814901;
|
||||
ROM[6] = 64'h4c814c014b814b01;
|
||||
ROM[7] = 64'h4e814e014d814d01;
|
||||
ROM[8] = 64'h0110011b4f814f01;
|
||||
ROM[9] = 64'h059b45011161016e;
|
||||
ROM[10] = 64'h0004063705fe0010;
|
||||
ROM[11] = 64'h05a000ef8006061b;
|
||||
ROM[12] = 64'h0ff003930000100f;
|
||||
ROM[13] = 64'h4e952e3110060e37;
|
||||
ROM[14] = 64'hc602829b0053f2b7;
|
||||
ROM[15] = 64'h2023fe02dfe312fd;
|
||||
ROM[16] = 64'h829b0053f2b7007e;
|
||||
ROM[17] = 64'hfe02dfe312fdc602;
|
||||
ROM[18] = 64'h4de31efd000e2023;
|
||||
ROM[19] = 64'h059bf1402573fdd0;
|
||||
ROM[20] = 64'h0000061705e20870;
|
||||
ROM[21] = 64'h0010029b01260613;
|
||||
ROM[22] = 64'h11010002806702fe;
|
||||
ROM[23] = 64'h84b2842ae426e822;
|
||||
ROM[24] = 64'h892ee04aec064511;
|
||||
ROM[25] = 64'h06e000ef07e000ef;
|
||||
ROM[26] = 64'h979334fd02905563;
|
||||
ROM[27] = 64'h07930177d4930204;
|
||||
ROM[28] = 64'h4089093394be2004;
|
||||
ROM[29] = 64'h04138522008905b3;
|
||||
ROM[30] = 64'h19e3014000ef2004;
|
||||
ROM[31] = 64'h64a2644260e2fe94;
|
||||
ROM[32] = 64'h6749808261056902;
|
||||
ROM[33] = 64'hdfed8b8510472783;
|
||||
ROM[34] = 64'h2423479110a73823;
|
||||
ROM[35] = 64'h10472783674910f7;
|
||||
ROM[36] = 64'h20058693ffed8b89;
|
||||
ROM[37] = 64'h05a1118737836749;
|
||||
ROM[38] = 64'hfed59be3fef5bc23;
|
||||
ROM[39] = 64'h1047278367498082;
|
||||
ROM[40] = 64'h47858082dfed8b85;
|
||||
ROM[41] = 64'h40a7853b4015551b;
|
||||
ROM[42] = 64'h808210a7a02367c9;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
module rom1p1r_128x32(
|
||||
input logic CLK,
|
||||
input logic CEB,
|
||||
input logic CEB,
|
||||
input logic [6:0] A,
|
||||
output logic [31:0] Q
|
||||
);
|
||||
|
|
|
@ -25,14 +25,14 @@
|
|||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
module rom1p1r_128x64(
|
||||
input logic CLK,
|
||||
input logic CEB,
|
||||
input logic CLK,
|
||||
input logic CEB,
|
||||
input logic [6:0] A,
|
||||
output logic [63:0] Q
|
||||
);
|
||||
|
||||
// replace "generic64x128RAM" with "TS3N..64X128.." module from your memory vendor
|
||||
ts3n28hpcpa128x64m8m romIP (.CLK, .CEB, .A, .Q);
|
||||
ts3n28hpcpa128x64m8m romIP (.CLK, .CEB, .A, .Q);
|
||||
// generic64x128ROM romIP (.CLK, .CEB, .A, .Q);
|
||||
|
||||
endmodule
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
`include "wally-config.vh"
|
||||
|
||||
module bmuctrl(
|
||||
input logic clk, reset,
|
||||
input logic clk, reset,
|
||||
// Decode stage control signals
|
||||
input logic StallD, FlushD, // Stall, flush Decode stage
|
||||
input logic [31:0] InstrD, // Instruction in Decode stage
|
||||
|
@ -43,7 +43,7 @@ module bmuctrl(
|
|||
output logic BSubArithD, // TRUE if ext, clr, andn, orn, xnor instruction in Decode Stage
|
||||
output logic IllegalBitmanipInstrD, // Indicates if it is unrecognized B instruction in Decode Stage
|
||||
// Execute stage control signals
|
||||
input logic StallE, FlushE, // Stall, flush Execute stage
|
||||
input logic StallE, FlushE, // Stall, flush Execute stage
|
||||
output logic [2:0] ALUSelectD, // ALU select
|
||||
output logic [1:0] BSelectE, // Indicates if ZBA_ZBB_ZBC_ZBS instruction in one-hot encoding
|
||||
output logic [2:0] ZBBSelectE, // ZBB mux select signal
|
||||
|
@ -66,7 +66,7 @@ module bmuctrl(
|
|||
|
||||
`define BMUCTRLW 17
|
||||
|
||||
logic [`BMUCTRLW-1:0] BMUControlsD; // Main B Instructions Decoder control signals
|
||||
logic [`BMUCTRLW-1:0] BMUControlsD; // Main B Instructions Decoder control signals
|
||||
|
||||
// Extract fields
|
||||
assign OpD = InstrD[6:0];
|
||||
|
@ -180,4 +180,4 @@ module bmuctrl(
|
|||
|
||||
// BMU Execute stage pipieline control register
|
||||
flopenrc#(10) controlregBMU(clk, reset, FlushE, ~StallE, {BSelectD, ZBBSelectD, BRegWriteD, BComparatorSignedD, BALUControlD}, {BSelectE, ZBBSelectE, BRegWriteE, BComparatorSignedE, BALUControlE});
|
||||
endmodule
|
||||
endmodule
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
|
||||
|
||||
module controller(
|
||||
input logic clk, reset,
|
||||
input logic clk, reset,
|
||||
// Decode stage control signals
|
||||
input logic StallD, FlushD, // Stall, flush Decode stage
|
||||
input logic [31:0] InstrD, // Instruction in Decode stage
|
||||
|
@ -41,11 +41,11 @@ module controller(
|
|||
output logic JumpD, // Jump instruction
|
||||
output logic BranchD, // Branch instruction
|
||||
// Execute stage control signals
|
||||
input logic StallE, FlushE, // Stall, flush Execute stage
|
||||
input logic StallE, FlushE, // Stall, flush Execute stage
|
||||
input logic [1:0] FlagsE, // Comparison flags ({eq, lt})
|
||||
input logic FWriteIntE, // Write integer register, coming from FPU controller
|
||||
output logic PCSrcE, // Select signal to choose next PC (for datapath and Hazard unit)
|
||||
output logic ALUSrcAE, ALUSrcBE, // ALU operands
|
||||
output logic ALUSrcAE, ALUSrcBE, // ALU operands
|
||||
output logic ALUResultSrcE, // Selects result to pass on to Memory stage
|
||||
output logic [2:0] ALUSelectE, // ALU mux select signal
|
||||
output logic MemReadE, CSRReadE, // Instruction reads memory, reads a CSR (needed for Hazard unit)
|
||||
|
@ -74,7 +74,7 @@ module controller(
|
|||
output logic FWriteIntM, // FPU controller writes integer register file
|
||||
// Writeback stage control signals
|
||||
input logic StallW, FlushW, // Stall, flush Writeback stage
|
||||
output logic RegWriteW, IntDivW, // Instruction writes a register, is an integer divide
|
||||
output logic RegWriteW, IntDivW, // Instruction writes a register, is an integer divide
|
||||
output logic [2:0] ResultSrcW, // Select source of result to write back to register file
|
||||
// Stall during CSRs
|
||||
output logic CSRWriteFenceM, // CSR write or fence instruction; needs to flush the following instructions
|
||||
|
@ -89,16 +89,16 @@ module controller(
|
|||
`define CTRLW 23
|
||||
|
||||
// pipelined control signals
|
||||
logic RegWriteD, RegWriteE; // RegWrite (register will be written)
|
||||
logic RegWriteD, RegWriteE; // RegWrite (register will be written)
|
||||
logic [2:0] ResultSrcD, ResultSrcE, ResultSrcM; // Select which result to write back to register file
|
||||
logic [1:0] MemRWD, MemRWE; // Store (write to memory)
|
||||
logic ALUOpD; // 0 for address generation, 1 for all other operations (must use Funct3)
|
||||
logic BaseW64D; // W64 for Base instructions specifically
|
||||
logic BaseRegWriteD; // Indicates if Base instruction register write instruction
|
||||
logic BaseSubArithD; // Indicates if Base instruction subtracts, sra, slt, sltu
|
||||
logic ALUOpD; // 0 for address generation, 1 for all other operations (must use Funct3)
|
||||
logic BaseW64D; // W64 for Base instructions specifically
|
||||
logic BaseRegWriteD; // Indicates if Base instruction register write instruction
|
||||
logic BaseSubArithD; // Indicates if Base instruction subtracts, sra, slt, sltu
|
||||
logic BaseALUSrcBD; // Base instruction ALU B source select signal
|
||||
logic [2:0] ALUControlD; // Determines ALU operation
|
||||
logic ALUSrcAD, ALUSrcBD; // ALU inputs
|
||||
logic ALUSrcAD, ALUSrcBD; // ALU inputs
|
||||
logic ALUResultSrcD, W64D, MDUD; // ALU result, is RV64 W-type, is multiply/divide instruction
|
||||
logic CSRZeroSrcD; // Ignore setting and clearing zeros to CSR
|
||||
logic CSRReadD; // CSR read instruction
|
||||
|
@ -115,7 +115,7 @@ module controller(
|
|||
logic BranchTakenE; // Branch is taken
|
||||
logic eqE, ltE; // Comparator outputs
|
||||
logic unused;
|
||||
logic BranchFlagE; // Branch flag to use (chosen between eq or lt)
|
||||
logic BranchFlagE; // Branch flag to use (chosen between eq or lt)
|
||||
logic IEURegWriteE; // Register write
|
||||
logic BRegWriteE; // Register write from BMU controller in Execute Stage
|
||||
logic IllegalERegAdrD; // RV32E attempts to write upper 16 registers
|
||||
|
@ -146,29 +146,29 @@ module controller(
|
|||
logic Funct7ZeroD, Funct7b5D, IShiftD, INoShiftD;
|
||||
logic Funct7ShiftZeroD, Funct7Shiftb5D;
|
||||
|
||||
assign Funct7ZeroD = (Funct7D == 7'b0000000); // most R-type instructions
|
||||
assign Funct7b5D = (Funct7D == 7'b0100000); // srai, sub
|
||||
assign Funct7ZeroD = (Funct7D == 7'b0000000); // most R-type instructions
|
||||
assign Funct7b5D = (Funct7D == 7'b0100000); // srai, sub
|
||||
assign Funct7ShiftZeroD = (`XLEN==64) ? (Funct7D[6:1] == 6'b000000) : Funct7ZeroD;
|
||||
assign Funct7Shiftb5D = (`XLEN==64) ? (Funct7D[6:1] == 6'b010000) : Funct7b5D;
|
||||
assign IShiftD = (Funct3D == 3'b001 & Funct7ShiftZeroD) | (Funct3D == 3'b101 & (Funct7ShiftZeroD | Funct7Shiftb5D)); // slli, srli, srai, or w forms
|
||||
assign INoShiftD = ((Funct3D != 3'b001) & (Funct3D != 3'b101));
|
||||
assign IFunctD = IShiftD | INoShiftD;
|
||||
assign RFunctD = ((Funct3D == 3'b000 | Funct3D == 3'b101) & Funct7b5D) | Funct7ZeroD;
|
||||
assign MFunctD = (Funct7D == 7'b0000001) & (`M_SUPPORTED | (`ZMMUL_SUPPORTED & ~Funct3D[2])); // muldiv
|
||||
assign LFunctD = Funct3D == 3'b000 | Funct3D == 3'b001 | Funct3D == 3'b010 | Funct3D == 3'b100 | Funct3D == 3'b101 |
|
||||
((`XLEN == 64) & (Funct3D == 3'b011 | Funct3D == 3'b110));
|
||||
assign SFunctD = Funct3D == 3'b000 | Funct3D == 3'b001 | Funct3D == 3'b010 |
|
||||
((`XLEN == 64) & (Funct3D == 3'b011));
|
||||
assign BFunctD = (Funct3D[2:1] != 2'b01); // legal branches
|
||||
assign JFunctD = (Funct3D == 3'b000);
|
||||
assign IShiftD = (Funct3D == 3'b001 & Funct7ShiftZeroD) | (Funct3D == 3'b101 & (Funct7ShiftZeroD | Funct7Shiftb5D)); // slli, srli, srai, or w forms
|
||||
assign INoShiftD = ((Funct3D != 3'b001) & (Funct3D != 3'b101));
|
||||
assign IFunctD = IShiftD | INoShiftD;
|
||||
assign RFunctD = ((Funct3D == 3'b000 | Funct3D == 3'b101) & Funct7b5D) | Funct7ZeroD;
|
||||
assign MFunctD = (Funct7D == 7'b0000001) & (`M_SUPPORTED | (`ZMMUL_SUPPORTED & ~Funct3D[2])); // muldiv
|
||||
assign LFunctD = Funct3D == 3'b000 | Funct3D == 3'b001 | Funct3D == 3'b010 | Funct3D == 3'b100 | Funct3D == 3'b101 |
|
||||
((`XLEN == 64) & (Funct3D == 3'b011 | Funct3D == 3'b110));
|
||||
assign SFunctD = Funct3D == 3'b000 | Funct3D == 3'b001 | Funct3D == 3'b010 |
|
||||
((`XLEN == 64) & (Funct3D == 3'b011));
|
||||
assign BFunctD = (Funct3D[2:1] != 2'b01); // legal branches
|
||||
assign JFunctD = (Funct3D == 3'b000);
|
||||
end else begin:legalcheck2
|
||||
assign IFunctD = 1; // Don't bother to separate out shift decoding
|
||||
assign RFunctD = ~Funct7D[0]; // Not a multiply
|
||||
assign MFunctD = Funct7D[0] & (`M_SUPPORTED | (`ZMMUL_SUPPORTED & ~Funct3D[2])); // muldiv
|
||||
assign LFunctD = 1; // don't bother to check Funct3 for loads
|
||||
assign SFunctD = 1; // don't bother to check Funct3 for stores
|
||||
assign BFunctD = 1; // don't bother to check Funct3 for branches
|
||||
assign JFunctD = 1; // don't bother to check Funct3 for jumps
|
||||
assign IFunctD = 1; // Don't bother to separate out shift decoding
|
||||
assign RFunctD = ~Funct7D[0]; // Not a multiply
|
||||
assign MFunctD = Funct7D[0] & (`M_SUPPORTED | (`ZMMUL_SUPPORTED & ~Funct3D[2])); // muldiv
|
||||
assign LFunctD = 1; // don't bother to check Funct3 for loads
|
||||
assign SFunctD = 1; // don't bother to check Funct3 for stores
|
||||
assign BFunctD = 1; // don't bother to check Funct3 for branches
|
||||
assign JFunctD = 1; // don't bother to check Funct3 for jumps
|
||||
end
|
||||
|
||||
// Main Instruction Decoder
|
||||
|
@ -182,7 +182,7 @@ module controller(
|
|||
7'b0000111: ControlsD = `CTRLW'b0_000_01_10_001_0_0_0_0_0_0_0_0_0_00_1; // flw - only legal if FP supported
|
||||
7'b0001111: if (`ZIFENCEI_SUPPORTED)
|
||||
ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_0_1_0_00_0; // fence
|
||||
else
|
||||
else
|
||||
ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_0_0_0_00_0; // fence treated as nop
|
||||
7'b0010011: if (IFunctD)
|
||||
ControlsD = `CTRLW'b1_000_01_00_000_0_1_0_0_0_0_0_0_0_00_0; // I-type ALU
|
||||
|
@ -337,4 +337,4 @@ module controller(
|
|||
// the synchronous DTIM cannot read immediately after write
|
||||
// a cache cannot read or write immediately after a write
|
||||
assign StoreStallD = MemRWE[0] & ((MemRWD[1] | (MemRWD[0] & `DCACHE_SUPPORTED)) | (|AtomicD));
|
||||
endmodule
|
||||
endmodule
|
||||
|
|
|
@ -108,7 +108,7 @@ module datapath (
|
|||
flopenrc #(5) Rs1EReg(clk, reset, FlushE, ~StallE, Rs1D, Rs1E);
|
||||
flopenrc #(5) Rs2EReg(clk, reset, FlushE, ~StallE, Rs2D, Rs2E);
|
||||
flopenrc #(5) RdEReg(clk, reset, FlushE, ~StallE, RdD, RdE);
|
||||
|
||||
|
||||
mux3 #(`XLEN) faemux(R1E, ResultW, IFResultM, ForwardAE, ForwardedSrcAE);
|
||||
mux3 #(`XLEN) fbemux(R2E, ResultW, IFResultM, ForwardBE, ForwardedSrcBE);
|
||||
comparator #(`XLEN) comp(ForwardedSrcAE, ForwardedSrcBE, BranchSignedE, FlagsE);
|
||||
|
@ -121,7 +121,7 @@ module datapath (
|
|||
// Memory stage pipeline register
|
||||
flopenrc #(`XLEN) SrcAMReg(clk, reset, FlushM, ~StallM, SrcAE, SrcAM);
|
||||
flopenrc #(`XLEN) IEUResultMReg(clk, reset, FlushM, ~StallM, IEUResultE, IEUResultM);
|
||||
flopenrc #(5) RdMReg(clk, reset, FlushM, ~StallM, RdE, RdM);
|
||||
flopenrc #(5) RdMReg(clk, reset, FlushM, ~StallM, RdE, RdM);
|
||||
flopenrc #(`XLEN) WriteDataMReg(clk, reset, FlushM, ~StallM, ForwardedSrcBE, WriteDataM);
|
||||
|
||||
// Writeback stage pipeline register and logic
|
||||
|
|
|
@ -34,7 +34,7 @@ module forward(
|
|||
input logic [4:0] Rs1D, Rs2D, Rs1E, Rs2E, RdE, RdM, RdW, // Source and destination registers
|
||||
input logic MemReadE, MDUE, CSRReadE, // Execute stage instruction is a load (MemReadE), divide (MDUE), or CSR read (CSRReadE)
|
||||
input logic RegWriteM, RegWriteW, // Instruction in Memory or Writeback stage writes register file
|
||||
input logic FCvtIntE, // FPU convert float to int
|
||||
input logic FCvtIntE, // FPU convert float to int
|
||||
input logic SCE, // Store Conditional instruction
|
||||
// Forwarding controls
|
||||
output logic [1:0] ForwardAE, ForwardBE, // Select signals for forwarding multiplexers
|
||||
|
|
|
@ -29,27 +29,27 @@
|
|||
`include "wally-config.vh"
|
||||
|
||||
module ieu (
|
||||
input logic clk, reset,
|
||||
input logic clk, reset,
|
||||
// Decode stage signals
|
||||
input logic [31:0] InstrD, // Instruction
|
||||
input logic IllegalIEUFPUInstrD, // Illegal instruction
|
||||
output logic IllegalBaseInstrD, // Illegal I-type instruction, or illegal RV32 access to upper 16 registers
|
||||
input logic [31:0] InstrD, // Instruction
|
||||
input logic IllegalIEUFPUInstrD, // Illegal instruction
|
||||
output logic IllegalBaseInstrD, // Illegal I-type instruction, or illegal RV32 access to upper 16 registers
|
||||
// Execute stage signals
|
||||
input logic [`XLEN-1:0] PCE, // PC
|
||||
input logic [`XLEN-1:0] PCLinkE, // PC + 4
|
||||
output logic PCSrcE, // Select next PC (between PC+4 and IEUAdrE)
|
||||
input logic FWriteIntE, FCvtIntE, // FPU writes to integer register file, FPU converts float to int
|
||||
output logic PCSrcE, // Select next PC (between PC+4 and IEUAdrE)
|
||||
input logic FWriteIntE, FCvtIntE, // FPU writes to integer register file, FPU converts float to int
|
||||
output logic [`XLEN-1:0] IEUAdrE, // Memory address
|
||||
output logic IntDivE, W64E, // Integer divide, RV64 W-type instruction
|
||||
output logic [2:0] Funct3E, // Funct3 instruction field
|
||||
output logic IntDivE, W64E, // Integer divide, RV64 W-type instruction
|
||||
output logic [2:0] Funct3E, // Funct3 instruction field
|
||||
output logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, // ALU src inputs before the mux choosing between them and PCE to put in srcA/B
|
||||
output logic [4:0] RdE, // Destination register
|
||||
// Memory stage signals
|
||||
input logic SquashSCW, // Squash store conditional, from LSU
|
||||
output logic [1:0] MemRWM, // Read/write control goes to LSU
|
||||
output logic [1:0] AtomicM, // Atomic control goes to LSU
|
||||
input logic SquashSCW, // Squash store conditional, from LSU
|
||||
output logic [1:0] MemRWM, // Read/write control goes to LSU
|
||||
output logic [1:0] AtomicM, // Atomic control goes to LSU
|
||||
output logic [`XLEN-1:0] WriteDataM, // Write data to LSU
|
||||
output logic [2:0] Funct3M, // Funct3 (size and signedness) to LSU
|
||||
output logic [2:0] Funct3M, // Funct3 (size and signedness) to LSU
|
||||
output logic [`XLEN-1:0] SrcAM, // ALU SrcA to Privileged unit and FPU
|
||||
output logic [4:0] RdM, // Destination register
|
||||
input logic [`XLEN-1:0] FIntResM, // Integer result from FPU (fmv, fclass, fcmp)
|
||||
|
@ -66,12 +66,12 @@ module ieu (
|
|||
output logic [4:0] RdW, // Destination register
|
||||
input logic [`XLEN-1:0] ReadDataW, // LSU's read data
|
||||
// Hazard unit signals
|
||||
input logic StallD, StallE, StallM, StallW, // Stall signals from hazard unit
|
||||
input logic FlushD, FlushE, FlushM, FlushW, // Flush signals
|
||||
output logic FCvtIntStallD, LoadStallD, // Stall causes from IEU to hazard unit
|
||||
input logic StallD, StallE, StallM, StallW, // Stall signals from hazard unit
|
||||
input logic FlushD, FlushE, FlushM, FlushW, // Flush signals
|
||||
output logic FCvtIntStallD, LoadStallD, // Stall causes from IEU to hazard unit
|
||||
output logic MDUStallD, CSRRdStallD, StoreStallD,
|
||||
output logic CSRReadM, CSRWriteM, PrivilegedM,// CSR read, CSR write, is privileged instruction
|
||||
output logic CSRWriteFenceM // CSR write or fence instruction needs to flush subsequent instructions
|
||||
output logic CSRReadM, CSRWriteM, PrivilegedM,// CSR read, CSR write, is privileged instruction
|
||||
output logic CSRWriteFenceM // CSR write or fence instruction needs to flush subsequent instructions
|
||||
);
|
||||
|
||||
logic [2:0] ImmSrcD; // Select type of immediate extension
|
||||
|
|
|
@ -52,7 +52,7 @@ module regfile (
|
|||
|
||||
always_ff @(negedge clk)
|
||||
if (reset) for(i=1; i<NUMREGS; i++) rf[i] <= 0;
|
||||
else if (we3) rf[a3] <= wd3;
|
||||
else if (we3) rf[a3] <= wd3;
|
||||
|
||||
assign #2 rd1 = (a1 != 0) ? rf[a1] : 0;
|
||||
assign #2 rd2 = (a2 != 0) ? rf[a2] : 0;
|
||||
|
|
|
@ -31,10 +31,10 @@
|
|||
|
||||
module RASPredictor #(parameter int StackSize = 16 )(
|
||||
input logic clk,
|
||||
input logic reset,
|
||||
input logic StallF, StallD, StallE, StallM, FlushD, FlushE, FlushM,
|
||||
input logic BPReturnWrongD, // Prediction class is wrong
|
||||
input logic ReturnD,
|
||||
input logic reset,
|
||||
input logic StallF, StallD, StallE, StallM, FlushD, FlushE, FlushM,
|
||||
input logic BPReturnWrongD, // Prediction class is wrong
|
||||
input logic ReturnD,
|
||||
input logic ReturnE, CallE, // Instr class
|
||||
input logic BPReturnF,
|
||||
input logic [`XLEN-1:0] PCLinkE, // PC of instruction after a call
|
||||
|
@ -48,14 +48,14 @@ module RASPredictor #(parameter int StackSize = 16 )(
|
|||
logic [StackSize-1:0] [`XLEN-1:0] memory;
|
||||
integer index;
|
||||
|
||||
logic PopF;
|
||||
logic PushE;
|
||||
logic RepairD;
|
||||
logic IncrRepairD, DecRepairD;
|
||||
logic PopF;
|
||||
logic PushE;
|
||||
logic RepairD;
|
||||
logic IncrRepairD, DecRepairD;
|
||||
|
||||
logic DecrementPtr;
|
||||
logic FlushedReturnDE;
|
||||
logic WrongPredReturnD;
|
||||
logic DecrementPtr;
|
||||
logic FlushedReturnDE;
|
||||
logic WrongPredReturnD;
|
||||
|
||||
|
||||
assign PopF = BPReturnF & ~StallD & ~FlushD;
|
||||
|
@ -85,7 +85,7 @@ module RASPredictor #(parameter int StackSize = 16 )(
|
|||
always_ff @ (posedge clk) begin
|
||||
if(reset) begin
|
||||
for(index=0; index<StackSize; index++)
|
||||
memory[index] <= {`XLEN{1'b0}};
|
||||
memory[index] <= {`XLEN{1'b0}};
|
||||
end else if(PushE) begin
|
||||
memory[NextPtr] <= #1 PCLinkE;
|
||||
end
|
||||
|
|
|
@ -69,35 +69,33 @@ module bpred (
|
|||
output logic IClassWrongM // Class prediction is wrong
|
||||
);
|
||||
|
||||
logic [1:0] BPDirPredF;
|
||||
logic [1:0] BPDirPredF;
|
||||
|
||||
logic [`XLEN-1:0] BPBTAF, RASPCF;
|
||||
logic BPPCWrongE;
|
||||
logic IClassWrongE;
|
||||
logic BPDirPredWrongE;
|
||||
logic [`XLEN-1:0] BPBTAF, RASPCF;
|
||||
logic BPPCWrongE;
|
||||
logic IClassWrongE;
|
||||
logic BPDirPredWrongE;
|
||||
|
||||
logic BPPCSrcF;
|
||||
logic [`XLEN-1:0] BPPCF;
|
||||
logic [`XLEN-1:0] PC0NextF;
|
||||
logic [`XLEN-1:0] PCCorrectE;
|
||||
logic [3:0] WrongPredInstrClassD;
|
||||
logic BPPCSrcF;
|
||||
logic [`XLEN-1:0] BPPCF;
|
||||
logic [`XLEN-1:0] PC0NextF;
|
||||
logic [`XLEN-1:0] PCCorrectE;
|
||||
logic [3:0] WrongPredInstrClassD;
|
||||
|
||||
logic BTBTargetWrongE;
|
||||
logic RASTargetWrongE;
|
||||
logic BTBTargetWrongE;
|
||||
logic RASTargetWrongE;
|
||||
|
||||
logic [`XLEN-1:0] BPBTAD;
|
||||
logic [`XLEN-1:0] BPBTAD;
|
||||
|
||||
logic BTBCallF, BTBReturnF, BTBJumpF, BTBBranchF;
|
||||
logic BPBranchF, BPJumpF, BPReturnF, BPCallF;
|
||||
logic BPBranchD, BPJumpD, BPReturnD, BPCallD;
|
||||
logic ReturnD, CallD;
|
||||
logic ReturnE, CallE;
|
||||
logic BranchM, JumpM, ReturnM, CallM;
|
||||
logic BranchW, JumpW, ReturnW, CallW;
|
||||
logic BPReturnWrongD;
|
||||
logic [`XLEN-1:0] BPBTAE;
|
||||
|
||||
|
||||
logic BTBCallF, BTBReturnF, BTBJumpF, BTBBranchF;
|
||||
logic BPBranchF, BPJumpF, BPReturnF, BPCallF;
|
||||
logic BPBranchD, BPJumpD, BPReturnD, BPCallD;
|
||||
logic ReturnD, CallD;
|
||||
logic ReturnE, CallE;
|
||||
logic BranchM, JumpM, ReturnM, CallM;
|
||||
logic BranchW, JumpW, ReturnW, CallW;
|
||||
logic BPReturnWrongD;
|
||||
logic [`XLEN-1:0] BPBTAE;
|
||||
|
||||
// Part 1 branch direction prediction
|
||||
// look into the 2 port Sram model. something is wrong.
|
||||
|
@ -128,7 +126,7 @@ module bpred (
|
|||
gsharebasic #(`BPRED_SIZE, 0) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW,
|
||||
.PCNextF, .PCM, .BPDirPredF, .BPDirPredWrongE,
|
||||
.BranchE, .BranchM, .PCSrcE);
|
||||
|
||||
|
||||
end else if (`BPRED_TYPE == "BPLOCALPAg") begin:Predictor
|
||||
// *** Fix me
|
||||
/* -----\/----- EXCLUDED -----\/-----
|
||||
|
@ -149,25 +147,25 @@ module bpred (
|
|||
|
||||
btb #(`BTB_SIZE)
|
||||
TargetPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW,
|
||||
.PCNextF, .PCF, .PCD, .PCE, .PCM,
|
||||
.BPBTAF, .BPBTAD, .BPBTAE,
|
||||
.BTBIClassF({BTBCallF, BTBReturnF, BTBJumpF, BTBBranchF}),
|
||||
.IClassWrongM, .IClassWrongE,
|
||||
.IEUAdrE, .IEUAdrM,
|
||||
.InstrClassD({CallD, ReturnD, JumpD, BranchD}),
|
||||
.InstrClassE({CallE, ReturnE, JumpE, BranchE}),
|
||||
.InstrClassM({CallM, ReturnM, JumpM, BranchM}),
|
||||
.InstrClassW({CallW, ReturnW, JumpW, BranchW}));
|
||||
.PCNextF, .PCF, .PCD, .PCE, .PCM,
|
||||
.BPBTAF, .BPBTAD, .BPBTAE,
|
||||
.BTBIClassF({BTBCallF, BTBReturnF, BTBJumpF, BTBBranchF}),
|
||||
.IClassWrongM, .IClassWrongE,
|
||||
.IEUAdrE, .IEUAdrM,
|
||||
.InstrClassD({CallD, ReturnD, JumpD, BranchD}),
|
||||
.InstrClassE({CallE, ReturnE, JumpE, BranchE}),
|
||||
.InstrClassM({CallM, ReturnM, JumpM, BranchM}),
|
||||
.InstrClassW({CallW, ReturnW, JumpW, BranchW}));
|
||||
|
||||
icpred #(`INSTR_CLASS_PRED) icpred(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW,
|
||||
.PostSpillInstrRawF, .InstrD, .BranchD, .BranchE, .JumpD, .JumpE, .BranchM, .BranchW, .JumpM, .JumpW,
|
||||
.CallD, .CallE, .CallM, .CallW, .ReturnD, .ReturnE, .ReturnM, .ReturnW, .BTBCallF, .BTBReturnF, .BTBJumpF,
|
||||
.BTBBranchF, .BPCallF, .BPReturnF, .BPJumpF, .BPBranchF, .IClassWrongM, .IClassWrongE, .BPReturnWrongD);
|
||||
.PostSpillInstrRawF, .InstrD, .BranchD, .BranchE, .JumpD, .JumpE, .BranchM, .BranchW, .JumpM, .JumpW,
|
||||
.CallD, .CallE, .CallM, .CallW, .ReturnD, .ReturnE, .ReturnM, .ReturnW, .BTBCallF, .BTBReturnF, .BTBJumpF,
|
||||
.BTBBranchF, .BPCallF, .BPReturnF, .BPJumpF, .BPBranchF, .IClassWrongM, .IClassWrongE, .BPReturnWrongD);
|
||||
|
||||
// Part 3 RAS
|
||||
RASPredictor RASPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .FlushD, .FlushE, .FlushM,
|
||||
.BPReturnF, .ReturnD, .ReturnE, .CallE,
|
||||
.BPReturnWrongD, .RASPCF, .PCLinkE);
|
||||
.BPReturnF, .ReturnD, .ReturnE, .CallE,
|
||||
.BPReturnWrongD, .RASPCF, .PCLinkE);
|
||||
|
||||
// Check the prediction
|
||||
// if it is a CFI then check if the next instruction address (PCD) matches the branch's target or fallthrough address.
|
||||
|
@ -192,11 +190,11 @@ module bpred (
|
|||
// If the fence/csrw was predicted as a taken branch then we select PCF, rather PCE.
|
||||
// Effectively this is PCM+4 or the non-existant PCLinkM
|
||||
if(`INSTR_CLASS_PRED) mux2 #(`XLEN) pcmuxBPWrongInvalidateFlush(PCE, PCF, BPWrongM, NextValidPCE);
|
||||
else assign NextValidPCE = PCE;
|
||||
else assign NextValidPCE = PCE;
|
||||
|
||||
if(`ZICOUNTERS_SUPPORTED) begin
|
||||
logic [`XLEN-1:0] RASPCD, RASPCE;
|
||||
logic BTAWrongE, RASPredPCWrongE;
|
||||
logic [`XLEN-1:0] RASPCD, RASPCE;
|
||||
logic BTAWrongE, RASPredPCWrongE;
|
||||
// performance counters
|
||||
// 1. class (class wrong / minstret) (IClassWrongM / csr) // Correct now
|
||||
// 2. target btb (btb target wrong / class[0,1,3]) (btb target wrong / (br + j + jal)
|
||||
|
@ -207,15 +205,15 @@ module bpred (
|
|||
// could be wrong or the fall through address selected for branch predict not taken.
|
||||
// By pipeline the BTB's PC and RAS address through the pipeline we can measure the accuracy of
|
||||
// both without the above inaccuracies.
|
||||
// **** use BPBTAWrongM from BTB.
|
||||
// **** use BPBTAWrongM from BTB.
|
||||
assign BTAWrongE = (BPBTAE != IEUAdrE) & (BranchE | JumpE & ~ReturnE) & PCSrcE;
|
||||
assign RASPredPCWrongE = (RASPCE != IEUAdrE) & ReturnE & PCSrcE;
|
||||
|
||||
flopenrc #(`XLEN) RASTargetDReg(clk, reset, FlushD, ~StallD, RASPCF, RASPCD);
|
||||
flopenrc #(`XLEN) RASTargetEReg(clk, reset, FlushE, ~StallE, RASPCD, RASPCE);
|
||||
flopenrc #(3) BPPredWrongRegM(clk, reset, FlushM, ~StallM,
|
||||
{BPDirPredWrongE, BTAWrongE, RASPredPCWrongE},
|
||||
{BPDirPredWrongM, BTAWrongM, RASPredPCWrongM});
|
||||
{BPDirPredWrongE, BTAWrongE, RASPredPCWrongE},
|
||||
{BPDirPredWrongM, BTAWrongM, RASPredPCWrongM});
|
||||
|
||||
end else begin
|
||||
assign {BTAWrongM, RASPredPCWrongM} = '0;
|
||||
|
|
|
@ -31,34 +31,34 @@
|
|||
`include "wally-config.vh"
|
||||
|
||||
module btb #(parameter Depth = 10 ) (
|
||||
input logic clk,
|
||||
input logic reset,
|
||||
input logic StallF, StallD, StallE, StallM, StallW, FlushD, FlushE, FlushM, FlushW,
|
||||
input logic clk,
|
||||
input logic reset,
|
||||
input logic StallF, StallD, StallE, StallM, StallW, FlushD, FlushE, FlushM, FlushW,
|
||||
input logic [`XLEN-1:0] PCNextF, PCF, PCD, PCE, PCM,// PC at various stages
|
||||
output logic [`XLEN-1:0] BPBTAF, // BTB's guess at PC
|
||||
output logic [`XLEN-1:0] BPBTAD,
|
||||
output logic [`XLEN-1:0] BPBTAE,
|
||||
output logic [3:0] BTBIClassF, // BTB's guess at instruction class
|
||||
output logic [3:0] BTBIClassF, // BTB's guess at instruction class
|
||||
// update
|
||||
input logic IClassWrongM, // BTB's instruction class guess was wrong
|
||||
input logic IClassWrongM, // BTB's instruction class guess was wrong
|
||||
input logic IClassWrongE,
|
||||
input logic [`XLEN-1:0] IEUAdrE, // Branch/jump target address to insert into btb
|
||||
input logic [`XLEN-1:0] IEUAdrM, // Branch/jump target address to insert into btb
|
||||
input logic [3:0] InstrClassD, // Instruction class to insert into btb
|
||||
input logic [3:0] InstrClassE, // Instruction class to insert into btb
|
||||
input logic [3:0] InstrClassM, // Instruction class to insert into btb
|
||||
input logic [3:0] InstrClassD, // Instruction class to insert into btb
|
||||
input logic [3:0] InstrClassE, // Instruction class to insert into btb
|
||||
input logic [3:0] InstrClassM, // Instruction class to insert into btb
|
||||
input logic [3:0] InstrClassW
|
||||
);
|
||||
|
||||
logic [Depth-1:0] PCNextFIndex, PCFIndex, PCDIndex, PCEIndex, PCMIndex, PCWIndex;
|
||||
logic [`XLEN-1:0] ResetPC;
|
||||
logic MatchD, MatchE, MatchM, MatchW, MatchX;
|
||||
logic [`XLEN+3:0] ForwardBTBPrediction, ForwardBTBPredictionF;
|
||||
logic [`XLEN+3:0] TableBTBPredF;
|
||||
logic [`XLEN-1:0] IEUAdrW;
|
||||
logic [Depth-1:0] PCNextFIndex, PCFIndex, PCDIndex, PCEIndex, PCMIndex, PCWIndex;
|
||||
logic [`XLEN-1:0] ResetPC;
|
||||
logic MatchD, MatchE, MatchM, MatchW, MatchX;
|
||||
logic [`XLEN+3:0] ForwardBTBPrediction, ForwardBTBPredictionF;
|
||||
logic [`XLEN+3:0] TableBTBPredF;
|
||||
logic [`XLEN-1:0] IEUAdrW;
|
||||
logic [`XLEN-1:0] PCW;
|
||||
logic BTBWrongE, BPBTAWrongE;
|
||||
logic BTBWrongM, BPBTAWrongM;
|
||||
logic BTBWrongE, BPBTAWrongE;
|
||||
logic BTBWrongM, BPBTAWrongM;
|
||||
|
||||
|
||||
// hashing function for indexing the PC
|
||||
|
@ -111,5 +111,4 @@ module btb #(parameter Depth = 10 ) (
|
|||
flopenr #(`XLEN) PCWReg(clk, reset, ~StallW, PCM, PCW);
|
||||
flopenr #(`XLEN) IEUAdrWReg(clk, reset, ~StallW, IEUAdrM, IEUAdrW);
|
||||
|
||||
|
||||
endmodule
|
||||
|
|
|
@ -42,30 +42,30 @@ module gshare #(parameter k = 10,
|
|||
input logic BPBranchF, BranchD, BranchE, BranchM, BranchW, PCSrcE
|
||||
);
|
||||
|
||||
logic MatchF, MatchD, MatchE, MatchM, MatchW;
|
||||
logic MatchX;
|
||||
logic MatchF, MatchD, MatchE, MatchM, MatchW;
|
||||
logic MatchX;
|
||||
|
||||
logic [1:0] TableBPDirPredF, BPDirPredD, BPDirPredE, FwdNewDirPredF;
|
||||
logic [1:0] NewBPDirPredE, NewBPDirPredM, NewBPDirPredW;
|
||||
logic [1:0] TableBPDirPredF, BPDirPredD, BPDirPredE, FwdNewDirPredF;
|
||||
logic [1:0] NewBPDirPredE, NewBPDirPredM, NewBPDirPredW;
|
||||
|
||||
logic [k-1:0] IndexNextF, IndexF, IndexD, IndexE, IndexM, IndexW;
|
||||
logic [k-1:0] IndexNextF, IndexF, IndexD, IndexE, IndexM, IndexW;
|
||||
|
||||
logic [k-1:0] GHRF, GHRD, GHRE, GHRM;
|
||||
logic [k-1:0] GHRNextM, GHRNextF;
|
||||
logic PCSrcM;
|
||||
logic [k-1:0] GHRF, GHRD, GHRE, GHRM;
|
||||
logic [k-1:0] GHRNextM, GHRNextF;
|
||||
logic PCSrcM;
|
||||
|
||||
if(TYPE == 1) begin
|
||||
assign IndexNextF = GHRNextF ^ {PCNextF[k+1] ^ PCNextF[1], PCNextF[k:2]};
|
||||
assign IndexF = GHRF ^ {PCF[k+1] ^ PCF[1], PCF[k:2]};
|
||||
assign IndexD = GHRD ^ {PCD[k+1] ^ PCD[1], PCD[k:2]};
|
||||
assign IndexE = GHRE ^ {PCE[k+1] ^ PCE[1], PCE[k:2]};
|
||||
assign IndexM = GHRM ^ {PCM[k+1] ^ PCM[1], PCM[k:2]};
|
||||
assign IndexNextF = GHRNextF ^ {PCNextF[k+1] ^ PCNextF[1], PCNextF[k:2]};
|
||||
assign IndexF = GHRF ^ {PCF[k+1] ^ PCF[1], PCF[k:2]};
|
||||
assign IndexD = GHRD ^ {PCD[k+1] ^ PCD[1], PCD[k:2]};
|
||||
assign IndexE = GHRE ^ {PCE[k+1] ^ PCE[1], PCE[k:2]};
|
||||
assign IndexM = GHRM ^ {PCM[k+1] ^ PCM[1], PCM[k:2]};
|
||||
end else if(TYPE == 0) begin
|
||||
assign IndexNextF = GHRNextF;
|
||||
assign IndexF = GHRF;
|
||||
assign IndexD = GHRD;
|
||||
assign IndexE = GHRE;
|
||||
assign IndexM = GHRM;
|
||||
assign IndexNextF = GHRNextF;
|
||||
assign IndexF = GHRF;
|
||||
assign IndexD = GHRD;
|
||||
assign IndexE = GHRE;
|
||||
assign IndexM = GHRM;
|
||||
end
|
||||
|
||||
flopenrc #(k) IndexWReg(clk, reset, FlushW, ~StallW, IndexM, IndexW);
|
||||
|
@ -79,7 +79,7 @@ module gshare #(parameter k = 10,
|
|||
assign FwdNewDirPredF = MatchD ? {2{BPDirPredD[1]}} :
|
||||
MatchE ? {NewBPDirPredE} :
|
||||
MatchM ? {NewBPDirPredM} :
|
||||
NewBPDirPredW ;
|
||||
NewBPDirPredW ;
|
||||
|
||||
assign BPDirPredF = MatchX ? FwdNewDirPredF : TableBPDirPredF;
|
||||
|
||||
|
|
|
@ -42,20 +42,20 @@ module gsharebasic #(parameter k = 10,
|
|||
input logic BranchE, BranchM, PCSrcE
|
||||
);
|
||||
|
||||
logic [k-1:0] IndexNextF, IndexM;
|
||||
logic [1:0] BPDirPredD, BPDirPredE;
|
||||
logic [1:0] NewBPDirPredE, NewBPDirPredM;
|
||||
logic [k-1:0] IndexNextF, IndexM;
|
||||
logic [1:0] BPDirPredD, BPDirPredE;
|
||||
logic [1:0] NewBPDirPredE, NewBPDirPredM;
|
||||
|
||||
logic [k-1:0] GHRF, GHRD, GHRE, GHRM, GHR;
|
||||
logic [k-1:0] GHRNext;
|
||||
logic PCSrcM;
|
||||
logic [k-1:0] GHRF, GHRD, GHRE, GHRM, GHR;
|
||||
logic [k-1:0] GHRNext;
|
||||
logic PCSrcM;
|
||||
|
||||
if(TYPE == 1) begin
|
||||
assign IndexNextF = GHR ^ {PCNextF[k+1] ^ PCNextF[1], PCNextF[k:2]};
|
||||
assign IndexM = GHRM ^ {PCM[k+1] ^ PCM[1], PCM[k:2]};
|
||||
assign IndexNextF = GHR ^ {PCNextF[k+1] ^ PCNextF[1], PCNextF[k:2]};
|
||||
assign IndexM = GHRM ^ {PCM[k+1] ^ PCM[1], PCM[k:2]};
|
||||
end else if(TYPE == 0) begin
|
||||
assign IndexNextF = GHRNext;
|
||||
assign IndexM = GHRM;
|
||||
assign IndexNextF = GHRNext;
|
||||
assign IndexM = GHRM;
|
||||
end
|
||||
|
||||
ram2p1r1wbe #(2**k, 2) PHT(.clk(clk),
|
||||
|
|
|
@ -45,16 +45,16 @@ module icpred #(parameter INSTR_CLASS_PRED = 1)(
|
|||
output logic IClassWrongM, BPReturnWrongD, IClassWrongE
|
||||
);
|
||||
|
||||
logic IClassWrongD;
|
||||
logic BPBranchD, BPJumpD, BPReturnD, BPCallD;
|
||||
logic IClassWrongD;
|
||||
logic BPBranchD, BPJumpD, BPReturnD, BPCallD;
|
||||
|
||||
if (!INSTR_CLASS_PRED) begin : DirectClassDecode
|
||||
// This section is mainly for testing, verification, and PPA comparison.
|
||||
// An alternative to using the BTB to store the instruction class is to partially decode
|
||||
// the instructions in the Fetch stage into, Call, Return, Jump, and Branch instructions.
|
||||
// This logic is not described in the text book as of 23 February 2023.
|
||||
logic ccall, cj, cjr, ccallr, CJumpF, CBranchF;
|
||||
logic NCJumpF, NCBranchF;
|
||||
logic ccall, cj, cjr, ccallr, CJumpF, CBranchF;
|
||||
logic NCJumpF, NCBranchF;
|
||||
|
||||
if(`C_SUPPORTED) begin
|
||||
logic [4:0] CompressedOpcF;
|
||||
|
@ -75,10 +75,10 @@ module icpred #(parameter INSTR_CLASS_PRED = 1)(
|
|||
assign BPBranchF = NCBranchF | (`C_SUPPORTED & CBranchF);
|
||||
assign BPJumpF = NCJumpF | (`C_SUPPORTED & (CJumpF));
|
||||
assign BPReturnF = (NCJumpF & (PostSpillInstrRawF[19:15] & 5'h1B) == 5'h01) | // returnurn must returnurn to ra or r5
|
||||
(`C_SUPPORTED & (ccallr | cjr) & ((PostSpillInstrRawF[11:7] & 5'h1B) == 5'h01));
|
||||
(`C_SUPPORTED & (ccallr | cjr) & ((PostSpillInstrRawF[11:7] & 5'h1B) == 5'h01));
|
||||
|
||||
assign BPCallF = (NCJumpF & (PostSpillInstrRawF[11:07] & 5'h1B) == 5'h01) | // call(r) must link to ra or x5
|
||||
(`C_SUPPORTED & (ccall | (ccallr & (PostSpillInstrRawF[11:7] & 5'h1b) == 5'h01)));
|
||||
(`C_SUPPORTED & (ccall | (ccallr & (PostSpillInstrRawF[11:7] & 5'h1b) == 5'h01)));
|
||||
|
||||
end else begin
|
||||
// This section connects the BTB's instruction class prediction.
|
||||
|
|
196
src/ifu/ifu.sv
196
src/ifu/ifu.sv
|
@ -28,116 +28,116 @@
|
|||
`include "wally-config.vh"
|
||||
|
||||
module ifu (
|
||||
input logic clk, reset,
|
||||
input logic StallF, StallD, StallE, StallM, StallW,
|
||||
input logic FlushD, FlushE, FlushM, FlushW,
|
||||
output logic IFUStallF, // IFU stalsl pipeline during a multicycle operation
|
||||
input logic clk, reset,
|
||||
input logic StallF, StallD, StallE, StallM, StallW,
|
||||
input logic FlushD, FlushE, FlushM, FlushW,
|
||||
output logic IFUStallF, // IFU stalsl pipeline during a multicycle operation
|
||||
// Command from CPU
|
||||
input logic InvalidateICacheM, // Clears all instruction cache valid bits
|
||||
input logic CSRWriteFenceM, // CSR write or fence instruction, PCNextF = the next valid PC (typically PCE)
|
||||
input logic InstrValidD, InstrValidE, InstrValidM,
|
||||
input logic BranchD, BranchE,
|
||||
input logic JumpD, JumpE,
|
||||
// Bus interface
|
||||
output logic [`PA_BITS-1:0] IFUHADDR, // Bus address from IFU to EBU
|
||||
input logic [`XLEN-1:0] HRDATA, // Bus read data from IFU to EBU
|
||||
input logic IFUHREADY, // Bus ready from IFU to EBU
|
||||
output logic IFUHWRITE, // Bus write operation from IFU to EBU
|
||||
output logic [2:0] IFUHSIZE, // Bus operation size from IFU to EBU
|
||||
output logic [2:0] IFUHBURST, // Bus burst from IFU to EBU
|
||||
output logic [1:0] IFUHTRANS, // Bus transaction type from IFU to EBU
|
||||
input logic InvalidateICacheM, // Clears all instruction cache valid bits
|
||||
input logic CSRWriteFenceM, // CSR write or fence instruction, PCNextF = the next valid PC (typically PCE)
|
||||
input logic InstrValidD, InstrValidE, InstrValidM,
|
||||
input logic BranchD, BranchE,
|
||||
input logic JumpD, JumpE,
|
||||
// Bus interface
|
||||
output logic [`PA_BITS-1:0] IFUHADDR, // Bus address from IFU to EBU
|
||||
input logic [`XLEN-1:0] HRDATA, // Bus read data from IFU to EBU
|
||||
input logic IFUHREADY, // Bus ready from IFU to EBU
|
||||
output logic IFUHWRITE, // Bus write operation from IFU to EBU
|
||||
output logic [2:0] IFUHSIZE, // Bus operation size from IFU to EBU
|
||||
output logic [2:0] IFUHBURST, // Bus burst from IFU to EBU
|
||||
output logic [1:0] IFUHTRANS, // Bus transaction type from IFU to EBU
|
||||
|
||||
output logic [`XLEN-1:0] PCSpillF, // PCF with possible + 2 to handle spill to HPTW
|
||||
output logic [`XLEN-1:0] PCSpillF, // PCF with possible + 2 to handle spill to HPTW
|
||||
// Execute
|
||||
output logic [`XLEN-1:0] PCLinkE, // The address following the branch instruction. (AKA Fall through address)
|
||||
input logic PCSrcE, // Executation stage branch is taken
|
||||
input logic [`XLEN-1:0] IEUAdrE, // The branch/jump target address
|
||||
input logic [`XLEN-1:0] IEUAdrM, // The branch/jump target address
|
||||
output logic [`XLEN-1:0] PCE, // Execution stage instruction address
|
||||
output logic BPWrongE, // Prediction is wrong
|
||||
output logic BPWrongM, // Prediction is wrong
|
||||
output logic [`XLEN-1:0] PCLinkE, // The address following the branch instruction. (AKA Fall through address)
|
||||
input logic PCSrcE, // Executation stage branch is taken
|
||||
input logic [`XLEN-1:0] IEUAdrE, // The branch/jump target address
|
||||
input logic [`XLEN-1:0] IEUAdrM, // The branch/jump target address
|
||||
output logic [`XLEN-1:0] PCE, // Execution stage instruction address
|
||||
output logic BPWrongE, // Prediction is wrong
|
||||
output logic BPWrongM, // Prediction is wrong
|
||||
// Mem
|
||||
output logic CommittedF, // I$ or bus memory operation started, delay interrupts
|
||||
input logic [`XLEN-1:0] UnalignedPCNextF, // The next PCF, but not aligned to 2 bytes.
|
||||
output logic [`XLEN-1:0] PC2NextF, // Selected PC between branch prediction and next valid PC if CSRWriteFence
|
||||
output logic [31:0] InstrD, // The decoded instruction in Decode stage
|
||||
output logic [31:0] InstrM, // The decoded instruction in Memory stage
|
||||
output logic [31:0] InstrOrigM, // Original compressed or uncompressed instruction in Memory stage for Illegal Instruction MTVAL
|
||||
output logic [`XLEN-1:0] PCM, // Memory stage instruction address
|
||||
output logic CommittedF, // I$ or bus memory operation started, delay interrupts
|
||||
input logic [`XLEN-1:0] UnalignedPCNextF, // The next PCF, but not aligned to 2 bytes.
|
||||
output logic [`XLEN-1:0] PC2NextF, // Selected PC between branch prediction and next valid PC if CSRWriteFence
|
||||
output logic [31:0] InstrD, // The decoded instruction in Decode stage
|
||||
output logic [31:0] InstrM, // The decoded instruction in Memory stage
|
||||
output logic [31:0] InstrOrigM, // Original compressed or uncompressed instruction in Memory stage for Illegal Instruction MTVAL
|
||||
output logic [`XLEN-1:0] PCM, // Memory stage instruction address
|
||||
// branch predictor
|
||||
output logic [3:0] InstrClassM, // The valid instruction class. 1-hot encoded as jalr, ret, jr (not ret), j, br
|
||||
output logic BPDirPredWrongM, // Prediction direction is wrong
|
||||
output logic BTAWrongM, // Prediction target wrong
|
||||
output logic RASPredPCWrongM, // RAS prediction is wrong
|
||||
output logic IClassWrongM, // Class prediction is wrong
|
||||
output logic ICacheStallF, // I$ busy with multicycle operation
|
||||
output logic [3:0] InstrClassM, // The valid instruction class. 1-hot encoded as jalr, ret, jr (not ret), j, br
|
||||
output logic BPDirPredWrongM, // Prediction direction is wrong
|
||||
output logic BTAWrongM, // Prediction target wrong
|
||||
output logic RASPredPCWrongM, // RAS prediction is wrong
|
||||
output logic IClassWrongM, // Class prediction is wrong
|
||||
output logic ICacheStallF, // I$ busy with multicycle operation
|
||||
// Faults
|
||||
input logic IllegalBaseInstrD, // Illegal non-compressed instruction
|
||||
input logic IllegalFPUInstrD, // Illegal FP instruction
|
||||
output logic InstrPageFaultF, // Instruction page fault
|
||||
output logic IllegalIEUFPUInstrD, // Illegal instruction including compressed & FP
|
||||
output logic InstrMisalignedFaultM, // Branch target not aligned to 4 bytes if no compressed allowed (2 bytes if allowed)
|
||||
input logic IllegalBaseInstrD, // Illegal non-compressed instruction
|
||||
input logic IllegalFPUInstrD, // Illegal FP instruction
|
||||
output logic InstrPageFaultF, // Instruction page fault
|
||||
output logic IllegalIEUFPUInstrD, // Illegal instruction including compressed & FP
|
||||
output logic InstrMisalignedFaultM, // Branch target not aligned to 4 bytes if no compressed allowed (2 bytes if allowed)
|
||||
// mmu management
|
||||
input logic [1:0] PrivilegeModeW, // Priviledge mode in Writeback stage
|
||||
input logic [`XLEN-1:0] PTE, // Hardware page table walker (HPTW) writes Page table entry (PTE) to ITLB
|
||||
input logic [1:0] PageType, // Hardware page table walker (HPTW) writes PageType to ITLB
|
||||
input logic ITLBWriteF, // Writes PTE and PageType to ITLB
|
||||
input logic [`XLEN-1:0] SATP_REGW, // Location of the root page table and page table configuration
|
||||
input logic STATUS_MXR, // Status CSR: make executable page readable
|
||||
input logic STATUS_SUM, // Status CSR: Supervisor access to user memory
|
||||
input logic STATUS_MPRV, // Status CSR: modify machine privilege
|
||||
input logic [1:0] STATUS_MPP, // Status CSR: previous machine privilege level
|
||||
input logic sfencevmaM, // Virtual memory address fence, invalidate TLB entries
|
||||
output logic ITLBMissF, // ITLB miss causes HPTW (hardware pagetable walker) walk
|
||||
output logic InstrUpdateDAF, // ITLB hit needs to update dirty or access bits
|
||||
input var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0], // PMP configuration from privileged unit
|
||||
input var logic [`PA_BITS-3:0] PMPADDR_ARRAY_REGW[`PMP_ENTRIES-1:0], // PMP address from privileged unit
|
||||
output logic InstrAccessFaultF, // Instruction access fault
|
||||
output logic ICacheAccess, // Report I$ read to performance counters
|
||||
output logic ICacheMiss // Report I$ miss to performance counters
|
||||
input logic [1:0] PrivilegeModeW, // Priviledge mode in Writeback stage
|
||||
input logic [`XLEN-1:0] PTE, // Hardware page table walker (HPTW) writes Page table entry (PTE) to ITLB
|
||||
input logic [1:0] PageType, // Hardware page table walker (HPTW) writes PageType to ITLB
|
||||
input logic ITLBWriteF, // Writes PTE and PageType to ITLB
|
||||
input logic [`XLEN-1:0] SATP_REGW, // Location of the root page table and page table configuration
|
||||
input logic STATUS_MXR, // Status CSR: make executable page readable
|
||||
input logic STATUS_SUM, // Status CSR: Supervisor access to user memory
|
||||
input logic STATUS_MPRV, // Status CSR: modify machine privilege
|
||||
input logic [1:0] STATUS_MPP, // Status CSR: previous machine privilege level
|
||||
input logic sfencevmaM, // Virtual memory address fence, invalidate TLB entries
|
||||
output logic ITLBMissF, // ITLB miss causes HPTW (hardware pagetable walker) walk
|
||||
output logic InstrUpdateDAF, // ITLB hit needs to update dirty or access bits
|
||||
input var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0], // PMP configuration from privileged unit
|
||||
input var logic [`PA_BITS-3:0] PMPADDR_ARRAY_REGW[`PMP_ENTRIES-1:0], // PMP address from privileged unit
|
||||
output logic InstrAccessFaultF, // Instruction access fault
|
||||
output logic ICacheAccess, // Report I$ read to performance counters
|
||||
output logic ICacheMiss // Report I$ miss to performance counters
|
||||
);
|
||||
|
||||
localparam [31:0] nop = 32'h00000013; // instruction for NOP
|
||||
localparam [31:0] nop = 32'h00000013; // instruction for NOP
|
||||
|
||||
logic [`XLEN-1:0] PCNextF; // Next PCF, selected from Branch predictor, Privilege, or PC+2/4
|
||||
logic BranchMisalignedFaultE; // Branch target not aligned to 4 bytes if no compressed allowed (2 bytes if allowed)
|
||||
logic [`XLEN-1:0] PCPlus2or4F; // PCF + 2 (CompressedF) or PCF + 4 (Non-compressed)
|
||||
logic [`XLEN-1:0] PCSpillNextF; // Next PCF after possible + 2 to handle spill
|
||||
logic [`XLEN-1:0] PCLinkD; // PCF2or4F delayed 1 cycle. This is next PC after a control flow instruction (br or j)
|
||||
logic [`XLEN-1:2] PCPlus4F; // PCPlus4F is always PCF + 4. Fancy way to compute PCPlus2or4F
|
||||
logic [`XLEN-1:0] PCD; // Decode stage instruction address
|
||||
logic [`XLEN-1:0] NextValidPCE; // The PC of the next valid instruction in the pipeline after csr write or fence
|
||||
logic [`XLEN-1:0] PCF; // Fetch stage instruction address
|
||||
logic [`PA_BITS-1:0] PCPF; // Physical address after address translation
|
||||
logic [`XLEN+1:0] PCFExt; //
|
||||
logic [`XLEN-1:0] PCNextF; // Next PCF, selected from Branch predictor, Privilege, or PC+2/4
|
||||
logic BranchMisalignedFaultE; // Branch target not aligned to 4 bytes if no compressed allowed (2 bytes if allowed)
|
||||
logic [`XLEN-1:0] PCPlus2or4F; // PCF + 2 (CompressedF) or PCF + 4 (Non-compressed)
|
||||
logic [`XLEN-1:0] PCSpillNextF; // Next PCF after possible + 2 to handle spill
|
||||
logic [`XLEN-1:0] PCLinkD; // PCF2or4F delayed 1 cycle. This is next PC after a control flow instruction (br or j)
|
||||
logic [`XLEN-1:2] PCPlus4F; // PCPlus4F is always PCF + 4. Fancy way to compute PCPlus2or4F
|
||||
logic [`XLEN-1:0] PCD; // Decode stage instruction address
|
||||
logic [`XLEN-1:0] NextValidPCE; // The PC of the next valid instruction in the pipeline after csr write or fence
|
||||
logic [`XLEN-1:0] PCF; // Fetch stage instruction address
|
||||
logic [`PA_BITS-1:0] PCPF; // Physical address after address translation
|
||||
logic [`XLEN+1:0] PCFExt; //
|
||||
|
||||
logic [31:0] IROMInstrF; // Instruction from the IROM
|
||||
logic [31:0] ICacheInstrF; // Instruction from the I$
|
||||
logic [31:0] InstrRawF; // Instruction from the IROM, I$, or bus
|
||||
logic CompressedF; // The fetched instruction is compressed
|
||||
logic CompressedD; // The decoded instruction is compressed
|
||||
logic CompressedE; // The execution instruction is compressed
|
||||
logic CompressedM; // The execution instruction is compressed
|
||||
logic [31:0] PostSpillInstrRawF; // Fetch instruction after merge two halves of spill
|
||||
logic [31:0] InstrRawD; // Non-decompressed instruction in the Decode stage
|
||||
logic IllegalIEUInstrD; // IEU Instruction (regular or compressed) is not good
|
||||
logic [31:0] IROMInstrF; // Instruction from the IROM
|
||||
logic [31:0] ICacheInstrF; // Instruction from the I$
|
||||
logic [31:0] InstrRawF; // Instruction from the IROM, I$, or bus
|
||||
logic CompressedF; // The fetched instruction is compressed
|
||||
logic CompressedD; // The decoded instruction is compressed
|
||||
logic CompressedE; // The execution instruction is compressed
|
||||
logic CompressedM; // The execution instruction is compressed
|
||||
logic [31:0] PostSpillInstrRawF; // Fetch instruction after merge two halves of spill
|
||||
logic [31:0] InstrRawD; // Non-decompressed instruction in the Decode stage
|
||||
logic IllegalIEUInstrD; // IEU Instruction (regular or compressed) is not good
|
||||
|
||||
logic [1:0] IFURWF; // IFU alreays read IFURWF = 10
|
||||
logic [31:0] InstrE; // Instruction in the Execution stage
|
||||
logic [31:0] NextInstrD, NextInstrE; // Instruction into the next stage after possible stage flush
|
||||
logic [1:0] IFURWF; // IFU alreays read IFURWF = 10
|
||||
logic [31:0] InstrE; // Instruction in the Execution stage
|
||||
logic [31:0] NextInstrD, NextInstrE; // Instruction into the next stage after possible stage flush
|
||||
|
||||
|
||||
logic CacheableF; // PMA indicates instruction address is cacheable
|
||||
logic SelSpillNextF; // In a spill, stall pipeline and gate local stallF
|
||||
logic BusStall; // Bus interface busy with multicycle operation
|
||||
logic IFUCacheBusStallD; // EIther I$ or bus busy with multicycle operation
|
||||
logic GatedStallD; // StallD gated by selected next spill
|
||||
logic CacheableF; // PMA indicates instruction address is cacheable
|
||||
logic SelSpillNextF; // In a spill, stall pipeline and gate local stallF
|
||||
logic BusStall; // Bus interface busy with multicycle operation
|
||||
logic IFUCacheBusStallD; // EIther I$ or bus busy with multicycle operation
|
||||
logic GatedStallD; // StallD gated by selected next spill
|
||||
// branch predictor signal
|
||||
logic [`XLEN-1:0] PC1NextF; // Branch predictor next PCF
|
||||
logic BusCommittedF; // Bus memory operation in flight, delay interrupts
|
||||
logic CacheCommittedF; // I$ memory operation started, delay interrupts
|
||||
logic SelIROM; // PMA indicates instruction address is in the IROM
|
||||
logic [15:0] InstrRawE, InstrRawM;
|
||||
logic [`XLEN-1:0] PC1NextF; // Branch predictor next PCF
|
||||
logic BusCommittedF; // Bus memory operation in flight, delay interrupts
|
||||
logic CacheCommittedF; // I$ memory operation started, delay interrupts
|
||||
logic SelIROM; // PMA indicates instruction address is in the IROM
|
||||
logic [15:0] InstrRawE, InstrRawM;
|
||||
|
||||
assign PCFExt = {2'b00, PCSpillF};
|
||||
|
||||
|
@ -208,13 +208,13 @@ module ifu (
|
|||
// delay the interrupt until the LSU is in a clean state.
|
||||
assign CommittedF = CacheCommittedF | BusCommittedF;
|
||||
|
||||
logic IgnoreRequest;
|
||||
logic IgnoreRequest;
|
||||
assign IgnoreRequest = ITLBMissF | FlushD;
|
||||
|
||||
// The IROM uses untranslated addresses, so it is not compatible with virtual memory.
|
||||
if (`IROM_SUPPORTED) begin : irom
|
||||
logic IROMce;
|
||||
assign IROMce = ~GatedStallD | reset;
|
||||
logic IROMce;
|
||||
assign IROMce = ~GatedStallD | reset;
|
||||
assign IFURWF = 2'b10;
|
||||
irom irom(.clk, .ce(IROMce), .Adr(PCSpillNextF[`XLEN-1:0]), .IROMInstrF);
|
||||
end else begin
|
||||
|
|
|
@ -27,10 +27,10 @@
|
|||
`include "wally-config.vh"
|
||||
|
||||
module irom(
|
||||
input logic clk,
|
||||
input logic ce, // Chip Enable. 0: Holds IROMInstrF constant
|
||||
input logic clk,
|
||||
input logic ce, // Chip Enable. 0: Holds IROMInstrF constant
|
||||
input logic [`XLEN-1:0] Adr, // PCNextFSpill
|
||||
output logic [31:0] IROMInstrF // Instruction read data
|
||||
output logic [31:0] IROMInstrF // Instruction read data
|
||||
);
|
||||
|
||||
localparam XLENBYTES = `XLEN/8;
|
||||
|
@ -38,16 +38,16 @@ module irom(
|
|||
localparam OFFSET = $clog2(XLENBYTES);
|
||||
|
||||
logic [`XLEN-1:0] IROMInstrFFull;
|
||||
logic [31:0] RawIROMInstrF;
|
||||
logic [31:0] RawIROMInstrF;
|
||||
|
||||
logic [1:0] AdrD;
|
||||
logic [1:0] AdrD;
|
||||
flopen #(2) AdrReg(clk, ce, Adr[2:1], AdrD);
|
||||
|
||||
rom1p1r #(ADDR_WDITH, `XLEN) rom(.clk, .ce, .addr(Adr[ADDR_WDITH+OFFSET-1:OFFSET]), .dout(IROMInstrFFull));
|
||||
if (`XLEN == 32) assign RawIROMInstrF = IROMInstrFFull;
|
||||
else begin
|
||||
// IROM is aligned to XLEN words, but instructions are 32 bits. Select between the two
|
||||
// haves. Adr is the Next PCF not PCF so we delay 1 cycle.
|
||||
// IROM is aligned to XLEN words, but instructions are 32 bits. Select between the two
|
||||
// haves. Adr is the Next PCF not PCF so we delay 1 cycle.
|
||||
assign RawIROMInstrF = AdrD[1] ? IROMInstrFFull[63:32] : IROMInstrFFull[31:0];
|
||||
end
|
||||
// If the memory addres is aligned to 2 bytes return the upper 2 bytes in the lower 2 bytes.
|
||||
|
|
|
@ -34,31 +34,32 @@
|
|||
module spill #(
|
||||
parameter CACHE_ENABLED // Changes spill threshold to 1 if there is no cache
|
||||
)(input logic clk,
|
||||
input logic reset,
|
||||
input logic StallD, FlushD,
|
||||
input logic reset,
|
||||
input logic StallD, FlushD,
|
||||
input logic [`XLEN-1:0] PCF, // 2 byte aligned PC in Fetch stage
|
||||
input logic [`XLEN-1:2] PCPlus4F, // PCF + 4
|
||||
input logic [`XLEN-1:0] PCNextF, // The next PCF
|
||||
input logic [31:0] InstrRawF, // Instruction from the IROM, I$, or bus. Used to check if the instruction if compressed
|
||||
input logic IFUCacheBusStallD, // I$ or bus are stalled. Transition to second fetch of spill after the first is fetched
|
||||
input logic ITLBMissF, // ITLB miss, ignore memory request
|
||||
input logic InstrUpdateDAF, // Ignore memory request if the hptw support write and a DA page fault occurs (hptw is still active)
|
||||
input logic [31:0] InstrRawF, // Instruction from the IROM, I$, or bus. Used to check if the instruction if compressed
|
||||
input logic IFUCacheBusStallD, // I$ or bus are stalled. Transition to second fetch of spill after the first is fetched
|
||||
input logic ITLBMissF, // ITLB miss, ignore memory request
|
||||
input logic InstrUpdateDAF, // Ignore memory request if the hptw support write and a DA page fault occurs (hptw is still active)
|
||||
output logic [`XLEN-1:0] PCSpillNextF, // The next PCF for one of the two memory addresses of the spill
|
||||
output logic [`XLEN-1:0] PCSpillF, // PCF for one of the two memory addresses of the spill
|
||||
output logic SelSpillNextF, // During the transition between the two spill operations, the IFU should stall the pipeline
|
||||
output logic [31:0] PostSpillInstrRawF,// The final 32 bit instruction after merging the two spilled fetches into 1 instruction
|
||||
output logic CompressedF); // The fetched instruction is compressed
|
||||
output logic SelSpillNextF, // During the transition between the two spill operations, the IFU should stall the pipeline
|
||||
output logic [31:0] PostSpillInstrRawF,// The final 32 bit instruction after merging the two spilled fetches into 1 instruction
|
||||
output logic CompressedF); // The fetched instruction is compressed
|
||||
|
||||
// Spill threshold occurs when all the cache offset PC bits are 1 (except [0]). Without a cache this is just PCF[1]
|
||||
typedef enum logic [1:0] {STATE_READY, STATE_SPILL} statetype;
|
||||
statetype CurrState, NextState;
|
||||
localparam SPILLTHRESHOLD = CACHE_ENABLED ? `ICACHE_LINELENINBITS/32 : 1;
|
||||
logic [`XLEN-1:0] PCPlus2F;
|
||||
logic TakeSpillF;
|
||||
logic SpillF;
|
||||
logic SelSpillF;
|
||||
logic SpillSaveF;
|
||||
logic [15:0] InstrFirstHalfF;
|
||||
|
||||
statetype CurrState, NextState;
|
||||
logic [`XLEN-1:0] PCPlus2F;
|
||||
logic TakeSpillF;
|
||||
logic SpillF;
|
||||
logic SelSpillF;
|
||||
logic SpillSaveF;
|
||||
logic [15:0] InstrFirstHalfF;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// PC logic
|
||||
|
@ -109,7 +110,7 @@ module spill #(
|
|||
|
||||
// Need to use always comb to avoid pessimistic x propagation if PostSpillInstrRawF is x
|
||||
always_comb
|
||||
if (PostSpillInstrRawF[1:0] != 2'b11) CompressedF = 1'b1;
|
||||
else CompressedF = 1'b0;
|
||||
if (PostSpillInstrRawF[1:0] != 2'b11) CompressedF = 1'b1;
|
||||
else CompressedF = 1'b0;
|
||||
|
||||
endmodule
|
||||
|
|
|
@ -30,14 +30,14 @@
|
|||
`include "wally-config.vh"
|
||||
|
||||
module dtim(
|
||||
input logic clk,
|
||||
input logic FlushW,
|
||||
input logic ce, // Chip Enable. 0: Holds ReadDataWordM
|
||||
input logic [1:0] MemRWM, // Read/Write control
|
||||
input logic clk,
|
||||
input logic FlushW,
|
||||
input logic ce, // Chip Enable. 0: Holds ReadDataWordM
|
||||
input logic [1:0] MemRWM, // Read/Write control
|
||||
input logic [`PA_BITS-1:0] DTIMAdr, // No stall: Execution stage memory address. Stall: Memory stage memory address
|
||||
input logic [`LLEN-1:0] WriteDataM, // Write data from IEU
|
||||
input logic [`LLEN-1:0] WriteDataM, // Write data from IEU
|
||||
input logic [`LLEN/8-1:0] ByteMaskM, // Selects which bytes within a word to write
|
||||
output logic [`LLEN-1:0] ReadDataWordM // Read data before subword selection
|
||||
output logic [`LLEN-1:0] ReadDataWordM // Read data before subword selection
|
||||
);
|
||||
|
||||
logic we;
|
||||
|
|
|
@ -37,17 +37,17 @@ module lrsc(
|
|||
input logic MemReadM, // Memory read
|
||||
input logic [1:0] PreLSURWM, // Memory operation from the HPTW or IEU [1]: read, [0]: write
|
||||
output logic [1:0] LSURWM, // Memory operation after potential squash of SC
|
||||
input logic [1:0] LSUAtomicM, // Atomic memory operaiton
|
||||
input logic [1:0] LSUAtomicM, // Atomic memory operaiton
|
||||
input logic [`PA_BITS-1:0] PAdrM, // Physical memory address
|
||||
output logic SquashSCW // Squash the store conditional by not allowing rf write
|
||||
);
|
||||
|
||||
// possible bug: *** double check if PreLSURWM needs to be flushed by ignorerequest.
|
||||
// Handle atomic load reserved / store conditional
|
||||
logic [`PA_BITS-1:2] ReservationPAdrW;
|
||||
logic ReservationValidM, ReservationValidW;
|
||||
logic lrM, scM, WriteAdrMatchM;
|
||||
logic SquashSCM;
|
||||
logic [`PA_BITS-1:2] ReservationPAdrW;
|
||||
logic ReservationValidM, ReservationValidW;
|
||||
logic lrM, scM, WriteAdrMatchM;
|
||||
logic SquashSCM;
|
||||
|
||||
assign lrM = MemReadM & LSUAtomicM[0];
|
||||
assign scM = PreLSURWM[0] & LSUAtomicM[0];
|
||||
|
@ -56,7 +56,7 @@ module lrsc(
|
|||
assign LSURWM = SquashSCM ? 2'b00 : PreLSURWM;
|
||||
always_comb begin // ReservationValidM (next value of valid reservation)
|
||||
if (lrM) ReservationValidM = 1; // set valid on load reserve
|
||||
// if we implement multiple harts invalidate reservation if another hart stores to this reservation.
|
||||
// if we implement multiple harts invalidate reservation if another hart stores to this reservation.
|
||||
else if (scM) ReservationValidM = 0; // clear valid on store to same address or any sc
|
||||
else ReservationValidM = ReservationValidW; // otherwise don't change valid
|
||||
end
|
||||
|
|
108
src/lsu/lsu.sv
108
src/lsu/lsu.sv
|
@ -78,61 +78,61 @@ module lsu (
|
|||
output logic [`XLEN/8-1:0] LSUHWSTRB, // Bus byte write enables from LSU to EBU
|
||||
// page table walker
|
||||
input logic [`XLEN-1:0] SATP_REGW, // SATP (supervisor address translation and protection) CSR
|
||||
input logic STATUS_MXR, STATUS_SUM, STATUS_MPRV, // STATUS CSR bits: make executable readable, supervisor user memory, machine privilege
|
||||
input logic STATUS_MXR, STATUS_SUM, STATUS_MPRV, // STATUS CSR bits: make executable readable, supervisor user memory, machine privilege
|
||||
input logic [1:0] STATUS_MPP, // Machine previous privilege mode
|
||||
input logic [`XLEN-1:0] PCSpillF, // Fetch PC
|
||||
input logic [`XLEN-1:0] PCSpillF, // Fetch PC
|
||||
input logic ITLBMissF, // ITLB miss causes HPTW (hardware pagetable walker) walk
|
||||
input logic InstrUpdateDAF, // ITLB hit needs to update dirty or access bits
|
||||
input logic InstrUpdateDAF, // ITLB hit needs to update dirty or access bits
|
||||
output logic [`XLEN-1:0] PTE, // Page table entry write to ITLB
|
||||
output logic [1:0] PageType, // Type of page table entry to write to ITLB
|
||||
output logic ITLBWriteF, // Write PTE to ITLB
|
||||
output logic SelHPTW, // During a HPTW walk the effective privilege mode becomes S_MODE
|
||||
input var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0], // PMP configuration from privileged unit
|
||||
input var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0], // PMP configuration from privileged unit
|
||||
input var logic [`PA_BITS-3:0] PMPADDR_ARRAY_REGW[`PMP_ENTRIES-1:0] // PMP address from privileged unit
|
||||
);
|
||||
|
||||
logic [`XLEN+1:0] IEUAdrExtM; // Memory stage address zero-extended to PA_BITS or XLEN whichever is longer
|
||||
logic [`XLEN+1:0] IEUAdrExtE; // Execution stage address zero-extended to PA_BITS or XLEN whichever is longer
|
||||
logic [`PA_BITS-1:0] PAdrM; // Physical memory address
|
||||
logic [`XLEN+1:0] IHAdrM; // Either IEU or HPTW memory address
|
||||
logic [`XLEN+1:0] IEUAdrExtM; // Memory stage address zero-extended to PA_BITS or XLEN whichever is longer
|
||||
logic [`XLEN+1:0] IEUAdrExtE; // Execution stage address zero-extended to PA_BITS or XLEN whichever is longer
|
||||
logic [`PA_BITS-1:0] PAdrM; // Physical memory address
|
||||
logic [`XLEN+1:0] IHAdrM; // Either IEU or HPTW memory address
|
||||
|
||||
logic [1:0] PreLSURWM; // IEU or HPTW Read/Write signal
|
||||
logic [1:0] LSURWM; // IEU or HPTW Read/Write signal gated by LR/SC
|
||||
logic [2:0] LSUFunct3M; // IEU or HPTW memory operation size
|
||||
logic [6:0] LSUFunct7M; // AMO function gated by HPTW
|
||||
logic [1:0] LSUAtomicM; // AMO signal gated by HPTW
|
||||
logic [1:0] PreLSURWM; // IEU or HPTW Read/Write signal
|
||||
logic [1:0] LSURWM; // IEU or HPTW Read/Write signal gated by LR/SC
|
||||
logic [2:0] LSUFunct3M; // IEU or HPTW memory operation size
|
||||
logic [6:0] LSUFunct7M; // AMO function gated by HPTW
|
||||
logic [1:0] LSUAtomicM; // AMO signal gated by HPTW
|
||||
|
||||
logic GatedStallW; // Hazard unit StallW gated when SelHPTW = 1
|
||||
|
||||
logic BusStall; // Bus interface busy with multicycle operation
|
||||
logic HPTWStall; // HPTW busy with multicycle operation
|
||||
logic GatedStallW; // Hazard unit StallW gated when SelHPTW = 1
|
||||
|
||||
logic BusStall; // Bus interface busy with multicycle operation
|
||||
logic HPTWStall; // HPTW busy with multicycle operation
|
||||
|
||||
logic CacheableM; // PMA indicates memory address is cacheable
|
||||
logic BusCommittedM; // Bus memory operation in flight, delay interrupts
|
||||
logic DCacheCommittedM; // D$ memory operation started, delay interrupts
|
||||
logic CacheableM; // PMA indicates memory address is cacheable
|
||||
logic BusCommittedM; // Bus memory operation in flight, delay interrupts
|
||||
logic DCacheCommittedM; // D$ memory operation started, delay interrupts
|
||||
|
||||
logic [`LLEN-1:0] DTIMReadDataWordM; // DTIM read data
|
||||
logic [`LLEN-1:0] DCacheReadDataWordM; // D$ read data
|
||||
logic [`LLEN-1:0] ReadDataWordMuxM; // DTIM or D$ read data
|
||||
logic [`LLEN-1:0] LittleEndianReadDataWordM; // Endian-swapped read data
|
||||
logic [`LLEN-1:0] ReadDataWordM; // Read data before subword selection
|
||||
logic [`LLEN-1:0] ReadDataM; // Final read data
|
||||
logic [`LLEN-1:0] DTIMReadDataWordM; // DTIM read data
|
||||
logic [`LLEN-1:0] DCacheReadDataWordM; // D$ read data
|
||||
logic [`LLEN-1:0] ReadDataWordMuxM; // DTIM or D$ read data
|
||||
logic [`LLEN-1:0] LittleEndianReadDataWordM; // Endian-swapped read data
|
||||
logic [`LLEN-1:0] ReadDataWordM; // Read data before subword selection
|
||||
logic [`LLEN-1:0] ReadDataM; // Final read data
|
||||
|
||||
logic [`XLEN-1:0] IHWriteDataM; // IEU or HPTW write data
|
||||
logic [`XLEN-1:0] IMAWriteDataM; // IEU, HPTW, or AMO write data
|
||||
logic [`LLEN-1:0] IMAFWriteDataM; // IEU, HPTW, AMO, or FPU write data
|
||||
logic [`LLEN-1:0] LittleEndianWriteDataM; // Ending-swapped write data
|
||||
logic [`LLEN-1:0] LSUWriteDataM; // Final write data
|
||||
logic [(`LLEN-1)/8:0] ByteMaskM; // Selects which bytes within a word to write
|
||||
logic [`XLEN-1:0] IHWriteDataM; // IEU or HPTW write data
|
||||
logic [`XLEN-1:0] IMAWriteDataM; // IEU, HPTW, or AMO write data
|
||||
logic [`LLEN-1:0] IMAFWriteDataM; // IEU, HPTW, AMO, or FPU write data
|
||||
logic [`LLEN-1:0] LittleEndianWriteDataM; // Ending-swapped write data
|
||||
logic [`LLEN-1:0] LSUWriteDataM; // Final write data
|
||||
logic [(`LLEN-1)/8:0] ByteMaskM; // Selects which bytes within a word to write
|
||||
|
||||
logic DTLBMissM; // DTLB miss causes HPTW walk
|
||||
logic DTLBWriteM; // Writes PTE and PageType to DTLB
|
||||
logic DataUpdateDAM; // DTLB hit needs to update dirty or access bits
|
||||
logic LSULoadAccessFaultM; // Load acces fault
|
||||
logic LSUStoreAmoAccessFaultM; // Store access fault
|
||||
logic IgnoreRequestTLB; // On either ITLB or DTLB miss, ignore miss so HPTW can handle
|
||||
logic IgnoreRequest; // On FlushM or TLB miss ignore memory operation
|
||||
logic SelDTIM; // Select DTIM rather than bus or D$
|
||||
logic DTLBMissM; // DTLB miss causes HPTW walk
|
||||
logic DTLBWriteM; // Writes PTE and PageType to DTLB
|
||||
logic DataUpdateDAM; // DTLB hit needs to update dirty or access bits
|
||||
logic LSULoadAccessFaultM; // Load acces fault
|
||||
logic LSUStoreAmoAccessFaultM; // Store access fault
|
||||
logic IgnoreRequestTLB; // On either ITLB or DTLB miss, ignore miss so HPTW can handle
|
||||
logic IgnoreRequest; // On FlushM or TLB miss ignore memory operation
|
||||
logic SelDTIM; // Select DTIM rather than bus or D$
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -164,8 +164,8 @@ module lsu (
|
|||
assign PreLSURWM = MemRWM;
|
||||
assign IHAdrM = IEUAdrExtM;
|
||||
assign LSUFunct3M = Funct3M;
|
||||
assign LSUFunct7M = Funct7M;
|
||||
assign LSUAtomicM = AtomicM;
|
||||
assign LSUFunct7M = Funct7M;
|
||||
assign LSUAtomicM = AtomicM;
|
||||
assign IHWriteDataM = WriteDataM;
|
||||
assign LoadAccessFaultM = LSULoadAccessFaultM;
|
||||
assign StoreAmoAccessFaultM = LSUStoreAmoAccessFaultM;
|
||||
|
@ -194,7 +194,7 @@ module lsu (
|
|||
.PhysicalAddress(PAdrM), .TLBMiss(DTLBMissM), .Cacheable(CacheableM), .Idempotent(), .SelTIM(SelDTIM),
|
||||
.InstrAccessFaultF(), .LoadAccessFaultM(LSULoadAccessFaultM),
|
||||
.StoreAmoAccessFaultM(LSUStoreAmoAccessFaultM), .InstrPageFaultF(), .LoadPageFaultM,
|
||||
.StoreAmoPageFaultM,
|
||||
.StoreAmoPageFaultM,
|
||||
.LoadMisalignedFaultM, .StoreAmoMisalignedFaultM, // *** these faults need to be supressed during hptw.
|
||||
.UpdateDA(DataUpdateDAM),
|
||||
.AtomicAccessM(|LSUAtomicM), .ExecuteAccessF(1'b0),
|
||||
|
@ -227,7 +227,7 @@ module lsu (
|
|||
logic [1:0] DTIMMemRWM;
|
||||
|
||||
// The DTIM uses untranslated addresses, so it is not compatible with virtual memory.
|
||||
mux2 #(`PA_BITS) DTIMAdrMux(IEUAdrExtE[`PA_BITS-1:0], IEUAdrExtM[`PA_BITS-1:0], MemRWM[0], DTIMAdr);
|
||||
mux2 #(`PA_BITS) DTIMAdrMux(IEUAdrExtE[`PA_BITS-1:0], IEUAdrExtM[`PA_BITS-1:0], MemRWM[0], DTIMAdr);
|
||||
assign DTIMMemRWM = SelDTIM & ~IgnoreRequestTLB ? LSURWM : '0;
|
||||
// **** fix ReadDataWordM to be LLEN. ByteMask is wrong length.
|
||||
// **** create config to support DTIM with floating point.
|
||||
|
@ -250,18 +250,18 @@ module lsu (
|
|||
logic [AHBWLOGBWPL-1:0] BeatCount; // Position within a cacheline. ahbcacheinterface to cache
|
||||
logic DCacheBusAck; // ahbcacheinterface completed fetch or writeback
|
||||
logic SelBusBeat; // ahbcacheinterface selects postion in cacheline with BeatCount
|
||||
logic [1:0] CacheBusRW; // Cache sends request to ahbcacheinterface
|
||||
logic [1:0] BusRW; // Uncached bus memory access
|
||||
logic [1:0] CacheBusRW; // Cache sends request to ahbcacheinterface
|
||||
logic [1:0] BusRW; // Uncached bus memory access
|
||||
logic CacheableOrFlushCacheM; // Memory address is cacheable or operation is a cache flush
|
||||
logic [1:0] CacheRWM; // Cache read (10), write (01), AMO (11)
|
||||
logic [1:0] CacheAtomicM; // Cache AMO
|
||||
logic FlushDCache; // Suppress d cache flush if there is an ITLB miss.
|
||||
logic [1:0] CacheRWM; // Cache read (10), write (01), AMO (11)
|
||||
logic [1:0] CacheAtomicM; // Cache AMO
|
||||
logic FlushDCache; // Suppress d cache flush if there is an ITLB miss.
|
||||
|
||||
assign BusRW = ~CacheableM & ~IgnoreRequestTLB & ~SelDTIM ? LSURWM : '0;
|
||||
assign CacheableOrFlushCacheM = CacheableM | FlushDCacheM;
|
||||
assign CacheRWM = CacheableM & ~IgnoreRequestTLB & ~SelDTIM ? LSURWM : '0;
|
||||
assign CacheAtomicM = CacheableM & ~IgnoreRequestTLB & ~SelDTIM ? LSUAtomicM : '0;
|
||||
assign FlushDCache = FlushDCacheM & ~(IgnoreRequestTLB | SelHPTW);
|
||||
assign FlushDCache = FlushDCacheM & ~(IgnoreRequestTLB | SelHPTW);
|
||||
|
||||
cache #(.LINELEN(`DCACHE_LINELENINBITS), .NUMLINES(`DCACHE_WAYSIZEINBYTES*8/LINELEN),
|
||||
.NUMWAYS(`DCACHE_NUMWAYS), .LOGBWPL(LLENLOGBWPL), .WORDLEN(`LLEN), .MUXINTERVAL(`LLEN), .READ_ONLY_CACHE(0)) dcache(
|
||||
|
@ -285,8 +285,8 @@ module lsu (
|
|||
.Cacheable(CacheableOrFlushCacheM), .BusRW, .Stall(GatedStallW),
|
||||
.BusStall, .BusCommitted(BusCommittedM));
|
||||
|
||||
// Mux between the 3 sources of read data, 0: cache, 1: Bus, 2: DTIM
|
||||
// Uncache bus access may be smaller width than LLEN. Duplicate LLENPOVERAHBW times.
|
||||
// Mux between the 3 sources of read data, 0: cache, 1: Bus, 2: DTIM
|
||||
// Uncache bus access may be smaller width than LLEN. Duplicate LLENPOVERAHBW times.
|
||||
// *** DTIMReadDataWordM should be increased to LLEN.
|
||||
// pma should generate exception for LLEN read to periph.
|
||||
mux3 #(`LLEN) UnCachedDataMux(.d0(DCacheReadDataWordM), .d1({LLENPOVERAHBW{FetchBuffer[`XLEN-1:0]}}),
|
||||
|
@ -305,7 +305,7 @@ module lsu (
|
|||
.HWSTRB(LSUHWSTRB), .BusRW, .ByteMask(ByteMaskM), .WriteData(LSUWriteDataM),
|
||||
.Stall(GatedStallW), .BusStall, .BusCommitted(BusCommittedM), .FetchBuffer(FetchBuffer));
|
||||
|
||||
// Mux between the 2 sources of read data, 0: Bus, 1: DTIM
|
||||
// Mux between the 2 sources of read data, 0: Bus, 1: DTIM
|
||||
if(`DTIM_SUPPORTED) mux2 #(`XLEN) ReadDataMux2(FetchBuffer, DTIMReadDataWordM, SelDTIM, ReadDataWordMuxM);
|
||||
else assign ReadDataWordMuxM = FetchBuffer[`XLEN-1:0];
|
||||
assign LSUHBURST = 3'b0;
|
||||
|
@ -338,7 +338,7 @@ module lsu (
|
|||
// Subword Accesses
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
subwordread subwordread(.ReadDataWordMuxM(LittleEndianReadDataWordM), .PAdrM(PAdrM[2:0]), .BigEndianM,
|
||||
.FpLoadStoreM, .Funct3M(LSUFunct3M), .ReadDataM);
|
||||
.FpLoadStoreM, .Funct3M(LSUFunct3M), .ReadDataM);
|
||||
subwordwrite subwordwrite(.LSUFunct3M, .IMAFWriteDataM, .LittleEndianWriteDataM);
|
||||
|
||||
// Compute byte masks
|
||||
|
|
|
@ -31,16 +31,16 @@
|
|||
|
||||
module subwordread
|
||||
(
|
||||
input logic [`LLEN-1:0] ReadDataWordMuxM,
|
||||
input logic [2:0] PAdrM,
|
||||
input logic [2:0] Funct3M,
|
||||
input logic [`LLEN-1:0] ReadDataWordMuxM,
|
||||
input logic [2:0] PAdrM,
|
||||
input logic [2:0] Funct3M,
|
||||
input logic FpLoadStoreM,
|
||||
input logic BigEndianM,
|
||||
output logic [`LLEN-1:0] ReadDataM
|
||||
);
|
||||
|
||||
logic [7:0] ByteM;
|
||||
logic [15:0] HalfwordM;
|
||||
logic [7:0] ByteM;
|
||||
logic [15:0] HalfwordM;
|
||||
logic [2:0] PAdrSwap;
|
||||
// Funct3M[2] is the unsigned bit. mask upper bits.
|
||||
// Funct3M[1:0] is the size of the memory access.
|
||||
|
@ -87,11 +87,11 @@ module subwordread
|
|||
3'b001: ReadDataM = {{`LLEN-16{HalfwordM[15]|FpLoadStoreM}}, HalfwordM[15:0]}; // lh/flh
|
||||
3'b010: ReadDataM = {{`LLEN-32{WordM[31]|FpLoadStoreM}}, WordM[31:0]}; // lw/flw
|
||||
3'b011: ReadDataM = {{`LLEN-64{DblWordM[63]|FpLoadStoreM}}, DblWordM[63:0]}; // ld/fld
|
||||
3'b100: ReadDataM = {{`LLEN-8{1'b0}}, ByteM[7:0]}; // lbu
|
||||
// 3'b100: ReadDataM = FpLoadStoreM ? ReadDataWordMuxM : {{`LLEN-8{1'b0}}, ByteM[7:0]}; // lbu/flq - only needed when LLEN=128
|
||||
3'b101: ReadDataM = {{`LLEN-16{1'b0}}, HalfwordM[15:0]}; // lhu
|
||||
3'b110: ReadDataM = {{`LLEN-32{1'b0}}, WordM[31:0]}; // lwu
|
||||
default: ReadDataM = ReadDataWordMuxM; // Shouldn't happen
|
||||
3'b100: ReadDataM = {{`LLEN-8{1'b0}}, ByteM[7:0]}; // lbu
|
||||
//3'b100: ReadDataM = FpLoadStoreM ? ReadDataWordMuxM : {{`LLEN-8{1'b0}}, ByteM[7:0]}; // lbu/flq - only needed when LLEN=128
|
||||
3'b101: ReadDataM = {{`LLEN-16{1'b0}}, HalfwordM[15:0]}; // lhu
|
||||
3'b110: ReadDataM = {{`LLEN-32{1'b0}}, WordM[31:0]}; // lwu
|
||||
default: ReadDataM = ReadDataWordMuxM; // Shouldn't happen
|
||||
endcase
|
||||
|
||||
end else begin:swrmux // 32-bit
|
||||
|
@ -114,13 +114,13 @@ module subwordread
|
|||
// sign extension
|
||||
always_comb
|
||||
case(Funct3M)
|
||||
3'b000: ReadDataM = {{`LLEN-8{ByteM[7]}}, ByteM}; // lb
|
||||
3'b001: ReadDataM = {{`LLEN-16{HalfwordM[15]|FpLoadStoreM}}, HalfwordM[15:0]}; // lh/flh
|
||||
3'b010: ReadDataM = {{`LLEN-32{ReadDataWordMuxM[31]|FpLoadStoreM}}, ReadDataWordMuxM[31:0]}; // lw/flw
|
||||
3'b011: ReadDataM = ReadDataWordMuxM; // fld
|
||||
3'b100: ReadDataM = {{`LLEN-8{1'b0}}, ByteM[7:0]}; // lbu
|
||||
3'b101: ReadDataM = {{`LLEN-16{1'b0}}, HalfwordM[15:0]}; // lhu
|
||||
default: ReadDataM = ReadDataWordMuxM; // Shouldn't happen
|
||||
3'b000: ReadDataM = {{`LLEN-8{ByteM[7]}}, ByteM}; // lb
|
||||
3'b001: ReadDataM = {{`LLEN-16{HalfwordM[15]|FpLoadStoreM}}, HalfwordM[15:0]}; // lh/flh
|
||||
3'b010: ReadDataM = {{`LLEN-32{ReadDataWordMuxM[31]|FpLoadStoreM}}, ReadDataWordMuxM[31:0]}; // lw/flw
|
||||
3'b011: ReadDataM = ReadDataWordMuxM; // fld
|
||||
3'b100: ReadDataM = {{`LLEN-8{1'b0}}, ByteM[7:0]}; // lbu
|
||||
3'b101: ReadDataM = {{`LLEN-16{1'b0}}, HalfwordM[15:0]}; // lhu
|
||||
default: ReadDataM = ReadDataWordMuxM; // Shouldn't happen
|
||||
endcase
|
||||
end
|
||||
endmodule
|
||||
|
|
|
@ -36,7 +36,7 @@ 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 [`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
|
||||
);
|
||||
|
@ -76,7 +76,7 @@ module div(
|
|||
mux2 #(`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;
|
||||
assign DinE = ForwardedSrcBE;
|
||||
end
|
||||
|
||||
// Extract sign bits and check fo division by zero
|
||||
|
|
100
src/mdu/mdu.sv
100
src/mdu/mdu.sv
|
@ -29,62 +29,62 @@
|
|||
`include "wally-config.vh"
|
||||
|
||||
module mdu(
|
||||
input logic clk, reset,
|
||||
input logic StallM, StallW,
|
||||
input logic FlushE, FlushM, FlushW,
|
||||
input logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, // inputs A and B from IEU forwarding mux output
|
||||
input logic [2:0] Funct3E, Funct3M, // type of MDU operation
|
||||
input logic IntDivE, W64E, // Integer division/remainder, and W-type instrutions
|
||||
output logic [`XLEN-1:0] MDUResultW, // multiply/divide result
|
||||
output logic DivBusyE // busy signal to stall pipeline in Execute stage
|
||||
input logic clk, reset,
|
||||
input logic StallM, StallW,
|
||||
input logic FlushE, FlushM, FlushW,
|
||||
input logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, // inputs A and B from IEU forwarding mux output
|
||||
input logic [2:0] Funct3E, Funct3M, // type of MDU operation
|
||||
input logic IntDivE, W64E, // Integer division/remainder, and W-type instrutions
|
||||
output logic [`XLEN-1:0] MDUResultW, // multiply/divide result
|
||||
output logic DivBusyE // busy signal to stall pipeline in Execute stage
|
||||
);
|
||||
|
||||
logic [`XLEN*2-1:0] ProdM; // double-width product from mul
|
||||
logic [`XLEN-1:0] QuotM, RemM; // quotient and remainder from intdivrestoring
|
||||
logic [`XLEN-1:0] PrelimResultM; // selected result before W truncation
|
||||
logic [`XLEN-1:0] MDUResultM; // result after W truncation
|
||||
logic W64M; // W-type instruction
|
||||
logic [`XLEN*2-1:0] ProdM; // double-width product from mul
|
||||
logic [`XLEN-1:0] QuotM, RemM; // quotient and remainder from intdivrestoring
|
||||
logic [`XLEN-1:0] PrelimResultM; // selected result before W truncation
|
||||
logic [`XLEN-1:0] MDUResultM; // result after W truncation
|
||||
logic W64M; // W-type instruction
|
||||
|
||||
// Multiplier
|
||||
mul mul(.clk, .reset, .StallM, .FlushM, .ForwardedSrcAE, .ForwardedSrcBE, .Funct3E, .ProdM);
|
||||
// Multiplier
|
||||
mul mul(.clk, .reset, .StallM, .FlushM, .ForwardedSrcAE, .ForwardedSrcBE, .Funct3E, .ProdM);
|
||||
|
||||
// Divider
|
||||
// Start a divide when a new division instruction is received and the divider isn't already busy or finishing
|
||||
// When IDIV_ON_FPU is set, use the FPU divider instead
|
||||
// In ZMMUL, with M_SUPPORTED = 0, omit the divider
|
||||
if ((`IDIV_ON_FPU) || (!`M_SUPPORTED)) begin:nodiv
|
||||
assign QuotM = 0;
|
||||
assign RemM = 0;
|
||||
assign DivBusyE = 0;
|
||||
end else begin:div
|
||||
div div(.clk, .reset, .StallM, .FlushE, .DivSignedE(~Funct3E[0]), .W64E, .IntDivE,
|
||||
.ForwardedSrcAE, .ForwardedSrcBE, .DivBusyE, .QuotM, .RemM);
|
||||
end
|
||||
|
||||
// Result multiplexer
|
||||
// For ZMMUL, QuotM and RemM are tied to 0, so the mux automatically simplifies
|
||||
always_comb
|
||||
case (Funct3M)
|
||||
3'b000: PrelimResultM = ProdM[`XLEN-1:0]; // mul
|
||||
3'b001: PrelimResultM = ProdM[`XLEN*2-1:`XLEN]; // mulh
|
||||
3'b010: PrelimResultM = ProdM[`XLEN*2-1:`XLEN]; // mulhsu
|
||||
3'b011: PrelimResultM = ProdM[`XLEN*2-1:`XLEN]; // mulhu
|
||||
3'b100: PrelimResultM = QuotM; // div
|
||||
3'b101: PrelimResultM = QuotM; // divu
|
||||
3'b110: PrelimResultM = RemM; // rem
|
||||
3'b111: PrelimResultM = RemM; // remu
|
||||
endcase
|
||||
// Divider
|
||||
// Start a divide when a new division instruction is received and the divider isn't already busy or finishing
|
||||
// When IDIV_ON_FPU is set, use the FPU divider instead
|
||||
// In ZMMUL, with M_SUPPORTED = 0, omit the divider
|
||||
if ((`IDIV_ON_FPU) || (!`M_SUPPORTED)) begin:nodiv
|
||||
assign QuotM = 0;
|
||||
assign RemM = 0;
|
||||
assign DivBusyE = 0;
|
||||
end else begin:div
|
||||
div div(.clk, .reset, .StallM, .FlushE, .DivSignedE(~Funct3E[0]), .W64E, .IntDivE,
|
||||
.ForwardedSrcAE, .ForwardedSrcBE, .DivBusyE, .QuotM, .RemM);
|
||||
end
|
||||
|
||||
// Result multiplexer
|
||||
// For ZMMUL, QuotM and RemM are tied to 0, so the mux automatically simplifies
|
||||
always_comb
|
||||
case (Funct3M)
|
||||
3'b000: PrelimResultM = ProdM[`XLEN-1:0]; // mul
|
||||
3'b001: PrelimResultM = ProdM[`XLEN*2-1:`XLEN]; // mulh
|
||||
3'b010: PrelimResultM = ProdM[`XLEN*2-1:`XLEN]; // mulhsu
|
||||
3'b011: PrelimResultM = ProdM[`XLEN*2-1:`XLEN]; // mulhu
|
||||
3'b100: PrelimResultM = QuotM; // div
|
||||
3'b101: PrelimResultM = QuotM; // divu
|
||||
3'b110: PrelimResultM = RemM; // rem
|
||||
3'b111: PrelimResultM = RemM; // remu
|
||||
endcase
|
||||
|
||||
// Handle sign extension for W-type instructions
|
||||
flopenrc #(1) W64MReg(clk, reset, FlushM, ~StallM, W64E, W64M);
|
||||
if (`XLEN == 64) begin:resmux // RV64 has W-type instructions
|
||||
assign MDUResultM = W64M ? {{32{PrelimResultM[31]}}, PrelimResultM[31:0]} : PrelimResultM;
|
||||
end else begin:resmux // RV32 has no W-type instructions
|
||||
assign MDUResultM = PrelimResultM;
|
||||
end
|
||||
// Handle sign extension for W-type instructions
|
||||
flopenrc #(1) W64MReg(clk, reset, FlushM, ~StallM, W64E, W64M);
|
||||
if (`XLEN == 64) begin:resmux // RV64 has W-type instructions
|
||||
assign MDUResultM = W64M ? {{32{PrelimResultM[31]}}, PrelimResultM[31:0]} : PrelimResultM;
|
||||
end else begin:resmux // RV32 has no W-type instructions
|
||||
assign MDUResultM = PrelimResultM;
|
||||
end
|
||||
|
||||
// Writeback stage pipeline register
|
||||
flopenrc #(`XLEN) MDUResultWReg(clk, reset, FlushW, ~StallW, MDUResultM, MDUResultW);
|
||||
// Writeback stage pipeline register
|
||||
flopenrc #(`XLEN) MDUResultWReg(clk, reset, FlushW, ~StallW, MDUResultM, MDUResultW);
|
||||
endmodule // mdu
|
||||
|
||||
|
||||
|
|
354
src/mmu/hptw.sv
354
src/mmu/hptw.sv
|
@ -32,118 +32,118 @@
|
|||
`include "wally-config.vh"
|
||||
|
||||
module hptw (
|
||||
input logic clk, reset,
|
||||
input logic [`XLEN-1:0] SATP_REGW, // includes SATP.MODE to determine number of levels in page table
|
||||
input logic [`XLEN-1:0] PCSpillF, // addresses to translate
|
||||
input logic [`XLEN+1:0] IEUAdrExtM, // addresses to translate
|
||||
input logic [1:0] MemRWM, AtomicM,
|
||||
// system status
|
||||
input logic STATUS_MXR, STATUS_SUM, STATUS_MPRV,
|
||||
input logic [1:0] STATUS_MPP,
|
||||
input logic [1:0] PrivilegeModeW,
|
||||
input logic [`XLEN-1:0] ReadDataM, // page table entry from LSU
|
||||
input logic [`XLEN-1:0] WriteDataM,
|
||||
input logic DCacheStallM, // stall from LSU
|
||||
input logic [2:0] Funct3M,
|
||||
input logic [6:0] Funct7M,
|
||||
input logic ITLBMissF,
|
||||
input logic DTLBMissM,
|
||||
input logic FlushW,
|
||||
input logic InstrUpdateDAF,
|
||||
input logic DataUpdateDAM,
|
||||
output logic [`XLEN-1:0] PTE, // page table entry to TLBs
|
||||
output logic [1:0] PageType, // page type to TLBs
|
||||
output logic ITLBWriteF, DTLBWriteM, // write TLB with new entry
|
||||
output logic [1:0] PreLSURWM,
|
||||
output logic [`XLEN+1:0] IHAdrM,
|
||||
output logic [`XLEN-1:0] IHWriteDataM,
|
||||
output logic [1:0] LSUAtomicM,
|
||||
output logic [2:0] LSUFunct3M,
|
||||
output logic [6:0] LSUFunct7M,
|
||||
output logic IgnoreRequestTLB,
|
||||
output logic SelHPTW,
|
||||
output logic HPTWStall,
|
||||
input logic LSULoadAccessFaultM, LSUStoreAmoAccessFaultM,
|
||||
output logic LoadAccessFaultM, StoreAmoAccessFaultM, HPTWInstrAccessFaultM
|
||||
input logic clk, reset,
|
||||
input logic [`XLEN-1:0] SATP_REGW, // includes SATP.MODE to determine number of levels in page table
|
||||
input logic [`XLEN-1:0] PCSpillF, // addresses to translate
|
||||
input logic [`XLEN+1:0] IEUAdrExtM, // addresses to translate
|
||||
input logic [1:0] MemRWM, AtomicM,
|
||||
// system status
|
||||
input logic STATUS_MXR, STATUS_SUM, STATUS_MPRV,
|
||||
input logic [1:0] STATUS_MPP,
|
||||
input logic [1:0] PrivilegeModeW,
|
||||
input logic [`XLEN-1:0] ReadDataM, // page table entry from LSU
|
||||
input logic [`XLEN-1:0] WriteDataM,
|
||||
input logic DCacheStallM, // stall from LSU
|
||||
input logic [2:0] Funct3M,
|
||||
input logic [6:0] Funct7M,
|
||||
input logic ITLBMissF,
|
||||
input logic DTLBMissM,
|
||||
input logic FlushW,
|
||||
input logic InstrUpdateDAF,
|
||||
input logic DataUpdateDAM,
|
||||
output logic [`XLEN-1:0] PTE, // page table entry to TLBs
|
||||
output logic [1:0] PageType, // page type to TLBs
|
||||
output logic ITLBWriteF, DTLBWriteM, // write TLB with new entry
|
||||
output logic [1:0] PreLSURWM,
|
||||
output logic [`XLEN+1:0] IHAdrM,
|
||||
output logic [`XLEN-1:0] IHWriteDataM,
|
||||
output logic [1:0] LSUAtomicM,
|
||||
output logic [2:0] LSUFunct3M,
|
||||
output logic [6:0] LSUFunct7M,
|
||||
output logic IgnoreRequestTLB,
|
||||
output logic SelHPTW,
|
||||
output logic HPTWStall,
|
||||
input logic LSULoadAccessFaultM, LSUStoreAmoAccessFaultM,
|
||||
output logic LoadAccessFaultM, StoreAmoAccessFaultM, HPTWInstrAccessFaultM
|
||||
);
|
||||
|
||||
typedef enum logic [3:0] {L0_ADR, L0_RD,
|
||||
L1_ADR, L1_RD,
|
||||
L2_ADR, L2_RD,
|
||||
L3_ADR, L3_RD,
|
||||
LEAF, IDLE, UPDATE_PTE} statetype;
|
||||
L1_ADR, L1_RD,
|
||||
L2_ADR, L2_RD,
|
||||
L3_ADR, L3_RD,
|
||||
LEAF, IDLE, UPDATE_PTE} statetype;
|
||||
|
||||
logic DTLBWalk; // register TLBs translation miss requests
|
||||
logic [`PPN_BITS-1:0] BasePageTablePPN;
|
||||
logic [`PPN_BITS-1:0] CurrentPPN;
|
||||
logic Executable, Writable, Readable, Valid, PTE_U;
|
||||
logic Misaligned, MegapageMisaligned;
|
||||
logic ValidPTE, LeafPTE, ValidLeafPTE, ValidNonLeafPTE;
|
||||
logic StartWalk;
|
||||
logic TLBMiss;
|
||||
logic PRegEn;
|
||||
logic [1:0] NextPageType;
|
||||
logic DTLBWalk; // register TLBs translation miss requests
|
||||
logic [`PPN_BITS-1:0] BasePageTablePPN;
|
||||
logic [`PPN_BITS-1:0] CurrentPPN;
|
||||
logic Executable, Writable, Readable, Valid, PTE_U;
|
||||
logic Misaligned, MegapageMisaligned;
|
||||
logic ValidPTE, LeafPTE, ValidLeafPTE, ValidNonLeafPTE;
|
||||
logic StartWalk;
|
||||
logic TLBMiss;
|
||||
logic PRegEn;
|
||||
logic [1:0] NextPageType;
|
||||
logic [`SVMODE_BITS-1:0] SvMode;
|
||||
logic [`XLEN-1:0] TranslationVAdr;
|
||||
logic [`XLEN-1:0] NextPTE;
|
||||
logic UpdatePTE;
|
||||
logic HPTWUpdateDA;
|
||||
logic [`PA_BITS-1:0] HPTWReadAdr;
|
||||
logic SelHPTWAdr;
|
||||
logic [`XLEN+1:0] HPTWAdrExt;
|
||||
logic ITLBMissOrUpdateDAF;
|
||||
logic DTLBMissOrUpdateDAM;
|
||||
logic [`XLEN-1:0] TranslationVAdr;
|
||||
logic [`XLEN-1:0] NextPTE;
|
||||
logic UpdatePTE;
|
||||
logic HPTWUpdateDA;
|
||||
logic [`PA_BITS-1:0] HPTWReadAdr;
|
||||
logic SelHPTWAdr;
|
||||
logic [`XLEN+1:0] HPTWAdrExt;
|
||||
logic ITLBMissOrUpdateDAF;
|
||||
logic DTLBMissOrUpdateDAM;
|
||||
logic LSUAccessFaultM;
|
||||
logic [`PA_BITS-1:0] HPTWAdr;
|
||||
logic [1:0] HPTWRW;
|
||||
logic [2:0] HPTWSize; // 32 or 64 bit access
|
||||
statetype WalkerState, NextWalkerState, InitialWalkerState;
|
||||
logic [`PA_BITS-1:0] HPTWAdr;
|
||||
logic [1:0] HPTWRW;
|
||||
logic [2:0] HPTWSize; // 32 or 64 bit access
|
||||
statetype WalkerState, NextWalkerState, InitialWalkerState;
|
||||
|
||||
// map hptw access faults onto either the original LSU load/store fault or instruction access fault
|
||||
assign LSUAccessFaultM = LSULoadAccessFaultM | LSUStoreAmoAccessFaultM;
|
||||
assign LoadAccessFaultM = WalkerState == IDLE ? LSULoadAccessFaultM : LSUAccessFaultM & DTLBWalk & MemRWM[1] & ~MemRWM[0];
|
||||
assign StoreAmoAccessFaultM = WalkerState == IDLE ? LSUStoreAmoAccessFaultM : LSUAccessFaultM & DTLBWalk & MemRWM[0];
|
||||
assign HPTWInstrAccessFaultM = WalkerState == IDLE ? 1'b0: LSUAccessFaultM & ~DTLBWalk;
|
||||
assign LSUAccessFaultM = LSULoadAccessFaultM | LSUStoreAmoAccessFaultM;
|
||||
assign LoadAccessFaultM = WalkerState == IDLE ? LSULoadAccessFaultM : LSUAccessFaultM & DTLBWalk & MemRWM[1] & ~MemRWM[0];
|
||||
assign StoreAmoAccessFaultM = WalkerState == IDLE ? LSUStoreAmoAccessFaultM : LSUAccessFaultM & DTLBWalk & MemRWM[0];
|
||||
assign HPTWInstrAccessFaultM = WalkerState == IDLE ? 1'b0: LSUAccessFaultM & ~DTLBWalk;
|
||||
|
||||
// Extract bits from CSRs and inputs
|
||||
assign SvMode = SATP_REGW[`XLEN-1:`XLEN-`SVMODE_BITS];
|
||||
assign BasePageTablePPN = SATP_REGW[`PPN_BITS-1:0];
|
||||
assign TLBMiss = (DTLBMissOrUpdateDAM | ITLBMissOrUpdateDAF);
|
||||
// Extract bits from CSRs and inputs
|
||||
assign SvMode = SATP_REGW[`XLEN-1:`XLEN-`SVMODE_BITS];
|
||||
assign BasePageTablePPN = SATP_REGW[`PPN_BITS-1:0];
|
||||
assign TLBMiss = (DTLBMissOrUpdateDAM | ITLBMissOrUpdateDAF);
|
||||
|
||||
// Determine which address to translate
|
||||
mux2 #(`XLEN) vadrmux(PCSpillF, IEUAdrExtM[`XLEN-1:0], DTLBWalk, TranslationVAdr);
|
||||
assign CurrentPPN = PTE[`PPN_BITS+9:10];
|
||||
// Determine which address to translate
|
||||
mux2 #(`XLEN) vadrmux(PCSpillF, IEUAdrExtM[`XLEN-1:0], DTLBWalk, TranslationVAdr);
|
||||
assign CurrentPPN = PTE[`PPN_BITS+9:10];
|
||||
|
||||
// State flops
|
||||
flopenr #(1) TLBMissMReg(clk, reset, StartWalk, DTLBMissOrUpdateDAM, DTLBWalk); // when walk begins, record whether it was for DTLB (or record 0 for ITLB)
|
||||
assign PRegEn = HPTWRW[1] & ~DCacheStallM | UpdatePTE;
|
||||
flopenr #(`XLEN) PTEReg(clk, reset, PRegEn, NextPTE, PTE); // Capture page table entry from data cache
|
||||
// State flops
|
||||
flopenr #(1) TLBMissMReg(clk, reset, StartWalk, DTLBMissOrUpdateDAM, DTLBWalk); // when walk begins, record whether it was for DTLB (or record 0 for ITLB)
|
||||
assign PRegEn = HPTWRW[1] & ~DCacheStallM | UpdatePTE;
|
||||
flopenr #(`XLEN) PTEReg(clk, reset, PRegEn, NextPTE, PTE); // Capture page table entry from data cache
|
||||
|
||||
// Assign PTE descriptors common across all XLEN values
|
||||
// For non-leaf PTEs, D, A, U bits are reserved and ignored. They do not cause faults while walking the page table
|
||||
assign {PTE_U, Executable, Writable, Readable, Valid} = PTE[4:0];
|
||||
assign LeafPTE = Executable | Writable | Readable;
|
||||
assign ValidPTE = Valid & ~(Writable & ~Readable);
|
||||
assign ValidLeafPTE = ValidPTE & LeafPTE;
|
||||
assign ValidNonLeafPTE = ValidPTE & ~LeafPTE;
|
||||
// Assign PTE descriptors common across all XLEN values
|
||||
// For non-leaf PTEs, D, A, U bits are reserved and ignored. They do not cause faults while walking the page table
|
||||
assign {PTE_U, Executable, Writable, Readable, Valid} = PTE[4:0];
|
||||
assign LeafPTE = Executable | Writable | Readable;
|
||||
assign ValidPTE = Valid & ~(Writable & ~Readable);
|
||||
assign ValidLeafPTE = ValidPTE & LeafPTE;
|
||||
assign ValidNonLeafPTE = ValidPTE & ~LeafPTE;
|
||||
|
||||
if(`SVADU_SUPPORTED) begin : hptwwrites
|
||||
logic ReadAccess, WriteAccess;
|
||||
logic InvalidRead, InvalidWrite, InvalidOp;
|
||||
logic UpperBitsUnequal;
|
||||
logic OtherPageFault;
|
||||
logic [1:0] EffectivePrivilegeMode;
|
||||
logic ImproperPrivilege;
|
||||
logic SaveHPTWAdr, SelHPTWWriteAdr;
|
||||
logic [`PA_BITS-1:0] HPTWWriteAdr;
|
||||
logic SetDirty;
|
||||
logic Dirty, Accessed;
|
||||
logic [`XLEN-1:0] AccessedPTE;
|
||||
logic ReadAccess, WriteAccess;
|
||||
logic InvalidRead, InvalidWrite, InvalidOp;
|
||||
logic UpperBitsUnequal;
|
||||
logic OtherPageFault;
|
||||
logic [1:0] EffectivePrivilegeMode;
|
||||
logic ImproperPrivilege;
|
||||
logic SaveHPTWAdr, SelHPTWWriteAdr;
|
||||
logic [`PA_BITS-1:0] HPTWWriteAdr;
|
||||
logic SetDirty;
|
||||
logic Dirty, Accessed;
|
||||
logic [`XLEN-1:0] AccessedPTE;
|
||||
|
||||
assign AccessedPTE = {PTE[`XLEN-1:8], (SetDirty | PTE[7]), 1'b1, PTE[5:0]}; // set accessed bit, conditionally set dirty bit
|
||||
mux2 #(`XLEN) NextPTEMux(ReadDataM, AccessedPTE, UpdatePTE, NextPTE);
|
||||
assign AccessedPTE = {PTE[`XLEN-1:8], (SetDirty | PTE[7]), 1'b1, PTE[5:0]}; // set accessed bit, conditionally set dirty bit
|
||||
mux2 #(`XLEN) NextPTEMux(ReadDataM, AccessedPTE, UpdatePTE, NextPTE);
|
||||
flopenr #(`PA_BITS) HPTWAdrWriteReg(clk, reset, SaveHPTWAdr, HPTWReadAdr, HPTWWriteAdr);
|
||||
|
||||
|
||||
assign SaveHPTWAdr = WalkerState == L0_ADR;
|
||||
assign SelHPTWWriteAdr = UpdatePTE | HPTWRW[0];
|
||||
mux2 #(`PA_BITS) HPTWWriteAdrMux(HPTWReadAdr, HPTWWriteAdr, SelHPTWWriteAdr, HPTWAdr);
|
||||
|
@ -158,11 +158,11 @@ module hptw (
|
|||
((EffectivePrivilegeMode == `S_MODE) & PTE_U & (~STATUS_SUM & DTLBWalk));
|
||||
|
||||
// Check for page faults
|
||||
vm64check vm64check(.SATP_MODE(SATP_REGW[`XLEN-1:`XLEN-`SVMODE_BITS]), .VAdr(TranslationVAdr),
|
||||
.SV39Mode(), .UpperBitsUnequal);
|
||||
vm64check vm64check(.SATP_MODE(SATP_REGW[`XLEN-1:`XLEN-`SVMODE_BITS]), .VAdr(TranslationVAdr),
|
||||
.SV39Mode(), .UpperBitsUnequal);
|
||||
assign InvalidRead = ReadAccess & ~Readable & (~STATUS_MXR | ~Executable);
|
||||
assign InvalidWrite = WriteAccess & ~Writable;
|
||||
assign InvalidOp = DTLBWalk ? (InvalidRead | InvalidWrite) : ~Executable;
|
||||
assign InvalidOp = DTLBWalk ? (InvalidRead | InvalidWrite) : ~Executable;
|
||||
assign OtherPageFault = ImproperPrivilege | InvalidOp | UpperBitsUnequal | Misaligned | ~Valid;
|
||||
|
||||
// hptw needs to know if there is a Dirty or Access fault occuring on this
|
||||
|
@ -181,62 +181,62 @@ module hptw (
|
|||
assign HPTWRW[0] = '0;
|
||||
end
|
||||
|
||||
// Enable and select signals based on states
|
||||
assign StartWalk = (WalkerState == IDLE) & TLBMiss;
|
||||
assign HPTWRW[1] = (WalkerState == L3_RD) | (WalkerState == L2_RD) | (WalkerState == L1_RD) | (WalkerState == L0_RD);
|
||||
assign DTLBWriteM = (WalkerState == LEAF & ~HPTWUpdateDA) & DTLBWalk;
|
||||
assign ITLBWriteF = (WalkerState == LEAF & ~HPTWUpdateDA) & ~DTLBWalk;
|
||||
// Enable and select signals based on states
|
||||
assign StartWalk = (WalkerState == IDLE) & TLBMiss;
|
||||
assign HPTWRW[1] = (WalkerState == L3_RD) | (WalkerState == L2_RD) | (WalkerState == L1_RD) | (WalkerState == L0_RD);
|
||||
assign DTLBWriteM = (WalkerState == LEAF & ~HPTWUpdateDA) & DTLBWalk;
|
||||
assign ITLBWriteF = (WalkerState == LEAF & ~HPTWUpdateDA) & ~DTLBWalk;
|
||||
|
||||
// FSM to track PageType based on the levels of the page table traversed
|
||||
flopr #(2) PageTypeReg(clk, reset, NextPageType, PageType);
|
||||
always_comb
|
||||
case (WalkerState)
|
||||
L3_RD: NextPageType = 2'b11; // terapage
|
||||
L2_RD: NextPageType = 2'b10; // gigapage
|
||||
L1_RD: NextPageType = 2'b01; // megapage
|
||||
L0_RD: NextPageType = 2'b00; // kilopage
|
||||
default: NextPageType = PageType;
|
||||
endcase
|
||||
// FSM to track PageType based on the levels of the page table traversed
|
||||
flopr #(2) PageTypeReg(clk, reset, NextPageType, PageType);
|
||||
always_comb
|
||||
case (WalkerState)
|
||||
L3_RD: NextPageType = 2'b11; // terapage
|
||||
L2_RD: NextPageType = 2'b10; // gigapage
|
||||
L1_RD: NextPageType = 2'b01; // megapage
|
||||
L0_RD: NextPageType = 2'b00; // kilopage
|
||||
default: NextPageType = PageType;
|
||||
endcase
|
||||
|
||||
// HPTWAdr muxing
|
||||
if (`XLEN==32) begin // RV32
|
||||
logic [9:0] VPN;
|
||||
logic [`PPN_BITS-1:0] PPN;
|
||||
assign VPN = ((WalkerState == L1_ADR) | (WalkerState == L1_RD)) ? TranslationVAdr[31:22] : TranslationVAdr[21:12]; // select VPN field based on HPTW state
|
||||
assign PPN = ((WalkerState == L1_ADR) | (WalkerState == L1_RD)) ? BasePageTablePPN : CurrentPPN;
|
||||
assign HPTWReadAdr = {PPN, VPN, 2'b00};
|
||||
assign HPTWSize = 3'b010;
|
||||
end else begin // RV64
|
||||
logic [8:0] VPN;
|
||||
logic [`PPN_BITS-1:0] PPN;
|
||||
always_comb
|
||||
case (WalkerState) // select VPN field based on HPTW state
|
||||
L3_ADR, L3_RD: VPN = TranslationVAdr[47:39];
|
||||
L2_ADR, L2_RD: VPN = TranslationVAdr[38:30];
|
||||
L1_ADR, L1_RD: VPN = TranslationVAdr[29:21];
|
||||
default: VPN = TranslationVAdr[20:12];
|
||||
endcase
|
||||
assign PPN = ((WalkerState == L3_ADR) | (WalkerState == L3_RD) |
|
||||
(SvMode != `SV48 & ((WalkerState == L2_ADR) | (WalkerState == L2_RD)))) ? BasePageTablePPN : CurrentPPN;
|
||||
assign HPTWReadAdr = {PPN, VPN, 3'b000};
|
||||
assign HPTWSize = 3'b011;
|
||||
end
|
||||
// HPTWAdr muxing
|
||||
if (`XLEN==32) begin // RV32
|
||||
logic [9:0] VPN;
|
||||
logic [`PPN_BITS-1:0] PPN;
|
||||
assign VPN = ((WalkerState == L1_ADR) | (WalkerState == L1_RD)) ? TranslationVAdr[31:22] : TranslationVAdr[21:12]; // select VPN field based on HPTW state
|
||||
assign PPN = ((WalkerState == L1_ADR) | (WalkerState == L1_RD)) ? BasePageTablePPN : CurrentPPN;
|
||||
assign HPTWReadAdr = {PPN, VPN, 2'b00};
|
||||
assign HPTWSize = 3'b010;
|
||||
end else begin // RV64
|
||||
logic [8:0] VPN;
|
||||
logic [`PPN_BITS-1:0] PPN;
|
||||
always_comb
|
||||
case (WalkerState) // select VPN field based on HPTW state
|
||||
L3_ADR, L3_RD: VPN = TranslationVAdr[47:39];
|
||||
L2_ADR, L2_RD: VPN = TranslationVAdr[38:30];
|
||||
L1_ADR, L1_RD: VPN = TranslationVAdr[29:21];
|
||||
default: VPN = TranslationVAdr[20:12];
|
||||
endcase
|
||||
assign PPN = ((WalkerState == L3_ADR) | (WalkerState == L3_RD) |
|
||||
(SvMode != `SV48 & ((WalkerState == L2_ADR) | (WalkerState == L2_RD)))) ? BasePageTablePPN : CurrentPPN;
|
||||
assign HPTWReadAdr = {PPN, VPN, 3'b000};
|
||||
assign HPTWSize = 3'b011;
|
||||
end
|
||||
|
||||
// Initial state and misalignment for RV32/64
|
||||
if (`XLEN == 32) begin
|
||||
assign InitialWalkerState = L1_ADR;
|
||||
assign MegapageMisaligned = |(CurrentPPN[9:0]); // must have zero PPN0
|
||||
assign Misaligned = ((WalkerState == L0_ADR) & MegapageMisaligned);
|
||||
end else begin
|
||||
logic GigapageMisaligned, TerapageMisaligned;
|
||||
assign InitialWalkerState = (SvMode == `SV48) ? L3_ADR : L2_ADR;
|
||||
assign TerapageMisaligned = |(CurrentPPN[26:0]); // must have zero PPN2, PPN1, PPN0
|
||||
assign GigapageMisaligned = |(CurrentPPN[17:0]); // must have zero PPN1 and PPN0
|
||||
assign MegapageMisaligned = |(CurrentPPN[8:0]); // must have zero PPN0
|
||||
assign Misaligned = ((WalkerState == L2_ADR) & TerapageMisaligned) | ((WalkerState == L1_ADR) & GigapageMisaligned) | ((WalkerState == L0_ADR) & MegapageMisaligned);
|
||||
end
|
||||
// Initial state and misalignment for RV32/64
|
||||
if (`XLEN == 32) begin
|
||||
assign InitialWalkerState = L1_ADR;
|
||||
assign MegapageMisaligned = |(CurrentPPN[9:0]); // must have zero PPN0
|
||||
assign Misaligned = ((WalkerState == L0_ADR) & MegapageMisaligned);
|
||||
end else begin
|
||||
logic GigapageMisaligned, TerapageMisaligned;
|
||||
assign InitialWalkerState = (SvMode == `SV48) ? L3_ADR : L2_ADR;
|
||||
assign TerapageMisaligned = |(CurrentPPN[26:0]); // must have zero PPN2, PPN1, PPN0
|
||||
assign GigapageMisaligned = |(CurrentPPN[17:0]); // must have zero PPN1 and PPN0
|
||||
assign MegapageMisaligned = |(CurrentPPN[8:0]); // must have zero PPN0
|
||||
assign Misaligned = ((WalkerState == L2_ADR) & TerapageMisaligned) | ((WalkerState == L1_ADR) & GigapageMisaligned) | ((WalkerState == L0_ADR) & MegapageMisaligned);
|
||||
end
|
||||
|
||||
// Page Table Walker FSM
|
||||
// Page Table Walker FSM
|
||||
// there is a bug here. Each memory access needs to be potentially flushed if the PMA/P checkers
|
||||
// generate an access fault. Specially the store on UDPATE_PTE needs to check for access violation.
|
||||
// I think the solution is to do 1 of the following
|
||||
|
@ -244,32 +244,32 @@ module hptw (
|
|||
// 2. If the store would generate an exception don't store to dcache but still write the TLB. When we go back
|
||||
// to LEAF then the PMA/P. Wait this does not work. The PMA/P won't be looking a the address in the table, but
|
||||
// rather than physical address of the translated instruction/data. So we must generate the exception.
|
||||
flopenl #(.TYPE(statetype)) WalkerStateReg(clk, reset | FlushW, 1'b1, NextWalkerState, IDLE, WalkerState);
|
||||
always_comb
|
||||
case (WalkerState)
|
||||
IDLE: if (TLBMiss & ~DCacheStallM) NextWalkerState = InitialWalkerState;
|
||||
else NextWalkerState = IDLE;
|
||||
L3_ADR: NextWalkerState = L3_RD; // first access in SV48
|
||||
L3_RD: if (DCacheStallM) NextWalkerState = L3_RD;
|
||||
else NextWalkerState = L2_ADR;
|
||||
L2_ADR: if (InitialWalkerState == L2_ADR | ValidNonLeafPTE) NextWalkerState = L2_RD; // first access in SV39
|
||||
else NextWalkerState = LEAF;
|
||||
L2_RD: if (DCacheStallM) NextWalkerState = L2_RD;
|
||||
else NextWalkerState = L1_ADR;
|
||||
L1_ADR: if (InitialWalkerState == L1_ADR | ValidNonLeafPTE) NextWalkerState = L1_RD; // first access in SV32
|
||||
else NextWalkerState = LEAF;
|
||||
L1_RD: if (DCacheStallM) NextWalkerState = L1_RD;
|
||||
else NextWalkerState = L0_ADR;
|
||||
L0_ADR: if (ValidNonLeafPTE) NextWalkerState = L0_RD;
|
||||
else NextWalkerState = LEAF;
|
||||
L0_RD: if (DCacheStallM) NextWalkerState = L0_RD;
|
||||
else NextWalkerState = LEAF;
|
||||
LEAF: if (`SVADU_SUPPORTED & HPTWUpdateDA) NextWalkerState = UPDATE_PTE;
|
||||
else NextWalkerState = IDLE;
|
||||
UPDATE_PTE: if(DCacheStallM) NextWalkerState = UPDATE_PTE;
|
||||
else NextWalkerState = LEAF;
|
||||
default: NextWalkerState = IDLE; // should never be reached
|
||||
endcase // case (WalkerState)
|
||||
flopenl #(.TYPE(statetype)) WalkerStateReg(clk, reset | FlushW, 1'b1, NextWalkerState, IDLE, WalkerState);
|
||||
always_comb
|
||||
case (WalkerState)
|
||||
IDLE: if (TLBMiss & ~DCacheStallM) NextWalkerState = InitialWalkerState;
|
||||
else NextWalkerState = IDLE;
|
||||
L3_ADR: NextWalkerState = L3_RD; // first access in SV48
|
||||
L3_RD: if (DCacheStallM) NextWalkerState = L3_RD;
|
||||
else NextWalkerState = L2_ADR;
|
||||
L2_ADR: if (InitialWalkerState == L2_ADR | ValidNonLeafPTE) NextWalkerState = L2_RD; // first access in SV39
|
||||
else NextWalkerState = LEAF;
|
||||
L2_RD: if (DCacheStallM) NextWalkerState = L2_RD;
|
||||
else NextWalkerState = L1_ADR;
|
||||
L1_ADR: if (InitialWalkerState == L1_ADR | ValidNonLeafPTE) NextWalkerState = L1_RD; // first access in SV32
|
||||
else NextWalkerState = LEAF;
|
||||
L1_RD: if (DCacheStallM) NextWalkerState = L1_RD;
|
||||
else NextWalkerState = L0_ADR;
|
||||
L0_ADR: if (ValidNonLeafPTE) NextWalkerState = L0_RD;
|
||||
else NextWalkerState = LEAF;
|
||||
L0_RD: if (DCacheStallM) NextWalkerState = L0_RD;
|
||||
else NextWalkerState = LEAF;
|
||||
LEAF: if (`SVADU_SUPPORTED & HPTWUpdateDA) NextWalkerState = UPDATE_PTE;
|
||||
else NextWalkerState = IDLE;
|
||||
UPDATE_PTE: if(DCacheStallM) NextWalkerState = UPDATE_PTE;
|
||||
else NextWalkerState = LEAF;
|
||||
default: NextWalkerState = IDLE; // should never be reached
|
||||
endcase // case (WalkerState)
|
||||
|
||||
assign IgnoreRequestTLB = WalkerState == IDLE & TLBMiss;
|
||||
assign SelHPTW = WalkerState != IDLE;
|
||||
|
|
|
@ -84,8 +84,8 @@ module tlb #(parameter TLB_ENTRIES = 8, ITLB = 0) (
|
|||
logic [1:0] HitPageType;
|
||||
logic CAMHit;
|
||||
logic SV39Mode;
|
||||
logic Misaligned;
|
||||
logic MegapageMisaligned;
|
||||
logic Misaligned;
|
||||
logic MegapageMisaligned;
|
||||
|
||||
if(`XLEN == 32) begin
|
||||
assign MegapageMisaligned = |(PPN[9:0]); // must have zero PPN0
|
||||
|
@ -94,7 +94,7 @@ module tlb #(parameter TLB_ENTRIES = 8, ITLB = 0) (
|
|||
logic GigapageMisaligned, TerapageMisaligned;
|
||||
assign TerapageMisaligned = |(PPN[26:0]); // must have zero PPN2, PPN1, PPN0
|
||||
assign GigapageMisaligned = |(PPN[17:0]); // must have zero PPN1 and PPN0
|
||||
assign MegapageMisaligned = |(PPN[8:0]); // must have zero PPN0
|
||||
assign MegapageMisaligned = |(PPN[8:0]); // must have zero PPN0
|
||||
assign Misaligned = ((HitPageType == 2'b11) & TerapageMisaligned) |
|
||||
((HitPageType == 2'b10) & GigapageMisaligned) |
|
||||
((HitPageType == 2'b01) & MegapageMisaligned);
|
||||
|
|
|
@ -96,11 +96,11 @@ module csr #(parameter
|
|||
);
|
||||
|
||||
logic [`XLEN-1:0] CSRMReadValM, CSRSReadValM, CSRUReadValM, CSRCReadValM;
|
||||
logic [`XLEN-1:0] CSRReadValM;
|
||||
logic [`XLEN-1:0] CSRSrcM;
|
||||
logic [`XLEN-1:0] CSRRWM, CSRRSM, CSRRCM;
|
||||
logic [`XLEN-1:0] CSRWriteValM;
|
||||
logic [`XLEN-1:0] MSTATUS_REGW, SSTATUS_REGW, MSTATUSH_REGW;
|
||||
logic [`XLEN-1:0] CSRReadValM;
|
||||
logic [`XLEN-1:0] CSRSrcM;
|
||||
logic [`XLEN-1:0] CSRRWM, CSRRSM, CSRRCM;
|
||||
logic [`XLEN-1:0] CSRWriteValM;
|
||||
logic [`XLEN-1:0] MSTATUS_REGW, SSTATUS_REGW, MSTATUSH_REGW;
|
||||
logic [`XLEN-1:0] STVEC_REGW, MTVEC_REGW;
|
||||
logic [`XLEN-1:0] MEPC_REGW, SEPC_REGW;
|
||||
logic [31:0] MCOUNTINHIBIT_REGW, MCOUNTEREN_REGW, SCOUNTEREN_REGW;
|
||||
|
@ -117,7 +117,7 @@ module csr #(parameter
|
|||
logic [`XLEN-1:0] TVecM, TrapVectorM, NextFaultMtvalM;
|
||||
logic MTrapM, STrapM;
|
||||
logic [`XLEN-1:0] EPC;
|
||||
logic RetM;
|
||||
logic RetM;
|
||||
logic SelMtvecM;
|
||||
logic [`XLEN-1:0] TVecAlignedM;
|
||||
logic InstrValidNotFlushedM;
|
||||
|
@ -153,7 +153,7 @@ module csr #(parameter
|
|||
logic VectoredM;
|
||||
logic [`XLEN-1:0] TVecPlusCauseM;
|
||||
assign VectoredM = InterruptM & (TVecM[1:0] == 2'b01);
|
||||
assign TVecPlusCauseM = {TVecAlignedM[`XLEN-1:6], CauseM[3:0], 2'b00}; // 64-byte alignment allows concatenation rather than addition
|
||||
assign TVecPlusCauseM = {TVecAlignedM[`XLEN-1:6], CauseM[3:0], 2'b00}; // 64-byte alignment allows concatenation rather than addition
|
||||
mux2 #(`XLEN) trapvecmux(TVecAlignedM, TVecPlusCauseM, VectoredM, TrapVectorM);
|
||||
end else
|
||||
assign TrapVectorM = TVecAlignedM;
|
||||
|
|
|
@ -40,52 +40,52 @@ module csrc #(parameter
|
|||
TIME = 12'hC01,
|
||||
TIMEH = 12'hC81
|
||||
) (
|
||||
input logic clk, reset,
|
||||
input logic StallE, StallM,
|
||||
input logic FlushM,
|
||||
input logic InstrValidNotFlushedM, LoadStallD, StoreStallD,
|
||||
input logic CSRMWriteM, CSRWriteM,
|
||||
input logic BPDirPredWrongM,
|
||||
input logic BTAWrongM,
|
||||
input logic RASPredPCWrongM,
|
||||
input logic IClassWrongM,
|
||||
input logic BPWrongM, // branch predictor is wrong
|
||||
input logic [3:0] InstrClassM,
|
||||
input logic DCacheMiss,
|
||||
input logic DCacheAccess,
|
||||
input logic ICacheMiss,
|
||||
input logic ICacheAccess,
|
||||
input logic ICacheStallF,
|
||||
input logic DCacheStallM,
|
||||
input logic sfencevmaM,
|
||||
input logic InterruptM,
|
||||
input logic ExceptionM,
|
||||
input logic InvalidateICacheM,
|
||||
input logic DivBusyE, // integer divide busy
|
||||
input logic FDivBusyE, // floating point divide busy
|
||||
input logic [11:0] CSRAdrM,
|
||||
input logic [1:0] PrivilegeModeW,
|
||||
input logic [`XLEN-1:0] CSRWriteValM,
|
||||
input logic [31:0] MCOUNTINHIBIT_REGW, MCOUNTEREN_REGW, SCOUNTEREN_REGW,
|
||||
input logic [63:0] MTIME_CLINT,
|
||||
output logic [`XLEN-1:0] CSRCReadValM,
|
||||
output logic IllegalCSRCAccessM
|
||||
input logic clk, reset,
|
||||
input logic StallE, StallM,
|
||||
input logic FlushM,
|
||||
input logic InstrValidNotFlushedM, LoadStallD, StoreStallD,
|
||||
input logic CSRMWriteM, CSRWriteM,
|
||||
input logic BPDirPredWrongM,
|
||||
input logic BTAWrongM,
|
||||
input logic RASPredPCWrongM,
|
||||
input logic IClassWrongM,
|
||||
input logic BPWrongM, // branch predictor is wrong
|
||||
input logic [3:0] InstrClassM,
|
||||
input logic DCacheMiss,
|
||||
input logic DCacheAccess,
|
||||
input logic ICacheMiss,
|
||||
input logic ICacheAccess,
|
||||
input logic ICacheStallF,
|
||||
input logic DCacheStallM,
|
||||
input logic sfencevmaM,
|
||||
input logic InterruptM,
|
||||
input logic ExceptionM,
|
||||
input logic InvalidateICacheM,
|
||||
input logic DivBusyE, // integer divide busy
|
||||
input logic FDivBusyE, // floating point divide busy
|
||||
input logic [11:0] CSRAdrM,
|
||||
input logic [1:0] PrivilegeModeW,
|
||||
input logic [`XLEN-1:0] CSRWriteValM,
|
||||
input logic [31:0] MCOUNTINHIBIT_REGW, MCOUNTEREN_REGW, SCOUNTEREN_REGW,
|
||||
input logic [63:0] MTIME_CLINT,
|
||||
output logic [`XLEN-1:0] CSRCReadValM,
|
||||
output logic IllegalCSRCAccessM
|
||||
);
|
||||
|
||||
logic [4:0] CounterNumM;
|
||||
logic [`XLEN-1:0] HPMCOUNTER_REGW[`COUNTERS-1:0];
|
||||
logic [`XLEN-1:0] HPMCOUNTERH_REGW[`COUNTERS-1:0];
|
||||
logic LoadStallE, LoadStallM;
|
||||
logic StoreStallE, StoreStallM;
|
||||
logic [`COUNTERS-1:0] WriteHPMCOUNTERM;
|
||||
logic [`COUNTERS-1:0] CounterEvent;
|
||||
logic [63:0] HPMCOUNTERPlusM[`COUNTERS-1:0];
|
||||
logic [`XLEN-1:0] NextHPMCOUNTERM[`COUNTERS-1:0];
|
||||
genvar i;
|
||||
logic [4:0] CounterNumM;
|
||||
logic [`XLEN-1:0] HPMCOUNTER_REGW[`COUNTERS-1:0];
|
||||
logic [`XLEN-1:0] HPMCOUNTERH_REGW[`COUNTERS-1:0];
|
||||
logic LoadStallE, LoadStallM;
|
||||
logic StoreStallE, StoreStallM;
|
||||
logic [`COUNTERS-1:0] WriteHPMCOUNTERM;
|
||||
logic [`COUNTERS-1:0] CounterEvent;
|
||||
logic [63:0] HPMCOUNTERPlusM[`COUNTERS-1:0];
|
||||
logic [`XLEN-1:0] NextHPMCOUNTERM[`COUNTERS-1:0];
|
||||
genvar i;
|
||||
|
||||
// Interface signals
|
||||
flopenrc #(2) LoadStallEReg(.clk, .reset, .clear(1'b0), .en(~StallE), .d({StoreStallD, LoadStallD}), .q({StoreStallE, LoadStallE})); // don't flush the load stall during a load stall.
|
||||
flopenrc #(2) LoadStallMReg(.clk, .reset, .clear(FlushM), .en(~StallM), .d({StoreStallE, LoadStallE}), .q({StoreStallM, LoadStallM}));
|
||||
flopenrc #(2) LoadStallMReg(.clk, .reset, .clear(FlushM), .en(~StallM), .d({StoreStallE, LoadStallE}), .q({StoreStallM, LoadStallM}));
|
||||
|
||||
// Determine when to increment each counter
|
||||
assign CounterEvent[0] = 1'b1; // MCYCLE always increments
|
||||
|
@ -97,11 +97,11 @@ module csrc #(parameter
|
|||
assign CounterEvent[3] = InstrClassM[0] & InstrValidNotFlushedM; // branch instruction
|
||||
assign CounterEvent[4] = InstrClassM[1] & ~InstrClassM[2] & InstrValidNotFlushedM; // jump and not return instructions
|
||||
assign CounterEvent[5] = InstrClassM[2] & InstrValidNotFlushedM; // return instructions
|
||||
assign CounterEvent[6] = BPWrongM & InstrValidNotFlushedM; // branch predictor wrong
|
||||
assign CounterEvent[6] = BPWrongM & InstrValidNotFlushedM; // branch predictor wrong
|
||||
assign CounterEvent[7] = BPDirPredWrongM & InstrValidNotFlushedM; // Branch predictor wrong direction
|
||||
assign CounterEvent[8] = BTAWrongM & InstrValidNotFlushedM; // branch predictor wrong target
|
||||
assign CounterEvent[8] = BTAWrongM & InstrValidNotFlushedM; // branch predictor wrong target
|
||||
assign CounterEvent[9] = RASPredPCWrongM & InstrValidNotFlushedM; // return address stack wrong address
|
||||
assign CounterEvent[10] = IClassWrongM & InstrValidNotFlushedM; // instruction class predictor wrong
|
||||
assign CounterEvent[10] = IClassWrongM & InstrValidNotFlushedM; // instruction class predictor wrong
|
||||
assign CounterEvent[11] = LoadStallM & InstrValidNotFlushedM; // Load Stalls. don't want to suppress on flush as this only happens if flushed.
|
||||
assign CounterEvent[12] = StoreStallM & InstrValidNotFlushedM; // Store Stall
|
||||
assign CounterEvent[13] = DCacheAccess & InstrValidNotFlushedM; // data cache access
|
||||
|
@ -111,7 +111,7 @@ module csrc #(parameter
|
|||
assign CounterEvent[17] = ICacheMiss; // instruction cache miss. Miss asserted 1 cycle at start of cache miss
|
||||
assign CounterEvent[18] = ICacheStallF; // i cache miss cycles
|
||||
assign CounterEvent[19] = CSRWriteM & InstrValidNotFlushedM; // CSR writes
|
||||
assign CounterEvent[20] = InvalidateICacheM & InstrValidNotFlushedM; // fence.i
|
||||
assign CounterEvent[20] = InvalidateICacheM & InstrValidNotFlushedM; // fence.i
|
||||
assign CounterEvent[21] = sfencevmaM & InstrValidNotFlushedM; // sfence.vma
|
||||
assign CounterEvent[22] = InterruptM; // interrupt, InstrValidNotFlushedM will be low
|
||||
assign CounterEvent[23] = ExceptionM; // exceptions, InstrValidNotFlushedM will be low
|
||||
|
|
|
@ -34,14 +34,14 @@ module csri #(parameter
|
|||
MIP = 12'h344,
|
||||
SIE = 12'h104,
|
||||
SIP = 12'h144) (
|
||||
input logic clk, reset,
|
||||
input logic InstrValidNotFlushedM,
|
||||
input logic CSRMWriteM, CSRSWriteM,
|
||||
input logic clk, reset,
|
||||
input logic InstrValidNotFlushedM,
|
||||
input logic CSRMWriteM, CSRSWriteM,
|
||||
input logic [`XLEN-1:0] CSRWriteValM,
|
||||
input logic [11:0] CSRAdrM,
|
||||
input logic [11:0] CSRAdrM,
|
||||
input logic MExtInt, SExtInt, MTimerInt, STimerInt, MSwInt,
|
||||
input logic [11:0] MIDELEG_REGW,
|
||||
output logic [11:0] MIP_REGW, MIE_REGW,
|
||||
output logic [11:0] MIP_REGW, MIE_REGW,
|
||||
output logic [11:0] MIP_REGW_writeable // only SEIP, STIP, SSIP are actually writeable; the rest are hardwired to 0
|
||||
);
|
||||
|
||||
|
|
|
@ -72,30 +72,30 @@ module csrm #(parameter
|
|||
MEDELEG_MASK = ~(ZERO | `XLEN'b1 << 11),
|
||||
MIDELEG_MASK = 12'h222 // we choose to not make machine interrupts delegable
|
||||
) (
|
||||
input logic clk, reset,
|
||||
input logic InstrValidNotFlushedM,
|
||||
input logic CSRMWriteM, MTrapM,
|
||||
input logic [11:0] CSRAdrM,
|
||||
input logic [`XLEN-1:0] NextEPCM, NextCauseM, NextMtvalM, MSTATUS_REGW, MSTATUSH_REGW,
|
||||
input logic [`XLEN-1:0] CSRWriteValM,
|
||||
input logic [11:0] MIP_REGW, MIE_REGW,
|
||||
output logic [`XLEN-1:0] CSRMReadValM, MTVEC_REGW,
|
||||
output logic [`XLEN-1:0] MEPC_REGW,
|
||||
output logic [31:0] MCOUNTEREN_REGW, MCOUNTINHIBIT_REGW,
|
||||
output logic [`XLEN-1:0] MEDELEG_REGW,
|
||||
output logic [11:0] MIDELEG_REGW,
|
||||
output var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0],
|
||||
input logic clk, reset,
|
||||
input logic InstrValidNotFlushedM,
|
||||
input logic CSRMWriteM, MTrapM,
|
||||
input logic [11:0] CSRAdrM,
|
||||
input logic [`XLEN-1:0] NextEPCM, NextCauseM, NextMtvalM, MSTATUS_REGW, MSTATUSH_REGW,
|
||||
input logic [`XLEN-1:0] CSRWriteValM,
|
||||
input logic [11:0] MIP_REGW, MIE_REGW,
|
||||
output logic [`XLEN-1:0] CSRMReadValM, MTVEC_REGW,
|
||||
output logic [`XLEN-1:0] MEPC_REGW,
|
||||
output logic [31:0] MCOUNTEREN_REGW, MCOUNTINHIBIT_REGW,
|
||||
output logic [`XLEN-1:0] MEDELEG_REGW,
|
||||
output logic [11:0] MIDELEG_REGW,
|
||||
output var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0],
|
||||
output var logic [`PA_BITS-3:0] PMPADDR_ARRAY_REGW [`PMP_ENTRIES-1:0],
|
||||
output logic WriteMSTATUSM, WriteMSTATUSHM,
|
||||
output logic IllegalCSRMAccessM, IllegalCSRMWriteReadonlyM
|
||||
output logic WriteMSTATUSM, WriteMSTATUSHM,
|
||||
output logic IllegalCSRMAccessM, IllegalCSRMWriteReadonlyM
|
||||
);
|
||||
|
||||
logic [`XLEN-1:0] MISA_REGW, MHARTID_REGW;
|
||||
logic [`XLEN-1:0] MSCRATCH_REGW;
|
||||
logic [`XLEN-1:0] MCAUSE_REGW, MTVAL_REGW;
|
||||
logic WriteMTVECM, WriteMEDELEGM, WriteMIDELEGM;
|
||||
logic WriteMSCRATCHM, WriteMEPCM, WriteMCAUSEM, WriteMTVALM;
|
||||
logic WriteMCOUNTERENM, WriteMCOUNTINHIBITM;
|
||||
logic [`XLEN-1:0] MISA_REGW, MHARTID_REGW;
|
||||
logic [`XLEN-1:0] MSCRATCH_REGW;
|
||||
logic [`XLEN-1:0] MCAUSE_REGW, MTVAL_REGW;
|
||||
logic WriteMTVECM, WriteMEDELEGM, WriteMIDELEGM;
|
||||
logic WriteMSCRATCHM, WriteMEPCM, WriteMCAUSEM, WriteMTVALM;
|
||||
logic WriteMCOUNTERENM, WriteMCOUNTINHIBITM;
|
||||
|
||||
// There are PMP_ENTRIES = 0, 16, or 64 PMPADDR registers, each of which has its own flop
|
||||
genvar i;
|
||||
|
|
|
@ -44,23 +44,23 @@ module csrs #(parameter
|
|||
STIMECMP = 12'h14D,
|
||||
STIMECMPH = 12'h15D,
|
||||
SATP = 12'h180) (
|
||||
input logic clk, reset,
|
||||
input logic InstrValidNotFlushedM,
|
||||
input logic CSRSWriteM, STrapM,
|
||||
input logic [11:0] CSRAdrM,
|
||||
input logic clk, reset,
|
||||
input logic InstrValidNotFlushedM,
|
||||
input logic CSRSWriteM, STrapM,
|
||||
input logic [11:0] CSRAdrM,
|
||||
input logic [`XLEN-1:0] NextEPCM, NextCauseM, NextMtvalM, SSTATUS_REGW,
|
||||
input logic STATUS_TVM,
|
||||
input logic STATUS_TVM,
|
||||
input logic MCOUNTEREN_TM, // TM bit (1) of MCOUNTEREN; cause illegal instruction when trying to access STIMECMP if clear
|
||||
input logic [`XLEN-1:0] CSRWriteValM,
|
||||
input logic [1:0] PrivilegeModeW,
|
||||
input logic [1:0] PrivilegeModeW,
|
||||
output logic [`XLEN-1:0] CSRSReadValM, STVEC_REGW,
|
||||
output logic [`XLEN-1:0] SEPC_REGW,
|
||||
output logic [31:0] SCOUNTEREN_REGW,
|
||||
output logic [`XLEN-1:0] SATP_REGW,
|
||||
input logic [11:0] MIP_REGW, MIE_REGW, MIDELEG_REGW,
|
||||
input logic [63:0] MTIME_CLINT,
|
||||
output logic WriteSSTATUSM,
|
||||
output logic IllegalCSRSAccessM,
|
||||
output logic WriteSSTATUSM,
|
||||
output logic IllegalCSRSAccessM,
|
||||
output logic STimerInt
|
||||
);
|
||||
|
||||
|
@ -68,13 +68,13 @@ module csrs #(parameter
|
|||
localparam ZERO = {(`XLEN){1'b0}};
|
||||
localparam SEDELEG_MASK = ~(ZERO | `XLEN'b111 << 9);
|
||||
|
||||
logic WriteSTVECM;
|
||||
logic WriteSSCRATCHM, WriteSEPCM;
|
||||
logic WriteSCAUSEM, WriteSTVALM, WriteSATPM, WriteSCOUNTERENM;
|
||||
logic WriteSTIMECMPM, WriteSTIMECMPHM;
|
||||
logic [`XLEN-1:0] SSCRATCH_REGW, STVAL_REGW;
|
||||
logic [`XLEN-1:0] SCAUSE_REGW;
|
||||
logic [63:0] STIMECMP_REGW;
|
||||
logic WriteSTVECM;
|
||||
logic WriteSSCRATCHM, WriteSEPCM;
|
||||
logic WriteSCAUSEM, WriteSTVALM, WriteSATPM, WriteSCOUNTERENM;
|
||||
logic WriteSTIMECMPM, WriteSTIMECMPHM;
|
||||
logic [`XLEN-1:0] SSCRATCH_REGW, STVAL_REGW;
|
||||
logic [`XLEN-1:0] SCAUSE_REGW;
|
||||
logic [63:0] STIMECMP_REGW;
|
||||
|
||||
// write enables
|
||||
// *** can InstrValidNotFlushed be factored out of all these writes into CSRWriteM?
|
||||
|
@ -129,10 +129,10 @@ module csrs #(parameter
|
|||
SCAUSE: CSRSReadValM = SCAUSE_REGW;
|
||||
STVAL: CSRSReadValM = STVAL_REGW;
|
||||
SATP: if (`VIRTMEM_SUPPORTED & (PrivilegeModeW == `M_MODE | ~STATUS_TVM)) CSRSReadValM = SATP_REGW;
|
||||
else begin
|
||||
CSRSReadValM = 0;
|
||||
if (PrivilegeModeW == `S_MODE & STATUS_TVM) IllegalCSRSAccessM = 1;
|
||||
end
|
||||
else begin
|
||||
CSRSReadValM = 0;
|
||||
if (PrivilegeModeW == `S_MODE & STATUS_TVM) IllegalCSRSAccessM = 1;
|
||||
end
|
||||
SCOUNTEREN:CSRSReadValM = {{(`XLEN-32){1'b0}}, SCOUNTEREN_REGW};
|
||||
STIMECMP: if (`SSTC_SUPPORTED & (PrivilegeModeW == `M_MODE | MCOUNTEREN_TM)) CSRSReadValM = STIMECMP_REGW[`XLEN-1:0];
|
||||
else begin
|
||||
|
|
|
@ -68,7 +68,7 @@ module csrsr (
|
|||
STATUS_XS, STATUS_FS, /*STATUS_MPP, 2'b0*/ 4'b0,
|
||||
STATUS_SPP, /*STATUS_MPIE*/ 1'b0, STATUS_UBE, STATUS_SPIE,
|
||||
/*1'b0, STATUS_MIE, 1'b0*/ 3'b0, STATUS_SIE, 1'b0};
|
||||
assign MSTATUSH_REGW = '0; // *** does not exist when XLEN=64, but don't want it to have an undefined value. Spec is not clear what it should be.
|
||||
assign MSTATUSH_REGW = '0; // *** does not exist when XLEN=64, but don't want it to have an undefined value. Spec is not clear what it should be.
|
||||
end else begin: csrsr32 // RV32
|
||||
assign MSTATUS_REGW = {STATUS_SD, 8'b0,
|
||||
STATUS_TSR, STATUS_TW, STATUS_TVM, STATUS_MXR, STATUS_SUM, STATUS_MPRV,
|
||||
|
|
|
@ -48,7 +48,7 @@ module csru #(parameter
|
|||
logic [4:0] FFLAGS_REGW;
|
||||
logic [2:0] NextFRMM;
|
||||
logic [4:0] NextFFLAGSM;
|
||||
logic SetOrWriteFFLAGSM;
|
||||
logic SetOrWriteFFLAGSM;
|
||||
|
||||
// Write enables
|
||||
//assign WriteFCSRM = CSRUWriteM & (CSRAdrM == FCSR) & InstrValidNotFlushedM;
|
||||
|
|
|
@ -34,86 +34,86 @@ module privileged (
|
|||
input logic StallD, StallE, StallM, StallW,
|
||||
input logic FlushD, FlushE, FlushM, FlushW,
|
||||
// CSR Reads and Writes, and values needed for traps
|
||||
input logic CSRReadM, CSRWriteM, // Read or write CSRs
|
||||
input logic [`XLEN-1:0] SrcAM, // GPR register to write
|
||||
input logic [31:0] InstrM, // Instruction
|
||||
input logic [31:0] InstrOrigM, // Original compressed or uncompressed instruction in Memory stage for Illegal Instruction MTVAL
|
||||
input logic [`XLEN-1:0] IEUAdrM, // address from IEU
|
||||
input logic [`XLEN-1:0] PCM, PC2NextF, // program counter, next PC going to trap/return PC logic
|
||||
// control signals
|
||||
input logic InstrValidM, // Current instruction is valid (not flushed)
|
||||
input logic CommittedM, CommittedF, // current instruction is using bus; don't interrupt
|
||||
input logic PrivilegedM, // privileged instruction
|
||||
// processor events for performance counter logging
|
||||
input logic FRegWriteM, // instruction will write floating-point registers
|
||||
input logic LoadStallD, // load instruction is stalling
|
||||
input logic StoreStallD, // store instruction is stalling
|
||||
input logic ICacheStallF, // I cache stalled
|
||||
input logic DCacheStallM, // D cache stalled
|
||||
input logic BPDirPredWrongM, // branch predictor guessed wrong direction
|
||||
input logic BTAWrongM, // branch predictor guessed wrong target
|
||||
input logic RASPredPCWrongM, // return adddress stack guessed wrong target
|
||||
input logic IClassWrongM, // branch predictor guessed wrong instruction class
|
||||
input logic BPWrongM, // branch predictor is wrong
|
||||
input logic [3:0] InstrClassM, // actual instruction class
|
||||
input logic DCacheMiss, // data cache miss
|
||||
input logic DCacheAccess, // data cache accessed (hit or miss)
|
||||
input logic ICacheMiss, // instruction cache miss
|
||||
input logic ICacheAccess, // instruction cache access
|
||||
input logic DivBusyE, // integer divide busy
|
||||
input logic FDivBusyE, // floating point divide busy
|
||||
// fault sources
|
||||
input logic InstrAccessFaultF, // instruction access fault
|
||||
input logic LoadAccessFaultM, StoreAmoAccessFaultM, // load or store access fault
|
||||
input logic HPTWInstrAccessFaultM, // hardware page table access fault while fetching instruction PTE
|
||||
input logic InstrPageFaultF, // page faults
|
||||
input logic LoadPageFaultM, StoreAmoPageFaultM, // page faults
|
||||
input logic InstrMisalignedFaultM, // misaligned instruction fault
|
||||
input logic LoadMisalignedFaultM, StoreAmoMisalignedFaultM, // misaligned data fault
|
||||
input logic IllegalIEUFPUInstrD, // illegal instruction from IEU or FPU
|
||||
input logic MTimerInt, MExtInt, SExtInt, MSwInt, // interrupt sources
|
||||
input logic [63:0] MTIME_CLINT, // timer value from CLINT
|
||||
input logic [4:0] SetFflagsM, // set FCSR flags from FPU
|
||||
input logic SelHPTW, // HPTW in use. Causes system to use S-mode endianness for accesses
|
||||
// CSR outputs
|
||||
output logic [`XLEN-1:0] CSRReadValW, // Value read from CSR
|
||||
output logic [1:0] PrivilegeModeW, // current privilege mode
|
||||
output logic [`XLEN-1:0] SATP_REGW, // supervisor address translation register
|
||||
output logic STATUS_MXR, STATUS_SUM, STATUS_MPRV, // status register bits
|
||||
output logic [1:0] STATUS_MPP, STATUS_FS, // status register bits
|
||||
output var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0], // PMP configuration entries to MMU
|
||||
output var logic [`PA_BITS-3:0] PMPADDR_ARRAY_REGW [`PMP_ENTRIES-1:0], // PMP address entries to MMU
|
||||
output logic [2:0] FRM_REGW, // FPU rounding mode
|
||||
// PC logic output in privileged unit
|
||||
output logic [`XLEN-1:0] UnalignedPCNextF, // Next PC from trap/return PC logic
|
||||
// control outputs
|
||||
output logic RetM, TrapM, // return instruction, or trap
|
||||
output logic sfencevmaM, // sfence.vma instruction
|
||||
input logic InvalidateICacheM, // fence instruction
|
||||
output logic BigEndianM, // Use big endian in current privilege mode
|
||||
// Fault outputs
|
||||
output logic BreakpointFaultM, EcallFaultM, // breakpoint and Ecall traps should retire
|
||||
output logic WFIStallM // Stall in Memory stage for WFI until interrupt or timeout
|
||||
);
|
||||
|
||||
logic [`LOG_XLEN-1:0] CauseM; // trap cause
|
||||
logic [`XLEN-1:0] MEDELEG_REGW; // exception delegation CSR
|
||||
logic [11:0] MIDELEG_REGW; // interrupt delegation CSR
|
||||
logic sretM, mretM; // supervisor / machine return instruction
|
||||
logic IllegalCSRAccessM; // Illegal access to CSR
|
||||
logic IllegalIEUFPUInstrM; // Illegal IEU or FPU instruction, delayed to Mem stage
|
||||
logic InstrPageFaultM; // Instruction page fault, delayed to Mem stage
|
||||
logic InstrAccessFaultM; // Instruction access fault, delayed to Mem stages
|
||||
logic IllegalInstrFaultM; // Illegal instruction fault
|
||||
logic STATUS_SPP, STATUS_TSR, STATUS_TW, STATUS_TVM; // Status bits needed within privileged unit
|
||||
logic STATUS_MIE, STATUS_SIE; // status bits: interrupt enables
|
||||
logic [11:0] MIP_REGW, MIE_REGW; // interrupt pending and enable bits
|
||||
logic [1:0] NextPrivilegeModeM; // next privilege mode based on trap or return
|
||||
logic DelegateM; // trap should be delegated
|
||||
logic wfiM; // wait for interrupt instruction
|
||||
logic IntPendingM; // interrupt is pending, even if not enabled. ends wfi
|
||||
logic InterruptM; // interrupt occuring
|
||||
logic ExceptionM; // Memory stage instruction caused a fault
|
||||
input logic CSRReadM, CSRWriteM, // Read or write CSRs
|
||||
input logic [`XLEN-1:0] SrcAM, // GPR register to write
|
||||
input logic [31:0] InstrM, // Instruction
|
||||
input logic [31:0] InstrOrigM, // Original compressed or uncompressed instruction in Memory stage for Illegal Instruction MTVAL
|
||||
input logic [`XLEN-1:0] IEUAdrM, // address from IEU
|
||||
input logic [`XLEN-1:0] PCM, PC2NextF, // program counter, next PC going to trap/return PC logic
|
||||
// control signals
|
||||
input logic InstrValidM, // Current instruction is valid (not flushed)
|
||||
input logic CommittedM, CommittedF, // current instruction is using bus; don't interrupt
|
||||
input logic PrivilegedM, // privileged instruction
|
||||
// processor events for performance counter logging
|
||||
input logic FRegWriteM, // instruction will write floating-point registers
|
||||
input logic LoadStallD, // load instruction is stalling
|
||||
input logic StoreStallD, // store instruction is stalling
|
||||
input logic ICacheStallF, // I cache stalled
|
||||
input logic DCacheStallM, // D cache stalled
|
||||
input logic BPDirPredWrongM, // branch predictor guessed wrong direction
|
||||
input logic BTAWrongM, // branch predictor guessed wrong target
|
||||
input logic RASPredPCWrongM, // return adddress stack guessed wrong target
|
||||
input logic IClassWrongM, // branch predictor guessed wrong instruction class
|
||||
input logic BPWrongM, // branch predictor is wrong
|
||||
input logic [3:0] InstrClassM, // actual instruction class
|
||||
input logic DCacheMiss, // data cache miss
|
||||
input logic DCacheAccess, // data cache accessed (hit or miss)
|
||||
input logic ICacheMiss, // instruction cache miss
|
||||
input logic ICacheAccess, // instruction cache access
|
||||
input logic DivBusyE, // integer divide busy
|
||||
input logic FDivBusyE, // floating point divide busy
|
||||
// fault sources
|
||||
input logic InstrAccessFaultF, // instruction access fault
|
||||
input logic LoadAccessFaultM, StoreAmoAccessFaultM, // load or store access fault
|
||||
input logic HPTWInstrAccessFaultM, // hardware page table access fault while fetching instruction PTE
|
||||
input logic InstrPageFaultF, // page faults
|
||||
input logic LoadPageFaultM, StoreAmoPageFaultM, // page faults
|
||||
input logic InstrMisalignedFaultM, // misaligned instruction fault
|
||||
input logic LoadMisalignedFaultM, StoreAmoMisalignedFaultM, // misaligned data fault
|
||||
input logic IllegalIEUFPUInstrD, // illegal instruction from IEU or FPU
|
||||
input logic MTimerInt, MExtInt, SExtInt, MSwInt, // interrupt sources
|
||||
input logic [63:0] MTIME_CLINT, // timer value from CLINT
|
||||
input logic [4:0] SetFflagsM, // set FCSR flags from FPU
|
||||
input logic SelHPTW, // HPTW in use. Causes system to use S-mode endianness for accesses
|
||||
// CSR outputs
|
||||
output logic [`XLEN-1:0] CSRReadValW, // Value read from CSR
|
||||
output logic [1:0] PrivilegeModeW, // current privilege mode
|
||||
output logic [`XLEN-1:0] SATP_REGW, // supervisor address translation register
|
||||
output logic STATUS_MXR, STATUS_SUM, STATUS_MPRV, // status register bits
|
||||
output logic [1:0] STATUS_MPP, STATUS_FS, // status register bits
|
||||
output var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0], // PMP configuration entries to MMU
|
||||
output var logic [`PA_BITS-3:0] PMPADDR_ARRAY_REGW [`PMP_ENTRIES-1:0], // PMP address entries to MMU
|
||||
output logic [2:0] FRM_REGW, // FPU rounding mode
|
||||
// PC logic output in privileged unit
|
||||
output logic [`XLEN-1:0] UnalignedPCNextF, // Next PC from trap/return PC logic
|
||||
// control outputs
|
||||
output logic RetM, TrapM, // return instruction, or trap
|
||||
output logic sfencevmaM, // sfence.vma instruction
|
||||
input logic InvalidateICacheM, // fence instruction
|
||||
output logic BigEndianM, // Use big endian in current privilege mode
|
||||
// Fault outputs
|
||||
output logic BreakpointFaultM, EcallFaultM, // breakpoint and Ecall traps should retire
|
||||
output logic WFIStallM // Stall in Memory stage for WFI until interrupt or timeout
|
||||
);
|
||||
|
||||
logic [`LOG_XLEN-1:0] CauseM; // trap cause
|
||||
logic [`XLEN-1:0] MEDELEG_REGW; // exception delegation CSR
|
||||
logic [11:0] MIDELEG_REGW; // interrupt delegation CSR
|
||||
logic sretM, mretM; // supervisor / machine return instruction
|
||||
logic IllegalCSRAccessM; // Illegal access to CSR
|
||||
logic IllegalIEUFPUInstrM; // Illegal IEU or FPU instruction, delayed to Mem stage
|
||||
logic InstrPageFaultM; // Instruction page fault, delayed to Mem stage
|
||||
logic InstrAccessFaultM; // Instruction access fault, delayed to Mem stages
|
||||
logic IllegalInstrFaultM; // Illegal instruction fault
|
||||
logic STATUS_SPP, STATUS_TSR, STATUS_TW, STATUS_TVM; // Status bits needed within privileged unit
|
||||
logic STATUS_MIE, STATUS_SIE; // status bits: interrupt enables
|
||||
logic [11:0] MIP_REGW, MIE_REGW; // interrupt pending and enable bits
|
||||
logic [1:0] NextPrivilegeModeM; // next privilege mode based on trap or return
|
||||
logic DelegateM; // trap should be delegated
|
||||
logic wfiM; // wait for interrupt instruction
|
||||
logic IntPendingM; // interrupt is pending, even if not enabled. ends wfi
|
||||
logic InterruptM; // interrupt occuring
|
||||
logic ExceptionM; // Memory stage instruction caused a fault
|
||||
|
||||
// track the current privilege level
|
||||
privmode privmode(.clk, .reset, .StallW, .TrapM, .mretM, .sretM, .DelegateM,
|
||||
|
|
|
@ -29,33 +29,33 @@
|
|||
`include "wally-config.vh"
|
||||
|
||||
module trap (
|
||||
input logic reset,
|
||||
input logic InstrMisalignedFaultM, InstrAccessFaultM, HPTWInstrAccessFaultM, IllegalInstrFaultM,
|
||||
input logic BreakpointFaultM, LoadMisalignedFaultM, StoreAmoMisalignedFaultM,
|
||||
input logic LoadAccessFaultM, StoreAmoAccessFaultM, EcallFaultM, InstrPageFaultM,
|
||||
input logic LoadPageFaultM, StoreAmoPageFaultM, // various trap sources
|
||||
input logic mretM, sretM, // return instructions
|
||||
input logic wfiM, // wait for interrupt instruction
|
||||
input logic [1:0] PrivilegeModeW, // current privilege mode
|
||||
input logic [11:0] MIP_REGW, MIE_REGW, MIDELEG_REGW, // interrupt pending, enabled, and delegate CSRs
|
||||
input logic [`XLEN-1:0] MEDELEG_REGW, // exception delegation SR
|
||||
input logic STATUS_MIE, STATUS_SIE, // machine/supervisor interrupt enables
|
||||
input logic InstrValidM, // current instruction is valid, not flushed
|
||||
input logic CommittedM, CommittedF, // LSU/IFU has committed to a bus operation that can't be interrupted
|
||||
output logic TrapM, // Trap is occurring
|
||||
output logic RetM, // Return instruction being executed
|
||||
output logic InterruptM, // Interrupt is occurring
|
||||
output logic ExceptionM, // exception is occurring
|
||||
output logic IntPendingM, // Interrupt is pending, might occur if enabled
|
||||
output logic DelegateM, // Delegate trap to supervisor handler
|
||||
output logic WFIStallM, // Stall due to WFI instruction
|
||||
output logic [`LOG_XLEN-1:0] CauseM // trap cause
|
||||
input logic reset,
|
||||
input logic InstrMisalignedFaultM, InstrAccessFaultM, HPTWInstrAccessFaultM, IllegalInstrFaultM,
|
||||
input logic BreakpointFaultM, LoadMisalignedFaultM, StoreAmoMisalignedFaultM,
|
||||
input logic LoadAccessFaultM, StoreAmoAccessFaultM, EcallFaultM, InstrPageFaultM,
|
||||
input logic LoadPageFaultM, StoreAmoPageFaultM, // various trap sources
|
||||
input logic mretM, sretM, // return instructions
|
||||
input logic wfiM, // wait for interrupt instruction
|
||||
input logic [1:0] PrivilegeModeW, // current privilege mode
|
||||
input logic [11:0] MIP_REGW, MIE_REGW, MIDELEG_REGW, // interrupt pending, enabled, and delegate CSRs
|
||||
input logic [`XLEN-1:0] MEDELEG_REGW, // exception delegation SR
|
||||
input logic STATUS_MIE, STATUS_SIE, // machine/supervisor interrupt enables
|
||||
input logic InstrValidM, // current instruction is valid, not flushed
|
||||
input logic CommittedM, CommittedF, // LSU/IFU has committed to a bus operation that can't be interrupted
|
||||
output logic TrapM, // Trap is occurring
|
||||
output logic RetM, // Return instruction being executed
|
||||
output logic InterruptM, // Interrupt is occurring
|
||||
output logic ExceptionM, // exception is occurring
|
||||
output logic IntPendingM, // Interrupt is pending, might occur if enabled
|
||||
output logic DelegateM, // Delegate trap to supervisor handler
|
||||
output logic WFIStallM, // Stall due to WFI instruction
|
||||
output logic [`LOG_XLEN-1:0] CauseM // trap cause
|
||||
);
|
||||
|
||||
logic MIntGlobalEnM, SIntGlobalEnM; // Global interupt enables
|
||||
logic Committed; // LSU or IFU has committed to a bus operation that can't be interrupted
|
||||
logic BothInstrAccessFaultM; // instruction or HPTW ITLB fill caused an Instruction Access Fault
|
||||
logic [11:0] PendingIntsM, ValidIntsM, EnabledIntsM; // interrupts are pending, valid, or enabled
|
||||
logic MIntGlobalEnM, SIntGlobalEnM; // Global interupt enables
|
||||
logic Committed; // LSU or IFU has committed to a bus operation that can't be interrupted
|
||||
logic BothInstrAccessFaultM; // instruction or HPTW ITLB fill caused an Instruction Access Fault
|
||||
logic [11:0] PendingIntsM, ValidIntsM, EnabledIntsM; // interrupts are pending, valid, or enabled
|
||||
|
||||
///////////////////////////////////////////
|
||||
// Determine pending enabled interrupts
|
||||
|
|
|
@ -40,7 +40,7 @@ module clint_apb (
|
|||
output logic [`XLEN-1:0] PRDATA,
|
||||
output logic PREADY,
|
||||
output logic [63:0] MTIME,
|
||||
output logic MTimerInt, MSwInt
|
||||
output logic MTimerInt, MSwInt
|
||||
);
|
||||
|
||||
logic MSIP;
|
||||
|
|
|
@ -43,37 +43,37 @@
|
|||
// hardcoded to 2 contexts for now; later upgrade to arbitrary (up to 15872) contexts
|
||||
|
||||
module plic_apb (
|
||||
input logic PCLK, PRESETn,
|
||||
input logic PSEL,
|
||||
input logic [27:0] PADDR,
|
||||
input logic [`XLEN-1:0] PWDATA,
|
||||
input logic PCLK, PRESETn,
|
||||
input logic PSEL,
|
||||
input logic [27:0] PADDR,
|
||||
input logic [`XLEN-1:0] PWDATA,
|
||||
input logic [`XLEN/8-1:0] PSTRB,
|
||||
input logic PWRITE,
|
||||
input logic PENABLE,
|
||||
output logic [`XLEN-1:0] PRDATA,
|
||||
output logic PREADY,
|
||||
input logic UARTIntr,GPIOIntr,
|
||||
output logic MExtInt, SExtInt
|
||||
input logic PWRITE,
|
||||
input logic PENABLE,
|
||||
output logic [`XLEN-1:0] PRDATA,
|
||||
output logic PREADY,
|
||||
input logic UARTIntr,GPIOIntr,
|
||||
output logic MExtInt, SExtInt
|
||||
);
|
||||
|
||||
logic memwrite, memread;
|
||||
logic [23:0] entry;
|
||||
logic [31:0] Din, Dout;
|
||||
logic memwrite, memread;
|
||||
logic [23:0] entry;
|
||||
logic [31:0] Din, Dout;
|
||||
|
||||
// context-independent signals
|
||||
logic [`N:1] requests;
|
||||
logic [`N:1][2:0] intPriority;
|
||||
logic [`N:1] intInProgress, intPending, nextIntPending;
|
||||
logic [`N:1] requests;
|
||||
logic [`N:1][2:0] intPriority;
|
||||
logic [`N:1] intInProgress, intPending, nextIntPending;
|
||||
|
||||
// context-dependent signals
|
||||
logic [`C-1:0][2:0] intThreshold;
|
||||
logic [`C-1:0][`N:1] intEn;
|
||||
logic [`C-1:0][5:0] intClaim; // ID's are 6 bits if we stay within 63 sources
|
||||
logic [`C-1:0][7:1][`N:1] irqMatrix;
|
||||
logic [`C-1:0][7:1] priorities_with_irqs;
|
||||
logic [`C-1:0][7:1] max_priority_with_irqs;
|
||||
logic [`C-1:0][`N:1] irqs_at_max_priority;
|
||||
logic [`C-1:0][7:1] threshMask;
|
||||
logic [`C-1:0][2:0] intThreshold;
|
||||
logic [`C-1:0][`N:1] intEn;
|
||||
logic [`C-1:0][5:0] intClaim; // ID's are 6 bits if we stay within 63 sources
|
||||
logic [`C-1:0][7:1][`N:1] irqMatrix;
|
||||
logic [`C-1:0][7:1] priorities_with_irqs;
|
||||
logic [`C-1:0][7:1] max_priority_with_irqs;
|
||||
logic [`C-1:0][`N:1] irqs_at_max_priority;
|
||||
logic [`C-1:0][7:1] threshMask;
|
||||
|
||||
// =======
|
||||
// AHB I/O
|
||||
|
@ -128,7 +128,7 @@ module plic_apb (
|
|||
if (memread)
|
||||
casez(entry)
|
||||
24'h000000: Dout <= #1 32'b0; // there is no intPriority[0]
|
||||
24'h0000??: Dout <= #1 {29'b0,intPriority[entry[7:2]]};
|
||||
24'h0000??: Dout <= #1 {29'b0,intPriority[entry[7:2]]};
|
||||
`ifdef PLIC_NUM_SRC_LT_32
|
||||
24'h001000: Dout <= #1 {{(31-`N){1'b0}},intPending,1'b0};
|
||||
24'h002000: Dout <= #1 {{(31-`N){1'b0}},intEn[0],1'b0};
|
||||
|
|
|
@ -30,27 +30,27 @@
|
|||
`define RAM_LATENCY 0
|
||||
|
||||
module ram_ahb #(parameter BASE=0, RANGE = 65535) (
|
||||
input logic HCLK, HRESETn,
|
||||
input logic HSELRam,
|
||||
input logic [`PA_BITS-1:0] HADDR,
|
||||
input logic HWRITE,
|
||||
input logic HREADY,
|
||||
input logic [1:0] HTRANS,
|
||||
input logic [`XLEN-1:0] HWDATA,
|
||||
input logic [`XLEN/8-1:0] HWSTRB,
|
||||
output logic [`XLEN-1:0] HREADRam,
|
||||
output logic HRESPRam, HREADYRam
|
||||
input logic HCLK, HRESETn,
|
||||
input logic HSELRam,
|
||||
input logic [`PA_BITS-1:0] HADDR,
|
||||
input logic HWRITE,
|
||||
input logic HREADY,
|
||||
input logic [1:0] HTRANS,
|
||||
input logic [`XLEN-1:0] HWDATA,
|
||||
input logic [`XLEN/8-1:0] HWSTRB,
|
||||
output logic [`XLEN-1:0] HREADRam,
|
||||
output logic HRESPRam, HREADYRam
|
||||
);
|
||||
|
||||
localparam ADDR_WIDTH = $clog2(RANGE/8);
|
||||
localparam OFFSET = $clog2(`XLEN/8);
|
||||
|
||||
logic [`XLEN/8-1:0] ByteMask;
|
||||
logic [`PA_BITS-1:0] HADDRD, RamAddr;
|
||||
logic initTrans;
|
||||
logic memwrite, memwriteD, memread;
|
||||
logic nextHREADYRam;
|
||||
logic DelayReady;
|
||||
logic [`XLEN/8-1:0] ByteMask;
|
||||
logic [`PA_BITS-1:0] HADDRD, RamAddr;
|
||||
logic initTrans;
|
||||
logic memwrite, memwriteD, memread;
|
||||
logic nextHREADYRam;
|
||||
logic DelayReady;
|
||||
|
||||
// a new AHB transactions starts when HTRANS requests a transaction,
|
||||
// the peripheral is selected, and the previous transaction is completing
|
||||
|
@ -92,13 +92,13 @@ module ram_ahb #(parameter BASE=0, RANGE = 65535) (
|
|||
else CurrState <= #1 NextState;
|
||||
|
||||
always_comb begin
|
||||
case(CurrState)
|
||||
READY: if(initTrans & ~CycleFlag) NextState = DELAY;
|
||||
case(CurrState)
|
||||
READY: if(initTrans & ~CycleFlag) NextState = DELAY;
|
||||
else NextState = READY;
|
||||
DELAY: if(CycleFlag) NextState = READY;
|
||||
else NextState = DELAY;
|
||||
default: NextState = READY;
|
||||
endcase
|
||||
else NextState = DELAY;
|
||||
default: NextState = READY;
|
||||
endcase
|
||||
end
|
||||
|
||||
assign CycleFlag = Cycle == `RAM_LATENCY;
|
||||
|
@ -108,7 +108,6 @@ module ram_ahb #(parameter BASE=0, RANGE = 65535) (
|
|||
end else begin
|
||||
assign DelayReady = 0;
|
||||
end
|
||||
|
||||
|
||||
|
||||
endmodule
|
||||
|
||||
|
|
|
@ -37,19 +37,19 @@
|
|||
/* verilator lint_off UNOPTFLAT */
|
||||
|
||||
module uartPC16550D(
|
||||
// Processor Interface
|
||||
input logic PCLK, PRESETn, // UART clock and active low reset
|
||||
input logic [2:0] A, // address input (8 registers)
|
||||
input logic [7:0] Din, // 8-bit WriteData
|
||||
output logic [7:0] Dout, // 8-bit ReadData
|
||||
input logic MEMRb, MEMWb, // Active low memory read/write
|
||||
output logic INTR, TXRDYb, RXRDYb, // interrupt and ready lines
|
||||
// Clocks
|
||||
output logic BAUDOUTb, // active low baud clock
|
||||
input logic RCLK, // usually BAUDOUTb tied to RCLK externally
|
||||
// E1A Driver
|
||||
input logic SIN, DSRb, DCDb, CTSb, RIb, // UART external serial and flow-control inputs
|
||||
output logic SOUT, RTSb, DTRb, OUT1b, OUT2b // UART external serial and flow-control outputs
|
||||
// Processor Interface
|
||||
input logic PCLK, PRESETn, // UART clock and active low reset
|
||||
input logic [2:0] A, // address input (8 registers)
|
||||
input logic [7:0] Din, // 8-bit WriteData
|
||||
output logic [7:0] Dout, // 8-bit ReadData
|
||||
input logic MEMRb, MEMWb, // Active low memory read/write
|
||||
output logic INTR, TXRDYb, RXRDYb, // interrupt and ready lines
|
||||
// Clocks
|
||||
output logic BAUDOUTb, // active low baud clock
|
||||
input logic RCLK, // usually BAUDOUTb tied to RCLK externally
|
||||
// E1A Driver
|
||||
input logic SIN, DSRb, DCDb, CTSb, RIb, // UART external serial and flow-control inputs
|
||||
output logic SOUT, RTSb, DTRb, OUT1b, OUT2b // UART external serial and flow-control outputs
|
||||
);
|
||||
|
||||
// transmit and receive states
|
||||
|
@ -62,63 +62,63 @@ module uartPC16550D(
|
|||
logic [4:0] MCR;
|
||||
|
||||
// Syncrhonized and delayed UART signals
|
||||
logic SINd, DSRbd, DCDbd, CTSbd, RIbd;
|
||||
logic SINsync, DSRbsync, DCDbsync, CTSbsync, RIbsync;
|
||||
logic DSRb2, DCDb2, CTSb2, RIb2;
|
||||
logic SOUTbit;
|
||||
logic SINd, DSRbd, DCDbd, CTSbd, RIbd;
|
||||
logic SINsync, DSRbsync, DCDbsync, CTSbsync, RIbsync;
|
||||
logic DSRb2, DCDb2, CTSb2, RIb2;
|
||||
logic SOUTbit;
|
||||
|
||||
// Control signals
|
||||
logic loop; // loopback mode
|
||||
logic DLAB; // Divisor Latch Access Bit (LCR bit 7)
|
||||
logic loop; // loopback mode
|
||||
logic DLAB; // Divisor Latch Access Bit (LCR bit 7)
|
||||
|
||||
// Baud and rx/tx timing
|
||||
logic baudpulse, txbaudpulse, rxbaudpulse; // high one system clk cycle each baud/16 period
|
||||
logic baudpulse, txbaudpulse, rxbaudpulse; // high one system clk cycle each baud/16 period
|
||||
logic [16+`UART_PRESCALE-1:0] baudcount;
|
||||
logic [3:0] rxoversampledcnt, txoversampledcnt; // count oversampled-by-16
|
||||
logic [3:0] rxbitsreceived, txbitssent;
|
||||
statetype rxstate, txstate;
|
||||
logic [3:0] rxoversampledcnt, txoversampledcnt; // count oversampled-by-16
|
||||
logic [3:0] rxbitsreceived, txbitssent;
|
||||
statetype rxstate, txstate;
|
||||
|
||||
// shift registrs and FIFOs
|
||||
logic [9:0] rxshiftreg;
|
||||
logic [10:0] rxfifo[15:0];
|
||||
logic [7:0] txfifo[15:0];
|
||||
logic [4:0] rxfifotailunwrapped;
|
||||
logic [3:0] rxfifohead, rxfifotail, txfifohead, txfifotail, rxfifotriggerlevel;
|
||||
logic [3:0] rxfifoentries, txfifoentries;
|
||||
logic [3:0] rxbitsexpected, txbitsexpected;
|
||||
logic [9:0] rxshiftreg;
|
||||
logic [10:0] rxfifo[15:0];
|
||||
logic [7:0] txfifo[15:0];
|
||||
logic [4:0] rxfifotailunwrapped;
|
||||
logic [3:0] rxfifohead, rxfifotail, txfifohead, txfifotail, rxfifotriggerlevel;
|
||||
logic [3:0] rxfifoentries, txfifoentries;
|
||||
logic [3:0] rxbitsexpected, txbitsexpected;
|
||||
|
||||
// receive data
|
||||
logic [10:0] RXBR;
|
||||
logic [9:0] rxtimeoutcnt;
|
||||
logic rxcentered;
|
||||
logic rxparity, rxparitybit, rxstopbit;
|
||||
logic rxparityerr, rxoverrunerr, rxframingerr, rxbreak, rxfifohaserr;
|
||||
logic rxdataready;
|
||||
logic rxfifoempty, rxfifotriggered, rxfifotimeout;
|
||||
logic rxfifodmaready;
|
||||
logic [8:0] rxdata9;
|
||||
logic [7:0] rxdata;
|
||||
logic [15:0] RXerrbit, rxfullbit;
|
||||
logic [31:0] rxfullbitunwrapped;
|
||||
logic [10:0] RXBR;
|
||||
logic [9:0] rxtimeoutcnt;
|
||||
logic rxcentered;
|
||||
logic rxparity, rxparitybit, rxstopbit;
|
||||
logic rxparityerr, rxoverrunerr, rxframingerr, rxbreak, rxfifohaserr;
|
||||
logic rxdataready;
|
||||
logic rxfifoempty, rxfifotriggered, rxfifotimeout;
|
||||
logic rxfifodmaready;
|
||||
logic [8:0] rxdata9;
|
||||
logic [7:0] rxdata;
|
||||
logic [15:0] RXerrbit, rxfullbit;
|
||||
logic [31:0] rxfullbitunwrapped;
|
||||
|
||||
// transmit data
|
||||
logic [7:0] TXHR, nexttxdata;
|
||||
logic [11:0] txdata, txsr;
|
||||
logic txnextbit, txhrfull, txsrfull;
|
||||
logic txparity;
|
||||
logic txfifoempty, txfifofull, txfifodmaready;
|
||||
logic [7:0] TXHR, nexttxdata;
|
||||
logic [11:0] txdata, txsr;
|
||||
logic txnextbit, txhrfull, txsrfull;
|
||||
logic txparity;
|
||||
logic txfifoempty, txfifofull, txfifodmaready;
|
||||
|
||||
// control signals
|
||||
logic fifoenabled, fifodmamodesel, evenparitysel;
|
||||
logic fifoenabled, fifodmamodesel, evenparitysel;
|
||||
|
||||
// interrupts
|
||||
logic RXerr, RXerrIP, squashRXerrIP, prevSquashRXerrIP, setSquashRXerrIP, resetSquashRXerrIP;
|
||||
logic THRE, THRE_IP, squashTHRE_IP, prevSquashTHRE_IP, setSquashTHRE_IP, resetSquashTHRE_IP;
|
||||
logic rxdataavailintr, modemstatusintr, intrpending;
|
||||
logic [2:0] intrID;
|
||||
logic RXerr, RXerrIP, squashRXerrIP, prevSquashRXerrIP, setSquashRXerrIP, resetSquashRXerrIP;
|
||||
logic THRE, THRE_IP, squashTHRE_IP, prevSquashTHRE_IP, setSquashTHRE_IP, resetSquashTHRE_IP;
|
||||
logic rxdataavailintr, modemstatusintr, intrpending;
|
||||
logic [2:0] intrID;
|
||||
|
||||
logic baudpulseComb;
|
||||
logic HeadPointerLastMove;
|
||||
logic baudpulseComb;
|
||||
logic HeadPointerLastMove;
|
||||
|
||||
///////////////////////////////////////////
|
||||
// Input synchronization: 2-stage synchronizer
|
||||
|
@ -126,7 +126,7 @@ module uartPC16550D(
|
|||
always_ff @(posedge PCLK) begin
|
||||
{SINd, DSRbd, DCDbd, CTSbd, RIbd} <= #1 {SIN, DSRb, DCDb, CTSb, RIb};
|
||||
{SINsync, DSRbsync, DCDbsync, CTSbsync, RIbsync} <= #1 loop ? {SOUTbit, ~MCR[0], ~MCR[3], ~MCR[1], ~MCR[2]} :
|
||||
{SINd, DSRbd, DCDbd, CTSbd, RIbd}; // syncrhonized signals, handle loopback testing
|
||||
{SINd, DSRbd, DCDbd, CTSbd, RIbd}; // syncrhonized signals, handle loopback testing
|
||||
{DSRb2, DCDb2, CTSb2, RIb2} <= #1 {DSRbsync, DCDbsync, CTSbsync, RIbsync}; // for detecting state changes
|
||||
end
|
||||
|
||||
|
@ -141,8 +141,8 @@ module uartPC16550D(
|
|||
MCR <= #1 5'b0;
|
||||
LSR <= #1 8'b01100000;
|
||||
MSR <= #1 4'b0;
|
||||
DLL <= #1 8'd1; // this cannot be zero with DLM also zer0.
|
||||
DLM <= #1 8'b0;
|
||||
DLL <= #1 8'd1; // this cannot be zero with DLM also zer0.
|
||||
DLM <= #1 8'b0;
|
||||
SCR <= #1 8'b0; // not strictly necessary to reset
|
||||
end else begin
|
||||
if (~MEMWb) begin
|
||||
|
@ -367,7 +367,7 @@ module uartPC16550D(
|
|||
end
|
||||
|
||||
///////////////////////////////////////////
|
||||
// transmit timing and control
|
||||
// transmit timing and control
|
||||
///////////////////////////////////////////
|
||||
always_ff @(posedge PCLK, negedge PRESETn)
|
||||
if (~PRESETn) begin
|
||||
|
@ -455,20 +455,20 @@ module uartPC16550D(
|
|||
end
|
||||
|
||||
always_ff @(posedge PCLK, negedge PRESETn) begin
|
||||
// special condition to check if the fifo is empty or full. Because the head
|
||||
// pointer indicates where the next write goes and not the location of the
|
||||
// current head, the head and tail pointer being equal imply two different
|
||||
// things. First it could mean the fifo is empty and second it could mean
|
||||
// the fifo is full. To differenciate we need to know which pointer moved
|
||||
// to cause them to be equal. If the head pointer moved then it is full.
|
||||
// If the tail pointer moved then it is empty. it resets to empty so
|
||||
// if reset with the tail pointer indicating the last update.
|
||||
if(~PRESETn)
|
||||
HeadPointerLastMove <= 1'b0;
|
||||
else if(fifoenabled & ~MEMWb & A == 3'b000 & ~DLAB)
|
||||
HeadPointerLastMove <= 1'b1;
|
||||
else if(fifoenabled & ~txfifoempty & ~txsrfull & txstate == UART_IDLE)
|
||||
HeadPointerLastMove <= 1'b0;
|
||||
// special condition to check if the fifo is empty or full. Because the head
|
||||
// pointer indicates where the next write goes and not the location of the
|
||||
// current head, the head and tail pointer being equal imply two different
|
||||
// things. First it could mean the fifo is empty and second it could mean
|
||||
// the fifo is full. To differenciate we need to know which pointer moved
|
||||
// to cause them to be equal. If the head pointer moved then it is full.
|
||||
// If the tail pointer moved then it is empty. it resets to empty so
|
||||
// if reset with the tail pointer indicating the last update.
|
||||
if(~PRESETn)
|
||||
HeadPointerLastMove <= 1'b0;
|
||||
else if(fifoenabled & ~MEMWb & A == 3'b000 & ~DLAB)
|
||||
HeadPointerLastMove <= 1'b1;
|
||||
else if(fifoenabled & ~txfifoempty & ~txsrfull & txstate == UART_IDLE)
|
||||
HeadPointerLastMove <= 1'b0;
|
||||
end
|
||||
|
||||
assign txfifoempty = (txfifohead == txfifotail) & ~HeadPointerLastMove;
|
||||
|
@ -477,7 +477,7 @@ module uartPC16550D(
|
|||
(txfifohead + 16 - txfifotail);
|
||||
// verilator lint_on WIDTH
|
||||
//assign txfifofull = (txfifoentries == 4'b1111);
|
||||
assign txfifofull = (txfifohead == txfifotail) & HeadPointerLastMove;
|
||||
assign txfifofull = (txfifohead == txfifotail) & HeadPointerLastMove;
|
||||
|
||||
// transmit buffer ready bit
|
||||
always_ff @(posedge PCLK, negedge PRESETn) // track txrdy for DMA mode (FCR3 = FCR0 = 1)
|
||||
|
|
|
@ -31,58 +31,58 @@
|
|||
|
||||
module uncore (
|
||||
// AHB Bus Interface
|
||||
input logic HCLK, HRESETn,
|
||||
input logic TIMECLK,
|
||||
input logic HCLK, HRESETn,
|
||||
input logic TIMECLK,
|
||||
input logic [`PA_BITS-1:0] HADDR,
|
||||
input logic [`AHBW-1:0] HWDATA,
|
||||
input logic [`XLEN/8-1:0] HWSTRB,
|
||||
input logic HWRITE,
|
||||
input logic [2:0] HSIZE,
|
||||
input logic [2:0] HBURST,
|
||||
input logic [3:0] HPROT,
|
||||
input logic [1:0] HTRANS,
|
||||
input logic HMASTLOCK,
|
||||
input logic [`AHBW-1:0] HRDATAEXT,
|
||||
input logic HREADYEXT, HRESPEXT,
|
||||
output logic [`AHBW-1:0] HRDATA,
|
||||
output logic HREADY, HRESP,
|
||||
output logic HSELEXT,
|
||||
// peripheral pins
|
||||
output logic MTimerInt, MSwInt, // Timer and software interrupts from CLINT
|
||||
output logic MExtInt, SExtInt, // External interrupts from PLIC
|
||||
output logic [63:0] MTIME_CLINT, // MTIME, from CLINT
|
||||
input logic [31:0] GPIOPinsIn, // GPIO pin input value
|
||||
output logic [31:0] GPIOPinsOut, GPIOPinsEn, // GPIO pin output value and enable
|
||||
input logic UARTSin, // UART serial input
|
||||
output logic UARTSout, // UART serial output
|
||||
output logic SDCCmdOut, // SD Card command output
|
||||
output logic SDCCmdOE, // SD Card command output enable
|
||||
input logic SDCCmdIn, // SD Card command input
|
||||
input logic [3:0] SDCDatIn, // SD Card data input
|
||||
output logic SDCCLK // SD Card clock
|
||||
input logic [`AHBW-1:0] HWDATA,
|
||||
input logic [`XLEN/8-1:0] HWSTRB,
|
||||
input logic HWRITE,
|
||||
input logic [2:0] HSIZE,
|
||||
input logic [2:0] HBURST,
|
||||
input logic [3:0] HPROT,
|
||||
input logic [1:0] HTRANS,
|
||||
input logic HMASTLOCK,
|
||||
input logic [`AHBW-1:0] HRDATAEXT,
|
||||
input logic HREADYEXT, HRESPEXT,
|
||||
output logic [`AHBW-1:0] HRDATA,
|
||||
output logic HREADY, HRESP,
|
||||
output logic HSELEXT,
|
||||
// peripheral pins
|
||||
output logic MTimerInt, MSwInt, // Timer and software interrupts from CLINT
|
||||
output logic MExtInt, SExtInt, // External interrupts from PLIC
|
||||
output logic [63:0] MTIME_CLINT, // MTIME, from CLINT
|
||||
input logic [31:0] GPIOPinsIn, // GPIO pin input value
|
||||
output logic [31:0] GPIOPinsOut, GPIOPinsEn, // GPIO pin output value and enable
|
||||
input logic UARTSin, // UART serial input
|
||||
output logic UARTSout, // UART serial output
|
||||
output logic SDCCmdOut, // SD Card command output
|
||||
output logic SDCCmdOE, // SD Card command output enable
|
||||
input logic SDCCmdIn, // SD Card command input
|
||||
input logic [3:0] SDCDatIn, // SD Card data input
|
||||
output logic SDCCLK // SD Card clock
|
||||
);
|
||||
|
||||
logic [`XLEN-1:0] HREADRam, HREADSDC;
|
||||
logic [`XLEN-1:0] HREADRam, HREADSDC;
|
||||
|
||||
logic [10:0] HSELRegions;
|
||||
logic HSELDTIM, HSELIROM, HSELRam, HSELCLINT, HSELPLIC, HSELGPIO, HSELUART, HSELSDC;
|
||||
logic HSELDTIMD, HSELIROMD, HSELEXTD, HSELRamD, HSELCLINTD, HSELPLICD, HSELGPIOD, HSELUARTD, HSELSDCD;
|
||||
logic HRESPRam, HRESPSDC;
|
||||
logic HREADYRam, HRESPSDCD;
|
||||
logic [`XLEN-1:0] HREADBootRom;
|
||||
logic HSELBootRom, HSELBootRomD, HRESPBootRom, HREADYBootRom, HREADYSDC;
|
||||
logic HSELNoneD;
|
||||
logic UARTIntr,GPIOIntr;
|
||||
logic SDCIntM;
|
||||
logic [10:0] HSELRegions;
|
||||
logic HSELDTIM, HSELIROM, HSELRam, HSELCLINT, HSELPLIC, HSELGPIO, HSELUART, HSELSDC;
|
||||
logic HSELDTIMD, HSELIROMD, HSELEXTD, HSELRamD, HSELCLINTD, HSELPLICD, HSELGPIOD, HSELUARTD, HSELSDCD;
|
||||
logic HRESPRam, HRESPSDC;
|
||||
logic HREADYRam, HRESPSDCD;
|
||||
logic [`XLEN-1:0] HREADBootRom;
|
||||
logic HSELBootRom, HSELBootRomD, HRESPBootRom, HREADYBootRom, HREADYSDC;
|
||||
logic HSELNoneD;
|
||||
logic UARTIntr,GPIOIntr;
|
||||
logic SDCIntM;
|
||||
|
||||
logic PCLK, PRESETn, PWRITE, PENABLE;
|
||||
logic [3:0] PSEL, PREADY;
|
||||
logic [31:0] PADDR;
|
||||
logic [`XLEN-1:0] PWDATA;
|
||||
logic [`XLEN/8-1:0] PSTRB;
|
||||
logic [3:0][`XLEN-1:0] PRDATA;
|
||||
logic [`XLEN-1:0] HREADBRIDGE;
|
||||
logic HRESPBRIDGE, HREADYBRIDGE, HSELBRIDGE, HSELBRIDGED;
|
||||
logic PCLK, PRESETn, PWRITE, PENABLE;
|
||||
logic [3:0] PSEL, PREADY;
|
||||
logic [31:0] PADDR;
|
||||
logic [`XLEN-1:0] PWDATA;
|
||||
logic [`XLEN/8-1:0] PSTRB;
|
||||
logic [3:0][`XLEN-1:0] PRDATA;
|
||||
logic [`XLEN-1:0] HREADBRIDGE;
|
||||
logic HRESPBRIDGE, HREADYBRIDGE, HSELBRIDGE, HSELBRIDGED;
|
||||
|
||||
// Determine which region of physical memory (if any) is being accessed
|
||||
// Use a trimmed down portion of the PMA checker - only the address decoders
|
||||
|
@ -153,7 +153,7 @@ module uncore (
|
|||
// sdc interface
|
||||
.SDCCmdOut, .SDCCmdIn, .SDCCmdOE, .SDCDatIn, .SDCCLK,
|
||||
// interrupt to PLIC
|
||||
.SDCIntM
|
||||
.SDCIntM
|
||||
);
|
||||
end else begin : sdc
|
||||
assign SDCCLK = 0;
|
||||
|
@ -163,22 +163,22 @@ module uncore (
|
|||
|
||||
// AHB Read Multiplexer
|
||||
assign HRDATA = ({`XLEN{HSELRamD}} & HREADRam) |
|
||||
({`XLEN{HSELEXTD}} & HRDATAEXT) |
|
||||
({`XLEN{HSELEXTD}} & HRDATAEXT) |
|
||||
({`XLEN{HSELBRIDGED}} & HREADBRIDGE) |
|
||||
({`XLEN{HSELBootRomD}} & HREADBootRom) |
|
||||
({`XLEN{HSELSDCD}} & HREADSDC);
|
||||
|
||||
assign HRESP = HSELRamD & HRESPRam |
|
||||
HSELEXTD & HRESPEXT |
|
||||
HSELEXTD & HRESPEXT |
|
||||
HSELBRIDGE & HRESPBRIDGE |
|
||||
HSELBootRomD & HRESPBootRom |
|
||||
HSELSDC & HRESPSDC;
|
||||
HSELSDC & HRESPSDC;
|
||||
|
||||
assign HREADY = HSELRamD & HREADYRam |
|
||||
HSELEXTD & HREADYEXT |
|
||||
HSELEXTD & HREADYEXT |
|
||||
HSELBRIDGED & HREADYBRIDGE |
|
||||
HSELBootRomD & HREADYBootRom |
|
||||
HSELSDCD & HREADYSDC |
|
||||
HSELSDCD & HREADYSDC |
|
||||
HSELNoneD; // don't lock up the bus if no region is being accessed
|
||||
|
||||
// Address Decoder Delay (figure 4-2 in spec)
|
||||
|
|
|
@ -35,12 +35,12 @@ module wallypipelinedcore (
|
|||
input logic MTimerInt, MExtInt, SExtInt, MSwInt,
|
||||
input logic [63:0] MTIME_CLINT,
|
||||
// Bus Interface
|
||||
input logic [`AHBW-1:0] HRDATA,
|
||||
input logic [`AHBW-1:0] HRDATA,
|
||||
input logic HREADY, HRESP,
|
||||
output logic HCLK, HRESETn,
|
||||
output logic [`PA_BITS-1:0] HADDR,
|
||||
output logic [`AHBW-1:0] HWDATA,
|
||||
output logic [`XLEN/8-1:0] HWSTRB,
|
||||
output logic [`PA_BITS-1:0] HADDR,
|
||||
output logic [`AHBW-1:0] HWDATA,
|
||||
output logic [`XLEN/8-1:0] HWSTRB,
|
||||
output logic HWRITE,
|
||||
output logic [2:0] HSIZE,
|
||||
output logic [2:0] HBURST,
|
||||
|
@ -58,17 +58,17 @@ module wallypipelinedcore (
|
|||
logic IntDivE, W64E;
|
||||
logic CSRReadM, CSRWriteM, PrivilegedM;
|
||||
logic [1:0] AtomicM;
|
||||
logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE;
|
||||
logic [`XLEN-1:0] SrcAM;
|
||||
logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE;
|
||||
logic [`XLEN-1:0] SrcAM;
|
||||
logic [2:0] Funct3E;
|
||||
logic [31:0] InstrD;
|
||||
logic [31:0] InstrM, InstrOrigM;
|
||||
logic [`XLEN-1:0] PCSpillF, PCE, PCLinkE;
|
||||
logic [`XLEN-1:0] PCM;
|
||||
logic [`XLEN-1:0] CSRReadValW, MDUResultW;
|
||||
logic [`XLEN-1:0] UnalignedPCNextF, PC2NextF;
|
||||
logic [1:0] MemRWM;
|
||||
logic InstrValidD, InstrValidE, InstrValidM;
|
||||
logic [31:0] InstrM, InstrOrigM;
|
||||
logic [`XLEN-1:0] PCSpillF, PCE, PCLinkE;
|
||||
logic [`XLEN-1:0] PCM;
|
||||
logic [`XLEN-1:0] CSRReadValW, MDUResultW;
|
||||
logic [`XLEN-1:0] UnalignedPCNextF, PC2NextF;
|
||||
logic [1:0] MemRWM;
|
||||
logic InstrValidD, InstrValidE, InstrValidM;
|
||||
logic InstrMisalignedFaultM;
|
||||
logic IllegalBaseInstrD, IllegalFPUInstrD, IllegalIEUFPUInstrD;
|
||||
logic InstrPageFaultF, LoadPageFaultM, StoreAmoPageFaultM;
|
||||
|
@ -86,8 +86,8 @@ module wallypipelinedcore (
|
|||
logic [4:0] RdE, RdM, RdW;
|
||||
logic FPUStallD;
|
||||
logic FWriteIntE;
|
||||
logic [`FLEN-1:0] FWriteDataM;
|
||||
logic [`XLEN-1:0] FIntResM;
|
||||
logic [`FLEN-1:0] FWriteDataM;
|
||||
logic [`XLEN-1:0] FIntResM;
|
||||
logic [`XLEN-1:0] FCvtIntResW;
|
||||
logic FCvtIntW;
|
||||
logic FDivBusyE;
|
||||
|
@ -95,22 +95,22 @@ module wallypipelinedcore (
|
|||
logic FCvtIntStallD;
|
||||
logic FpLoadStoreM;
|
||||
logic [4:0] SetFflagsM;
|
||||
logic [`XLEN-1:0] FIntDivResultW;
|
||||
logic [`XLEN-1:0] FIntDivResultW;
|
||||
|
||||
// memory management unit signals
|
||||
logic ITLBWriteF;
|
||||
logic ITLBMissF;
|
||||
logic [`XLEN-1:0] SATP_REGW;
|
||||
logic [`XLEN-1:0] SATP_REGW;
|
||||
logic STATUS_MXR, STATUS_SUM, STATUS_MPRV;
|
||||
logic [1:0] STATUS_MPP, STATUS_FS;
|
||||
logic [1:0] STATUS_MPP, STATUS_FS;
|
||||
logic [1:0] PrivilegeModeW;
|
||||
logic [`XLEN-1:0] PTE;
|
||||
logic [`XLEN-1:0] PTE;
|
||||
logic [1:0] PageType;
|
||||
logic sfencevmaM, WFIStallM;
|
||||
logic SelHPTW;
|
||||
|
||||
// PMA checker signals
|
||||
var logic [`PA_BITS-3:0] PMPADDR_ARRAY_REGW[`PMP_ENTRIES-1:0];
|
||||
var logic [`PA_BITS-3:0] PMPADDR_ARRAY_REGW[`PMP_ENTRIES-1:0];
|
||||
var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0];
|
||||
|
||||
// IMem stalls
|
||||
|
@ -119,14 +119,14 @@ module wallypipelinedcore (
|
|||
|
||||
// cpu lsu interface
|
||||
logic [2:0] Funct3M;
|
||||
logic [`XLEN-1:0] IEUAdrE;
|
||||
logic [`XLEN-1:0] WriteDataM;
|
||||
logic [`XLEN-1:0] IEUAdrM;
|
||||
logic [`LLEN-1:0] ReadDataW;
|
||||
logic [`XLEN-1:0] IEUAdrE;
|
||||
logic [`XLEN-1:0] WriteDataM;
|
||||
logic [`XLEN-1:0] IEUAdrM;
|
||||
logic [`LLEN-1:0] ReadDataW;
|
||||
logic CommittedM;
|
||||
|
||||
// AHB ifu interface
|
||||
logic [`PA_BITS-1:0] IFUHADDR;
|
||||
logic [`PA_BITS-1:0] IFUHADDR;
|
||||
logic [2:0] IFUHBURST;
|
||||
logic [1:0] IFUHTRANS;
|
||||
logic [2:0] IFUHSIZE;
|
||||
|
@ -134,9 +134,9 @@ module wallypipelinedcore (
|
|||
logic IFUHREADY;
|
||||
|
||||
// AHB LSU interface
|
||||
logic [`PA_BITS-1:0] LSUHADDR;
|
||||
logic [`XLEN-1:0] LSUHWDATA;
|
||||
logic [`XLEN/8-1:0] LSUHWSTRB;
|
||||
logic [`PA_BITS-1:0] LSUHADDR;
|
||||
logic [`XLEN-1:0] LSUHWDATA;
|
||||
logic [`XLEN/8-1:0] LSUHWSTRB;
|
||||
logic LSUHWRITE;
|
||||
logic LSUHREADY;
|
||||
|
||||
|
@ -160,8 +160,8 @@ module wallypipelinedcore (
|
|||
logic BigEndianM;
|
||||
logic FCvtIntE;
|
||||
logic CommittedF;
|
||||
logic BranchD, BranchE, JumpD, JumpE;
|
||||
logic DCacheStallM, ICacheStallF;
|
||||
logic BranchD, BranchE, JumpD, JumpE;
|
||||
logic DCacheStallM, ICacheStallF;
|
||||
|
||||
// instruction fetch unit: PC, branch prediction, instruction cache
|
||||
ifu ifu(.clk, .reset,
|
||||
|
@ -247,20 +247,10 @@ module wallypipelinedcore (
|
|||
ebu ebu(// IFU connections
|
||||
.clk, .reset,
|
||||
// IFU interface
|
||||
.IFUHADDR,
|
||||
.IFUHBURST,
|
||||
.IFUHTRANS,
|
||||
.IFUHREADY,
|
||||
.IFUHSIZE,
|
||||
.IFUHADDR, .IFUHBURST, .IFUHTRANS, .IFUHREADY, .IFUHSIZE,
|
||||
// LSU interface
|
||||
.LSUHADDR,
|
||||
.LSUHWDATA,
|
||||
.LSUHWSTRB,
|
||||
.LSUHSIZE,
|
||||
.LSUHBURST,
|
||||
.LSUHTRANS,
|
||||
.LSUHWRITE,
|
||||
.LSUHREADY,
|
||||
.LSUHADDR, .LSUHWDATA, .LSUHWSTRB, .LSUHSIZE, .LSUHBURST,
|
||||
.LSUHTRANS, .LSUHWRITE, .LSUHREADY,
|
||||
// BUS interface
|
||||
.HREADY, .HRESP, .HCLK, .HRESETn,
|
||||
.HADDR, .HWDATA, .HWSTRB, .HWRITE, .HSIZE, .HBURST,
|
||||
|
|
|
@ -30,43 +30,43 @@
|
|||
`include "wally-config.vh"
|
||||
|
||||
module wallypipelinedsoc (
|
||||
input logic clk,
|
||||
input logic clk,
|
||||
input logic reset_ext, // external asynchronous reset pin
|
||||
output logic reset, // reset synchronized to clk to prevent races on release
|
||||
// AHB Interface
|
||||
input logic [`AHBW-1:0] HRDATAEXT,
|
||||
input logic HREADYEXT, HRESPEXT,
|
||||
output logic HSELEXT,
|
||||
input logic [`AHBW-1:0] HRDATAEXT,
|
||||
input logic HREADYEXT, HRESPEXT,
|
||||
output logic HSELEXT,
|
||||
// outputs to external memory, shared with uncore memory
|
||||
output logic HCLK, HRESETn,
|
||||
output logic [`PA_BITS-1:0] HADDR,
|
||||
output logic [`AHBW-1:0] HWDATA,
|
||||
output logic [`XLEN/8-1:0] HWSTRB,
|
||||
output logic HWRITE,
|
||||
output logic [2:0] HSIZE,
|
||||
output logic [2:0] HBURST,
|
||||
output logic [3:0] HPROT,
|
||||
output logic [1:0] HTRANS,
|
||||
output logic HMASTLOCK,
|
||||
output logic HREADY,
|
||||
output logic HCLK, HRESETn,
|
||||
output logic [`PA_BITS-1:0] HADDR,
|
||||
output logic [`AHBW-1:0] HWDATA,
|
||||
output logic [`XLEN/8-1:0] HWSTRB,
|
||||
output logic HWRITE,
|
||||
output logic [2:0] HSIZE,
|
||||
output logic [2:0] HBURST,
|
||||
output logic [3:0] HPROT,
|
||||
output logic [1:0] HTRANS,
|
||||
output logic HMASTLOCK,
|
||||
output logic HREADY,
|
||||
// I/O Interface
|
||||
input logic TIMECLK, // optional for CLINT MTIME counter
|
||||
input logic [31:0] GPIOPinsIn, // inputs from GPIO
|
||||
output logic [31:0] GPIOPinsOut, // output values for GPIO
|
||||
input logic [31:0] GPIOPinsIn, // inputs from GPIO
|
||||
output logic [31:0] GPIOPinsOut, // output values for GPIO
|
||||
output logic [31:0] GPIOPinsEn, // output enables for GPIO
|
||||
input logic UARTSin, // UART serial data input
|
||||
output logic UARTSout, // UART serial data output
|
||||
input logic SDCCmdIn, // SDC Command input
|
||||
output logic SDCCmdOut, // SDC Command output
|
||||
output logic SDCCmdOE, // SDC Command output enable
|
||||
input logic [3:0] SDCDatIn, // SDC data input
|
||||
output logic SDCCLK // SDC clock
|
||||
input logic UARTSin, // UART serial data input
|
||||
output logic UARTSout, // UART serial data output
|
||||
input logic SDCCmdIn, // SDC Command input
|
||||
output logic SDCCmdOut, // SDC Command output
|
||||
output logic SDCCmdOE, // SDC Command output enable
|
||||
input logic [3:0] SDCDatIn, // SDC data input
|
||||
output logic SDCCLK // SDC clock
|
||||
);
|
||||
|
||||
// Uncore signals
|
||||
logic [`AHBW-1:0] HRDATA; // from AHB mux in uncore
|
||||
logic [`AHBW-1:0] HRDATA; // from AHB mux in uncore
|
||||
logic HRESP; // response from AHB
|
||||
logic MTimerInt, MSwInt; // timer and software interrupts from CLINT
|
||||
logic MTimerInt, MSwInt;// timer and software interrupts from CLINT
|
||||
logic [63:0] MTIME_CLINT; // from CLINT to CSRs
|
||||
logic MExtInt,SExtInt; // from PLIC
|
||||
|
||||
|
@ -86,8 +86,8 @@ module wallypipelinedsoc (
|
|||
.HADDR, .HWDATA, .HWSTRB, .HWRITE, .HSIZE, .HBURST, .HPROT, .HTRANS, .HMASTLOCK, .HRDATAEXT,
|
||||
.HREADYEXT, .HRESPEXT, .HRDATA, .HREADY, .HRESP, .HSELEXT,
|
||||
.MTimerInt, .MSwInt, .MExtInt, .SExtInt, .GPIOPinsIn, .GPIOPinsOut, .GPIOPinsEn, .UARTSin,
|
||||
.UARTSout, .MTIME_CLINT,
|
||||
.SDCCmdOut, .SDCCmdOE, .SDCCmdIn, .SDCDatIn, .SDCCLK);
|
||||
.UARTSout, .MTIME_CLINT,
|
||||
.SDCCmdOut, .SDCCmdOE, .SDCCmdIn, .SDCDatIn, .SDCCLK);
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue