forked from Github_Repos/cvw
		
	Merge branch 'main' of https://github.com/davidharrishmc/riscv-wally into main
This commit is contained in:
		
						commit
						01685b982c
					
				@ -1 +1 @@
 | 
			
		||||
Subproject commit 261a65e0a2d3e8d62d81b1d8fe7e309a096bc6a9
 | 
			
		||||
Subproject commit 2d2aaa7b85c60219c591555b647dfa1785ffe1b3
 | 
			
		||||
@ -1 +1 @@
 | 
			
		||||
Subproject commit 307c77b26e070ae85ffea665ad9b642b40e33c86
 | 
			
		||||
Subproject commit effd553a6a91ed9b0ba251796a8a44505a45174f
 | 
			
		||||
@ -1 +1 @@
 | 
			
		||||
Subproject commit a7e27bc046405f0dbcde091be99f5a5d564e2172
 | 
			
		||||
Subproject commit cb4295f9ce5da2881d7746015a6105adb8f09071
 | 
			
		||||
@ -1 +1 @@
 | 
			
		||||
Subproject commit cf04274f50621fd9ef9147793cca6dd1657985c7
 | 
			
		||||
Subproject commit 3e2bf06b071a77ae62c09bf07c5229d1f9397d94
 | 
			
		||||
@ -1,10 +0,0 @@
 | 
			
		||||
ch5.debug: ch5
 | 
			
		||||
	riscv64-unknown-elf-objdump -D ch5 > ch5.debug
 | 
			
		||||
 | 
			
		||||
ch5: ch5.S Makefile
 | 
			
		||||
	riscv64-unknown-elf-gcc -nodefaultlibs -nostartfiles -o ch5 ch5.S
 | 
			
		||||
# -ffreestanding 
 | 
			
		||||
# -nostdlib 
 | 
			
		||||
 | 
			
		||||
clean: 
 | 
			
		||||
	rm -f ch5 ch5.debug
 | 
			
		||||
										
											Binary file not shown.
										
									
								
							@ -1,16 +0,0 @@
 | 
			
		||||
# ch5.s
 | 
			
		||||
# David_Harris@hmc.edu 14 December 2021
 | 
			
		||||
 | 
			
		||||
.section .text.init
 | 
			
		||||
 | 
			
		||||
.globl _start
 | 
			
		||||
_start:
 | 
			
		||||
    lw x1, 4(x0)
 | 
			
		||||
    sw x1, 8(x0)
 | 
			
		||||
    add x2, x1, x1
 | 
			
		||||
    beq x1, x2, done
 | 
			
		||||
loop:
 | 
			
		||||
    jal x0, loop
 | 
			
		||||
done:
 | 
			
		||||
 | 
			
		||||
.end
 | 
			
		||||
@ -1,38 +0,0 @@
 | 
			
		||||
 | 
			
		||||
ch5:     file format elf64-littleriscv
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Disassembly of section .text:
 | 
			
		||||
 | 
			
		||||
0000000000010078 <_start>:
 | 
			
		||||
   10078:	00402083          	lw	ra,4(zero) # 4 <_start-0x10074>
 | 
			
		||||
   1007c:	00102423          	sw	ra,8(zero) # 8 <_start-0x10070>
 | 
			
		||||
   10080:	00108133          	add	sp,ra,ra
 | 
			
		||||
   10084:	00208463          	beq	ra,sp,1008c <done>
 | 
			
		||||
 | 
			
		||||
0000000000010088 <loop>:
 | 
			
		||||
   10088:	0000006f          	j	10088 <loop>
 | 
			
		||||
 | 
			
		||||
Disassembly of section .riscv.attributes:
 | 
			
		||||
 | 
			
		||||
