mirror of
				https://github.com/openhwgroup/cvw
				synced 2025-02-11 06:05:49 +00:00 
			
		
		
		
	Merge branch 'openhwgroup:main' into main
This commit is contained in:
		
						commit
						e711948369
					
				
							
								
								
									
										120
									
								
								src/fpu/fctrl.sv
									
									
									
									
									
								
							
							
						
						
									
										120
									
								
								src/fpu/fctrl.sv
									
									
									
									
									
								
							@ -75,44 +75,42 @@ module fctrl (
 | 
			
		||||
  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 [1:0]                 Fmt, Fmt2;          // format - before possible reduction
 | 
			
		||||
  logic                       SupportedFmt;       // is the format supported
 | 
			
		||||
  logic                       SupportedFmt2;      // is the source format supported for fp -> fp
 | 
			
		||||
  logic                       FCvtIntD, FCvtIntM; // convert to integer opperation
 | 
			
		||||
 | 
			
		||||
  // FPU Instruction Decoder
 | 
			
		||||
  assign Fmt = Funct7D[1:0];
 | 
			
		||||
  assign Fmt2 = Rs2D[1:0]; // source format for fcvt fp->fp
 | 
			
		||||
 | 
			
		||||
  // Note: only Fmt is checked; fcvt does not check destination format
 | 
			
		||||
  assign SupportedFmt = (Fmt == 2'b00 | (Fmt == 2'b01 & `D_SUPPORTED) |
 | 
			
		||||
                         (Fmt == 2'b10 & `ZFH_SUPPORTED) | (Fmt == 2'b11 & `Q_SUPPORTED));
 | 
			
		||||
  assign SupportedFmt2 = (Fmt2 == 2'b00 | (Fmt2 == 2'b01 & `D_SUPPORTED) |
 | 
			
		||||
                         (Fmt2 == 2'b10 & `ZFH_SUPPORTED) | (Fmt2 == 2'b11 & `Q_SUPPORTED));
 | 
			
		||||
 | 
			
		||||
  // decode the instruction                       
 | 
			
		||||
  always_comb
 | 
			
		||||
   // ControlsD: FRegWrite_FWriteInt_FResSel_PostProcSel_FOpCtrl_FDivStart_IllegalFPUInstr_FCvtInt
 | 
			
		||||
   always_comb
 | 
			
		||||
    if (STATUS_FS == 2'b00) // FPU instructions are illegal when FPU is disabled
 | 
			
		||||
      ControlsD = `FCTRLW'b0_0_00_xx_000_0_1_0;
 | 
			
		||||
    else if (OpD != 7'b0000111 & OpD != 7'b0100111 & ~SupportedFmt) 
 | 
			
		||||
      ControlsD = `FCTRLW'b0_0_00_xx_000_0_1_0; // for anything other than loads and stores, check for supported format
 | 
			
		||||
    else case(OpD)
 | 
			
		||||
    // FRegWrite_FWriteInt_FResSel_PostProcSel_FOpCtrl_FDivStart_IllegalFPUInstr_FCvtInt
 | 
			
		||||
    else begin
 | 
			
		||||
      ControlsD = `FCTRLW'b0_0_00_xx_0xx_0_1_0; // default: illegal FPU instruction
 | 
			
		||||
      /* verilator lint_off CASEINCOMPLETE */ // default value above has priority so no other default needed
 | 
			
		||||
      case(OpD)
 | 
			
		||||
      7'b0000111: case(Funct3D)
 | 
			
		||||
                    3'b010:                      ControlsD = `FCTRLW'b1_0_10_xx_0xx_0_0_0; // flw
 | 
			
		||||
                    3'b011:  if (`D_SUPPORTED)   ControlsD = `FCTRLW'b1_0_10_xx_0xx_0_0_0; // fld
 | 
			
		||||
                             else                ControlsD = `FCTRLW'b0_0_00_xx_0xx_0_1_0; // fld not supported
 | 
			
		||||
                    3'b100:  if (`Q_SUPPORTED)   ControlsD = `FCTRLW'b1_0_10_xx_0xx_0_0_0; // flq
 | 
			
		||||
                             else                ControlsD = `FCTRLW'b0_0_00_xx_0xx_0_1_0; // flq not supported
 | 
			
		||||
                    3'b001:  if (`ZFH_SUPPORTED) ControlsD = `FCTRLW'b1_0_10_xx_0xx_0_0_0; // flh
 | 
			
		||||
                             else                ControlsD = `FCTRLW'b0_0_00_xx_0xx_0_1_0; // flh not supported
 | 
			
		||||
                    default:                     ControlsD = `FCTRLW'b0_0_00_xx_000_0_1_0; // non-implemented instruction
 | 
			
		||||
                  endcase
 | 
			
		||||
      7'b0100111: case(Funct3D)
 | 
			
		||||
                    3'b010:                      ControlsD = `FCTRLW'b0_0_10_xx_0xx_0_0_0; // fsw
 | 
			
		||||
                    3'b011:  if (`D_SUPPORTED)   ControlsD = `FCTRLW'b0_0_10_xx_0xx_0_0_0; // fsd
 | 
			
		||||
                             else                ControlsD = `FCTRLW'b0_0_00_xx_0xx_0_1_0; // fsd not supported
 | 
			
		||||
                    3'b100:  if (`Q_SUPPORTED)   ControlsD = `FCTRLW'b0_0_10_xx_0xx_0_0_0; // fsq
 | 
			
		||||
                             else                ControlsD = `FCTRLW'b0_0_00_xx_0xx_0_1_0; // fsq not supported
 | 
			
		||||
                    3'b001:  if (`ZFH_SUPPORTED) ControlsD = `FCTRLW'b0_0_10_xx_0xx_0_0_0; // fsh
 | 
			
		||||
                             else                ControlsD = `FCTRLW'b0_0_00_xx_0xx_0_1_0; // fsh not supported
 | 
			
		||||
                    default:                     ControlsD = `FCTRLW'b0_0_00_xx_000_0_1_0; // non-implemented instruction
 | 
			
		||||
                  endcase
 | 
			
		||||
      7'b1000011:   ControlsD = `FCTRLW'b1_0_01_10_000_0_0_0; // fmadd
 | 
			
		||||
      7'b1000111:   ControlsD = `FCTRLW'b1_0_01_10_001_0_0_0; // fmsub
 | 
			
		||||
@ -128,56 +126,82 @@ module fctrl (
 | 
			
		||||
                                  3'b000:  ControlsD = `FCTRLW'b1_0_00_xx_000_0_0_0; // fsgnj
 | 
			
		||||
                                  3'b001:  ControlsD = `FCTRLW'b1_0_00_xx_001_0_0_0; // fsgnjn
 | 
			
		||||
                                  3'b010:  ControlsD = `FCTRLW'b1_0_00_xx_010_0_0_0; // fsgnjx
 | 
			
		||||
                                  default: ControlsD = `FCTRLW'b0_0_00_xx_000_0_1_0; // non-implemented instruction
 | 
			
		||||
                                endcase
 | 
			
		||||
                               endcase
 | 
			
		||||
                    7'b00101??: case(Funct3D)
 | 
			
		||||
                                  3'b000:  ControlsD = `FCTRLW'b1_0_00_xx_110_0_0_0; // fmin
 | 
			
		||||
                                  3'b001:  ControlsD = `FCTRLW'b1_0_00_xx_101_0_0_0; // fmax
 | 
			
		||||
                                  default: ControlsD = `FCTRLW'b0_0_00_xx_000_0_1_0; // non-implemented instruction
 | 
			
		||||
                                endcase
 | 
			
		||||
                    7'b10100??: case(Funct3D)
 | 
			
		||||
                                  3'b010:  ControlsD = `FCTRLW'b0_1_00_xx_010_0_0_0; // feq
 | 
			
		||||
                                  3'b001:  ControlsD = `FCTRLW'b0_1_00_xx_001_0_0_0; // flt
 | 
			
		||||
                                  3'b000:  ControlsD = `FCTRLW'b0_1_00_xx_011_0_0_0; // fle
 | 
			
		||||
                                  default: ControlsD = `FCTRLW'b0_0_00_xx_000__0_1_0; // non-implemented instruction
 | 
			
		||||
                                endcase
 | 
			
		||||
                    7'b11100??: if (Funct3D == 3'b001 & Rs2D == 5'b00000)          
 | 
			
		||||
                                                                ControlsD = `FCTRLW'b0_1_10_xx_000_0_0_0; // fclass
 | 
			
		||||
                                else if (Funct3D[1:0] == 2'b00) ControlsD = `FCTRLW'b0_1_11_xx_000_0_0_0; // fmv.x.w   to int reg
 | 
			
		||||
                                else if (Funct3D[1:0] == 2'b01) ControlsD = `FCTRLW'b0_1_11_xx_000_0_0_0; // fmv.x.d   to int reg
 | 
			
		||||
                                else                            ControlsD = `FCTRLW'b0_0_00_xx_000_0_1_0; // non-implemented instruction
 | 
			
		||||
                    7'b1101000: case(Rs2D[1:0])
 | 
			
		||||
                                  2'b00:    ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0; // fcvt.s.w   w->s
 | 
			
		||||
                                  2'b01:    ControlsD = `FCTRLW'b1_0_01_00_100_0_0_0; // fcvt.s.wu wu->s
 | 
			
		||||
                                  2'b10:    ControlsD = `FCTRLW'b1_0_01_00_111_0_0_0; // fcvt.s.l   l->s
 | 
			
		||||
                                  2'b11:    ControlsD = `FCTRLW'b1_0_01_00_110_0_0_0; // fcvt.s.lu lu->s
 | 
			
		||||
                                               ControlsD = `FCTRLW'b0_1_10_xx_000_0_0_0; // fclass
 | 
			
		||||
                                else if (Funct3D == 3'b000 & Rs2D == 5'b00000) 
 | 
			
		||||
                                               ControlsD = `FCTRLW'b0_1_11_xx_000_0_0_0; // fmv.x.w / fmv.x.d to int register
 | 
			
		||||
                    7'b111100?: if (Funct3D == 3'b000 & Rs2D == 5'b00000) 
 | 
			
		||||
                                               ControlsD = `FCTRLW'b1_0_00_xx_011_0_0_0; // fmv.w.x / fmv.d.x   to fp reg
 | 
			
		||||
                    7'b0100000: if (Rs2D[4:2] == 3'b000 & SupportedFmt2 & Rs2D[1:0] != 2'b00)
 | 
			
		||||
                                               ControlsD = `FCTRLW'b1_0_01_00_000_0_0_0; // fcvt.s.(d/q/h)
 | 
			
		||||
                    7'b0100001: if (Rs2D[4:2] == 3'b000  & SupportedFmt2 & Rs2D[1:0] != 2'b01)
 | 
			
		||||
                                               ControlsD = `FCTRLW'b1_0_01_00_001_0_0_0; // fcvt.d.(s/h/q)
 | 
			
		||||
                    7'b0100010: if (Rs2D[4:2] == 3'b000 & SupportedFmt2 & Rs2D[1:0] != 2'b10)
 | 
			
		||||
                                               ControlsD = `FCTRLW'b1_0_01_00_010_0_0_0; // fcvt.h.(s/d/q)
 | 
			
		||||
                    7'b0100011: if (Rs2D[4:2] == 3'b000  & SupportedFmt2 & Rs2D[1:0] != 2'b11)
 | 
			
		||||
                                               ControlsD = `FCTRLW'b1_0_01_00_011_0_0_0; // fcvt.q.(s/h/d)
 | 
			
		||||
                   7'b1101000: case(Rs2D)
 | 
			
		||||
                                  5'b00000:    ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0; // fcvt.s.w   w->s
 | 
			
		||||
                                  5'b00001:    ControlsD = `FCTRLW'b1_0_01_00_100_0_0_0; // fcvt.s.wu wu->s
 | 
			
		||||
                                  5'b00010:    ControlsD = `FCTRLW'b1_0_01_00_111_0_0_0; // fcvt.s.l   l->s
 | 
			
		||||
                                  5'b00011:    ControlsD = `FCTRLW'b1_0_01_00_110_0_0_0; // fcvt.s.lu lu->s
 | 
			
		||||
                                endcase
 | 
			
		||||
                    7'b1100000: case(Rs2D[1:0])
 | 
			
		||||
                                  2'b00:    ControlsD = `FCTRLW'b0_1_01_00_001_0_0_1; // fcvt.w.s   s->w
 | 
			
		||||
                                  2'b01:    ControlsD = `FCTRLW'b0_1_01_00_000_0_0_1; // fcvt.wu.s  s->wu
 | 
			
		||||
                                  2'b10:    ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1; // fcvt.l.s   s->l
 | 
			
		||||
                                  2'b11:    ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1; // fcvt.lu.s  s->lu
 | 
			
		||||
                    7'b1100000: case(Rs2D)
 | 
			
		||||
                                  5'b00000:    ControlsD = `FCTRLW'b0_1_01_00_001_0_0_1; // fcvt.w.s   s->w
 | 
			
		||||
                                  5'b00001:    ControlsD = `FCTRLW'b0_1_01_00_000_0_0_1; // fcvt.wu.s  s->wu
 | 
			
		||||
                                  5'b00010:    ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1; // fcvt.l.s   s->l
 | 
			
		||||
                                  5'b00011:    ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1; // fcvt.lu.s  s->lu
 | 
			
		||||
                                endcase
 | 
			
		||||
                    7'b1111000: ControlsD = `FCTRLW'b1_0_00_xx_011_0_0_0; // fmv.w.x   to fp reg
 | 
			
		||||
                    7'b0100000: ControlsD = `FCTRLW'b1_0_01_00_000_0_0_0; // fcvt.s.d
 | 
			
		||||
                    7'b1101001: case(Rs2D[1:0])
 | 
			
		||||
                                  2'b00:    ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0; // fcvt.d.w   w->d
 | 
			
		||||
                                  2'b01:    ControlsD = `FCTRLW'b1_0_01_00_100_0_0_0; // fcvt.d.wu wu->d
 | 
			
		||||
                                  2'b10:    ControlsD = `FCTRLW'b1_0_01_00_111_0_0_0; // fcvt.d.l   l->d
 | 
			
		||||
                                  2'b11:    ControlsD = `FCTRLW'b1_0_01_00_110_0_0_0; // fcvt.d.lu lu->d
 | 
			
		||||
                    7'b1101001: case(Rs2D)
 | 
			
		||||
                                  5'b00000:    ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0; // fcvt.d.w   w->d
 | 
			
		||||
                                  5'b00001:    ControlsD = `FCTRLW'b1_0_01_00_100_0_0_0; // fcvt.d.wu wu->d
 | 
			
		||||
                                  5'b00010:    ControlsD = `FCTRLW'b1_0_01_00_111_0_0_0; // fcvt.d.l   l->d
 | 
			
		||||
                                  5'b00011:    ControlsD = `FCTRLW'b1_0_01_00_110_0_0_0; // fcvt.d.lu lu->d
 | 
			
		||||
                                endcase
 | 
			
		||||
                    7'b1100001: case(Rs2D[1:0])
 | 
			
		||||
                                  2'b00:    ControlsD = `FCTRLW'b0_1_01_00_001_0_0_1; // fcvt.w.d   d->w
 | 
			
		||||
                                  2'b01:    ControlsD = `FCTRLW'b0_1_01_00_000_0_0_1; // fcvt.wu.d  d->wu
 | 
			
		||||
                                  2'b10:    ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1; // fcvt.l.d   d->l
 | 
			
		||||
                                  2'b11:    ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1; // fcvt.lu.d  d->lu
 | 
			
		||||
                    7'b1100001: case(Rs2D)
 | 
			
		||||
                                  5'b00000:    ControlsD = `FCTRLW'b0_1_01_00_001_0_0_1; // fcvt.w.d   d->w
 | 
			
		||||
                                  5'b00001:    ControlsD = `FCTRLW'b0_1_01_00_000_0_0_1; // fcvt.wu.d  d->wu
 | 
			
		||||
                                  5'b00010:    ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1; // fcvt.l.d   d->l
 | 
			
		||||
                                  5'b00011:    ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1; // fcvt.lu.d  d->lu
 | 
			
		||||
                                endcase
 | 
			
		||||
                    7'b1111001: ControlsD = `FCTRLW'b1_0_00_xx_011_0_0_0; // fmv.d.x   to fp reg
 | 
			
		||||
                    7'b0100001: ControlsD = `FCTRLW'b1_0_01_00_001_0_0_0; // fcvt.d.s
 | 
			
		||||
                    default:    ControlsD = `FCTRLW'b0_0_00_xx_000_0_1_0; // non-implemented instruction
 | 
			
		||||
                    7'b1101010: case(Rs2D)
 | 
			
		||||
                                  5'b00000:    ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0; // fcvt.h.w   w->h
 | 
			
		||||
                                  5'b00001:    ControlsD = `FCTRLW'b1_0_01_00_100_0_0_0; // fcvt.h.wu wu->h
 | 
			
		||||
                                  5'b00010:    ControlsD = `FCTRLW'b1_0_01_00_111_0_0_0; // fcvt.h.l   l->h
 | 
			
		||||
                                  5'b00011:    ControlsD = `FCTRLW'b1_0_01_00_110_0_0_0; // fcvt.h.lu lu->h
 | 
			
		||||
                                endcase
 | 
			
		||||
                    7'b1100010: case(Rs2D)
 | 
			
		||||
                                  5'b00000:    ControlsD = `FCTRLW'b0_1_01_00_001_0_0_1; // fcvt.w.h   h->w
 | 
			
		||||
                                  5'b00001:    ControlsD = `FCTRLW'b0_1_01_00_000_0_0_1; // fcvt.wu.h  h->wu
 | 
			
		||||
                                  5'b00010:    ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1; // fcvt.l.h   h->l
 | 
			
		||||
                                  5'b00011:    ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1; // fcvt.lu.h  h->lu
 | 
			
		||||
                                endcase
 | 
			
		||||
                    7'b1101011: case(Rs2D)
 | 
			
		||||
                                  5'b00000:    ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0; // fcvt.q.w   w->q
 | 
			
		||||
                                  5'b00001:    ControlsD = `FCTRLW'b1_0_01_00_100_0_0_0; // fcvt.q.wu wu->q
 | 
			
		||||
                                  5'b00010:    ControlsD = `FCTRLW'b1_0_01_00_111_0_0_0; // fcvt.q.l   l->q
 | 
			
		||||
                                  5'b00011:    ControlsD = `FCTRLW'b1_0_01_00_110_0_0_0; // fcvt.q.lu lu->q
 | 
			
		||||
                                endcase
 | 
			
		||||
                    7'b1100011: case(Rs2D)
 | 
			
		||||
                                  5'b00000:    ControlsD = `FCTRLW'b0_1_01_00_001_0_0_1; // fcvt.w.q   q->w
 | 
			
		||||
                                  5'b00001:    ControlsD = `FCTRLW'b0_1_01_00_000_0_0_1; // fcvt.wu.q  q->wu
 | 
			
		||||
                                  5'b00010:    ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1; // fcvt.l.q   q->l
 | 
			
		||||
                                  5'b00011:    ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1; // fcvt.lu.q  q->lu
 | 
			
		||||
                                endcase                            
 | 
			
		||||
                  endcase
 | 
			
		||||
      default:      ControlsD = `FCTRLW'b0_0_00_xx_000_0_1_0; // non-implemented instruction
 | 
			
		||||
    endcase
 | 
			
		||||
      endcase
 | 
			
		||||
      /* verilator lint_off CASEINCOMPLETE */
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
  // unswizzle control bits
 | 
			
		||||
  assign #1 {FRegWriteD, FWriteIntD, FResSelD, PostProcSelD, OpCtrlD, FDivStartD, IllegalFPUInstrD, FCvtIntD} = ControlsD;
 | 
			
		||||
 | 
			
		||||
@ -37,7 +37,7 @@ module alu #(parameter WIDTH=32) (
 | 
			
		||||
  input  logic [1:0]       BSelect,     // Binary encoding of if it's a ZBA_ZBB_ZBC_ZBS instruction
 | 
			
		||||
  input  logic [2:0]       ZBBSelect,   // ZBB mux select signal
 | 
			
		||||
  input  logic [2:0]       Funct3,      // For BMU decoding
 | 
			
		||||
  input  logic [1:0]       CompFlags,   // Comparator flags
 | 
			
		||||
  input  logic             CompLT,      // Less-Than flag from comparator
 | 
			
		||||
  input  logic [2:0]       BALUControl, // ALU Control signals for B instructions in Execute Stage
 | 
			
		||||
  output logic [WIDTH-1:0] Result,      // ALU result
 | 
			
		||||
  output logic [WIDTH-1:0] Sum);        // Sum of operands
 | 
			
		||||
@ -90,7 +90,7 @@ module alu #(parameter WIDTH=32) (
 | 
			
		||||
  // Final Result B instruction select mux
 | 
			
		||||
  if (`ZBC_SUPPORTED | `ZBS_SUPPORTED | `ZBA_SUPPORTED | `ZBB_SUPPORTED) begin : bitmanipalu
 | 
			
		||||
    bitmanipalu #(WIDTH) balu(.A, .B, .W64, .BSelect, .ZBBSelect, 
 | 
			
		||||
      .Funct3, .CompFlags, .BALUControl, .ALUResult, .FullResult,
 | 
			
		||||
      .Funct3, .CompLT, .BALUControl, .ALUResult, .FullResult,
 | 
			
		||||
      .CondMaskB, .CondShiftA, .Result);
 | 
			
		||||
  end else begin
 | 
			
		||||
    assign Result = ALUResult;
 | 
			
		||||
 | 
			
		||||
@ -35,7 +35,7 @@ module bitmanipalu #(parameter WIDTH=32) (
 | 
			
		||||
  input  logic [1:0]       BSelect,                 // Binary encoding of if it's a ZBA_ZBB_ZBC_ZBS instruction
 | 
			
		||||
  input  logic [2:0]       ZBBSelect,               // ZBB mux select signal
 | 
			
		||||
  input  logic [2:0]       Funct3,                  // Funct3 field of opcode indicates operation to perform
 | 
			
		||||
  input  logic [1:0]       CompFlags,               // Comparator flags
 | 
			
		||||
  input  logic             CompLT,                  // Less-Than flag from comparator
 | 
			
		||||
  input  logic [2:0]       BALUControl,             // ALU Control signals for B instructions in Execute Stage
 | 
			
		||||
  input  logic [WIDTH-1:0] ALUResult, FullResult,   // ALUResult, FullResult signals
 | 
			
		||||
  output logic [WIDTH-1:0] CondMaskB,               // B is conditionally masked for ZBS instructions
 | 
			
		||||
@ -84,7 +84,7 @@ module bitmanipalu #(parameter WIDTH=32) (
 | 
			
		||||
 | 
			
		||||
  // ZBB Unit
 | 
			
		||||
  if (`ZBB_SUPPORTED) begin: zbb
 | 
			
		||||
    zbb #(WIDTH) ZBB(.A, .RevA, .B, .ALUResult, .W64, .lt(CompFlags[0]), .ZBBSelect, .ZBBResult);
 | 
			
		||||
    zbb #(WIDTH) ZBB(.A, .RevA, .B, .W64, .lt(CompLT), .ZBBSelect, .ZBBResult);
 | 
			
		||||
  end else assign ZBBResult = 0;
 | 
			
		||||
 | 
			
		||||
  // Result Select Mux
 | 
			
		||||
 | 
			
		||||
@ -32,7 +32,7 @@
 | 
			
		||||
 | 
			
		||||
module cnt #(parameter WIDTH = 32) (
 | 
			
		||||
  input  logic [WIDTH-1:0] A, RevA,    // Operands
 | 
			
		||||
  input  logic [4:0] B,                // Last 5 bits of immediate
 | 
			
		||||
  input  logic [1:0] B,                // Last 2 bits of immediate
 | 
			
		||||
  input  logic W64,                    // Indicates word operation
 | 
			
		||||
  output logic [WIDTH-1:0] CntResult   // count result
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
@ -32,18 +32,17 @@
 | 
			
		||||
 | 
			
		||||
module zbb #(parameter WIDTH=32) (
 | 
			
		||||
  input  logic [WIDTH-1:0] A, RevA, B,   // Operands
 | 
			
		||||
  input  logic [WIDTH-1:0] ALUResult,    // ALU Result
 | 
			
		||||
  input  logic             W64,          // Indicates word operation
 | 
			
		||||
  input  logic             lt,           // lt flag
 | 
			
		||||
  input  logic [2:0]       ZBBSelect,    // Indicates word operation
 | 
			
		||||
  input  logic [2:0]       ZBBSelect,    // ZBB Result select signal
 | 
			
		||||
  output logic [WIDTH-1:0] ZBBResult);   // ZBB result
 | 
			
		||||
  
 | 
			
		||||
  logic [WIDTH-1:0] CntResult;           // count result
 | 
			
		||||
  logic [WIDTH-1:0] MinMaxResult;        // min,max result
 | 
			
		||||
  logic [WIDTH-1:0] MinMaxResult;        // min, max result
 | 
			
		||||
  logic [WIDTH-1:0] ByteResult;          // byte results
 | 
			
		||||
  logic [WIDTH-1:0] ExtResult;           // sign/zero extend results
 | 
			
		||||
 | 
			
		||||
  cnt #(WIDTH) cnt(.A, .RevA, .B(B[4:0]), .W64, .CntResult);
 | 
			
		||||
  cnt #(WIDTH) cnt(.A, .RevA, .B(B[1:0]), .W64, .CntResult);
 | 
			
		||||
  byteUnit #(WIDTH) bu(.A, .ByteSelect(B[0]), .ByteResult);
 | 
			
		||||
  ext #(WIDTH) ext(.A, .ExtSelect({~B[2], {B[2] & B[0]}}), .ExtResult);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -131,6 +131,7 @@ module controller(
 | 
			
		||||
  logic        JFunctD;                        // detect jalr instruction
 | 
			
		||||
  logic        FenceM;                         // Fence.I or sfence.VMA instruction in memory stage
 | 
			
		||||
  logic [2:0]  ALUSelectD;                     // ALU Output selection mux control
 | 
			
		||||
  logic        IWValidFunct3D;                 // Detects if Funct3 is valid for IW instructions
 | 
			
		||||
 | 
			
		||||
  // Extract fields
 | 
			
		||||
  assign OpD = InstrD[6:0];
 | 
			
		||||
@ -161,6 +162,7 @@ module controller(
 | 
			
		||||
                              ((`XLEN == 64) & (Funct3D == 3'b011));
 | 
			
		||||
    assign BFunctD          = (Funct3D[2:1] != 2'b01); // legal branches
 | 
			
		||||
    assign JFunctD          = (Funct3D == 3'b000);
 | 
			
		||||
    assign IWValidFunct3D   = Funct3D == 3'b000 | Funct3D == 3'b001 | Funct3D == 3'b101;
 | 
			
		||||
  end else begin:legalcheck2
 | 
			
		||||
    assign IFunctD = 1; // Don't bother to separate out shift decoding
 | 
			
		||||
    assign RFunctD = ~Funct7D[0]; // Not a multiply
 | 
			
		||||
@ -168,7 +170,8 @@ module controller(
 | 
			
		||||
    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 JFunctD = 1; // don't bother to check Funct3 for jumps
 | 
			
		||||
    assign IWValidFunct3D = 1;
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  // Main Instruction Decoder
 | 
			
		||||
@ -187,7 +190,7 @@ module controller(
 | 
			
		||||
      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
 | 
			
		||||
      7'b0010111:     ControlsD = `CTRLW'b1_100_11_00_000_0_0_0_0_0_0_0_0_0_00_0; // auipc
 | 
			
		||||
      7'b0011011: if (IFunctD & `XLEN == 64)
 | 
			
		||||
      7'b0011011: if (IFunctD & IWValidFunct3D & `XLEN == 64)
 | 
			
		||||
                      ControlsD = `CTRLW'b1_000_01_00_000_0_1_0_0_1_0_0_0_0_00_0; // IW-type ALU for RV64i
 | 
			
		||||
      7'b0100011: if (SFunctD) 
 | 
			
		||||
                      ControlsD = `CTRLW'b0_001_01_01_000_0_0_0_0_0_0_0_0_0_00_0; // stores
 | 
			
		||||
 | 
			
		||||
@ -114,7 +114,7 @@ module datapath (
 | 
			
		||||
  comparator #(`XLEN) comp(ForwardedSrcAE, ForwardedSrcBE, BranchSignedE, FlagsE);
 | 
			
		||||
  mux2  #(`XLEN)  srcamux(ForwardedSrcAE, PCE, ALUSrcAE, SrcAE);
 | 
			
		||||
  mux2  #(`XLEN)  srcbmux(ForwardedSrcBE, ImmExtE, ALUSrcBE, SrcBE);
 | 
			
		||||
  alu   #(`XLEN)  alu(SrcAE, SrcBE, W64E, SubArithE, ALUSelectE, BSelectE, ZBBSelectE, Funct3E, FlagsE, BALUControlE, ALUResultE, IEUAdrE);
 | 
			
		||||
  alu   #(`XLEN)  alu(SrcAE, SrcBE, W64E, SubArithE, ALUSelectE, BSelectE, ZBBSelectE, Funct3E, FlagsE[0], BALUControlE, ALUResultE, IEUAdrE);
 | 
			
		||||
  mux2 #(`XLEN)   altresultmux(ImmExtE, PCLinkE, JumpE, AltResultE);
 | 
			
		||||
  mux2 #(`XLEN)   ieuresultmux(ALUResultE, AltResultE, ALUResultSrcE, IEUResultE);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -55,7 +55,7 @@ module csr #(parameter
 | 
			
		||||
  input  logic [4:0]       SetFflagsM,                // Set floating point flag bits in FCSR
 | 
			
		||||
  input  logic [1:0]       NextPrivilegeModeM,        // STATUS bits updated based on next privilege mode
 | 
			
		||||
  input  logic [1:0]       PrivilegeModeW,            // current privilege mode
 | 
			
		||||
  input  logic [`LOG_XLEN-1:0] CauseM,                // Trap cause
 | 
			
		||||
  input  logic [3:0]       CauseM,                    // Trap cause
 | 
			
		||||
  input  logic             SelHPTW,                   // hardware page table walker active, so base endianness on supervisor mode
 | 
			
		||||
  // inputs for performance counters
 | 
			
		||||
  input  logic             LoadStallD,
 | 
			
		||||
@ -79,7 +79,7 @@ module csr #(parameter
 | 
			
		||||
  // outputs from CSRs
 | 
			
		||||
  output logic [1:0]       STATUS_MPP,
 | 
			
		||||
  output logic             STATUS_SPP, STATUS_TSR, STATUS_TVM,
 | 
			
		||||
  output logic [`XLEN-1:0] MEDELEG_REGW, 
 | 
			
		||||
  output logic [15:0] MEDELEG_REGW, 
 | 
			
		||||
  output logic [`XLEN-1:0] SATP_REGW,
 | 
			
		||||
  output logic [11:0]      MIP_REGW, MIE_REGW, MIDELEG_REGW,
 | 
			
		||||
  output logic             STATUS_MIE, STATUS_SIE,
 | 
			
		||||
@ -107,7 +107,8 @@ module csr #(parameter
 | 
			
		||||
  logic                    WriteMSTATUSM, WriteMSTATUSHM, WriteSSTATUSM;
 | 
			
		||||
  logic                    CSRMWriteM, CSRSWriteM, CSRUWriteM;
 | 
			
		||||
  logic                    WriteFRMM, WriteFFLAGSM;
 | 
			
		||||
  logic [`XLEN-1:0]        UnalignedNextEPCM, NextEPCM, NextCauseM, NextMtvalM;
 | 
			
		||||
  logic [`XLEN-1:0]        UnalignedNextEPCM, NextEPCM, NextMtvalM;
 | 
			
		||||
  logic [4:0]              NextCauseM;
 | 
			
		||||
  logic [11:0]             CSRAdrM;
 | 
			
		||||
  logic                    IllegalCSRCAccessM, IllegalCSRMAccessM, IllegalCSRSAccessM, IllegalCSRUAccessM;
 | 
			
		||||
  logic                    InsufficientCSRPrivilegeM;
 | 
			
		||||
@ -153,7 +154,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, 2'b00}; // 64-byte alignment allows concatenation rather than addition
 | 
			
		||||
    mux2 #(`XLEN) trapvecmux(TVecAlignedM, TVecPlusCauseM, VectoredM, TrapVectorM);
 | 
			
		||||
  end else 
 | 
			
		||||
    assign TrapVectorM = TVecAlignedM;
 | 
			
		||||
@ -196,7 +197,7 @@ module csr #(parameter
 | 
			
		||||
  assign CSRAdrM = InstrM[31:20];
 | 
			
		||||
  assign UnalignedNextEPCM = TrapM ? ((wfiM & IntPendingM) ? PCM+4 : PCM) : CSRWriteValM;
 | 
			
		||||
  assign NextEPCM = `C_SUPPORTED ? {UnalignedNextEPCM[`XLEN-1:1], 1'b0} : {UnalignedNextEPCM[`XLEN-1:2], 2'b00}; // 3.1.15 alignment
 | 
			
		||||
  assign NextCauseM = TrapM ? {InterruptM, {(`XLEN-`LOG_XLEN-1){1'b0}}, CauseM}: CSRWriteValM;
 | 
			
		||||
  assign NextCauseM = TrapM ? {InterruptM, CauseM}: {CSRWriteValM[`XLEN-1], CSRWriteValM[3:0]};
 | 
			
		||||
  assign NextMtvalM = TrapM ? NextFaultMtvalM : CSRWriteValM;
 | 
			
		||||
  assign CSRMWriteM = CSRWriteM & (PrivilegeModeW == `M_MODE);
 | 
			
		||||
  assign CSRSWriteM = CSRWriteM & (|PrivilegeModeW);
 | 
			
		||||
 | 
			
		||||
@ -69,20 +69,21 @@ module csrm #(parameter
 | 
			
		||||
  DSCRATCH1 = 12'h7B3,
 | 
			
		||||
  // Constants
 | 
			
		||||
  ZERO = {(`XLEN){1'b0}},
 | 
			
		||||
  MEDELEG_MASK = ~(ZERO | `XLEN'b1 << 11),
 | 
			
		||||
  MEDELEG_MASK = 16'hB3FF,
 | 
			
		||||
  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]        NextEPCM, NextMtvalM, MSTATUS_REGW, MSTATUSH_REGW,
 | 
			
		||||
  input  logic [4:0]              NextCauseM,
 | 
			
		||||
  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 [15: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],
 | 
			
		||||
@ -91,8 +92,7 @@ module csrm #(parameter
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
  logic [`XLEN-1:0]               MISA_REGW, MHARTID_REGW;
 | 
			
		||||
  logic [`XLEN-1:0]               MSCRATCH_REGW;
 | 
			
		||||
  logic [`XLEN-1:0]               MCAUSE_REGW, MTVAL_REGW;
 | 
			
		||||
  logic [`XLEN-1:0]               MSCRATCH_REGW, MTVAL_REGW, MCAUSE_REGW;
 | 
			
		||||
  logic                           WriteMTVECM, WriteMEDELEGM, WriteMIDELEGM;
 | 
			
		||||
  logic                           WriteMSCRATCHM, WriteMEPCM, WriteMCAUSEM, WriteMTVALM;
 | 
			
		||||
  logic                           WriteMCOUNTERENM, WriteMCOUNTINHIBITM;
 | 
			
		||||
@ -150,13 +150,13 @@ module csrm #(parameter
 | 
			
		||||
  // CSRs
 | 
			
		||||
  flopenr #(`XLEN) MTVECreg(clk, reset, WriteMTVECM, {CSRWriteValM[`XLEN-1:2], 1'b0, CSRWriteValM[0]}, MTVEC_REGW); 
 | 
			
		||||
  if (`S_SUPPORTED) begin:deleg // DELEG registers should exist
 | 
			
		||||
    flopenr #(`XLEN) MEDELEGreg(clk, reset, WriteMEDELEGM, CSRWriteValM & MEDELEG_MASK, MEDELEG_REGW);
 | 
			
		||||
    flopenr #(12)    MIDELEGreg(clk, reset, WriteMIDELEGM, CSRWriteValM[11:0] & MIDELEG_MASK, MIDELEG_REGW);
 | 
			
		||||
    flopenr #(16) MEDELEGreg(clk, reset, WriteMEDELEGM, CSRWriteValM[15:0] & MEDELEG_MASK, MEDELEG_REGW);
 | 
			
		||||
    flopenr #(12) MIDELEGreg(clk, reset, WriteMIDELEGM, CSRWriteValM[11:0] & MIDELEG_MASK, MIDELEG_REGW);
 | 
			
		||||
  end else assign {MEDELEG_REGW, MIDELEG_REGW} = 0;
 | 
			
		||||
 | 
			
		||||
  flopenr #(`XLEN) MSCRATCHreg(clk, reset, WriteMSCRATCHM, CSRWriteValM, MSCRATCH_REGW);
 | 
			
		||||
  flopenr #(`XLEN) MEPCreg(clk, reset, WriteMEPCM, NextEPCM, MEPC_REGW); 
 | 
			
		||||
  flopenr #(`XLEN) MCAUSEreg(clk, reset, WriteMCAUSEM, NextCauseM, MCAUSE_REGW);
 | 
			
		||||
  flopenr #(`XLEN) MCAUSEreg(clk, reset, WriteMCAUSEM, {NextCauseM[4], {(`XLEN-5){1'b0}}, NextCauseM[3:0]}, MCAUSE_REGW);
 | 
			
		||||
  if(`QEMU) assign MTVAL_REGW = `XLEN'b0; // MTVAL tied to 0 in QEMU configuration
 | 
			
		||||
  else flopenr #(`XLEN) MTVALreg(clk, reset, WriteMTVALM, NextMtvalM, MTVAL_REGW);
 | 
			
		||||
  flopenr #(32)   MCOUNTINHIBITreg(clk, reset, WriteMCOUNTINHIBITM, CSRWriteValM[31:0], MCOUNTINHIBIT_REGW);
 | 
			
		||||
@ -192,7 +192,7 @@ module csrm #(parameter
 | 
			
		||||
      MSTATUS:   CSRMReadValM = MSTATUS_REGW;
 | 
			
		||||
      MSTATUSH:  CSRMReadValM = MSTATUSH_REGW; 
 | 
			
		||||
      MTVEC:     CSRMReadValM = MTVEC_REGW;
 | 
			
		||||
      MEDELEG:   CSRMReadValM = MEDELEG_REGW;
 | 
			
		||||
      MEDELEG:   CSRMReadValM = {{(`XLEN-16){1'b0}}, MEDELEG_REGW};
 | 
			
		||||
      MIDELEG:   CSRMReadValM = {{(`XLEN-12){1'b0}}, MIDELEG_REGW};
 | 
			
		||||
      MIP:       CSRMReadValM = {{(`XLEN-12){1'b0}}, MIP_REGW};
 | 
			
		||||
      MIE:       CSRMReadValM = {{(`XLEN-12){1'b0}}, MIE_REGW};
 | 
			
		||||
 | 
			
		||||
@ -48,7 +48,8 @@ module csrs #(parameter
 | 
			
		||||
  input  logic             InstrValidNotFlushedM, 
 | 
			
		||||
  input  logic             CSRSWriteM, STrapM,
 | 
			
		||||
  input  logic [11:0]      CSRAdrM,
 | 
			
		||||
  input  logic [`XLEN-1:0] NextEPCM, NextCauseM, NextMtvalM, SSTATUS_REGW, 
 | 
			
		||||
  input  logic [`XLEN-1:0] NextEPCM, NextMtvalM, SSTATUS_REGW, 
 | 
			
		||||
  input  logic [4:0]       NextCauseM,
 | 
			
		||||
  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,
 | 
			
		||||
@ -72,8 +73,7 @@ module csrs #(parameter
 | 
			
		||||
  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 [`XLEN-1:0]        SSCRATCH_REGW, STVAL_REGW, SCAUSE_REGW;
 | 
			
		||||
  logic [63:0]             STIMECMP_REGW;
 | 
			
		||||
  
 | 
			
		||||
  // write enables
 | 
			
		||||
@ -93,7 +93,7 @@ module csrs #(parameter
 | 
			
		||||
  flopenr #(`XLEN) STVECreg(clk, reset, WriteSTVECM, {CSRWriteValM[`XLEN-1:2], 1'b0, CSRWriteValM[0]}, STVEC_REGW); 
 | 
			
		||||
  flopenr #(`XLEN) SSCRATCHreg(clk, reset, WriteSSCRATCHM, CSRWriteValM, SSCRATCH_REGW);
 | 
			
		||||
  flopenr #(`XLEN) SEPCreg(clk, reset, WriteSEPCM, NextEPCM, SEPC_REGW); 
 | 
			
		||||
  flopenr #(`XLEN) SCAUSEreg(clk, reset, WriteSCAUSEM, NextCauseM, SCAUSE_REGW);
 | 
			
		||||
  flopenr #(`XLEN) SCAUSEreg(clk, reset, WriteSCAUSEM, {NextCauseM[4], {(`XLEN-5){1'b0}}, NextCauseM[3:0]}, SCAUSE_REGW);
 | 
			
		||||
  flopenr #(`XLEN) STVALreg(clk, reset, WriteSTVALM, NextMtvalM, STVAL_REGW);
 | 
			
		||||
  if (`VIRTMEM_SUPPORTED)
 | 
			
		||||
    flopenr #(`XLEN) SATPreg(clk, reset, WriteSATPM, CSRWriteValM, SATP_REGW);
 | 
			
		||||
 | 
			
		||||
@ -96,8 +96,8 @@ module privileged (
 | 
			
		||||
  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 [3:0]              CauseM;                                         // trap cause
 | 
			
		||||
  logic [15: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
 | 
			
		||||
 | 
			
		||||
@ -38,7 +38,7 @@ module trap (
 | 
			
		||||
  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 [15: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
 | 
			
		||||
@ -49,7 +49,7 @@ module trap (
 | 
			
		||||
  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
 | 
			
		||||
  output logic [3:0]           CauseM                                           // trap cause
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
  logic                        MIntGlobalEnM, SIntGlobalEnM;                    // Global interupt enables
 | 
			
		||||
@ -72,7 +72,7 @@ module trap (
 | 
			
		||||
  assign EnabledIntsM = ({12{MIntGlobalEnM}} & PendingIntsM & ~MIDELEG_REGW | {12{SIntGlobalEnM}} & PendingIntsM & MIDELEG_REGW);
 | 
			
		||||
  assign ValidIntsM = {12{~Committed}} & EnabledIntsM;
 | 
			
		||||
  assign InterruptM = (|ValidIntsM) & InstrValidM; // suppress interrupt if the memory system has partially processed a request.
 | 
			
		||||
  assign DelegateM = `S_SUPPORTED & (InterruptM ? MIDELEG_REGW[CauseM[3:0]] : MEDELEG_REGW[CauseM]) & 
 | 
			
		||||
  assign DelegateM = `S_SUPPORTED & (InterruptM ? MIDELEG_REGW[CauseM] : MEDELEG_REGW[CauseM]) & 
 | 
			
		||||
                     (PrivilegeModeW == `U_MODE | PrivilegeModeW == `S_MODE);
 | 
			
		||||
  assign WFIStallM = wfiM & ~IntPendingM;
 | 
			
		||||
 | 
			
		||||
@ -109,7 +109,7 @@ module trap (
 | 
			
		||||
    else if (IllegalInstrFaultM)       CauseM = 2;
 | 
			
		||||
    else if (InstrMisalignedFaultM)    CauseM = 0;
 | 
			
		||||
    else if (BreakpointFaultM)         CauseM = 3;
 | 
			
		||||
    else if (EcallFaultM)              CauseM = {{(`LOG_XLEN-4){1'b0}}, {2'b10}, PrivilegeModeW};
 | 
			
		||||
    else if (EcallFaultM)              CauseM = {2'b10, PrivilegeModeW};
 | 
			
		||||
    else if (LoadMisalignedFaultM)     CauseM = 4;
 | 
			
		||||
    else if (StoreAmoMisalignedFaultM) CauseM = 6;
 | 
			
		||||
    else if (LoadPageFaultM)           CauseM = 13;
 | 
			
		||||
 | 
			
		||||
@ -28,7 +28,7 @@
 | 
			
		||||
`include "wally-config.vh"
 | 
			
		||||
`include "tests.vh"
 | 
			
		||||
 | 
			
		||||
`define PrintHPMCounters 1
 | 
			
		||||
`define PrintHPMCounters 0
 | 
			
		||||
`define BPRED_LOGGER 0
 | 
			
		||||
`define I_CACHE_ADDR_LOGGER 0
 | 
			
		||||
`define D_CACHE_ADDR_LOGGER 0
 | 
			
		||||
 | 
			
		||||
@ -47,7 +47,9 @@ string tvpaths[] = '{
 | 
			
		||||
    "ieu",
 | 
			
		||||
    "ebu",
 | 
			
		||||
    "csrwrites",
 | 
			
		||||
    "priv"
 | 
			
		||||
    "priv",
 | 
			
		||||
    "ifu",
 | 
			
		||||
    "fpu"
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  string coremark[] = '{
 | 
			
		||||
 | 
			
		||||
@ -17,7 +17,7 @@ all: $(OBJECTS)
 | 
			
		||||
 | 
			
		||||
# Change many things if bit width isn't 64
 | 
			
		||||
%.elf: $(SRCDIR)/%.$(SEXT) WALLY-init-lib.h Makefile
 | 
			
		||||
	riscv64-unknown-elf-gcc -g -o $@ -march=rv64gc_zba_zbb_zbc_zbs -mabi=lp64 -mcmodel=medany \
 | 
			
		||||
	riscv64-unknown-elf-gcc -g -o $@ -march=rv64gqc_zba_zbb_zbc_zbs_zfh -mabi=lp64 -mcmodel=medany \
 | 
			
		||||
	    -nostartfiles -T../../examples/link/link.ld $<
 | 
			
		||||
	riscv64-unknown-elf-objdump -S $@ > $@.objdump
 | 
			
		||||
	riscv64-unknown-elf-elf2hex --bit-width 64 --input $@ --output $@.memfile
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										72
									
								
								tests/coverage/fpu.S
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								tests/coverage/fpu.S
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,72 @@
 | 
			
		||||
///////////////////////////////////////////
 | 
			
		||||
// fpu.S
 | 
			
		||||
//
 | 
			
		||||
// Written: David_Harris@hmc.edu 28 March 2023
 | 
			
		||||
//
 | 
			
		||||
// Purpose: Test coverage for FPU
 | 
			
		||||
//
 | 
			
		||||
// A component of the CORE-V-WALLY configurable RISC-V project.
 | 
			
		||||
// 
 | 
			
		||||
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
 | 
			
		||||
//
 | 
			
		||||
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file 
 | 
			
		||||
// except in compliance with the License, or, at your option, the Apache License version 2.0. You 
 | 
			
		||||
// may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
// https://solderpad.org/licenses/SHL-2.1/
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, any work distributed under the 
 | 
			
		||||
// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 
 | 
			
		||||
// either express or implied. See the License for the specific language governing permissions 
 | 
			
		||||
// and limitations under the License.
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
// load code to initalize stack, handle interrupts, terminate
 | 
			
		||||
#include "WALLY-init-lib.h"
 | 
			
		||||
 | 
			
		||||
main:
 | 
			
		||||
 | 
			
		||||
    bseti t0, zero, 14  # turn on FPU
 | 
			
		||||
    csrs mstatus, t0
 | 
			
		||||
 | 
			
		||||
    # Test legal instructions not covered elsewhere
 | 
			
		||||
    flq ft0, 0(a0)
 | 
			
		||||
    flh ft0, 8(a0)
 | 
			
		||||
    fsq ft0, 0(a0)
 | 
			
		||||
    fsh ft0, 8(a0)
 | 
			
		||||
    fcvt.h.s ft1, ft0
 | 
			
		||||
    fcvt.q.s ft2, ft0
 | 
			
		||||
    fcvt.h.w ft3, a0
 | 
			
		||||
    fcvt.h.wu ft3, a0
 | 
			
		||||
    fcvt.h.l ft3, a0
 | 
			
		||||
    fcvt.h.lu ft3, a0
 | 
			
		||||
    fcvt.w.h a0, ft3
 | 
			
		||||
    fcvt.wu.h a0, ft3
 | 
			
		||||
    fcvt.l.h a0, ft3
 | 
			
		||||
    fcvt.lu.h a0, ft3
 | 
			
		||||
    fcvt.q.w ft3, a0
 | 
			
		||||
    fcvt.q.wu ft3, a0
 | 
			
		||||
    fcvt.q.l ft3, a0
 | 
			
		||||
    fcvt.q.lu ft3, a0
 | 
			
		||||
    fcvt.w.q a0, ft3
 | 
			
		||||
    fcvt.wu.q a0, ft3
 | 
			
		||||
    fcvt.l.q a0, ft3
 | 
			
		||||
    fcvt.lu.q a0, ft3
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
    # Test illegal instructions are detected
 | 
			
		||||
    .word 0x00000007 // illegal floating-point load (bad Funct3)
 | 
			
		||||
    .word 0x00000027 // illegal floating-point store (bad Funct3)
 | 
			
		||||
    .word 0x58F00053 // illegal fsqrt (bad Rs2D)
 | 
			
		||||
    .word 0x20007053 // illegal fsgnj (bad Funct3)
 | 
			
		||||
    .word 0x28007053 // illegal fmin/max (bad Funct3)
 | 
			
		||||
    .word 0xA0007053 // illegal fcmp (bad Funct3)
 | 
			
		||||
    .word 0xE0007053 // illegal fclass/fmv (bad Funct3)
 | 
			
		||||
    .word 0xF0007053 // illegal fmv (bad Funct3)
 | 
			
		||||
    .word 0x43007053 // illegal fcvt.d.* (bad Rs2D)
 | 
			
		||||
    .word 0x42207053 // illegal fcvt.d.* (bad Rs2D[1])
 | 
			
		||||
 | 
			
		||||
    j done
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										40
									
								
								tests/coverage/ifu.S
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								tests/coverage/ifu.S
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,40 @@
 | 
			
		||||
///////////////////////////////////////////
 | 
			
		||||
// ifu.S
 | 
			
		||||
//
 | 
			
		||||
// Written: sriley@g.hmc.edu 28 March 2023
 | 
			
		||||
//
 | 
			
		||||
// Purpose: Test coverage for IFU
 | 
			
		||||
//
 | 
			
		||||
// A component of the CORE-V-WALLY configurable RISC-V project.
 | 
			
		||||
// 
 | 
			
		||||
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
 | 
			
		||||
//
 | 
			
		||||
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file 
 | 
			
		||||
// except in compliance with the License, or, at your option, the Apache License version 2.0. You 
 | 
			
		||||
// may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
// https://solderpad.org/licenses/SHL-2.1/
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, any work distributed under the 
 | 
			
		||||
// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 
 | 
			
		||||
// either express or implied. See the License for the specific language governing permissions 
 | 
			
		||||
// and limitations under the License.
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
// load code to initalize stack, handle interrupts, terminate
 | 
			
		||||
#include "WALLY-init-lib.h"
 | 
			
		||||
 | 
			
		||||
main:
 | 
			
		||||
    # turn floating point on
 | 
			
		||||
    li t0, 0x2000
 | 
			
		||||
    csrs mstatus, t0
 | 
			
		||||
 | 
			
		||||
    # calling compressed floating point load double instruction
 | 
			
		||||
    //.halfword 0x2000 // CL type compressed floating-point ld-->funct3,imm,rs1',imm,rd',op
 | 
			
		||||
                        // binary version 0000 0000 0000 0000 0010 0000 0000 0000
 | 
			
		||||
    mv s0, sp
 | 
			
		||||
    c.fld fs0, 0(s0)
 | 
			
		||||
 | 
			
		||||
    j done
 | 
			
		||||
@ -53,7 +53,7 @@
 | 
			
		||||
8000000b # mcause value from m ext interrupt
 | 
			
		||||
00000000 # mtval for mext interrupt (0x0)
 | 
			
		||||
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
 | 
			
		||||
fffff7ff # medeleg after attempted write of all 1's (only some bits are writeable)
 | 
			
		||||
0000b3ff # medeleg after attempted write of all 1's (only some bits are writeable)
 | 
			
		||||
00000222 # mideleg after attempted write of all 1's (only some bits are writeable) # skipping instruction address fault since they're impossible with compressed instrs enabled
 | 
			
		||||
00000001 # mcause from an instruction access fault
 | 
			
		||||
00000000 # mtval of faulting instruction address (0x0)
 | 
			
		||||
 | 
			
		||||
@ -48,7 +48,7 @@
 | 
			
		||||
00000009 # scause from S mode ecall
 | 
			
		||||
00000000 # stval of ecall (*** defined to be zero for now)
 | 
			
		||||
00000800 # masked out mstatus.mpp = 1, mstatus.MPIE = 0, and mstatus.MIE = 0
 | 
			
		||||
fffff7ff # medeleg after attempted write of all 1's (only some bits are writeable)
 | 
			
		||||
0000b3ff # medeleg after attempted write of all 1's (only some bits are writeable)
 | 
			
		||||
00000222 # mideleg after attempted write of all 1's (only some bits are writeable)
 | 
			
		||||
0000000b # scause from M mode ecall
 | 
			
		||||
00000000 # stval of ecall (*** defined to be zero for now)
 | 
			
		||||
 | 
			
		||||
@ -45,7 +45,7 @@
 | 
			
		||||
00000008 # scause from U mode ecall
 | 
			
		||||
00000000 # stval of ecall (*** defined to be zero for now)
 | 
			
		||||
00000000 # masked out mstatus.mpp = 0, mstatus.MPIE = 0, and mstatus.MIE = 0
 | 
			
		||||
fffff7ff # medeleg after attempted write of all 1's (only some bits are writeable)
 | 
			
		||||
0000b3ff # medeleg after attempted write of all 1's (only some bits are writeable)
 | 
			
		||||
00000222 # mideleg after attempted write of all 1's (only some bits are writeable)
 | 
			
		||||
0000000b # scause from M mode ecall 
 | 
			
		||||
00000000 # stval of ecall (*** defined to be zero for now)
 | 
			
		||||
 | 
			
		||||
@ -108,8 +108,8 @@
 | 
			
		||||
00000000
 | 
			
		||||
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
 | 
			
		||||
00000000
 | 
			
		||||
fffff7ff # medeleg after attempted write of all 1's (only some bits are writeable)
 | 
			
		||||
ffffffff
 | 
			
		||||
0000b3ff # medeleg after attempted write of all 1's (only some bits are writeable)
 | 
			
		||||
00000000
 | 
			
		||||
00000222 # mideleg after attempted write of all 1's (only some bits are writeable)
 | 
			
		||||
00000000 # skipping instruction address fault since they're impossible with compressed instrs enabled
 | 
			
		||||
00000001 # mcause from an instruction access fault
 | 
			
		||||
 | 
			
		||||
@ -98,8 +98,8 @@
 | 
			
		||||
00000000
 | 
			
		||||
00000800 # masked out mstatus.mpp = 1, mstatus.MPIE = 0, and mstatus.MIE = 0
 | 
			
		||||
00000000
 | 
			
		||||
fffff7ff # medeleg after attempted write of all 1's (only some bits are writeable)
 | 
			
		||||
ffffffff
 | 
			
		||||
0000b3ff # medeleg after attempted write of all 1's (only some bits are writeable)
 | 
			
		||||
00000000
 | 
			
		||||
00000222 # mideleg after attempted write of all 1's (only some bits are writeable)
 | 
			
		||||
00000000
 | 
			
		||||
0000000b # scause from M mode ecall 
 | 
			
		||||
 | 
			
		||||
@ -92,8 +92,8 @@
 | 
			
		||||
00000000
 | 
			
		||||
00000000 # masked out mstatus.mpp = 0, mstatus.MPIE = 0, and mstatus.MIE = 0
 | 
			
		||||
00000000
 | 
			
		||||
fffff7ff # medeleg after attempted write of all 1's (only some bits are writeable)
 | 
			
		||||
ffffffff
 | 
			
		||||
0000b3ff # medeleg after attempted write of all 1's (only some bits are writeable)
 | 
			
		||||
00000000
 | 
			
		||||
00000222 # mideleg after attempted write of all 1's (only some bits are writeable)
 | 
			
		||||
00000000
 | 
			
		||||
0000000b # scause from M mode ecall 
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user