Fixed all tap/space issue in RTL.

This commit is contained in:
Ross Thompson 2023-03-24 17:32:25 -05:00
parent b5a58502d0
commit 46b1bca4fc
68 changed files with 1561 additions and 1577 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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])

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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),

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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