mirror of
				https://github.com/openhwgroup/cvw
				synced 2025-02-11 06:05:49 +00:00 
			
		
		
		
	Merge branch 'main' of https://github.com/openhwgroup/cvw
This commit is contained in:
		
						commit
						f7838b869b
					
				| @ -54,47 +54,67 @@ module fdivsqrtpreproc ( | ||||
|   logic [`DIVb:0]             PreSqrtX; | ||||
|   logic [`DIVb+3:0]           DivX, DivXShifted, SqrtX, PreShiftX; // Variations of dividend, to be muxed
 | ||||
|   logic [`NE+1:0]             QeE;                                 // Quotient Exponent (FP only)
 | ||||
|   logic [`DIVb-1:0]           IFNormLenX, IFNormLenD;              // Correctly-sized inputs for iterator
 | ||||
|   logic [`DIVb-1:0]           IFX, IFD;                            // Correctly-sized inputs for iterator, selected from int or fp input
 | ||||
|   logic [`DIVBLEN:0]          mE, ell;                             // Leading zeros of inputs
 | ||||
|   logic                       NumerZeroE;                          // Numerator is zero (X or A)
 | ||||
|   logic                       AZeroE, BZeroE;                      // A or B is Zero for integer division
 | ||||
|   logic                       signedDiv;                           // signed division
 | ||||
|   logic                       NegQuotE;                            // Integer quotient is negative
 | ||||
|   logic                       AsE, BsE;                            // Signs of integer inputs
 | ||||
|   logic [`XLEN-1:0]           AE;                                  // input A after W64 adjustment
 | ||||
| 
 | ||||
|   if (`IDIV_ON_FPU) begin:intpreproc // Int Supported
 | ||||
|     logic signedDiv, NegQuotE; | ||||
|     logic AsBit, BsBit, AsE, BsE, ALTBE; | ||||
|     logic [`XLEN-1:0] AE, BE, PosA, PosB; | ||||
|     logic [`DIVBLEN:0] ZeroDiff, p; | ||||
|     logic [`XLEN-1:0] BE, PosA, PosB; | ||||
| 
 | ||||
|     // Extract inputs, signs, zero, depending on W64 mode if applicable
 | ||||
|     assign signedDiv = ~Funct3E[0]; | ||||
|     assign NegQuotE = AsE ^ BsE; // Quotient is negative
 | ||||
|    | ||||
|     // Source handling
 | ||||
|     if (`XLEN==64) begin // 64-bit, supports W64
 | ||||
|       mux2 #(1) azeromux(~(|ForwardedSrcAE), ~(|ForwardedSrcAE[31:0]), W64E, AZeroE); | ||||
|       mux2 #(1) bzeromux(~(|ForwardedSrcBE), ~(|ForwardedSrcBE[31:0]), W64E, BZeroE); | ||||
|       mux2 #(1)  abitmux(ForwardedSrcAE[63], ForwardedSrcAE[31], W64E, AsBit); | ||||
|       mux2 #(1)  bbitmux(ForwardedSrcBE[63], ForwardedSrcBE[31], W64E, BsBit); | ||||
|       mux2 #(64)    amux(ForwardedSrcAE, {{(`XLEN-32){AsE}}, ForwardedSrcAE[31:0]}, W64E, AE); | ||||
|       mux2 #(64)    bmux(ForwardedSrcBE, {{(`XLEN-32){BsE}}, ForwardedSrcBE[31:0]}, W64E, BE); | ||||
|       assign AsE = signedDiv & AsBit; | ||||
|       assign BsE = signedDiv & BsBit; | ||||
|       mux2 #(64)    amux(ForwardedSrcAE, {{32{ForwardedSrcAE[31] & signedDiv}}, ForwardedSrcAE[31:0]}, W64E, AE); | ||||
|       mux2 #(64)    bmux(ForwardedSrcBE, {{32{ForwardedSrcBE[31] & signedDiv}}, ForwardedSrcBE[31:0]}, W64E, BE); | ||||
|     end else begin // 32 bits only
 | ||||
|       assign AsE = signedDiv & ForwardedSrcAE[31]; | ||||
|       assign BsE = signedDiv & ForwardedSrcBE[31]; | ||||
|       assign AE = ForwardedSrcAE; | ||||
|       assign BE = ForwardedSrcBE; | ||||
|       assign AZeroE = ~(|ForwardedSrcAE); | ||||
|       assign BZeroE = ~(|ForwardedSrcBE); | ||||
|      end | ||||
|     assign AZeroE = ~(|AE); | ||||
|     assign BZeroE = ~(|BE); | ||||
|     assign AsE = AE[`XLEN-1] & signedDiv; | ||||
|     assign BsE = BE[`XLEN-1] & signedDiv;  | ||||
|     assign NegQuotE = AsE ^ BsE; // Integer Quotient is negative
 | ||||
| 
 | ||||
|     // Force integer inputs to be postiive
 | ||||
|     mux2 #(`XLEN) posamux(AE, -AE, AsE, PosA); | ||||
|     mux2 #(`XLEN) posbmux(BE, -BE, BsE, PosB); | ||||
| 
 | ||||
|     // Select integer or floating point inputs
 | ||||
|     mux2 #(`DIVb) ifxmux({Xm, {(`DIVb-`NF-1){1'b0}}}, {PosA, {(`DIVb-`XLEN){1'b0}}}, IntDivE, IFNormLenX); | ||||
|     mux2 #(`DIVb) ifdmux({Ym, {(`DIVb-`NF-1){1'b0}}}, {PosB, {(`DIVb-`XLEN){1'b0}}}, IntDivE, IFNormLenD); | ||||
|     mux2 #(`DIVb) ifxmux({Xm, {(`DIVb-`NF-1){1'b0}}}, {PosA, {(`DIVb-`XLEN){1'b0}}}, IntDivE, IFX); | ||||
|     mux2 #(`DIVb) ifdmux({Ym, {(`DIVb-`NF-1){1'b0}}}, {PosB, {(`DIVb-`XLEN){1'b0}}}, IntDivE, IFD); | ||||
| 
 | ||||
| 
 | ||||
|   end else begin // Int not supported
 | ||||
|     assign IFX = {Xm, {(`DIVb-`NF-1){1'b0}}}; | ||||
|     assign IFD = {Ym, {(`DIVb-`NF-1){1'b0}}}; | ||||
|   end | ||||
| 
 | ||||
|   // count leading zeros for Subnorm FP and to normalize integer inputs
 | ||||
|   lzc #(`DIVb) lzcX (IFX, ell); | ||||
|   lzc #(`DIVb) lzcY (IFD, mE); | ||||
| 
 | ||||
|   // Normalization shift
 | ||||
|   assign XPreproc = IFX << (ell + {{`DIVBLEN{1'b0}}, 1'b1}); // *** try to remove this +1
 | ||||
|   assign DPreproc = IFD << (mE + {{`DIVBLEN{1'b0}}, 1'b1});  | ||||
| 
 | ||||
|   // append leading 1 (for normal inputs)
 | ||||
|   // shift square root to be in range [1/4, 1)
 | ||||
|   // Normalized numbers are shifted right by 1 if the exponent is odd
 | ||||
|   // Denormalized numbers have Xe = 0 and an unbiased exponent of 1-BIAS.  They are shifted right if the number of leading zeros is odd.
 | ||||
|   mux2 #(`DIVb+1) sqrtxmux({~XZeroE, XPreproc}, {1'b0, ~XZeroE, XPreproc[`DIVb-1:1]}, (Xe[0] ^ ell[0]), PreSqrtX); | ||||
|   assign DivX = {3'b000, ~NumerZeroE, XPreproc}; | ||||
| 
 | ||||
|   if (`IDIV_ON_FPU) begin:intrightshift // Int Supported
 | ||||
|     logic [`DIVBLEN:0] ZeroDiff, p; | ||||
|     logic  ALTBE; | ||||
| 
 | ||||
|     // calculate number of fractional bits p
 | ||||
|     assign ZeroDiff = mE - ell;         // Difference in number of leading zeros
 | ||||
| @ -138,29 +158,11 @@ module fdivsqrtpreproc ( | ||||
|     flopen #(`XLEN)   srcareg(clk, IFDivStartE, AE,       AM); | ||||
|     if (`XLEN==64)  | ||||
|       flopen #(1)      w64reg(clk, IFDivStartE, W64E,     W64M); | ||||
| 
 | ||||
|   end else begin // Int not supported
 | ||||
|     assign IFNormLenX = {Xm, {(`DIVb-`NF-1){1'b0}}}; | ||||
|     assign IFNormLenD = {Ym, {(`DIVb-`NF-1){1'b0}}}; | ||||
|   end else begin | ||||
|     assign NumerZeroE = XZeroE; | ||||
|     assign X = PreShiftX; | ||||
|   end | ||||
| 
 | ||||
|   // count leading zeros for Subnorm FP and to normalize integer inputs
 | ||||
|   lzc #(`DIVb) lzcX (IFNormLenX, ell); | ||||
|   lzc #(`DIVb) lzcY (IFNormLenD, mE); | ||||
| 
 | ||||
|   // Normalization shift
 | ||||
|   assign XPreproc = IFNormLenX << (ell + {{`DIVBLEN{1'b0}}, 1'b1}); // *** try to remove this +1
 | ||||
|   assign DPreproc = IFNormLenD << (mE + {{`DIVBLEN{1'b0}}, 1'b1});  | ||||
| 
 | ||||
|   // append leading 1 (for normal inputs)
 | ||||
|   // shift square root to be in range [1/4, 1)
 | ||||
|   // Normalized numbers are shifted right by 1 if the exponent is odd
 | ||||
|   // Denormalized numbers have Xe = 0 and an unbiased exponent of 1-BIAS.  They are shifted right if the number of leading zeros is odd.
 | ||||
|   mux2 #(`DIVb+1) sqrtxmux({~XZeroE, XPreproc}, {1'b0, ~XZeroE, XPreproc[`DIVb-1:1]}, (Xe[0] ^ ell[0]), PreSqrtX); | ||||
|   assign DivX = {3'b000, ~NumerZeroE, XPreproc}; | ||||
| 
 | ||||
|   // Sqrt is initialized on step one as R(X-1), so depends on Radix
 | ||||
|   if (`RADIX == 2)  assign SqrtX = {3'b111, PreSqrtX}; | ||||
|   else              assign SqrtX = {2'b11, PreSqrtX, 1'b0}; | ||||
|  | ||||
| @ -122,11 +122,14 @@ module ram2p1r1wbe #(parameter DEPTH=1024, WIDTH=68) ( | ||||
|      if(ce1) rd1 <= #1 mem[ra1]; */ | ||||
|      | ||||
|     // Write divided into part for bytes and part for extra msbs
 | ||||
|     // coverage off     
 | ||||
|     //   when byte write enables are tied high, the last IF is always taken
 | ||||
|     if(WIDTH >= 8)  | ||||
|       always @(posedge clk)  | ||||
|         if (ce2 & we2)  | ||||
|           for(i = 0; i < WIDTH/8; i++)  | ||||
|             if(bwe2[i]) mem[wa2][i*8 +: 8] <= #1 wd2[i*8 +: 8]; | ||||
|     // coverage on
 | ||||
|    | ||||
|     if (WIDTH%8 != 0) // handle msbs if width not a multiple of 8
 | ||||
|       always @(posedge clk)  | ||||
|  | ||||
| @ -71,6 +71,7 @@ module hazard ( | ||||
|   // Similarly, CSR writes and fences flush all subsequent instructions and refetch them in light of the new operating modes and cache/TLB contents
 | ||||
|   // Branch misprediction is found in the Execute stage and must flush the next two instructions.
 | ||||
|   //   However, an active division operation resides in the Execute stage, and when the BP incorrectly mispredicts the divide as a taken branch, the divde must still complete
 | ||||
|   // When a WFI is interrupted and causes a trap, it flushes the rest of the pipeline but not the W stage, because the WFI needs to commit
 | ||||
|   assign FlushDCause = TrapM | RetM | CSRWriteFenceM | BPWrongE; | ||||
|   assign FlushECause = TrapM | RetM | CSRWriteFenceM |(BPWrongE & ~(DivBusyE | FDivBusyE)); | ||||
|   assign FlushMCause = TrapM | RetM | CSRWriteFenceM; | ||||
|  | ||||
| @ -62,7 +62,7 @@ module RASPredictor #(parameter int StackSize = 16 )( | ||||
|   assign PushE = CallE & ~StallM & ~FlushM; | ||||
| 
 | ||||
|   assign WrongPredReturnD = (BPReturnWrongD) & ~StallE & ~FlushE; | ||||
|   assign FlushedReturnDE = (~StallE & FlushE & ReturnD) | (~StallM & FlushM & ReturnE); // flushed return
 | ||||
|   assign FlushedReturnDE = (~StallE & FlushE & ReturnD) | (FlushM & ReturnE); // flushed return
 | ||||
| 
 | ||||
|   assign RepairD = WrongPredReturnD | FlushedReturnDE ; | ||||
| 
 | ||||
|  | ||||
| @ -130,7 +130,7 @@ module ifu ( | ||||
|   logic                       CacheableF;                            // PMA indicates instruction address is cacheable
 | ||||
|   logic                       SelSpillNextF;                         // In a spill, stall pipeline and gate local stallF
 | ||||
|   logic                       BusStall;                              // Bus interface busy with multicycle operation
 | ||||
|   logic                       IFUCacheBusStallD;                     // EIther I$ or bus busy with multicycle operation
 | ||||
|   logic                       IFUCacheBusStallF;                     // EIther I$ or bus busy with multicycle operation
 | ||||
|   logic                       GatedStallD;                           // StallD gated by selected next spill
 | ||||
|   // branch predictor signal
 | ||||
|   logic [`XLEN-1:0]           PC1NextF;                              // Branch predictor next PCF
 | ||||
| @ -147,7 +147,7 @@ module ifu ( | ||||
| 
 | ||||
|   if(`C_SUPPORTED) begin : Spill | ||||
|     spill #(`ICACHE_SUPPORTED) spill(.clk, .reset, .StallD, .FlushD, .PCF, .PCPlus4F, .PCNextF, .InstrRawF, | ||||
|       .InstrUpdateDAF, .IFUCacheBusStallD, .ITLBMissF, .PCSpillNextF, .PCSpillF, .SelSpillNextF, .PostSpillInstrRawF, .CompressedF); | ||||
|       .InstrUpdateDAF, .IFUCacheBusStallF, .ITLBMissF, .PCSpillNextF, .PCSpillF, .SelSpillNextF, .PostSpillInstrRawF, .CompressedF); | ||||
|   end else begin : NoSpill | ||||
|     assign PCSpillNextF = PCNextF; | ||||
|     assign PCSpillF = PCF; | ||||
| @ -288,8 +288,8 @@ module ifu ( | ||||
|     assign InstrRawF = IROMInstrF; | ||||
|   end | ||||
|    | ||||
|   assign IFUCacheBusStallD = ICacheStallF | BusStall; | ||||
|   assign IFUStallF = IFUCacheBusStallD | SelSpillNextF; | ||||
|   assign IFUCacheBusStallF = ICacheStallF | BusStall; | ||||
|   assign IFUStallF = IFUCacheBusStallF | SelSpillNextF; | ||||
|   assign GatedStallD = StallD & ~SelSpillNextF; | ||||
|    | ||||
|   flopenl #(32) AlignedInstrRawDFlop(clk, reset | FlushD, ~StallD, PostSpillInstrRawF, nop, InstrRawD); | ||||
|  | ||||
| @ -40,7 +40,7 @@ module spill #( | ||||
|   input logic [`XLEN-1:2]  PCPlus4F,          // PCF + 4
 | ||||
|   input logic [`XLEN-1:0]  PCNextF,           // The next PCF
 | ||||
|   input logic [31:0]       InstrRawF,         // Instruction from the IROM, I$, or bus. Used to check if the instruction if compressed
 | ||||
|   input logic              IFUCacheBusStallD, // I$ or bus are stalled. Transition to second fetch of spill after the first is fetched
 | ||||
|   input logic              IFUCacheBusStallF, // I$ or bus are stalled. Transition to second fetch of spill after the first is fetched
 | ||||
|   input logic              ITLBMissF,         // ITLB miss, ignore memory request
 | ||||
|   input logic              InstrUpdateDAF,    // Ignore memory request if the hptw support write and a DA page fault occurs (hptw is still active)
 | ||||
|   output logic [`XLEN-1:0] PCSpillNextF,      // The next PCF for one of the two memory addresses of the spill
 | ||||
| @ -78,7 +78,7 @@ module spill #( | ||||
|   ////////////////////////////////////////////////////////////////////////////////////////////////////
 | ||||
| 
 | ||||
|   assign SpillF = &PCF[$clog2(SPILLTHRESHOLD)+1:1]; | ||||
|   assign TakeSpillF = SpillF & ~IFUCacheBusStallD & ~(ITLBMissF | (`SVADU_SUPPORTED & InstrUpdateDAF)); | ||||
|   assign TakeSpillF = SpillF & ~IFUCacheBusStallF & ~(ITLBMissF | (`SVADU_SUPPORTED & InstrUpdateDAF)); | ||||
|    | ||||
|   always_ff @(posedge clk) | ||||
|     if (reset | FlushD)    CurrState <= #1 STATE_READY; | ||||
| @ -88,14 +88,14 @@ module spill #( | ||||
|     case (CurrState) | ||||
|       STATE_READY: if (TakeSpillF)                NextState = STATE_SPILL; | ||||
|                    else                           NextState = STATE_READY; | ||||
|       STATE_SPILL: if(IFUCacheBusStallD | StallD) NextState = STATE_SPILL; | ||||
|       STATE_SPILL: if(StallD)                     NextState = STATE_SPILL; | ||||
|                    else                           NextState = STATE_READY; | ||||
|       default:                                    NextState = STATE_READY; | ||||
|     endcase | ||||
|   end | ||||
| 
 | ||||
|   assign SelSpillF = (CurrState == STATE_SPILL); | ||||
|   assign SelSpillNextF = (CurrState == STATE_READY & TakeSpillF) | (CurrState == STATE_SPILL & IFUCacheBusStallD); | ||||
|   assign SelSpillNextF = (CurrState == STATE_READY & TakeSpillF) | (CurrState == STATE_SPILL & IFUCacheBusStallF); | ||||
|   assign SpillSaveF = (CurrState == STATE_READY) & TakeSpillF & ~FlushD; | ||||
| 
 | ||||
|   ////////////////////////////////////////////////////////////////////////////////////////////////////
 | ||||
|  | ||||
| @ -33,7 +33,9 @@ | ||||
| `include "wally-config.vh" | ||||
| module csrc #(parameter  | ||||
|   MHPMCOUNTERBASE = 12'hB00, | ||||
|   MTIME = 12'hB01,               // this is a memory-mapped register; no such CSR exists, and access should fault
 | ||||
|   MHPMCOUNTERHBASE = 12'hB80, | ||||
|   MTIMEH = 12'hB81,               // this is a memory-mapped register; no such CSR exists, and access should fault
 | ||||
|   MHPMEVENTBASE = 12'h320, | ||||
|   HPMCOUNTERBASE = 12'hC00, | ||||
|   HPMCOUNTERHBASE = 12'hC80, | ||||
| @ -152,8 +154,10 @@ module csrc #(parameter | ||||
|         /* verilator lint_off WIDTH */   | ||||
|         if      (CSRAdrM == TIME)  CSRCReadValM = MTIME_CLINT; // TIME register is a shadow of the memory-mapped MTIME from the CLINT
 | ||||
|         /* verilator lint_on WIDTH */   | ||||
|         else if (CSRAdrM >= MHPMCOUNTERBASE & CSRAdrM < MHPMCOUNTERBASE+`COUNTERS) CSRCReadValM = HPMCOUNTER_REGW[CounterNumM]; | ||||
|         else if (CSRAdrM >= HPMCOUNTERBASE & CSRAdrM  < HPMCOUNTERBASE+`COUNTERS)  CSRCReadValM = HPMCOUNTER_REGW[CounterNumM]; | ||||
|         else if (CSRAdrM >= MHPMCOUNTERBASE & CSRAdrM < MHPMCOUNTERBASE+`COUNTERS & CSRAdrM != MTIME)  | ||||
|                  CSRCReadValM = HPMCOUNTER_REGW[CounterNumM]; | ||||
|         else if (CSRAdrM >= HPMCOUNTERBASE & CSRAdrM  < HPMCOUNTERBASE+`COUNTERS)   | ||||
|                  CSRCReadValM = HPMCOUNTER_REGW[CounterNumM]; | ||||
|         else begin | ||||
|             CSRCReadValM = 0; | ||||
|             IllegalCSRCAccessM = 1;  // requested CSR doesn't exist
 | ||||
| @ -164,10 +168,14 @@ module csrc #(parameter | ||||
|         if      (CSRAdrM == TIME)  CSRCReadValM = MTIME_CLINT[31:0];// TIME register is a shadow of the memory-mapped MTIME from the CLINT
 | ||||
|         else if (CSRAdrM == TIMEH) CSRCReadValM = MTIME_CLINT[63:32]; | ||||
|         /* verilator lint_on WIDTH */   | ||||
|         else if (CSRAdrM >= MHPMCOUNTERBASE  & CSRAdrM < MHPMCOUNTERBASE+`COUNTERS)   CSRCReadValM = HPMCOUNTER_REGW[CounterNumM]; | ||||
|         else if (CSRAdrM >= HPMCOUNTERBASE   & CSRAdrM < HPMCOUNTERBASE+`COUNTERS)    CSRCReadValM = HPMCOUNTER_REGW[CounterNumM]; | ||||
|         else if (CSRAdrM >= MHPMCOUNTERHBASE & CSRAdrM < MHPMCOUNTERHBASE+`COUNTERS)  CSRCReadValM = HPMCOUNTERH_REGW[CounterNumM]; | ||||
|         else if (CSRAdrM >= HPMCOUNTERHBASE  & CSRAdrM < HPMCOUNTERHBASE+`COUNTERS)   CSRCReadValM = HPMCOUNTERH_REGW[CounterNumM]; | ||||
|         else if (CSRAdrM >= MHPMCOUNTERBASE  & CSRAdrM < MHPMCOUNTERBASE+`COUNTERS & CSRAdrM != MTIME)    | ||||
|                  CSRCReadValM = HPMCOUNTER_REGW[CounterNumM]; | ||||
|         else if (CSRAdrM >= HPMCOUNTERBASE   & CSRAdrM < HPMCOUNTERBASE+`COUNTERS)     | ||||
|                  CSRCReadValM = HPMCOUNTER_REGW[CounterNumM]; | ||||
|         else if (CSRAdrM >= MHPMCOUNTERHBASE & CSRAdrM < MHPMCOUNTERHBASE+`COUNTERS & CSRAdrM != MTIMEH)   | ||||
|                  CSRCReadValM = HPMCOUNTERH_REGW[CounterNumM]; | ||||
|         else if (CSRAdrM >= HPMCOUNTERHBASE  & CSRAdrM < HPMCOUNTERHBASE+`COUNTERS)    | ||||
|                  CSRCReadValM = HPMCOUNTERH_REGW[CounterNumM]; | ||||
|         else begin | ||||
|           CSRCReadValM = 0; | ||||
|           IllegalCSRCAccessM = 1; // requested CSR doesn't exist
 | ||||
|  | ||||
| @ -49,7 +49,9 @@ string tvpaths[] = '{ | ||||
|     "csrwrites", | ||||
|     "priv", | ||||
|     "ifu", | ||||
|     "fpu" | ||||
|     "fpu", | ||||
|     "lsu", | ||||
|     "vm64check" | ||||
|   }; | ||||
| 
 | ||||
|   string coremark[] = '{ | ||||
| @ -1052,6 +1054,28 @@ string imperas32f[] = '{ | ||||
| 
 | ||||
|   string arch64f[] = '{ | ||||
|     `RISCVARCHTEST, | ||||
|     "rv64i_m/F/src/fdiv_b1-01.S", | ||||
|     "rv64i_m/F/src/fdiv_b20-01.S", | ||||
|     "rv64i_m/F/src/fdiv_b2-01.S", | ||||
|     "rv64i_m/F/src/fdiv_b21-01.S", | ||||
|     "rv64i_m/F/src/fdiv_b3-01.S", | ||||
|     "rv64i_m/F/src/fdiv_b4-01.S", | ||||
|     "rv64i_m/F/src/fdiv_b5-01.S", | ||||
|     "rv64i_m/F/src/fdiv_b6-01.S", | ||||
|     "rv64i_m/F/src/fdiv_b7-01.S", | ||||
|     "rv64i_m/F/src/fdiv_b8-01.S", | ||||
|     "rv64i_m/F/src/fdiv_b9-01.S", | ||||
|     "rv64i_m/F/src/fsqrt_b1-01.S", | ||||
|     "rv64i_m/F/src/fsqrt_b20-01.S", | ||||
|     "rv64i_m/F/src/fsqrt_b2-01.S", | ||||
|     "rv64i_m/F/src/fsqrt_b3-01.S", | ||||
|     "rv64i_m/F/src/fsqrt_b4-01.S", | ||||
|     "rv64i_m/F/src/fsqrt_b5-01.S", | ||||
|     "rv64i_m/F/src/fsqrt_b7-01.S", | ||||
|     "rv64i_m/F/src/fsqrt_b8-01.S", | ||||
|     "rv64i_m/F/src/fsqrt_b9-01.S", | ||||
| 
 | ||||
| 
 | ||||
|     "rv64i_m/F/src/fadd_b10-01.S", | ||||
|     "rv64i_m/F/src/fadd_b1-01.S", | ||||
|     "rv64i_m/F/src/fadd_b11-01.S", | ||||
| @ -1203,6 +1227,28 @@ string imperas32f[] = '{ | ||||
| 
 | ||||
|   string arch64d[] = '{ | ||||
|     `RISCVARCHTEST, | ||||
|     // for speed | ||||
|     "rv64i_m/D/src/fdiv.d_b1-01.S", | ||||
|     "rv64i_m/D/src/fdiv.d_b20-01.S", | ||||
|     "rv64i_m/D/src/fdiv.d_b2-01.S", | ||||
|     "rv64i_m/D/src/fdiv.d_b21-01.S", | ||||
|     "rv64i_m/D/src/fdiv.d_b3-01.S", | ||||
|     "rv64i_m/D/src/fdiv.d_b4-01.S", | ||||
|     "rv64i_m/D/src/fdiv.d_b5-01.S", | ||||
|     "rv64i_m/D/src/fdiv.d_b6-01.S", | ||||
|     "rv64i_m/D/src/fdiv.d_b7-01.S", | ||||
|     "rv64i_m/D/src/fdiv.d_b8-01.S", | ||||
|     "rv64i_m/D/src/fdiv.d_b9-01.S", | ||||
|     "rv64i_m/D/src/fsqrt.d_b1-01.S", | ||||
|     "rv64i_m/D/src/fsqrt.d_b20-01.S", | ||||
|     "rv64i_m/D/src/fsqrt.d_b2-01.S", | ||||
|     "rv64i_m/D/src/fsqrt.d_b3-01.S", | ||||
|     "rv64i_m/D/src/fsqrt.d_b4-01.S", | ||||
|     "rv64i_m/D/src/fsqrt.d_b5-01.S", | ||||
|     "rv64i_m/D/src/fsqrt.d_b7-01.S", | ||||
|     "rv64i_m/D/src/fsqrt.d_b8-01.S", | ||||
|     "rv64i_m/D/src/fsqrt.d_b9-01.S", | ||||
| 
 | ||||
|     "rv64i_m/D/src/fadd.d_b10-01.S", | ||||
|     "rv64i_m/D/src/fadd.d_b1-01.S", | ||||
|     "rv64i_m/D/src/fadd.d_b11-01.S", | ||||
|  | ||||
| @ -36,6 +36,7 @@ rvtest_entry_point: | ||||
|     csrw mtvec, t0      # Initialize MTVEC to trap_handler | ||||
|     csrw mideleg, zero  # Don't delegate interrupts | ||||
|     csrw medeleg, zero  # Don't delegate exceptions | ||||
|     li t0, 0x80          | ||||
|     csrw mie, t0        # Enable machine timer interrupt | ||||
|     la t0, topoftrapstack  | ||||
|     csrw mscratch, t0   # MSCRATCH holds trap stack pointer | ||||
| @ -65,9 +66,8 @@ interrupt:              # must be a timer interrupt | ||||
|     j trap_return       # clean up and return | ||||
| 
 | ||||
| exception: | ||||
|     csrr t1, mepc   # add 4 to MEPC to determine return Address | ||||
|     addi t1, t1, 4 | ||||
|     csrw mepc, t1 | ||||
|     li t0, 2 | ||||
|     csrr t1, mcause | ||||
|     li t1, 8            # is it an ecall trap? | ||||
|     andi t0, t0, 0xFC # if CAUSE = 8, 9, or 11 | ||||
|     bne t0, t1, trap_return # ignore other exceptions | ||||
| @ -86,6 +86,20 @@ changeprivilege: | ||||
|     csrs mstatus, a0    # set mstatus.MPP with desired privilege | ||||
| 
 | ||||
| trap_return:            # return from trap handler | ||||
|     csrr t0, mepc  # get address of instruction that caused exception | ||||
|     lh t0, 0(t0)   # get instruction that caused exception | ||||
|     li t1, 3 | ||||
|     and t0, t0, t1  # mask off upper bits | ||||
|     beq t0, t1, instr32  # if lower 2 bits are 11, instruction is uncompresssed | ||||
|     li t0, 2        # increment PC by 2 for compressed instruction | ||||
|     j updateepc | ||||
| instr32: | ||||
|     li t0, 4 | ||||
| updateepc: | ||||
|     csrr t1, mepc   # add 2 or 4 (from t0) to MEPC to determine return Address | ||||
|     add t1, t1, t0 | ||||
|     csrw mepc, t1 | ||||
| 
 | ||||
|     ld t1, -8(tp)       # restore t1 and t0 | ||||
|     ld t0, 0(tp) | ||||
|     csrrw tp, mscratch, tp  # restore tp | ||||
|  | ||||
| @ -27,9 +27,11 @@ | ||||
| #include "WALLY-init-lib.h" | ||||
| 
 | ||||
| main: | ||||
|     li t0, -5 | ||||
|     csrw stimecmp, t0   # initialize so ImperasDV agrees | ||||
|     csrrw t0, stimecmp, t0 | ||||
|     csrrw t0, satp, t0 | ||||
|     csrrw t0, stvec, t0 | ||||
|     csrrw t0, sscratch, t0 | ||||
|     csrrw t0, satp, zero | ||||
|     csrrw t0, stvec, zero | ||||
|     csrrw t0, sscratch, zero | ||||
| 
 | ||||
|     j done | ||||
|  | ||||
| @ -42,6 +42,7 @@ main: | ||||
|     clz t1, t0 | ||||
| 
 | ||||
|     # Test forwarding from store conditional | ||||
|     mv a0, sp | ||||
|     lr.w t0, 0(a0) | ||||
|     sc.w t0, a1, 0(a0) | ||||
|     addi t0, t0, 1 | ||||
|  | ||||
| @ -43,4 +43,7 @@ main: | ||||
| 
 | ||||
|     //.hword 0x9C01     //# Illegal compressed instruction with op = 01, instr[15:10] = 100111, and 0's everywhere else | ||||
| 
 | ||||
| 
 | ||||
|      | ||||
|     | ||||
|     j done | ||||
|  | ||||
| @ -33,7 +33,8 @@ main: | ||||
|     ecall | ||||
| 
 | ||||
|     # Test read to stimecmp fails when MCOUNTEREN_TM is not set | ||||
|     addi t0, zero, 0 | ||||
|     li t1, -3 | ||||
|     csrw stimecmp, t1 | ||||
|     csrr t0, stimecmp  | ||||
| 
 | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										173
									
								
								tests/coverage/vm64check.S
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										173
									
								
								tests/coverage/vm64check.S
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,173 @@ | ||||
| /////////////////////////////////////////// | ||||
| // vm64check.S | ||||
| // | ||||
| // Written: David_Harris@hmc.edu 7 April 2023
 | ||||
| // | ||||
| // Purpose: vm64check coverage | ||||
| // | ||||
| // 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. | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| 
 | ||||
| // Cover IMMU vm64check block by jumping to illegal virtual addresses | ||||
| // Need a nonstandard trap handler to deal with returns from theses jumps | ||||
| //    assign eq_46_38 = &(VAdr[46:38]) | ~|(VAdr[46:38]);
 | ||||
|  //   assign eq_63_47 = &(VAdr[63:47]) | ~|(VAdr[63:47]); 
 | ||||
|  //   assign UpperBitsUnequal = SV39Mode ? ~(eq_63_47 & eq_46_38) : ~eq_63_47;
 | ||||
| 
 | ||||
| .section .text.init | ||||
| .global rvtest_entry_point
 | ||||
| 
 | ||||
| rvtest_entry_point: | ||||
|     la sp, topofstack       # Initialize stack pointer (not used) | ||||
| 
 | ||||
|     # Set up interrupts | ||||
|     la t0, trap_handler | ||||
|     csrw mtvec, t0      # Initialize MTVEC to trap_handler | ||||
|     # set up PMP so user and supervisor mode can access full address space | ||||
|     csrw pmpcfg0, 0xF   # configure PMP0 to TOR RWX | ||||
|     li t0, 0xFFFFFFFF    | ||||
|     csrw pmpaddr0, t0   # configure PMP0 top of range to 0xFFFFFFFF to allow all 32-bit addresses | ||||
|      | ||||
|     # SATP in non-39 mode | ||||
|     csrw satp, zero | ||||
| 
 | ||||
|     // vm64check coverage | ||||
| check1: | ||||
|     // check virtual addresses with bits 63:47 and/or 46:38 being equal or unequal | ||||
|     li t0, 0x00000001800F0000   # unimplemented memory with upper and lower all zero | ||||
|     la ra, check2 | ||||
|     jalr t0 | ||||
| 
 | ||||
| check2: | ||||
|     li t0, 0xFFFFFFF1800F0000   # unimplemented memory with upper and lower all one | ||||
|     la ra, check3 | ||||
|     jalr t0 | ||||
| 
 | ||||
| check3: | ||||
|     li t0, 0xFFF81001800F0000   # unimplemented memory with upper all one, lower mixed | ||||
|     la ra, check4 | ||||
|     jalr t0 | ||||
| 
 | ||||
| check4: | ||||
|     li t0, 0x03001001800F0000   # unimplemented memory with upper mixed, lower mixed | ||||
|     la ra, check5 | ||||
|     jalr t0 | ||||
| 
 | ||||
| check5: | ||||
|     li t0, 0x00001001800F0000   # unimplemented memory with upper all zero, lower mixed | ||||
|     la ra, check11 | ||||
|     jalr t0 | ||||
| 
 | ||||
| check11: | ||||
|     # SATP in SV39 mode | ||||
|     li t0, 0x8000000000000000 | ||||
|     csrw satp, t0 | ||||
| 
 | ||||
|     // check virtual addresses with bits 63:47 and/or 46:38 being equal or unequal | ||||
|     li t0, 0x00000001800F0000   # unimplemented memory with upper and lower all zero | ||||
|     la ra, check12 | ||||
|     jalr t0 | ||||
| 
 | ||||
| check12: | ||||
|     li t0, 0xFFFFFFF1800F0000   # unimplemented memory with upper and lower all one | ||||
|     la ra, check13 | ||||
|     jalr t0 | ||||
| 
 | ||||
| check13: | ||||
|     li t0, 0xFFF81001800F0000   # unimplemented memory with upper all one, lower mixed | ||||
|     la ra, check14 | ||||
|     jalr t0 | ||||
| 
 | ||||
| check14: | ||||
|     li t0, 0x03001001800F0000   # unimplemented memory with upper mixed, lower mixed | ||||
|     la ra, check15 | ||||
|     jalr t0 | ||||
| 
 | ||||
| check15: | ||||
|     li t0, 0x00001001800F0000   # unimplemented memory with upper all zero, lower mixed | ||||
|     la ra, check16 | ||||
|     jalr t0 | ||||
| 
 | ||||
| check16: | ||||
| 
 | ||||
| write_tohost: | ||||
|     la t1, tohost | ||||
|     li t0, 1            # 1 for success, 3 for failure | ||||
|     sd t0, 0(t1)        # send success code | ||||
| 
 | ||||
| self_loop: | ||||
|     j self_loop         # wait | ||||
| 
 | ||||
| .align 4                # trap handlers must be aligned to multiple of 4 | ||||
| trap_handler: | ||||
|     csrw mepc, ra       # return to address in ra | ||||
|     mret | ||||
|      | ||||
| .section .tohost  | ||||
| tohost:                 # write to HTIF | ||||
|     .dword 0
 | ||||
| fromhost: | ||||
|     .dword 0
 | ||||
| 
 | ||||
| 
 | ||||
| # Initialize stack with room for 512 bytes | ||||
| .bss | ||||
|     .space 512
 | ||||
| topofstack: | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|     j done | ||||
| 
 | ||||
|     lw t1, 0(t0) | ||||
|     li t0, 0xFFFFFFFF80000000 | ||||
|     lw t1, 0(t0) | ||||
|     li t1, 0xFFF8000080000000 | ||||
|     lw t1, 0(t0) | ||||
|     li t1, 0x1000000080000000 | ||||
|     lw t1, 0(t0) | ||||
|     li t1, 0x0000010080000000 | ||||
|     lw t1, 0(t0) | ||||
|    li t0, 0x8000000000000000  | ||||
|    csrw satp, t0   # SV39 mode | ||||
|     li t0, 0x0000000080000000 | ||||
|     lw t1, 0(t0) | ||||
|     li t0, 0xFFFFFFFF80000000 | ||||
|     lw t1, 0(t0) | ||||
|     li t1, 0xFFF8000080000000 | ||||
|     lw t1, 0(t0) | ||||
|     li t1, 0x1000000080000000 | ||||
|     lw t1, 0(t0) | ||||
|     li t1, 0x0000010080000000 | ||||
|     lw t1, 0(t0) | ||||
|    li t0, 0x9000000000000000  | ||||
|    csrw satp, t0   # SV48 mode | ||||
|     li t0, 0x0000000080000000 | ||||
|     lw t1, 0(t0) | ||||
|     li t0, 0xFFFFFFFF80000000 | ||||
|     lw t1, 0(t0) | ||||
|     li t1, 0xFFF8000080000000 | ||||
|     lw t1, 0(t0) | ||||
|     li t1, 0x1000000080000000 | ||||
|     lw t1, 0(t0) | ||||
|     li t1, 0x0000010080000000 | ||||
|     lw t1, 0(t0) | ||||
|    li t0, 0x0000000000000000  | ||||
|    csrw satp, t0   # disable virtual memory | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user