0000000000000000 <.riscv.attributes>:
 | 
			
		||||
   0:	3241                	addiw	tp,tp,-16
 | 
			
		||||
   2:	0000                	unimp
 | 
			
		||||
   4:	7200                	ld	s0,32(a2)
 | 
			
		||||
   6:	7369                	lui	t1,0xffffa
 | 
			
		||||
   8:	01007663          	bgeu	zero,a6,14 <_start-0x10064>
 | 
			
		||||
   c:	0028                	addi	a0,sp,8
 | 
			
		||||
   e:	0000                	unimp
 | 
			
		||||
  10:	7205                	lui	tp,0xfffe1
 | 
			
		||||
  12:	3676                	fld	fa2,376(sp)
 | 
			
		||||
  14:	6934                	ld	a3,80(a0)
 | 
			
		||||
  16:	7032                	0x7032
 | 
			
		||||
  18:	5f30                	lw	a2,120(a4)
 | 
			
		||||
  1a:	326d                	addiw	tp,tp,-5
 | 
			
		||||
  1c:	3070                	fld	fa2,224(s0)
 | 
			
		||||
  1e:	615f 7032 5f30      	0x5f307032615f
 | 
			
		||||
  24:	3266                	fld	ft4,120(sp)
 | 
			
		||||
  26:	3070                	fld	fa2,224(s0)
 | 
			
		||||
  28:	645f 7032 5f30      	0x5f307032645f
 | 
			
		||||
  2e:	30703263          	0x30703263
 | 
			
		||||
	...
 | 
			
		||||
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										1
									
								
								pipelined/src/cache/sram1p1rw.sv
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								pipelined/src/cache/sram1p1rw.sv
									
									
									
									
										vendored
									
									
								
							@ -43,7 +43,6 @@ module sram1p1rw #(parameter DEPTH=128, WIDTH=256) (
 | 
			
		||||
 | 
			
		||||
  logic [WIDTH-1:0]               StoredData[DEPTH-1:0];
 | 
			
		||||
  logic [$clog2(DEPTH)-1:0]       AdrD;
 | 
			
		||||
  logic                           WriteEnableD;
 | 
			
		||||
 | 
			
		||||
  always_ff @(posedge clk)       AdrD <= Adr;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -41,7 +41,7 @@ module fma(
 | 
			
		||||
    input logic [`NE-1:0]       XExpE, YExpE, ZExpE,    // input exponents - execute stage
 | 
			
		||||
    input logic [`NF:0]         XManE, YManE, ZManE,    // input mantissa - execute stage
 | 
			
		||||
    input logic                 XSgnM, YSgnM,           // input signs - memory stage
 | 
			
		||||
    input logic [`NE-1:0]       XExpM, YExpM, ZExpM,    // input exponents - memory stage
 | 
			
		||||
    input logic [`NE-1:0]       ZExpM,    // input exponents - memory stage
 | 
			
		||||
    input logic [`NF:0]         XManM, YManM, ZManM,    // input mantissa - memory stage
 | 
			
		||||
    input logic                 XDenormE, YDenormE, ZDenormE, // is denorm
 | 
			
		||||
    input logic                 XZeroE, YZeroE, ZZeroE,     // is zero - execute stage
 | 
			
		||||
@ -85,7 +85,7 @@ module fma(
 | 
			
		||||
                            {AddendStickyE, KillProdE, InvZE, NormCntE, NegSumE, ZSgnEffE, PSgnE, FOpCtrlE[2]&~FOpCtrlE[1]&~FOpCtrlE[0]},
 | 
			
		||||
                            {AddendStickyM, KillProdM, InvZM, NormCntM, NegSumM, ZSgnEffM, PSgnM, Mult});
 | 
			
		||||
 | 
			
		||||
    fma2 fma2(.XSgnM, .YSgnM, .XExpM, .YExpM, .ZExpM, .XManM, .YManM, .ZManM, 
 | 
			
		||||
    fma2 fma2(.XSgnM, .YSgnM, .ZExpM, .XManM, .YManM, .ZManM, 
 | 
			
		||||
            .FrmM, .FmtM,  .ProdExpM, .AddendStickyM, .KillProdM, .SumM, .NegSumM, .InvZM, .NormCntM, .ZSgnEffM, .PSgnM,
 | 
			
		||||
            .XZeroM, .YZeroM, .ZZeroM, .XInfM, .YInfM, .ZInfM, .XNaNM, .YNaNM, .ZNaNM, .XSNaNM, .YSNaNM, .ZSNaNM, .Mult,
 | 
			
		||||
            .FMAResM, .FMAFlgM);
 | 
			
		||||
@ -283,6 +283,7 @@ module align(
 | 
			
		||||
    //      - Denormal numbers have a diffrent exponent value depending on the precision
 | 
			
		||||
    assign ZExpVal = ZDenormE ? Denorm : ZExpE;
 | 
			
		||||
    // assign AlignCnt = ProdExpE - {2'b0, ZExpVal} + (`NF+3);
 | 
			
		||||
    // *** can we use ProdExpE instead of XExp/YExp to save an adder? DH 5/12/22
 | 
			
		||||
    assign AlignCnt = XZeroE|YZeroE ? -1 : {2'b0, XExpVal} + {2'b0, YExpVal} - {2'b0, (`NE)'(`BIAS)} + `NF+3 - {2'b0, ZExpVal};
 | 
			
		||||
 | 
			
		||||
    // Defualt Addition without shifting
 | 
			
		||||
@ -433,7 +434,7 @@ endmodule
 | 
			
		||||
module fma2(
 | 
			
		||||
    
 | 
			
		||||
    input logic                             XSgnM, YSgnM,        // input signs
 | 
			
		||||
    input logic     [`NE-1:0]               XExpM, YExpM, ZExpM, // input exponents
 | 
			
		||||
    input logic     [`NE-1:0]               ZExpM, // input exponents
 | 
			
		||||
    input logic     [`NF:0]                 XManM, YManM, ZManM, // input mantissas
 | 
			
		||||
    input logic     [2:0]                   FrmM,       // rounding mode 000 = rount to nearest, ties to even   001 = round twords zero  010 = round down  011 = round up  100 = round to nearest, ties to max magnitude
 | 
			
		||||
    input logic     [`FPSIZES/3:0]          FmtM,       // precision 1 = double 0 = single
 | 
			
		||||
@ -481,7 +482,7 @@ module fma2(
 | 
			
		||||
    // Normalization
 | 
			
		||||
    ///////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
    normalize normalize(.SumM, .ZExpM, .ProdExpM, .NormCntM, .FmtM, .KillProdM, .AddendStickyM, .NormSum, .NegSumM,
 | 
			
		||||
    normalize normalize(.SumM, .ZExpM, .ProdExpM, .NormCntM, .FmtM, .KillProdM, .AddendStickyM, .NormSum, 
 | 
			
		||||
            .SumZero, .NormSumSticky, .UfSticky, .SumExp, .ResultDenorm);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -529,7 +530,7 @@ module fma2(
 | 
			
		||||
    // Select the result
 | 
			
		||||
    ///////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
    resultselect resultselect(.XSgnM, .YSgnM, .XExpM, .YExpM, .ZExpM, .XManM, .YManM, .ZManM, 
 | 
			
		||||
    resultselect resultselect(.XSgnM, .YSgnM, .ZExpM, .XManM, .YManM, .ZManM, 
 | 
			
		||||
        .FrmM, .FmtM, .AddendStickyM, .KillProdM, .XInfM, .YInfM, .ZInfM, .XNaNM, .YNaNM, .ZNaNM, .RoundAdd,
 | 
			
		||||
        .ZSgnEffM, .PSgnM, .ResultSgn, .CalcPlus1, .Invalid, .Overflow, .Underflow, 
 | 
			
		||||
        .ResultDenorm, .ResultExp, .ResultFrac, .FMAResM);
 | 
			
		||||
@ -577,7 +578,6 @@ module normalize(
 | 
			
		||||
    input logic  [`FPSIZES/3:0]         FmtM,       // precision 1 = double 0 = single
 | 
			
		||||
    input logic                         KillProdM,  // is the product set to zero
 | 
			
		||||
    input logic                         AddendStickyM,  // the sticky bit caclulated from the aligned addend
 | 
			
		||||
    input logic                         NegSumM,    // was the sum negitive
 | 
			
		||||
    output logic [`NF+2:0]              NormSum,        // normalized sum
 | 
			
		||||
    output logic                        SumZero,        // is the sum zero
 | 
			
		||||
    output logic                        NormSumSticky, UfSticky,    // sticky bits
 | 
			
		||||
@ -1095,7 +1095,7 @@ endmodule
 | 
			
		||||
 | 
			
		||||
module resultselect(
 | 
			
		||||
    input logic                     XSgnM, YSgnM,        // input signs
 | 
			
		||||
    input logic     [`NE-1:0]       XExpM, YExpM, ZExpM, // input exponents
 | 
			
		||||
    input logic     [`NE-1:0]       ZExpM, // input exponents
 | 
			
		||||
    input logic     [`NF:0]         XManM, YManM, ZManM, // input mantissas
 | 
			
		||||
    input logic     [2:0]           FrmM,       // rounding mode 000 = rount to nearest, ties to even   001 = round twords zero  010 = round down  011 = round up  100 = round to nearest, ties to max magnitude
 | 
			
		||||
    input logic     [`FPSIZES/3:0]  FmtM,       // precision 1 = double 0 = single
 | 
			
		||||
 | 
			
		||||
@ -87,7 +87,7 @@ module fpu (
 | 
			
		||||
   logic 		  XSgnE, YSgnE, ZSgnE;                // input's sign - execute stage
 | 
			
		||||
   logic 		  XSgnM, YSgnM;                       // input's sign - memory stage
 | 
			
		||||
   logic [10:0] 	  XExpE, YExpE, ZExpE;                // input's exponent - execute stage
 | 
			
		||||
   logic [10:0] 	  XExpM, YExpM, ZExpM;                // input's exponent - memory stage
 | 
			
		||||
   logic [10:0] 	  ZExpM;                              // input's exponent - memory stage
 | 
			
		||||
   logic [52:0] 	  XManE, YManE, ZManE;                // input's fraction - execute stage
 | 
			
		||||
   logic [52:0] 	  XManM, YManM, ZManM;                // input's fraction - memory stage
 | 
			
		||||
   logic 		  XNaNE, YNaNE, ZNaNE;                // is the input a NaN - execute stage
 | 
			
		||||
@ -189,7 +189,7 @@ module fpu (
 | 
			
		||||
   fma fma (.clk, .reset, .FlushM, .StallM, 
 | 
			
		||||
      .XSgnE, .YSgnE, .ZSgnE, .XExpE, .YExpE, .ZExpE, .XManE, .YManE, .ZManE, 
 | 
			
		||||
      .XDenormE, .YDenormE, .ZDenormE, .XZeroE, .YZeroE, .ZZeroE,
 | 
			
		||||
      .XSgnM, .YSgnM, .XExpM, .YExpM, .ZExpM, .XManM, .YManM, .ZManM, 
 | 
			
		||||
      .XSgnM, .YSgnM, .ZExpM, .XManM, .YManM, .ZManM, 
 | 
			
		||||
      .XNaNM, .YNaNM, .ZNaNM, .XZeroM, .YZeroM, .ZZeroM, 
 | 
			
		||||
      .XInfM, .YInfM, .ZInfM, .XSNaNM, .YSNaNM, .ZSNaNM,
 | 
			
		||||
      .FOpCtrlE,
 | 
			
		||||
@ -212,25 +212,12 @@ module fpu (
 | 
			
		||||
         .XNaNQ, .YNaNQ, .XInfQ, .YInfQ, .XZeroQ, .YZeroQ, .load_preload,
 | 
			
		||||
         .FDivBusyE, .done(FDivSqrtDoneE), .AS_Result(FDivResM), .Flags(FDivFlgM));
 | 
			
		||||
 | 
			
		||||
   // convert from signle to double and vice versa
 | 
			
		||||
   // other FP execution units
 | 
			
		||||
   cvtfp cvtfp (.XExpE, .XManE, .XSgnE, .XZeroE, .XDenormE, .XInfE, .XNaNE, .XSNaNE, .FrmE, .FmtE, .CvtFpResE, .CvtFpFlgE);
 | 
			
		||||
 | 
			
		||||
   // compare unit
 | 
			
		||||
   //    - computation is done in one stage
 | 
			
		||||
   //    - writes to FP file durring min/max instructions
 | 
			
		||||
   //    - other comparisons write a 1 or 0 to the integer register
 | 
			
		||||
   fcmp fcmp (.FmtE, .FOpCtrlE, .XSgnE, .YSgnE, .XExpE, .YExpE, .XManE, .YManE, 
 | 
			
		||||
            .XZeroE, .YZeroE, .XNaNE, .YNaNE, .XSNaNE, .YSNaNE, .FSrcXE, .FSrcYE, .CmpNVE, .CmpResE);
 | 
			
		||||
 | 
			
		||||
   // sign injection unit
 | 
			
		||||
   fsgn fsgn (.SgnOpCodeE(FOpCtrlE[1:0]), .XSgnE, .YSgnE, .FSrcXE, .FmtE, .XExpMaxE,
 | 
			
		||||
    .SgnResE);
 | 
			
		||||
 | 
			
		||||
   // classify
 | 
			
		||||
   fclassify fclassify (.XSgnE, .XDenormE, .XZeroE, .XNaNE, .XInfE, .XNormE, 
 | 
			
		||||
         .XSNaNE, .ClassResE);
 | 
			
		||||
 | 
			
		||||
   // Convert
 | 
			
		||||
   fsgn fsgn (.SgnOpCodeE(FOpCtrlE[1:0]), .XSgnE, .YSgnE, .FSrcXE, .FmtE, .SgnResE);
 | 
			
		||||
   fclassify fclassify (.XSgnE, .XDenormE, .XZeroE, .XNaNE, .XInfE, .XNormE, .XSNaNE, .ClassResE);
 | 
			
		||||
   fcvt fcvt (.XSgnE, .XExpE, .XManE, .XZeroE, .XNaNE, .XInfE, .XDenormE, .ForwardedSrcAE, .FOpCtrlE, .FmtE, .FrmE,
 | 
			
		||||
   .CvtResE, .CvtFlgE);
 | 
			
		||||
 | 
			
		||||
@ -253,8 +240,8 @@ module fpu (
 | 
			
		||||
   // E/M pipe registers
 | 
			
		||||
 | 
			
		||||
   // flopenrc #(64) EMFpReg1(clk, reset, FlushM, ~StallM, FSrcXE, FSrcXM);
 | 
			
		||||
   flopenrc #(65) EMFpReg2 (clk, reset, FlushM, ~StallM, {XSgnE,XExpE,XManE}, {XSgnM,XExpM,XManM});
 | 
			
		||||
   flopenrc #(65) EMFpReg3 (clk, reset, FlushM, ~StallM, {YSgnE,YExpE,YManE}, {YSgnM,YExpM,YManM});
 | 
			
		||||
   flopenrc #(54) EMFpReg2 (clk, reset, FlushM, ~StallM, {XSgnE,XManE}, {XSgnM,XManM});
 | 
			
		||||
   flopenrc #(54) EMFpReg3 (clk, reset, FlushM, ~StallM, {YSgnE,YManE}, {YSgnM,YManM});
 | 
			
		||||
   flopenrc #(64) EMFpReg4 (clk, reset, FlushM, ~StallM, {ZExpE,ZManE}, {ZExpM,ZManM});
 | 
			
		||||
   flopenrc #(12) EMFpReg5 (clk, reset, FlushM, ~StallM, 
 | 
			
		||||
            {XZeroE, YZeroE, ZZeroE, XInfE, YInfE, ZInfE, XNaNE, YNaNE, ZNaNE, XSNaNE, YSNaNE, ZSNaNE},
 | 
			
		||||
 | 
			
		||||
@ -3,7 +3,6 @@
 | 
			
		||||
module fsgn (  
 | 
			
		||||
	input logic        	XSgnE, YSgnE,	// X and Y sign bits
 | 
			
		||||
	input logic [63:0] 	FSrcXE,			// X
 | 
			
		||||
	input logic			XExpMaxE,		// max possible exponent (all ones)
 | 
			
		||||
	input logic 		FmtE,			// precision 1 = double 0 = single
 | 
			
		||||
	input  logic [1:0]  SgnOpCodeE,		// operation control
 | 
			
		||||
	output logic [63:0] SgnResE		// result
 | 
			
		||||
 | 
			
		||||
@ -60,6 +60,8 @@ module hazard(
 | 
			
		||||
  // A stage must stall if the next stage is stalled
 | 
			
		||||
  // If any stages are stalled, the first stage that isn't stalled must flush.
 | 
			
		||||
 | 
			
		||||
  // *** can stalls be pushed into earlier stages (e.g. no stall after Decode?)
 | 
			
		||||
 | 
			
		||||
  assign StallFCause = CSRWritePendingDEM & ~(TrapM | RetM | BPPredWrongE);
 | 
			
		||||
  // stall in decode if instruction is a load/mul/csr dependent on previous
 | 
			
		||||
  assign StallDCause = (LoadStallD | StoreStallD | MDUStallD | CSRRdStallD | FPUStallD | FStallD) & ~(TrapM | RetM | BPPredWrongE);    
 | 
			
		||||
 | 
			
		||||
@ -52,7 +52,6 @@ module controller(
 | 
			
		||||
  output logic       MDUE, W64E,
 | 
			
		||||
  output logic       JumpE,	
 | 
			
		||||
  output logic       SCE,
 | 
			
		||||
  output logic [1:0] AtomicE,
 | 
			
		||||
  // Memory stage control signals
 | 
			
		||||
  input  logic       StallM, FlushM,
 | 
			
		||||
  output logic [1:0] MemRWM,
 | 
			
		||||
@ -107,6 +106,7 @@ module controller(
 | 
			
		||||
	logic        BranchFlagE;
 | 
			
		||||
  logic        IEURegWriteE;
 | 
			
		||||
  logic        IllegalERegAdrD;
 | 
			
		||||
  logic [1:0]  AtomicE;
 | 
			
		||||
 | 
			
		||||
  // Extract fields
 | 
			
		||||
  assign OpD = InstrD[6:0];
 | 
			
		||||
 | 
			
		||||
@ -77,11 +77,7 @@ module datapath (
 | 
			
		||||
  // Execute stage signals
 | 
			
		||||
  logic [`XLEN-1:0] R1E, R2E;
 | 
			
		||||
  logic [`XLEN-1:0] ExtImmE;
 | 
			
		||||
 | 
			
		||||
  // logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, SrcAE2, SrcBE2; // *** MAde forwardedsrcae an output to get rid of a mux in the critical path.
 | 
			
		||||
  logic [`XLEN-1:0] SrcAE, SrcBE;
 | 
			
		||||
  logic [`XLEN-1:0] SrcAE2, SrcBE2;
 | 
			
		||||
 | 
			
		||||
  logic [`XLEN-1:0] ALUResultE, AltResultE, IEUResultE;
 | 
			
		||||
  // Memory stage signals
 | 
			
		||||
  logic [`XLEN-1:0] IEUResultM;
 | 
			
		||||
 | 
			
		||||
@ -50,7 +50,6 @@ module ieu (
 | 
			
		||||
  // Memory stage interface
 | 
			
		||||
  input logic 		   SquashSCW, // from LSU
 | 
			
		||||
  output logic [1:0] 	   MemRWM, // read/write control goes to LSU
 | 
			
		||||
  output logic [1:0] 	   AtomicE, // atomic control goes to LSU	    
 | 
			
		||||
  output logic [1:0] 	   AtomicM, // atomic control goes to LSU
 | 
			
		||||
  output logic [`XLEN-1:0] WriteDataE, // Address and write data to LSU
 | 
			
		||||
 | 
			
		||||
@ -98,7 +97,7 @@ module ieu (
 | 
			
		||||
    .IllegalIEUInstrFaultD, .IllegalBaseInstrFaultD, .StallE, .FlushE, .FlagsE, .FWriteIntE,
 | 
			
		||||
    .PCSrcE, .ALUControlE, .ALUSrcAE, .ALUSrcBE, .ALUResultSrcE, .MemReadE, .CSRReadE, 
 | 
			
		||||
    .Funct3E, .MDUE, .W64E, .JumpE, .StallM, .FlushM, .MemRWM,
 | 
			
		||||
    .CSRReadM, .CSRWriteM, .PrivilegedM, .SCE, .AtomicE, .AtomicM, .Funct3M,
 | 
			
		||||
    .CSRReadM, .CSRWriteM, .PrivilegedM, .SCE, .AtomicM, .Funct3M,
 | 
			
		||||
    .RegWriteM, .InvalidateICacheM, .FlushDCacheM, .InstrValidM, .FWriteIntM,
 | 
			
		||||
    .StallW, .FlushW, .RegWriteW, .ResultSrcW, .CSRWritePendingDEM, .StoreStallD);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -33,8 +33,8 @@
 | 
			
		||||
 | 
			
		||||
module ifu (
 | 
			
		||||
	input logic 				clk, reset,
 | 
			
		||||
	input logic 				StallF, StallD, StallE, StallM, StallW,
 | 
			
		||||
	input logic 				FlushF, FlushD, FlushE, FlushM, FlushW,
 | 
			
		||||
	input logic 				StallF, StallD, StallE, StallM, 
 | 
			
		||||
	input logic 				FlushF, FlushD, FlushE, FlushM, 
 | 
			
		||||
	// Bus interface
 | 
			
		||||
(* mark_debug = "true" *)	input logic [`XLEN-1:0] 	IFUBusHRDATA,
 | 
			
		||||
(* mark_debug = "true" *)	input logic 				IFUBusAck,
 | 
			
		||||
@ -65,7 +65,6 @@ module ifu (
 | 
			
		||||
	output logic 				InstrPageFaultF,
 | 
			
		||||
	output logic 				IllegalIEUInstrFaultD,
 | 
			
		||||
	output logic 				InstrMisalignedFaultM,
 | 
			
		||||
	input logic 				ExceptionM,
 | 
			
		||||
	// mmu management
 | 
			
		||||
	input logic [1:0] 			PrivilegeModeW,
 | 
			
		||||
	input logic [`XLEN-1:0] 	PTE,
 | 
			
		||||
@ -183,11 +182,9 @@ module ifu (
 | 
			
		||||
    localparam integer   WORDSPERLINE = (CACHE_ENABLED) ? `ICACHE_LINELENINBITS/`XLEN : 1;
 | 
			
		||||
    localparam integer   LINELEN = (CACHE_ENABLED) ? `ICACHE_LINELENINBITS : `XLEN;
 | 
			
		||||
    localparam integer   LOGWPL = (`DMEM == `MEM_CACHE) ? $clog2(WORDSPERLINE) : 1;
 | 
			
		||||
    logic [LINELEN-1:0]  ReadDataLine;
 | 
			
		||||
    logic [LINELEN-1:0]  ICacheBusWriteData;
 | 
			
		||||
    logic [`PA_BITS-1:0] ICacheBusAdr;
 | 
			
		||||
    logic                ICacheBusAck;
 | 
			
		||||
    logic [31:0]         temp;
 | 
			
		||||
    logic                SelUncachedAdr;
 | 
			
		||||
    
 | 
			
		||||
    busdp #(WORDSPERLINE, LINELEN, LOGWPL, CACHE_ENABLED) 
 | 
			
		||||
 | 
			
		||||
@ -32,7 +32,7 @@
 | 
			
		||||
 | 
			
		||||
module atomic (
 | 
			
		||||
  input logic                clk,
 | 
			
		||||
  input logic                reset, FlushW, StallW,
 | 
			
		||||
  input logic                reset, StallW,
 | 
			
		||||
  input logic [`XLEN-1:0]    ReadDataM,
 | 
			
		||||
  input logic [`XLEN-1:0]    LSUWriteDataM, 
 | 
			
		||||
  input logic [`PA_BITS-1:0] LSUPAdrM,
 | 
			
		||||
@ -52,7 +52,7 @@ module atomic (
 | 
			
		||||
                .result(AMOResult));
 | 
			
		||||
  mux2 #(`XLEN) wdmux(LSUWriteDataM, AMOResult, LSUAtomicM[1], AMOWriteDataM);
 | 
			
		||||
  assign MemReadM = PreLSURWM[1] & ~IgnoreRequest;
 | 
			
		||||
  lrsc lrsc(.clk, .reset, .FlushW, .StallW, .MemReadM, .PreLSURWM, .LSUAtomicM, .LSUPAdrM,
 | 
			
		||||
  lrsc lrsc(.clk, .reset, .StallW, .MemReadM, .PreLSURWM, .LSUAtomicM, .LSUPAdrM,
 | 
			
		||||
    .SquashSCW, .LSURWM);
 | 
			
		||||
 | 
			
		||||
endmodule  
 | 
			
		||||
 | 
			
		||||
@ -34,7 +34,7 @@
 | 
			
		||||
module lrsc
 | 
			
		||||
  (
 | 
			
		||||
    input  logic                clk, reset,
 | 
			
		||||
    input  logic                FlushW, StallW,
 | 
			
		||||
    input  logic                StallW,
 | 
			
		||||
    input  logic                MemReadM,
 | 
			
		||||
    input  logic [1:0]          PreLSURWM,
 | 
			
		||||
    output logic [1:0]          LSURWM,
 | 
			
		||||
 | 
			
		||||
@ -93,7 +93,7 @@ module lsu (
 | 
			
		||||
  logic [6:0]               LSUFunct7M;
 | 
			
		||||
  logic [1:0]               LSUAtomicM;
 | 
			
		||||
  (* mark_debug = "true" *)  logic [`XLEN+1:0] 		   PreLSUPAdrM;
 | 
			
		||||
  logic [11:0]              PreLSUAdrE, LSUAdrE;  
 | 
			
		||||
  logic [11:0]              LSUAdrE;  
 | 
			
		||||
  logic                     CPUBusy;
 | 
			
		||||
  logic                     DCacheStallM;
 | 
			
		||||
  logic                     CacheableM;
 | 
			
		||||
@ -131,7 +131,7 @@ module lsu (
 | 
			
		||||
  end else begin
 | 
			
		||||
    assign {InterlockStall, SelHPTW, PTE, PageType, DTLBWriteM, ITLBWriteF, IgnoreRequestTLB} = '0;
 | 
			
		||||
    assign IgnoreRequestTrapM = TrapM; assign CPUBusy = StallW; assign PreLSURWM = MemRWM; 
 | 
			
		||||
    assign LSUAdrE = PreLSUAdrE; assign PreLSUAdrE = IEUAdrE[11:0]; 
 | 
			
		||||
    assign LSUAdrE = IEUAdrE[11:0]; 
 | 
			
		||||
    assign PreLSUPAdrM = IEUAdrExtM;
 | 
			
		||||
    assign LSUFunct3M = Funct3M;  assign LSUFunct7M = Funct7M; assign LSUAtomicM = AtomicM;
 | 
			
		||||
    assign LSUWriteDataM = WriteDataM;
 | 
			
		||||
@ -202,13 +202,11 @@ module lsu (
 | 
			
		||||
    localparam integer   WORDSPERLINE = (CACHE_ENABLED) ? `DCACHE_LINELENINBITS/`XLEN : 1;
 | 
			
		||||
    localparam integer   LINELEN = (CACHE_ENABLED) ? `DCACHE_LINELENINBITS : `XLEN;
 | 
			
		||||
    localparam integer   LOGWPL = (CACHE_ENABLED) ? $clog2(WORDSPERLINE) : 1;
 | 
			
		||||
    logic [LINELEN-1:0]  ReadDataLineM;
 | 
			
		||||
    logic [LINELEN-1:0]  DCacheBusWriteData;
 | 
			
		||||
    logic [`PA_BITS-1:0] DCacheBusAdr;
 | 
			
		||||
    logic                DCacheWriteLine;
 | 
			
		||||
    logic                DCacheFetchLine;
 | 
			
		||||
    logic                DCacheBusAck;
 | 
			
		||||
    logic                SelBus;
 | 
			
		||||
    logic [LOGWPL-1:0]   WordCount;
 | 
			
		||||
            
 | 
			
		||||
    busdp #(WORDSPERLINE, LINELEN, LOGWPL, CACHE_ENABLED) busdp(
 | 
			
		||||
@ -251,7 +249,7 @@ module lsu (
 | 
			
		||||
  // Atomic operations
 | 
			
		||||
  /////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
  if (`A_SUPPORTED) begin:atomic
 | 
			
		||||
    atomic atomic(.clk, .reset, .FlushW, .StallW, .ReadDataM, .LSUWriteDataM, .LSUPAdrM, 
 | 
			
		||||
    atomic atomic(.clk, .reset, .StallW, .ReadDataM, .LSUWriteDataM, .LSUPAdrM, 
 | 
			
		||||
      .LSUFunct7M, .LSUFunct3M, .LSUAtomicM, .PreLSURWM, .IgnoreRequest, 
 | 
			
		||||
      .AMOWriteDataM, .SquashSCW, .LSURWM);
 | 
			
		||||
  end else begin:lrsc
 | 
			
		||||
 | 
			
		||||
@ -61,7 +61,6 @@ module hptw
 | 
			
		||||
	logic			    DTLBWalk; // register TLBs translation miss requests
 | 
			
		||||
	logic [`PPN_BITS-1:0]	    BasePageTablePPN;
 | 
			
		||||
	logic [`PPN_BITS-1:0]	    CurrentPPN;
 | 
			
		||||
	logic			    MemWrite;
 | 
			
		||||
	logic			    Executable, Writable, Readable, Valid, PTE_U;
 | 
			
		||||
	logic 			Misaligned, MegapageMisaligned;
 | 
			
		||||
	logic			    ValidPTE, LeafPTE, ValidLeafPTE, ValidNonLeafPTE;
 | 
			
		||||
 | 
			
		||||
@ -58,8 +58,6 @@ module tlbcontrol #(parameter ITLB = 0) (
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
  // Sections of the page table entry
 | 
			
		||||
  logic [11:0]             PageOffset;
 | 
			
		||||
  logic [`SVMODE_BITS-1:0] SVMode;
 | 
			
		||||
  logic [1:0]              EffectivePrivilegeMode;
 | 
			
		||||
 | 
			
		||||
  logic PTE_D, PTE_A, PTE_U, PTE_X, PTE_W, PTE_R, PTE_V; // Useful PTE Control Bits
 | 
			
		||||
 | 
			
		||||
@ -41,7 +41,6 @@ module muldiv (
 | 
			
		||||
	       output logic [`XLEN-1:0] MDUResultW,
 | 
			
		||||
	       // Divide Done
 | 
			
		||||
	       output logic 		DivBusyE, 
 | 
			
		||||
           output logic         DivE,
 | 
			
		||||
	       // hazards
 | 
			
		||||
	       input logic 		StallM, StallW, FlushM, FlushW, TrapM 
 | 
			
		||||
	       );
 | 
			
		||||
@ -52,6 +51,7 @@ module muldiv (
 | 
			
		||||
	logic [`XLEN*2-1:0] ProdM; 
 | 
			
		||||
 | 
			
		||||
	logic 		     DivSignedE;	
 | 
			
		||||
	logic            DivE;
 | 
			
		||||
	logic           W64M; 
 | 
			
		||||
 | 
			
		||||
	// Multiplier
 | 
			
		||||
 | 
			
		||||
@ -41,7 +41,7 @@ module csr #(parameter
 | 
			
		||||
  input  logic             StallE, StallM, StallW,
 | 
			
		||||
  input  logic [31:0]      InstrM, 
 | 
			
		||||
  input  logic [`XLEN-1:0] PCM, SrcAM,
 | 
			
		||||
  input  logic             CSRReadM, CSRWriteM, TrapM, MTrapM, STrapM, UTrapM, mretM, sretM, wfiM, InterruptM,
 | 
			
		||||
  input  logic             CSRReadM, CSRWriteM, TrapM, MTrapM, STrapM, mretM, sretM, wfiM, InterruptM,
 | 
			
		||||
  input  logic             MTimerInt, MExtInt, SExtInt, MSwInt,
 | 
			
		||||
  input  logic [63:0]      MTIME_CLINT, 
 | 
			
		||||
  input  logic             InstrValidM, FRegWriteM, LoadStallD,
 | 
			
		||||
@ -62,7 +62,7 @@ module csr #(parameter
 | 
			
		||||
  output logic [`XLEN-1:0] MEPC_REGW, SEPC_REGW, STVEC_REGW, MTVEC_REGW,
 | 
			
		||||
  output logic [`XLEN-1:0]      MEDELEG_REGW, 
 | 
			
		||||
  output logic [`XLEN-1:0] SATP_REGW,
 | 
			
		||||
  output logic [11:0]      MIP_REGW, MIE_REGW, SIP_REGW, SIE_REGW, MIDELEG_REGW,
 | 
			
		||||
  output logic [11:0]      MIP_REGW, MIE_REGW, MIDELEG_REGW,
 | 
			
		||||
  output logic             STATUS_MIE, STATUS_SIE,
 | 
			
		||||
  output logic             STATUS_MXR, STATUS_SUM, STATUS_MPRV, STATUS_TW,
 | 
			
		||||
  output logic [1:0]       STATUS_FS,
 | 
			
		||||
@ -71,7 +71,6 @@ module csr #(parameter
 | 
			
		||||
  
 | 
			
		||||
  input  logic [4:0]       SetFflagsM,
 | 
			
		||||
  output logic [2:0]       FRM_REGW, 
 | 
			
		||||
//  output logic [11:0]     MIP_REGW, SIP_REGW, UIP_REGW, MIE_REGW, SIE_REGW, UIE_REGW,
 | 
			
		||||
  output logic [`XLEN-1:0] CSRReadValW,
 | 
			
		||||
  output logic             IllegalCSRAccessM, BigEndianM
 | 
			
		||||
);
 | 
			
		||||
@ -96,7 +95,7 @@ module csr #(parameter
 | 
			
		||||
  logic        IllegalCSRCAccessM, IllegalCSRMAccessM, IllegalCSRSAccessM, IllegalCSRUAccessM, InsufficientCSRPrivilegeM;
 | 
			
		||||
  logic IllegalCSRMWriteReadonlyM;
 | 
			
		||||
  logic [`XLEN-1:0] CSRReadVal2M;
 | 
			
		||||
  logic [11:0] IP_REGW_writeable;
 | 
			
		||||
  logic [11:0] MIP_REGW_writeable;
 | 
			
		||||
  
 | 
			
		||||
  logic InstrValidNotFlushedM;
 | 
			
		||||
  assign InstrValidNotFlushedM = ~StallW & ~FlushW;
 | 
			
		||||
@ -107,7 +106,7 @@ module csr #(parameter
 | 
			
		||||
    CSRSrcM = InstrM[14] ? {{(`XLEN-5){1'b0}}, InstrM[19:15]} : SrcAM;
 | 
			
		||||
 | 
			
		||||
    // CSR set and clear for MIP/SIP should only touch internal state, not interrupt inputs
 | 
			
		||||
    if (CSRAdrM == MIP | CSRAdrM == SIP) CSRReadVal2M = {{(`XLEN-12){1'b0}}, IP_REGW_writeable};
 | 
			
		||||
    if (CSRAdrM == MIP | CSRAdrM == SIP) CSRReadVal2M = {{(`XLEN-12){1'b0}}, MIP_REGW_writeable};
 | 
			
		||||
    else                                 CSRReadVal2M = CSRReadValM;
 | 
			
		||||
 | 
			
		||||
    // Compute AND/OR modification
 | 
			
		||||
@ -135,7 +134,7 @@ module csr #(parameter
 | 
			
		||||
  csri   csri(.clk, .reset, .InstrValidNotFlushedM, .StallW, 
 | 
			
		||||
              .CSRMWriteM, .CSRSWriteM, .CSRWriteValM, .CSRAdrM, 
 | 
			
		||||
              .MExtInt, .SExtInt, .MTimerInt, .MSwInt,
 | 
			
		||||
              .MIP_REGW, .MIE_REGW, .SIP_REGW, .SIE_REGW, .MIDELEG_REGW, .IP_REGW_writeable);
 | 
			
		||||
              .MIP_REGW, .MIE_REGW, .MIP_REGW_writeable);
 | 
			
		||||
  csrsr csrsr(.clk, .reset, .StallW,
 | 
			
		||||
              .WriteMSTATUSM, .WriteMSTATUSHM, .WriteSSTATUSM, 
 | 
			
		||||
              .TrapM, .FRegWriteM, .NextPrivilegeModeM, .PrivilegeModeW,
 | 
			
		||||
@ -145,7 +144,7 @@ module csr #(parameter
 | 
			
		||||
              .STATUS_MIE, .STATUS_SIE, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_TVM,
 | 
			
		||||
              .STATUS_FS, .BigEndianM);
 | 
			
		||||
  csrc  counters(.clk, .reset,
 | 
			
		||||
              .StallE, .StallM, .StallW, .FlushE, .FlushM, .FlushW,   
 | 
			
		||||
              .StallE, .StallM, .StallW, .FlushM, .FlushW,   
 | 
			
		||||
              .InstrValidM, .LoadStallD, .CSRMWriteM,
 | 
			
		||||
              .BPPredDirWrongM, .BTBPredPCWrongM, .RASPredPCWrongM, .BPPredClassNonCFIWrongM,
 | 
			
		||||
              .InstrClassM, .DCacheMiss, .DCacheAccess, .ICacheMiss, .ICacheAccess,
 | 
			
		||||
@ -166,7 +165,7 @@ module csr #(parameter
 | 
			
		||||
              .STATUS_TVM, .CSRWriteValM, .PrivilegeModeW,
 | 
			
		||||
              .CSRSReadValM, .STVEC_REGW, .SEPC_REGW,      
 | 
			
		||||
              .SCOUNTEREN_REGW,
 | 
			
		||||
              .SATP_REGW, .SIP_REGW, .SIE_REGW,
 | 
			
		||||
              .SATP_REGW, .MIP_REGW, .MIE_REGW,
 | 
			
		||||
              .WriteSSTATUSM, .IllegalCSRSAccessM);
 | 
			
		||||
  csru  csru(.clk, .reset, .InstrValidNotFlushedM, .StallW,
 | 
			
		||||
              .CSRUWriteM, .CSRAdrM, .CSRWriteValM, .STATUS_FS, .CSRUReadValM,  
 | 
			
		||||
 | 
			
		||||
@ -43,7 +43,7 @@ module csrc #(parameter
 | 
			
		||||
) (
 | 
			
		||||
    input logic 	     clk, reset,
 | 
			
		||||
    input logic 	     StallE, StallM, StallW,
 | 
			
		||||
    input  logic       FlushE, FlushM, FlushW,   
 | 
			
		||||
    input logic        FlushM, FlushW,   
 | 
			
		||||
    input logic 	     InstrValidM, LoadStallD, CSRMWriteM,
 | 
			
		||||
    input logic 	     BPPredDirWrongM,
 | 
			
		||||
    input logic 	     BTBPredPCWrongM,
 | 
			
		||||
 | 
			
		||||
@ -43,12 +43,10 @@ module csri #(parameter
 | 
			
		||||
    input logic [`XLEN-1:0] CSRWriteValM,
 | 
			
		||||
    input logic [11:0] 		CSRAdrM,
 | 
			
		||||
    (* mark_debug = "true" *)    input logic MExtInt, SExtInt, MTimerInt, MSwInt,
 | 
			
		||||
    input logic [11:0] 		MIDELEG_REGW,
 | 
			
		||||
    output logic [11:0] 	MIP_REGW, MIE_REGW, SIP_REGW, SIE_REGW, 
 | 
			
		||||
    (* mark_debug = "true" *) output logic [11:0]   IP_REGW_writeable // only SEIP, STIP, SSIP are actually writeable; the rest are hardwired to 0
 | 
			
		||||
    output logic [11:0] 	MIP_REGW, MIE_REGW,
 | 
			
		||||
    (* mark_debug = "true" *) output logic [11:0]   MIP_REGW_writeable // only SEIP, STIP, SSIP are actually writeable; the rest are hardwired to 0
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  logic [11:0]     IP_REGW, IE_REGW;
 | 
			
		||||
  logic [11:0]     MIP_WRITE_MASK, SIP_WRITE_MASK, MIE_WRITE_MASK;
 | 
			
		||||
  logic            WriteMIPM, WriteMIEM, WriteSIPM, WriteSIEM;
 | 
			
		||||
 | 
			
		||||
@ -63,8 +61,8 @@ module csri #(parameter
 | 
			
		||||
  // SEIP, STIP, SSIP is writable in MIP if S mode exists
 | 
			
		||||
  // SSIP is writable in SIP if S mode exists
 | 
			
		||||
  if (`S_SUPPORTED) begin:mask
 | 
			
		||||
    assign MIP_WRITE_MASK = 12'h222; // SEIP, STIP, SSIP are writable in MIP (20210108-draft 3.1.9)
 | 
			
		||||
    assign SIP_WRITE_MASK = 12'h002; // SSIP is writable in SIP (privileged 20210108-draft 4.1.3)
 | 
			
		||||
    assign MIP_WRITE_MASK = 12'h222; // SEIP, STIP, SSIP are writeable in MIP (20210108-draft 3.1.9)
 | 
			
		||||
    assign SIP_WRITE_MASK = 12'h002; // SSIP is writeable in SIP (privileged 20210108-draft 4.1.3)
 | 
			
		||||
    assign MIE_WRITE_MASK = 12'hAAA;
 | 
			
		||||
  end else begin:mask
 | 
			
		||||
    assign MIP_WRITE_MASK = 12'h000;
 | 
			
		||||
@ -72,25 +70,13 @@ module csri #(parameter
 | 
			
		||||
    assign MIE_WRITE_MASK = 12'h888;
 | 
			
		||||
  end
 | 
			
		||||
  always @(posedge clk)
 | 
			
		||||
    if (reset)          IP_REGW_writeable <= 12'b0;
 | 
			
		||||
    else if (WriteMIPM) IP_REGW_writeable <= (CSRWriteValM[11:0] & MIP_WRITE_MASK);
 | 
			
		||||
    else if (WriteSIPM) IP_REGW_writeable <= (CSRWriteValM[11:0] & SIP_WRITE_MASK);
 | 
			
		||||
    if (reset)          MIP_REGW_writeable <= 12'b0;
 | 
			
		||||
    else if (WriteMIPM) MIP_REGW_writeable <= (CSRWriteValM[11:0] & MIP_WRITE_MASK);
 | 
			
		||||
    else if (WriteSIPM) MIP_REGW_writeable <= (CSRWriteValM[11:0] & SIP_WRITE_MASK) | (MIP_REGW_writeable & ~SIP_WRITE_MASK);
 | 
			
		||||
  always @(posedge clk)
 | 
			
		||||
    if (reset)          IE_REGW <= 12'b0;
 | 
			
		||||
    else if (WriteMIEM) IE_REGW <= (CSRWriteValM[11:0] & MIE_WRITE_MASK); // MIE controls M and S fields
 | 
			
		||||
    else if (WriteSIEM) IE_REGW <= (CSRWriteValM[11:0] & 12'h222) | (IE_REGW & 12'h888); // only S fields
 | 
			
		||||
 | 
			
		||||
  assign IP_REGW = {MExtInt,1'b0,SExtInt|IP_REGW_writeable[9],1'b0,MTimerInt,1'b0,IP_REGW_writeable[5],1'b0,MSwInt,1'b0,IP_REGW_writeable[1],1'b0};
 | 
			
		||||
 | 
			
		||||
  assign MIP_REGW = IP_REGW;
 | 
			
		||||
  assign MIE_REGW = IE_REGW;
 | 
			
		||||
 | 
			
		||||
  if (`S_SUPPORTED) begin
 | 
			
		||||
    assign SIP_REGW = IP_REGW & 12'h222;
 | 
			
		||||
    assign SIE_REGW = IE_REGW & 12'h222;
 | 
			
		||||
  end else begin
 | 
			
		||||
    assign SIP_REGW = 12'b0;
 | 
			
		||||
    assign SIE_REGW = 12'b0;
 | 
			
		||||
  end
 | 
			
		||||
    if (reset)          MIE_REGW <= 12'b0;
 | 
			
		||||
    else if (WriteMIEM) MIE_REGW <= (CSRWriteValM[11:0] & MIE_WRITE_MASK); // MIE controls M and S fields
 | 
			
		||||
    else if (WriteSIEM) MIE_REGW <= (CSRWriteValM[11:0] & 12'h222) | (MIE_REGW & 12'h888); // only S fields
 | 
			
		||||
 | 
			
		||||
  assign MIP_REGW = {MExtInt,1'b0,SExtInt|MIP_REGW_writeable[9],1'b0,MTimerInt,1'b0,MIP_REGW_writeable[5],1'b0,MSwInt,1'b0,MIP_REGW_writeable[1],1'b0};
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
@ -187,7 +187,7 @@ module csrm #(parameter
 | 
			
		||||
      MARCHID:   CSRMReadValM = 0;
 | 
			
		||||
      MIMPID:    CSRMReadValM = `XLEN'h100; // pipelined implementation
 | 
			
		||||
      MHARTID:   CSRMReadValM = MHARTID_REGW; // hardwired to 0 
 | 
			
		||||
      MCONFIGPTR: CSRReadValM = 0; // hardwired to 0
 | 
			
		||||
      MCONFIGPTR: CSRMReadValM = 0; // hardwired to 0
 | 
			
		||||
      MSTATUS:   CSRMReadValM = MSTATUS_REGW;
 | 
			
		||||
      MSTATUSH:  CSRMReadValM = MSTATUSH_REGW; 
 | 
			
		||||
      MTVEC:     CSRMReadValM = MTVEC_REGW;
 | 
			
		||||
 | 
			
		||||
@ -61,14 +61,11 @@ module csrs #(parameter
 | 
			
		||||
    (* mark_debug = "true" *) output logic [`XLEN-1:0] SEPC_REGW,      
 | 
			
		||||
    output logic [31:0]      SCOUNTEREN_REGW, 
 | 
			
		||||
    output logic [`XLEN-1:0] SATP_REGW,
 | 
			
		||||
    (* mark_debug = "true" *) input logic [11:0] SIP_REGW, SIE_REGW,
 | 
			
		||||
    (* mark_debug = "true" *) input logic [11:0] MIP_REGW, MIE_REGW,
 | 
			
		||||
    output logic 	     WriteSSTATUSM,
 | 
			
		||||
    output logic 	     IllegalCSRSAccessM
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  //logic [`XLEN-1:0] zero = 0;
 | 
			
		||||
  //logic [31:0] allones = {32{1'b1}};
 | 
			
		||||
  //logic [`XLEN-1:0] SEDELEG_MASK = ~(zero | 3'b111 << 9); // sedeleg[11:9] hardwired to zero per Privileged Spec 3.1.8
 | 
			
		||||
 | 
			
		||||
  // Supervisor mode CSRs sometimes supported
 | 
			
		||||
  if (`S_SUPPORTED) begin:csrs
 | 
			
		||||
@ -105,8 +102,8 @@ module csrs #(parameter
 | 
			
		||||
      case (CSRAdrM) 
 | 
			
		||||
        SSTATUS:   CSRSReadValM = SSTATUS_REGW;
 | 
			
		||||
        STVEC:     CSRSReadValM = STVEC_REGW;
 | 
			
		||||
        SIP:       CSRSReadValM = {{(`XLEN-12){1'b0}}, SIP_REGW};
 | 
			
		||||
        SIE:       CSRSReadValM = {{(`XLEN-12){1'b0}}, SIE_REGW};
 | 
			
		||||
        SIP:       CSRSReadValM = {{(`XLEN-12){1'b0}}, MIP_REGW & 12'h222}; // only read supervisor fields
 | 
			
		||||
        SIE:       CSRSReadValM = {{(`XLEN-12){1'b0}}, MIE_REGW & 12'h222}; // only read supervisor fields
 | 
			
		||||
        SSCRATCH:  CSRSReadValM = SSCRATCH_REGW;
 | 
			
		||||
        SEPC:      CSRSReadValM = SEPC_REGW;
 | 
			
		||||
        SCAUSE:    CSRSReadValM = SCAUSE_REGW;
 | 
			
		||||
 | 
			
		||||
@ -32,29 +32,67 @@
 | 
			
		||||
`include "wally-config.vh"
 | 
			
		||||
 | 
			
		||||
module privdec (
 | 
			
		||||
  input  logic         clk, reset,
 | 
			
		||||
  input  logic         StallM,
 | 
			
		||||
  input  logic [31:20] InstrM,
 | 
			
		||||
  input  logic         PrivilegedM, IllegalIEUInstrFaultM, IllegalCSRAccessM, IllegalFPUInstrM, 
 | 
			
		||||
  input  logic         TrappedSRETM, WFITimeoutM,
 | 
			
		||||
  input  logic [1:0]   PrivilegeModeW, 
 | 
			
		||||
  input  logic         STATUS_TSR, STATUS_TVM,
 | 
			
		||||
  input  logic         STATUS_TSR, STATUS_TVM, STATUS_TW,
 | 
			
		||||
  input  logic [1:0]   STATUS_FS,
 | 
			
		||||
  output logic         IllegalInstrFaultM,
 | 
			
		||||
  output logic         sretM, mretM, ecallM, ebreakM, wfiM, sfencevmaM);
 | 
			
		||||
  output logic         IllegalInstrFaultM, ITLBFlushF, DTLBFlushM,
 | 
			
		||||
  output logic         EcallFaultM, BreakpointFaultM,
 | 
			
		||||
  output logic         sretM, mretM, wfiM, sfencevmaM);
 | 
			
		||||
 | 
			
		||||
  logic IllegalPrivilegedInstrM, IllegalOrDisabledFPUInstrM;
 | 
			
		||||
  logic WFITimeoutM;
 | 
			
		||||
  logic       StallMQ;
 | 
			
		||||
  logic       ebreakM, ecallM;
 | 
			
		||||
 | 
			
		||||
  // xRET defined in Privileged Spect 3.2.2
 | 
			
		||||
  ///////////////////////////////////////////
 | 
			
		||||
  // Decode privileged instructions
 | 
			
		||||
  ///////////////////////////////////////////
 | 
			
		||||
  assign sretM =      PrivilegedM & (InstrM[31:20] == 12'b000100000010) & `S_SUPPORTED & 
 | 
			
		||||
                      PrivilegeModeW[0] & ~STATUS_TSR; 
 | 
			
		||||
                      (PrivilegeModeW == `M_MODE || PrivilegeModeW == `S_MODE & ~STATUS_TSR); 
 | 
			
		||||
  assign mretM =      PrivilegedM & (InstrM[31:20] == 12'b001100000010) & (PrivilegeModeW == `M_MODE);
 | 
			
		||||
 | 
			
		||||
  assign ecallM =     PrivilegedM & (InstrM[31:20] == 12'b000000000000);
 | 
			
		||||
  assign ebreakM =    PrivilegedM & (InstrM[31:20] == 12'b000000000001);
 | 
			
		||||
  assign wfiM =       PrivilegedM & (InstrM[31:20] == 12'b000100000101);
 | 
			
		||||
  assign sfencevmaM = PrivilegedM & (InstrM[31:25] ==  7'b0001001) & 
 | 
			
		||||
                      (PrivilegeModeW == `M_MODE | (PrivilegeModeW == `S_MODE & ~STATUS_TVM)); 
 | 
			
		||||
 | 
			
		||||
  ///////////////////////////////////////////
 | 
			
		||||
  // WFI timeout Privileged Spec 3.1.6.5
 | 
			
		||||
  ///////////////////////////////////////////
 | 
			
		||||
  if (`U_SUPPORTED) begin:wfi
 | 
			
		||||
    logic [`WFI_TIMEOUT_BIT:0] WFICount, WFICountPlus1;
 | 
			
		||||
    assign WFICountPlus1 = WFICount + 1;
 | 
			
		||||
    floprc #(`WFI_TIMEOUT_BIT+1) wficountreg(clk, reset, ~wfiM, WFICountPlus1, WFICount);  // count while in WFI
 | 
			
		||||
    assign WFITimeoutM = ((STATUS_TW & PrivilegeModeW != `M_MODE) | (`S_SUPPORTED & PrivilegeModeW == `U_MODE)) & WFICount[`WFI_TIMEOUT_BIT]; 
 | 
			
		||||
  end else assign WFITimeoutM = 0;
 | 
			
		||||
 | 
			
		||||
  ///////////////////////////////////////////
 | 
			
		||||
  // Extract exceptions by name and handle them 
 | 
			
		||||
  ///////////////////////////////////////////
 | 
			
		||||
  assign BreakpointFaultM = ebreakM; // could have other causes from a debugger
 | 
			
		||||
  assign EcallFaultM = ecallM;
 | 
			
		||||
 | 
			
		||||
  ///////////////////////////////////////////
 | 
			
		||||
  // sfence.vma causes TLB flushes
 | 
			
		||||
  ///////////////////////////////////////////
 | 
			
		||||
  // sets ITLBFlush to pulse for one cycle of the sfence.vma instruction
 | 
			
		||||
  // In this instr we want to flush the tlb and then do a pagetable walk to update the itlb and continue the program.
 | 
			
		||||
  // But we're still in the stalled sfence instruction, so if itlbflushf == sfencevmaM, tlbflush would never drop and 
 | 
			
		||||
  // the tlbwrite would never take place after the pagetable walk. by adding in ~StallMQ, we are able to drop itlbflush 
 | 
			
		||||
  // after a cycle AND pulse it for another cycle on any further back-to-back sfences. 
 | 
			
		||||
  flopr #(1) StallMReg(.clk, .reset, .d(StallM), .q(StallMQ));
 | 
			
		||||
  assign ITLBFlushF = sfencevmaM & ~StallMQ;
 | 
			
		||||
  assign DTLBFlushM = sfencevmaM;
 | 
			
		||||
 | 
			
		||||
  ///////////////////////////////////////////
 | 
			
		||||
  // Fault on illegal instructions
 | 
			
		||||
  ///////////////////////////////////////////
 | 
			
		||||
  assign IllegalPrivilegedInstrM = PrivilegedM & ~(sretM|mretM|ecallM|ebreakM|wfiM|sfencevmaM);
 | 
			
		||||
  assign IllegalOrDisabledFPUInstrM = IllegalFPUInstrM | (STATUS_FS == 2'b00);
 | 
			
		||||
  assign IllegalInstrFaultM = (IllegalIEUInstrFaultM & IllegalOrDisabledFPUInstrM) | IllegalPrivilegedInstrM | IllegalCSRAccessM | 
 | 
			
		||||
                               TrappedSRETM | WFITimeoutM; 
 | 
			
		||||
                               WFITimeoutM; 
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
@ -39,7 +39,7 @@ module privileged (
 | 
			
		||||
  output logic [`XLEN-1:0] PrivilegedNextPCM,
 | 
			
		||||
  output logic             RetM, TrapM, 
 | 
			
		||||
  output logic             ITLBFlushF, DTLBFlushM,
 | 
			
		||||
  input  logic             InstrValidM, CommittedM, DivE,
 | 
			
		||||
  input  logic             InstrValidM, CommittedM, 
 | 
			
		||||
  input  logic             FRegWriteM, LoadStallD,
 | 
			
		||||
  input  logic 		   BPPredDirWrongM,
 | 
			
		||||
  input  logic 		   BTBPredPCWrongM,
 | 
			
		||||
@ -69,7 +69,6 @@ module privileged (
 | 
			
		||||
  input logic StoreAmoAccessFaultM,
 | 
			
		||||
  input logic SelHPTW,
 | 
			
		||||
 | 
			
		||||
  output logic 		   ExceptionM,
 | 
			
		||||
  output logic		   IllegalFPUInstrE,
 | 
			
		||||
  output logic [1:0]       PrivilegeModeW,
 | 
			
		||||
  output logic [`XLEN-1:0] SATP_REGW,
 | 
			
		||||
@ -82,76 +81,43 @@ module privileged (
 | 
			
		||||
  output logic             BreakpointFaultM, EcallFaultM, wfiM, IntPendingM, BigEndianM
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
  logic [1:0] NextPrivilegeModeM;
 | 
			
		||||
 | 
			
		||||
  logic [`XLEN-1:0] CauseM, NextFaultMtvalM;
 | 
			
		||||
  logic [`XLEN-1:0] MEPC_REGW, SEPC_REGW, STVEC_REGW, MTVEC_REGW;
 | 
			
		||||
  logic [`XLEN-1:0] MEDELEG_REGW;
 | 
			
		||||
  logic [11:0]      MIDELEG_REGW;
 | 
			
		||||
 | 
			
		||||
  logic sretM, mretM, ecallM, ebreakM, sfencevmaM;
 | 
			
		||||
  logic sretM, mretM, sfencevmaM;
 | 
			
		||||
  logic IllegalCSRAccessM;
 | 
			
		||||
  logic IllegalIEUInstrFaultE, IllegalIEUInstrFaultM;
 | 
			
		||||
  logic IllegalFPUInstrM;
 | 
			
		||||
  logic InstrPageFaultD, InstrPageFaultE, InstrPageFaultM;
 | 
			
		||||
  logic InstrAccessFaultD, InstrAccessFaultE, InstrAccessFaultM;
 | 
			
		||||
  logic IllegalInstrFaultM, TrappedSRETM;
 | 
			
		||||
  logic IllegalInstrFaultM;
 | 
			
		||||
 | 
			
		||||
  logic MTrapM, STrapM, UTrapM;
 | 
			
		||||
  logic MTrapM, STrapM;
 | 
			
		||||
  (* mark_debug = "true" *)  logic InterruptM; 
 | 
			
		||||
 | 
			
		||||
  logic       STATUS_SPP, STATUS_TSR, STATUS_TW, STATUS_TVM;
 | 
			
		||||
  logic       STATUS_MIE, STATUS_SIE;
 | 
			
		||||
  logic [11:0] MIP_REGW, MIE_REGW, SIP_REGW, SIE_REGW;
 | 
			
		||||
  logic md;
 | 
			
		||||
  logic       StallMQ;
 | 
			
		||||
  logic WFITimeoutM; 
 | 
			
		||||
 | 
			
		||||
  logic [11:0] MIP_REGW, MIE_REGW;
 | 
			
		||||
  logic [1:0] NextPrivilegeModeM;
 | 
			
		||||
 | 
			
		||||
  ///////////////////////////////////////////
 | 
			
		||||
  // track the current privilege level
 | 
			
		||||
  ///////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
  // get bits of DELEG registers based on CAUSE
 | 
			
		||||
  assign md = CauseM[`XLEN-1] ? MIDELEG_REGW[CauseM[3:0]] : MEDELEG_REGW[CauseM[`LOG_XLEN-1:0]];
 | 
			
		||||
  
 | 
			
		||||
  // PrivilegeMode FSM
 | 
			
		||||
  always_comb begin
 | 
			
		||||
    if (TrapM) begin // Change privilege based on DELEG registers (see 3.1.8)
 | 
			
		||||
      if (`S_SUPPORTED & md & (PrivilegeModeW == `U_MODE | PrivilegeModeW == `S_MODE))
 | 
			
		||||
                    NextPrivilegeModeM = `S_MODE;
 | 
			
		||||
      else          NextPrivilegeModeM = `M_MODE;
 | 
			
		||||
    end else if (mretM) NextPrivilegeModeM = STATUS_MPP;
 | 
			
		||||
    else if (sretM) begin
 | 
			
		||||
      if (STATUS_TSR & PrivilegeModeW == `S_MODE) begin
 | 
			
		||||
        NextPrivilegeModeM = PrivilegeModeW;
 | 
			
		||||
      end else      NextPrivilegeModeM = {1'b0, STATUS_SPP};
 | 
			
		||||
    end else        NextPrivilegeModeM = PrivilegeModeW;
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  assign TrappedSRETM = sretM & STATUS_TSR & PrivilegeModeW == `S_MODE;
 | 
			
		||||
 | 
			
		||||
  flopenl #(2) privmodereg(clk, reset, ~StallW, NextPrivilegeModeM, `M_MODE, PrivilegeModeW);
 | 
			
		||||
 | 
			
		||||
  ///////////////////////////////////////////
 | 
			
		||||
  // WFI timeout Privileged Spec 3.1.6.5
 | 
			
		||||
  ///////////////////////////////////////////
 | 
			
		||||
  if (`U_SUPPORTED) begin:wfi
 | 
			
		||||
    logic [`WFI_TIMEOUT_BIT:0] WFICount, WFICountPlus1;
 | 
			
		||||
    assign WFICountPlus1 = WFICount + 1;
 | 
			
		||||
    floprc #(`WFI_TIMEOUT_BIT+1) wficountreg(clk, reset, ~wfiM, WFICountPlus1, WFICount);  // count while in WFI
 | 
			
		||||
    assign WFITimeoutM = ((STATUS_TW & PrivilegeModeW != `M_MODE) | (`S_SUPPORTED & PrivilegeModeW == `U_MODE)) & WFICount[`WFI_TIMEOUT_BIT]; 
 | 
			
		||||
  end else assign WFITimeoutM = 0;
 | 
			
		||||
 | 
			
		||||
  privmode privmode(.clk, .reset, .StallW, .TrapM, .mretM, .sretM, .CauseM, 
 | 
			
		||||
                    .MEDELEG_REGW, .MIDELEG_REGW, .STATUS_MPP, .STATUS_SPP, .NextPrivilegeModeM, .PrivilegeModeW);
 | 
			
		||||
 | 
			
		||||
  ///////////////////////////////////////////
 | 
			
		||||
  // decode privileged instructions
 | 
			
		||||
  ///////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
   privdec pmd(.InstrM(InstrM[31:20]), 
 | 
			
		||||
              .PrivilegedM, .IllegalIEUInstrFaultM, .IllegalCSRAccessM, .IllegalFPUInstrM, .TrappedSRETM, .WFITimeoutM,
 | 
			
		||||
              .PrivilegeModeW, .STATUS_TSR, .STATUS_TVM, .STATUS_FS, .IllegalInstrFaultM, 
 | 
			
		||||
              .sretM, .mretM, .ecallM, .ebreakM, .wfiM, .sfencevmaM);
 | 
			
		||||
   privdec pmd(.clk, .reset, .StallM, .InstrM(InstrM[31:20]), 
 | 
			
		||||
              .PrivilegedM, .IllegalIEUInstrFaultM, .IllegalCSRAccessM, .IllegalFPUInstrM, 
 | 
			
		||||
              .PrivilegeModeW, .STATUS_TSR, .STATUS_TVM, .STATUS_TW, .STATUS_FS, .IllegalInstrFaultM, 
 | 
			
		||||
              .ITLBFlushF, .DTLBFlushM, .EcallFaultM, .BreakpointFaultM,
 | 
			
		||||
              .sretM, .mretM, .wfiM, .sfencevmaM);
 | 
			
		||||
 | 
			
		||||
  ///////////////////////////////////////////
 | 
			
		||||
  // Control and Status Registers
 | 
			
		||||
@ -160,7 +126,7 @@ module privileged (
 | 
			
		||||
          .FlushE, .FlushM, .FlushW,
 | 
			
		||||
          .StallE, .StallM, .StallW,
 | 
			
		||||
          .InstrM, .PCM, .SrcAM,
 | 
			
		||||
          .CSRReadM, .CSRWriteM, .TrapM, .MTrapM, .STrapM, .UTrapM, .mretM, .sretM, .wfiM, .InterruptM,
 | 
			
		||||
          .CSRReadM, .CSRWriteM, .TrapM, .MTrapM, .STrapM, .mretM, .sretM, .wfiM, .InterruptM,
 | 
			
		||||
          .MTimerInt, .MExtInt, .SExtInt, .MSwInt,
 | 
			
		||||
          .MTIME_CLINT, 
 | 
			
		||||
          .InstrValidM, .FRegWriteM, .LoadStallD,
 | 
			
		||||
@ -173,7 +139,7 @@ module privileged (
 | 
			
		||||
          .MEPC_REGW, .SEPC_REGW, .STVEC_REGW, .MTVEC_REGW,
 | 
			
		||||
          .MEDELEG_REGW, 
 | 
			
		||||
          .SATP_REGW,
 | 
			
		||||
          .MIP_REGW, .MIE_REGW, .SIP_REGW, .SIE_REGW, .MIDELEG_REGW,
 | 
			
		||||
          .MIP_REGW, .MIE_REGW, .MIDELEG_REGW,
 | 
			
		||||
          .STATUS_MIE, .STATUS_SIE,
 | 
			
		||||
          .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_TW, .STATUS_FS,
 | 
			
		||||
          .PMPCFG_ARRAY_REGW,
 | 
			
		||||
@ -183,21 +149,6 @@ module privileged (
 | 
			
		||||
          .CSRReadValW,
 | 
			
		||||
          .IllegalCSRAccessM, .BigEndianM);
 | 
			
		||||
 | 
			
		||||
  ///////////////////////////////////////////
 | 
			
		||||
  // Extract exceptions by name and handle them 
 | 
			
		||||
  ///////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
  assign BreakpointFaultM = ebreakM; // could have other causes too
 | 
			
		||||
  assign EcallFaultM = ecallM;
 | 
			
		||||
 | 
			
		||||
  flopr #(1) StallMReg(.clk, .reset, .d(StallM), .q(StallMQ));
 | 
			
		||||
  assign ITLBFlushF = sfencevmaM & ~StallMQ;
 | 
			
		||||
  assign DTLBFlushM = sfencevmaM;
 | 
			
		||||
  // sets ITLBFlush to pulse for one cycle of the sfence.vma instruction
 | 
			
		||||
  // In this instr we want to flush the tlb and then do a pagetable walk to update the itlb and continue the program.
 | 
			
		||||
  // But we're still in the stalled sfence instruction, so if itlbflushf == sfencevmaM, tlbflush would never drop and 
 | 
			
		||||
  // the tlbwrite would never take place after the pagetable walk. by adding in ~StallMQ, we are able to drop itlbflush 
 | 
			
		||||
  // after a cycle AND pulse it for another cycle on any further back-to-back sfences. 
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  // A page fault might occur because of insufficient privilege during a TLB
 | 
			
		||||
@ -214,7 +165,7 @@ module privileged (
 | 
			
		||||
                  {IllegalIEUInstrFaultE, InstrPageFaultE, InstrAccessFaultE, IllegalFPUInstrE},
 | 
			
		||||
                  {IllegalIEUInstrFaultM, InstrPageFaultM, InstrAccessFaultM, IllegalFPUInstrM});
 | 
			
		||||
  // *** it should be possible to combine some of these faults earlier to reduce module boundary crossings and save flops dh 5 july 2021
 | 
			
		||||
  trap trap(.clk, .reset,
 | 
			
		||||
  trap trap(.reset,
 | 
			
		||||
            .InstrMisalignedFaultM, .InstrAccessFaultM, .IllegalInstrFaultM,
 | 
			
		||||
            .BreakpointFaultM, .LoadMisalignedFaultM, .StoreAmoMisalignedFaultM,
 | 
			
		||||
            .LoadAccessFaultM, .StoreAmoAccessFaultM, .EcallFaultM, .InstrPageFaultM,
 | 
			
		||||
@ -222,15 +173,14 @@ module privileged (
 | 
			
		||||
            .mretM, .sretM, 
 | 
			
		||||
            .PrivilegeModeW, .NextPrivilegeModeM,
 | 
			
		||||
            .MEPC_REGW, .SEPC_REGW, .STVEC_REGW, .MTVEC_REGW,
 | 
			
		||||
            .MIP_REGW, .MIE_REGW, .SIP_REGW, .SIE_REGW, .MIDELEG_REGW,
 | 
			
		||||
            .MIP_REGW, .MIE_REGW, .MIDELEG_REGW,
 | 
			
		||||
            .STATUS_MIE, .STATUS_SIE,
 | 
			
		||||
            .PCM,
 | 
			
		||||
            .IEUAdrM, 
 | 
			
		||||
            .InstrM,
 | 
			
		||||
            .InstrValidM, .CommittedM, .DivE, 
 | 
			
		||||
            .TrapM, .MTrapM, .STrapM, .UTrapM, .RetM,
 | 
			
		||||
            .InstrValidM, .CommittedM,  
 | 
			
		||||
            .TrapM, .MTrapM, .STrapM, .RetM,
 | 
			
		||||
            .InterruptM, .IntPendingM,
 | 
			
		||||
            .ExceptionM,
 | 
			
		||||
             .PrivilegedNextPCM, .CauseM, .NextFaultMtvalM);
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										66
									
								
								pipelined/src/privileged/privmode.sv
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								pipelined/src/privileged/privmode.sv
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,66 @@
 | 
			
		||||
///////////////////////////////////////////
 | 
			
		||||
// privmode.sv
 | 
			
		||||
//
 | 
			
		||||
// Written: David_Harris@hmc.edu 12 May 2022
 | 
			
		||||
// Modified: 
 | 
			
		||||
//
 | 
			
		||||
// Purpose: Track privilege mode
 | 
			
		||||
//          See RISC-V Privileged Mode Specification 20190608 3.1.10-11
 | 
			
		||||
// 
 | 
			
		||||
// A component of the Wally configurable RISC-V project.
 | 
			
		||||
// 
 | 
			
		||||
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
 | 
			
		||||
//
 | 
			
		||||
// MIT LICENSE
 | 
			
		||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this 
 | 
			
		||||
// software and associated documentation files (the "Software"), to deal in the Software 
 | 
			
		||||
// without restriction, including without limitation the rights to use, copy, modify, merge, 
 | 
			
		||||
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons 
 | 
			
		||||
// to whom the Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
//
 | 
			
		||||
//   The above copyright notice and this permission notice shall be included in all copies or 
 | 
			
		||||
//   substantial portions of the Software.
 | 
			
		||||
//
 | 
			
		||||
//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 
 | 
			
		||||
//   INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 
 | 
			
		||||
//   PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 
 | 
			
		||||
//   BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 
 | 
			
		||||
//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 
 | 
			
		||||
//   OR OTHER DEALINGS IN THE SOFTWARE.
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
`include "wally-config.vh"
 | 
			
		||||
 | 
			
		||||
module privmode (
 | 
			
		||||
  input  logic             clk, reset,
 | 
			
		||||
  input  logic             StallW, TrapM, mretM, sretM,
 | 
			
		||||
  input  logic [`XLEN-1:0] CauseM, MEDELEG_REGW,
 | 
			
		||||
  input  logic [11:0]      MIDELEG_REGW,
 | 
			
		||||
  input  logic [1:0]       STATUS_MPP,
 | 
			
		||||
  input  logic             STATUS_SPP,
 | 
			
		||||
  output logic [1:0]       NextPrivilegeModeM, PrivilegeModeW
 | 
			
		||||
); 
 | 
			
		||||
  
 | 
			
		||||
  if (`U_SUPPORTED) begin:privmode
 | 
			
		||||
    logic       md;
 | 
			
		||||
 | 
			
		||||
    // get bits of DELEG registers based on CAUSE
 | 
			
		||||
    assign md = CauseM[`XLEN-1] ? MIDELEG_REGW[CauseM[3:0]] : MEDELEG_REGW[CauseM[`LOG_XLEN-1:0]];
 | 
			
		||||
    
 | 
			
		||||
    // PrivilegeMode FSM
 | 
			
		||||
    always_comb begin
 | 
			
		||||
      if (TrapM) begin // Change privilege based on DELEG registers (see 3.1.8)
 | 
			
		||||
        if (`S_SUPPORTED & md & (PrivilegeModeW == `U_MODE | PrivilegeModeW == `S_MODE))
 | 
			
		||||
                          NextPrivilegeModeM = `S_MODE;
 | 
			
		||||
        else              NextPrivilegeModeM = `M_MODE;
 | 
			
		||||
      end else if (mretM) NextPrivilegeModeM = STATUS_MPP;
 | 
			
		||||
      else if (sretM)     NextPrivilegeModeM = {1'b0, STATUS_SPP};
 | 
			
		||||
      else                NextPrivilegeModeM = PrivilegeModeW;
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    flopenl #(2) privmodereg(clk, reset, ~StallW, NextPrivilegeModeM, `M_MODE, PrivilegeModeW);
 | 
			
		||||
  end else begin  // only machine mode supported
 | 
			
		||||
    assign NextPrivilegeModeM = `M_MODE;
 | 
			
		||||
    assign PrivilegeModeW = `M_MODE;
 | 
			
		||||
  end
 | 
			
		||||
endmodule
 | 
			
		||||
@ -32,7 +32,6 @@
 | 
			
		||||
`include "wally-config.vh"
 | 
			
		||||
 | 
			
		||||
module trap (
 | 
			
		||||
  input logic 		   clk,
 | 
			
		||||
   input logic 		   reset, 
 | 
			
		||||
  (* mark_debug = "true" *) input logic 		   InstrMisalignedFaultM, InstrAccessFaultM, IllegalInstrFaultM,
 | 
			
		||||
  (* mark_debug = "true" *) input logic 		   BreakpointFaultM, LoadMisalignedFaultM, StoreAmoMisalignedFaultM,
 | 
			
		||||
@ -41,25 +40,24 @@ module trap (
 | 
			
		||||
  (* mark_debug = "true" *) input logic 		   mretM, sretM, 
 | 
			
		||||
  input logic [1:0] 	   PrivilegeModeW, NextPrivilegeModeM,
 | 
			
		||||
  (* mark_debug = "true" *) input logic [`XLEN-1:0]  MEPC_REGW, SEPC_REGW, STVEC_REGW, MTVEC_REGW,
 | 
			
		||||
  (* mark_debug = "true" *) input logic [11:0] 	   MIP_REGW, MIE_REGW, SIP_REGW, SIE_REGW, MIDELEG_REGW,
 | 
			
		||||
  (* mark_debug = "true" *) input logic [11:0] 	   MIP_REGW, MIE_REGW, MIDELEG_REGW,
 | 
			
		||||
  input logic 		   STATUS_MIE, STATUS_SIE,
 | 
			
		||||
  input logic [`XLEN-1:0]  PCM,
 | 
			
		||||
  input logic [`XLEN-1:0]  IEUAdrM, 
 | 
			
		||||
  input logic [31:0] 	   InstrM,
 | 
			
		||||
  input logic 		   InstrValidM, CommittedM, DivE, 
 | 
			
		||||
  output logic 		   TrapM, MTrapM, STrapM, UTrapM, RetM,
 | 
			
		||||
  input logic 		   InstrValidM, CommittedM, 
 | 
			
		||||
  output logic 		   TrapM, MTrapM, STrapM, RetM,
 | 
			
		||||
  output logic 		   InterruptM, IntPendingM,
 | 
			
		||||
  output logic 		   ExceptionM,
 | 
			
		||||
  output logic [`XLEN-1:0] PrivilegedNextPCM, CauseM, NextFaultMtvalM
 | 
			
		||||
//  output logic [11:0]     MIP_REGW, SIP_REGW, UIP_REGW, MIE_REGW, SIE_REGW, UIE_REGW,
 | 
			
		||||
//  input  logic            WriteMIPM, WriteSIPM, WriteUIPM, WriteMIEM, WriteSIEM, WriteUIEM
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
  logic MIntGlobalEnM, SIntGlobalEnM;
 | 
			
		||||
  logic ExceptionM;
 | 
			
		||||
  (* mark_debug = "true" *) logic [11:0] PendingIntsM, ValidIntsM; 
 | 
			
		||||
  //logic InterruptM;
 | 
			
		||||
  logic [`XLEN-1:0] PrivilegedTrapVector, PrivilegedVectoredTrapVector;
 | 
			
		||||
  logic Exception1M;
 | 
			
		||||
 | 
			
		||||
  // Determine pending enabled interrupts
 | 
			
		||||
  // interrupt if any sources are pending
 | 
			
		||||
 | 
			
		||||
@ -63,13 +63,11 @@ module wallypipelinedcore (
 | 
			
		||||
  // new signals that must connect through DP
 | 
			
		||||
  logic             MDUE, W64E;
 | 
			
		||||
  logic             CSRReadM, CSRWriteM, PrivilegedM;
 | 
			
		||||
  logic [1:0]             AtomicE;
 | 
			
		||||
  logic [1:0]             AtomicM;
 | 
			
		||||
  logic [`XLEN-1:0]     ForwardedSrcAE, ForwardedSrcBE; //, SrcAE, SrcBE;
 | 
			
		||||
(* mark_debug = "true" *)  logic [`XLEN-1:0]         SrcAM;
 | 
			
		||||
  logic [2:0]             Funct3E;
 | 
			
		||||
  //  logic [31:0] InstrF;
 | 
			
		||||
  logic [31:0]             InstrD, InstrW;
 | 
			
		||||
  logic [31:0]             InstrD;
 | 
			
		||||
  (* mark_debug = "true" *) logic [31:0]             InstrM;
 | 
			
		||||
  logic [`XLEN-1:0]         PCF, PCD, PCE, PCLinkE;
 | 
			
		||||
  (* mark_debug = "true" *) logic [`XLEN-1:0]         PCM;
 | 
			
		||||
@ -86,7 +84,6 @@ module wallypipelinedcore (
 | 
			
		||||
  logic             PCSrcE;
 | 
			
		||||
  logic             CSRWritePendingDEM;
 | 
			
		||||
  logic             DivBusyE;
 | 
			
		||||
  logic             DivE;
 | 
			
		||||
  logic             LoadStallD, StoreStallD, MDUStallD, CSRRdStallD;
 | 
			
		||||
  logic             SquashSCW;
 | 
			
		||||
  // floating point unit signals
 | 
			
		||||
@ -157,7 +154,6 @@ module wallypipelinedcore (
 | 
			
		||||
  logic             InstrAccessFaultF;
 | 
			
		||||
  logic [2:0]             LSUBusSize;
 | 
			
		||||
  
 | 
			
		||||
  logic             ExceptionM;
 | 
			
		||||
  logic             DCacheMiss;
 | 
			
		||||
  logic             DCacheAccess;
 | 
			
		||||
  logic             ICacheMiss;
 | 
			
		||||
@ -168,10 +164,8 @@ module wallypipelinedcore (
 | 
			
		||||
  
 | 
			
		||||
  ifu ifu(
 | 
			
		||||
    .clk, .reset,
 | 
			
		||||
    .StallF, .StallD, .StallE, .StallM, .StallW,
 | 
			
		||||
    .FlushF, .FlushD, .FlushE, .FlushM, .FlushW,
 | 
			
		||||
 | 
			
		||||
    .ExceptionM,
 | 
			
		||||
    .StallF, .StallD, .StallE, .StallM, 
 | 
			
		||||
    .FlushF, .FlushD, .FlushE, .FlushM, 
 | 
			
		||||
    // Fetch
 | 
			
		||||
    .IFUBusHRDATA, .IFUBusAck, .PCF, .IFUBusAdr,
 | 
			
		||||
    .IFUBusRead, .IFUStallF,
 | 
			
		||||
@ -221,7 +215,6 @@ module wallypipelinedcore (
 | 
			
		||||
     // Memory stage interface
 | 
			
		||||
     .SquashSCW, // from LSU
 | 
			
		||||
     .MemRWM, // read/write control goes to LSU
 | 
			
		||||
     .AtomicE, // atomic control goes to LSU        
 | 
			
		||||
     .AtomicM, // atomic control goes to LSU
 | 
			
		||||
     .WriteDataE, // Write data to LSU
 | 
			
		||||
     .Funct3M, // size and signedness to LSU
 | 
			
		||||
@ -323,7 +316,7 @@ module wallypipelinedcore (
 | 
			
		||||
         .InstrM, .CSRReadValW, .PrivilegedNextPCM,
 | 
			
		||||
         .RetM, .TrapM, 
 | 
			
		||||
         .ITLBFlushF, .DTLBFlushM,
 | 
			
		||||
         .InstrValidM, .CommittedM, .DivE,
 | 
			
		||||
         .InstrValidM, .CommittedM, 
 | 
			
		||||
         .FRegWriteM, .LoadStallD,
 | 
			
		||||
         .BPPredDirWrongM, .BTBPredPCWrongM,
 | 
			
		||||
         .RASPredPCWrongM, .BPPredClassNonCFIWrongM,
 | 
			
		||||
@ -339,7 +332,7 @@ module wallypipelinedcore (
 | 
			
		||||
         // *** do these need to be split up into one for dmem and one for ifu?
 | 
			
		||||
         // instead, could we only care about the instr and F pins that come from ifu and only care about the load/store and m pins that come from dmem?
 | 
			
		||||
         .InstrAccessFaultF, .LoadAccessFaultM, .StoreAmoAccessFaultM, .SelHPTW,
 | 
			
		||||
         .ExceptionM, .IllegalFPUInstrE,
 | 
			
		||||
         .IllegalFPUInstrE,
 | 
			
		||||
         .PrivilegeModeW, .SATP_REGW,
 | 
			
		||||
         .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .STATUS_FS,
 | 
			
		||||
         .PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW, 
 | 
			
		||||
@ -360,7 +353,7 @@ module wallypipelinedcore (
 | 
			
		||||
         .clk, .reset,
 | 
			
		||||
         .ForwardedSrcAE, .ForwardedSrcBE, 
 | 
			
		||||
         .Funct3E, .Funct3M, .MDUE, .W64E,
 | 
			
		||||
         .MDUResultW, .DivBusyE,  .DivE,
 | 
			
		||||
         .MDUResultW, .DivBusyE,  
 | 
			
		||||
         .StallM, .StallW, .FlushM, .FlushW, .TrapM 
 | 
			
		||||
      ); 
 | 
			
		||||
   end else begin // no M instructions supported
 | 
			
		||||
 | 
			
		||||
@ -138,7 +138,7 @@ module testbench;
 | 
			
		||||
  `define RF dut.core.ieu.dp.regf.rf
 | 
			
		||||
  `define PC dut.core.ifu.pcreg.q
 | 
			
		||||
  `define PRIV_BASE   dut.core.priv.priv
 | 
			
		||||
  `define PRIV        `PRIV_BASE.privmodereg.q
 | 
			
		||||
  `define PRIV        `PRIV_BASE.privmode.privmode.privmodereg.q
 | 
			
		||||
  `define CSR_BASE    `PRIV_BASE.csr
 | 
			
		||||
  `define MEIP        `PRIV_BASE.MExtInt
 | 
			
		||||
  `define SEIP        `PRIV_BASE.SExtInt
 | 
			
		||||
@ -146,8 +146,8 @@ module testbench;
 | 
			
		||||
  `define HPMCOUNTER  `CSR_BASE.counters.counters.HPMCOUNTER_REGW
 | 
			
		||||
  `define MEDELEG     `CSR_BASE.csrm.deleg.MEDELEGreg.q
 | 
			
		||||
  `define MIDELEG     `CSR_BASE.csrm.deleg.MIDELEGreg.q
 | 
			
		||||
  `define MIE         `CSR_BASE.csri.IE_REGW
 | 
			
		||||
  `define MIP         `CSR_BASE.csri.IP_REGW_writeable
 | 
			
		||||
  `define MIE         `CSR_BASE.csri.MIE_REGW
 | 
			
		||||
  `define MIP         `CSR_BASE.csri.MIP_REGW_writeable
 | 
			
		||||
  `define MCAUSE      `CSR_BASE.csrm.MCAUSEreg.q
 | 
			
		||||
  `define SCAUSE      `CSR_BASE.csrs.csrs.SCAUSEreg.q
 | 
			
		||||
  `define MEPC        `CSR_BASE.csrm.MEPCreg.q
 | 
			
		||||
@ -692,8 +692,6 @@ module testbench;
 | 
			
		||||
            "sstatus": `checkCSR(`CSR_BASE.csrs.SSTATUS_REGW)
 | 
			
		||||
            "mtvec":   `checkCSR(`CSR_BASE.csrm.MTVEC_REGW)
 | 
			
		||||
            "mie":     `checkCSR(`CSR_BASE.csrm.MIE_REGW)
 | 
			
		||||
            "sip":     `checkCSR(`CSR_BASE.csrs.SIP_REGW)
 | 
			
		||||
            "sie":     `checkCSR(`CSR_BASE.csrs.SIE_REGW)
 | 
			
		||||
            "mideleg": `checkCSR(`CSR_BASE.csrm.MIDELEG_REGW)
 | 
			
		||||
            "medeleg": `checkCSR(`CSR_BASE.csrm.MEDELEG_REGW)
 | 
			
		||||
            "mepc":    `checkCSR(`CSR_BASE.csrm.MEPC_REGW)
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user