Merge branch 'main' of github.com:davidharrishmc/riscv-wally into main

This commit is contained in:
Ross Thompson 2022-02-16 09:48:16 -06:00
commit c56c4db47f
44 changed files with 4734 additions and 823 deletions

View File

@ -22,7 +22,7 @@ def main():
break
checkpoint = checkpointList[0]
logFile = logDir+"checkpoint"+str(checkpoint)+".log"
runCommand="{\nvsim -c <<!\ndo wally-buildroot-batch.do 0 "+str(checkpoint+1)+" "+str(checkpoint)+"\n!\n} | tee "+logFile
runCommand="{\nvsim -c <<!\ndo wally-pipelined-batch.do buildroot buildroot 0 "+str(checkpoint+1)+" "+str(checkpoint)+"\n!\n} | tee "+logFile
print(runCommand)
os.system(runCommand)
try:

View File

@ -98,6 +98,7 @@ module ifu (
logic [`XLEN-1:0] PCD;
localparam [31:0] nop = 32'h00000013; // instruction for NOP
logic [31:0] NextInstrD, NextInstrE;
logic [`XLEN-1:0] PCBPWrongInvalidate;
@ -308,8 +309,10 @@ module ifu (
flopenr #(`XLEN) InstrMisalignedAdrReg(clk, reset, ~StallM, PCNextF, InstrMisalignedAdrM);
// Instruction and PC/PCLink pipeline registers
flopenr #(32) InstrEReg(clk, reset, ~StallE, FlushE ? nop : InstrD, InstrE);
flopenr #(32) InstrMReg(clk, reset, ~StallM, FlushM ? nop : InstrE, InstrM);
mux2 #(32) FlushInstrEMux(InstrD, nop, FlushE, NextInstrD);
mux2 #(32) FlushInstrMMux(InstrE, nop, FlushM, NextInstrE);
flopenr #(32) InstrEReg(clk, reset, ~StallE, NextInstrD, InstrE);
flopenr #(32) InstrMReg(clk, reset, ~StallM, NextInstrE, InstrM);
flopenr #(`XLEN) PCEReg(clk, reset, ~StallE, PCD, PCE);
flopenr #(`XLEN) PCMReg(clk, reset, ~StallM, PCE, PCM);
flopenr #(`XLEN) PCPDReg(clk, reset, ~StallD, PCPlus2or4F, PCLinkD);

View File

@ -190,7 +190,7 @@ module hptw
LEAF: NextWalkerState = IDLE; // updates TLB
default: begin
// synthesis translate_off
$error("Default state in HPTW should be unreachable");
$error("Default state in HPTW should be unreachable; was %d", WalkerState);
// synthesis translate_on
NextWalkerState = IDLE; // should never be reached
end

View File

@ -42,7 +42,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, uretM,
input logic CSRReadM, CSRWriteM, TrapM, MTrapM, STrapM, UTrapM, mretM, sretM,
input logic TimerIntM, ExtIntM, SwIntM,
input logic [63:0] MTIME_CLINT,
input logic InstrValidM, FRegWriteM, LoadStallD,
@ -59,8 +59,8 @@ module csr #(parameter
input logic [`XLEN-1:0] CauseM, NextFaultMtvalM,
output logic [1:0] STATUS_MPP,
output logic STATUS_SPP, STATUS_TSR,
output logic [`XLEN-1:0] MEPC_REGW, SEPC_REGW, UEPC_REGW, UTVEC_REGW, STVEC_REGW, MTVEC_REGW,
output logic [`XLEN-1:0] MEDELEG_REGW, MIDELEG_REGW, SEDELEG_REGW, SIDELEG_REGW,
output logic [`XLEN-1:0] MEPC_REGW, SEPC_REGW, STVEC_REGW, MTVEC_REGW,
output logic [`XLEN-1:0] MEDELEG_REGW, MIDELEG_REGW,
output logic [`XLEN-1:0] SATP_REGW,
output logic [11:0] MIP_REGW, MIE_REGW, SIP_REGW, SIE_REGW,
output logic STATUS_MIE, STATUS_SIE,
@ -76,12 +76,12 @@ module csr #(parameter
);
localparam NOP = 32'h13;
logic [`XLEN-1:0] CSRMReadValM, CSRSReadValM, CSRUReadValM, CSRNReadValM, CSRCReadValM, CSRReadValM;
logic [`XLEN-1:0] CSRMReadValM, CSRSReadValM, CSRUReadValM, CSRCReadValM, CSRReadValM;
logic [`XLEN-1:0] CSRSrcM, CSRRWM, CSRRSM, CSRRCM, CSRWriteValM;
(* mark_debug = "true" *) logic [`XLEN-1:0] MSTATUS_REGW, SSTATUS_REGW, USTATUS_REGW;
(* mark_debug = "true" *) logic [`XLEN-1:0] MSTATUS_REGW, SSTATUS_REGW;
logic [31:0] MCOUNTINHIBIT_REGW, MCOUNTEREN_REGW, SCOUNTEREN_REGW;
logic WriteMSTATUSM, WriteSSTATUSM, WriteUSTATUSM;
logic WriteMSTATUSM, WriteSSTATUSM;
logic CSRMWriteM, CSRSWriteM, CSRUWriteM;
logic STATUS_TVM;
logic WriteFRMM, WriteFFLAGSM;
@ -90,7 +90,7 @@ module csr #(parameter
logic [11:0] CSRAdrM;
//logic [11:0] UIP_REGW, UIE_REGW = 0; // N user-mode exceptions not supported
logic IllegalCSRCAccessM, IllegalCSRMAccessM, IllegalCSRSAccessM, IllegalCSRUAccessM, IllegalCSRNAccessM, InsufficientCSRPrivilegeM;
logic IllegalCSRCAccessM, IllegalCSRMAccessM, IllegalCSRSAccessM, IllegalCSRUAccessM, InsufficientCSRPrivilegeM;
logic IllegalCSRMWriteReadonlyM;
logic InstrValidNotFlushedM;
@ -126,10 +126,10 @@ module csr #(parameter
.CSRAdrM, .ExtIntM, .TimerIntM, .SwIntM,
.MIDELEG_REGW, .MIP_REGW, .MIE_REGW, .SIP_REGW, .SIE_REGW, .CSRWriteValM);
csrsr csrsr(.clk, .reset, .StallW,
.WriteMSTATUSM, .WriteSSTATUSM, .WriteUSTATUSM,
.WriteMSTATUSM, .WriteSSTATUSM,
.TrapM, .FRegWriteM, .NextPrivilegeModeM, .PrivilegeModeW,
.mretM, .sretM, .uretM, .WriteFRMM, .WriteFFLAGSM, .CSRWriteValM,
.MSTATUS_REGW, .SSTATUS_REGW, .USTATUS_REGW,
.mretM, .sretM, .WriteFRMM, .WriteFFLAGSM, .CSRWriteValM,
.MSTATUS_REGW, .SSTATUS_REGW,
.STATUS_MPP, .STATUS_SPP, .STATUS_TSR, .STATUS_TW,
.STATUS_MIE, .STATUS_SIE, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_TVM);
csrc counters(.clk, .reset,
@ -153,27 +153,22 @@ module csr #(parameter
.NextEPCM, .NextCauseM, .NextMtvalM, .SSTATUS_REGW,
.STATUS_TVM, .CSRWriteValM, .PrivilegeModeW,
.CSRSReadValM, .STVEC_REGW, .SEPC_REGW,
.SCOUNTEREN_REGW, .SEDELEG_REGW, .SIDELEG_REGW,
.SCOUNTEREN_REGW,
.SATP_REGW, .SIP_REGW, .SIE_REGW,
.WriteSSTATUSM, .IllegalCSRSAccessM);
csrn csrn(.clk, .reset, .InstrValidNotFlushedM, .StallW,
.CSRNWriteM(CSRUWriteM), .UTrapM, .CSRAdrM,
.NextEPCM, .NextCauseM, .NextMtvalM, .USTATUS_REGW,
.CSRWriteValM, .CSRNReadValM, .UEPC_REGW, .UTVEC_REGW,
.UIP_REGW, .UIE_REGW, .WriteUSTATUSM, .IllegalCSRNAccessM);
csru csru(.clk, .reset, .InstrValidNotFlushedM, .StallW,
.CSRUWriteM, .CSRAdrM, .CSRWriteValM, .CSRUReadValM,
.SetFflagsM, .FRM_REGW, .WriteFRMM, .WriteFFLAGSM,
.IllegalCSRUAccessM);
// merge CSR Reads
assign CSRReadValM = CSRUReadValM | CSRSReadValM | CSRMReadValM | CSRCReadValM | CSRNReadValM;
assign CSRReadValM = CSRUReadValM | CSRSReadValM | CSRMReadValM | CSRCReadValM;
flopenrc #(`XLEN) CSRValWReg(clk, reset, FlushW, ~StallW, CSRReadValM, CSRReadValW);
// merge illegal accesses: illegal if none of the CSR addresses is legal or privilege is insufficient
assign InsufficientCSRPrivilegeM = (CSRAdrM[9:8] == 2'b11 & PrivilegeModeW != `M_MODE) |
(CSRAdrM[9:8] == 2'b01 & PrivilegeModeW == `U_MODE);
assign IllegalCSRAccessM = ((IllegalCSRCAccessM & IllegalCSRMAccessM &
IllegalCSRSAccessM & IllegalCSRUAccessM & IllegalCSRNAccessM |
IllegalCSRSAccessM & IllegalCSRUAccessM |
InsufficientCSRPrivilegeM) & CSRReadM) | IllegalCSRMWriteReadonlyM;
endmodule

View File

@ -111,14 +111,5 @@ module csri #(parameter
SIP_REGW = 12'b0;
SIE_REGW = 12'b0;
end
// User Modes iterrupts depricated
/*if (`U_SUPPORTED & `N_SUPPORTED) begin
UIP_REGW = IP_REGW & MIDELEG_REGW & SIDELEG_REGW & 'h111; // only delegated interrupts visible
UIE_REGW = IE_REGW & MIDELEG_REGW & SIDELEG_REGW & 'h111; // only delegated interrupts visible
end else begin
UIP_REGW = 12'b0;
UIE_REGW = 12'b0;
end */
end
endmodule

View File

@ -146,7 +146,7 @@ module csrm #(parameter
// CSRs
flopenr #(`XLEN) MTVECreg(clk, reset, WriteMTVECM, {CSRWriteValM[`XLEN-1:2], 1'b0, CSRWriteValM[0]}, MTVEC_REGW);
if (`S_SUPPORTED | (`U_SUPPORTED & `N_SUPPORTED)) begin:deleg // DELEG registers should exist
if (`S_SUPPORTED) begin:deleg // DELEG registers should exist
flopenr #(`XLEN) MEDELEGreg(clk, reset, WriteMEDELEGM, CSRWriteValM & MEDELEG_MASK /*12'h7FF*/, MEDELEG_REGW);
flopenr #(`XLEN) MIDELEGreg(clk, reset, WriteMIDELEGM, CSRWriteValM & MIDELEG_MASK /*12'h222*/, MIDELEG_REGW);
end else assign {MEDELEG_REGW, MIDELEG_REGW} = 0;
@ -165,8 +165,7 @@ module csrm #(parameter
logic [5:0] entry;
always_comb begin
entry = '0;
IllegalCSRMAccessM = !(`S_SUPPORTED | `U_SUPPORTED & `N_SUPPORTED) &
(CSRAdrM == MEDELEG | CSRAdrM == MIDELEG); // trap on DELEG register access when no S or N-mode
IllegalCSRMAccessM = !(`S_SUPPORTED) & (CSRAdrM == MEDELEG | CSRAdrM == MIDELEG); // trap on DELEG register access when no S or N-mode
if (CSRAdrM >= PMPADDR0 & CSRAdrM < PMPADDR0 + `PMP_ENTRIES) // reading a PMP entry
CSRMReadValM = PMPADDR_ARRAY_REGW[CSRAdrM - PMPADDR0];
else if (CSRAdrM >= PMPCFG0 & CSRAdrM < PMPCFG0 + `PMP_ENTRIES/4) begin

View File

@ -1,103 +0,0 @@
///////////////////////////////////////////
// csrn.sv
//
// Written: David_Harris@hmc.edu 9 January 2021
// Modified:
// dottolia@hmc.edu 3 May 2021 - fix bug with utvec getting wrong value
//
// Purpose: User-Mode Control and Status Registers for User Mode Exceptions
// See RISC-V Privileged Mode Specification 20190608 Table 2.2
//
// 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 csrn #(parameter
USTATUS =12'h000,
UIE = 12'h004,
UTVEC = 12'h005,
USCRATCH = 12'h040,
UEPC = 12'h041,
UCAUSE = 12'h042,
UTVAL = 12'h043,
UIP = 12'h044) (
input logic clk, reset,
input logic InstrValidNotFlushedM, StallW,
input logic CSRNWriteM, UTrapM,
input logic [11:0] CSRAdrM,
input logic [`XLEN-1:0] NextEPCM, NextCauseM, NextMtvalM, USTATUS_REGW,
input logic [`XLEN-1:0] CSRWriteValM,
output logic [`XLEN-1:0] CSRNReadValM, UEPC_REGW, UTVEC_REGW,
input logic [11:0] UIP_REGW, UIE_REGW,
output logic WriteUSTATUSM,
output logic IllegalCSRNAccessM
);
// User mode CSRs below only needed when user mode traps are supported
if (`N_SUPPORTED) begin:nmode // depricated; consider removing***
logic WriteUTVECM;
logic WriteUSCRATCHM, WriteUEPCM;
logic WriteUCAUSEM, WriteUTVALM;
logic [`XLEN-1:0] UEDELEG_REGW, UIDELEG_REGW;
logic [`XLEN-1:0] USCRATCH_REGW, UCAUSE_REGW, UTVAL_REGW;
// Write enables
assign WriteUSTATUSM = CSRNWriteM & (CSRAdrM == USTATUS) & InstrValidNotFlushedM;
assign WriteUTVECM = CSRNWriteM & (CSRAdrM == UTVEC) & InstrValidNotFlushedM;
assign WriteUEPCM = UTrapM | (CSRNWriteM & (CSRAdrM == UEPC)) & InstrValidNotFlushedM;
assign WriteUCAUSEM = UTrapM | (CSRNWriteM & (CSRAdrM == UCAUSE)) & InstrValidNotFlushedM;
assign WriteUTVALM = UTrapM | (CSRNWriteM & (CSRAdrM == UTVAL)) & InstrValidNotFlushedM;
// CSRs
flopenl #(`XLEN) UTVECreg(clk, reset, WriteUTVECM, {CSRWriteValM[`XLEN-1:2], 1'b0, CSRWriteValM[0]}, `RESET_VECTOR, UTVEC_REGW);
flopenr #(`XLEN) USCRATCHreg(clk, reset, WriteUSCRATCHM, CSRWriteValM, USCRATCH_REGW);
flopenr #(`XLEN) UEPCreg(clk, reset, WriteUEPCM, NextEPCM, UEPC_REGW);
flopenr #(`XLEN) UCAUSEreg(clk, reset, WriteUCAUSEM, NextCauseM, UCAUSE_REGW);
flopenr #(`XLEN) UTVALreg(clk, reset, WriteUTVALM, NextMtvalM, UTVAL_REGW);
// CSR Reads
always_comb begin
IllegalCSRNAccessM = 0;
case (CSRAdrM)
USTATUS: CSRNReadValM = USTATUS_REGW;
UTVEC: CSRNReadValM = UTVEC_REGW;
UIP: CSRNReadValM = {{(`XLEN-12){1'b0}}, UIP_REGW};
UIE: CSRNReadValM = {{(`XLEN-12){1'b0}}, UIE_REGW};
USCRATCH: CSRNReadValM = USCRATCH_REGW;
UEPC: CSRNReadValM = UEPC_REGW;
UCAUSE: CSRNReadValM = UCAUSE_REGW;
UTVAL: CSRNReadValM = UTVAL_REGW;
default: begin
CSRNReadValM = 0;
IllegalCSRNAccessM = 1;
end
endcase
end
end else begin // if not supported
assign WriteUSTATUSM = 0;
assign CSRNReadValM = 0;
assign UEPC_REGW = 0;
assign UTVEC_REGW = 0;
assign IllegalCSRNAccessM = 1;
end
endmodule

View File

@ -35,8 +35,6 @@
module csrs #(parameter
// Supervisor CSRs
SSTATUS = 12'h100,
SEDELEG = 12'h102,
SIDELEG = 12'h103,
SIE = 12'h104,
STVEC = 12'h105,
SCOUNTEREN = 12'h106,
@ -62,7 +60,6 @@ module csrs #(parameter
output logic [`XLEN-1:0] CSRSReadValM, STVEC_REGW,
(* mark_debug = "true" *) output logic [`XLEN-1:0] SEPC_REGW,
output logic [31:0] SCOUNTEREN_REGW,
output logic [`XLEN-1:0] SEDELEG_REGW, SIDELEG_REGW,
output logic [`XLEN-1:0] SATP_REGW,
(* mark_debug = "true" *) input logic [11:0] SIP_REGW, SIE_REGW,
output logic WriteSSTATUSM,
@ -102,27 +99,12 @@ module csrs #(parameter
assign SATP_REGW = 0; // hardwire to zero if virtual memory not supported
flopens #(32) SCOUNTERENreg(clk, reset, WriteSCOUNTERENM, CSRWriteValM[31:0], SCOUNTEREN_REGW);
if (`N_SUPPORTED) begin:nregs
logic WriteSEDELEGM, WriteSIDELEGM;
assign WriteSEDELEGM = CSRSWriteM & (CSRAdrM == SEDELEG);
assign WriteSIDELEGM = CSRSWriteM & (CSRAdrM == SIDELEG);
flopenr #(`XLEN) SEDELEGreg(clk, reset, WriteSEDELEGM, CSRWriteValM & SEDELEG_MASK, SEDELEG_REGW);
flopenr #(`XLEN) SIDELEGreg(clk, reset, WriteSIDELEGM, CSRWriteValM, SIDELEG_REGW);
end else begin
assign SEDELEG_REGW = 0;
assign SIDELEG_REGW = 0;
end
// CSR Reads
always_comb begin:csrr
IllegalCSRSAccessM = !(`N_SUPPORTED) & (CSRAdrM == SEDELEG | CSRAdrM == SIDELEG); // trap on DELEG register access when no N-mode
IllegalCSRSAccessM = 0;
case (CSRAdrM)
SSTATUS: CSRSReadValM = SSTATUS_REGW;
STVEC: CSRSReadValM = STVEC_REGW;
// SIDELEG: CSRSReadValM = {{(`XLEN-12){1'b0}}, SIDELEG_REGW};
// SEDELEG: CSRSReadValM = {{(`XLEN-12){1'b0}}, SEDELEG_REGW};
SIDELEG: CSRSReadValM = SIDELEG_REGW;
SEDELEG: CSRSReadValM = SEDELEG_REGW;
SIP: CSRSReadValM = {{(`XLEN-12){1'b0}}, SIP_REGW};
SIE: CSRSReadValM = {{(`XLEN-12){1'b0}}, SIE_REGW};
SSCRATCH: CSRSReadValM = SSCRATCH_REGW;
@ -146,8 +128,6 @@ module csrs #(parameter
assign CSRSReadValM = 0;
assign SEPC_REGW = 0;
assign STVEC_REGW = 0;
assign SEDELEG_REGW = 0;
assign SIDELEG_REGW = 0;
assign SCOUNTEREN_REGW = 0;
assign SATP_REGW = 0;
assign IllegalCSRSAccessM = 1;

View File

@ -33,13 +33,13 @@
module csrsr (
input logic clk, reset, StallW,
input logic WriteMSTATUSM, WriteSSTATUSM, WriteUSTATUSM,
input logic WriteMSTATUSM, WriteSSTATUSM,
input logic TrapM, FRegWriteM,
input logic [1:0] NextPrivilegeModeM, PrivilegeModeW,
input logic mretM, sretM, uretM,
input logic mretM, sretM,
input logic WriteFRMM, WriteFFLAGSM,
input logic [`XLEN-1:0] CSRWriteValM,
output logic [`XLEN-1:0] MSTATUS_REGW, SSTATUS_REGW, USTATUS_REGW,
output logic [`XLEN-1:0] MSTATUS_REGW, SSTATUS_REGW,
output logic [1:0] STATUS_MPP,
output logic STATUS_SPP, STATUS_TSR, STATUS_TW,
output logic STATUS_MIE, STATUS_SIE,
@ -66,11 +66,6 @@ module csrsr (
STATUS_XS, STATUS_FS, /*STATUS_MPP, 2'b0*/ 4'b0,
STATUS_SPP, /*STATUS_MPIE, 1'b0*/ 2'b0, STATUS_SPIE, STATUS_UPIE,
/*STATUS_MIE, 1'b0*/ 2'b0, STATUS_SIE, STATUS_UIE};
assign USTATUS_REGW = {/*STATUS_SD, */ 59'b0, /*STATUS_SXL, STATUS_UXL, 9'b0, */
/*STATUS_TSR, STATUS_TW, STATUS_TVM, STATUS_MXR, STATUS_SUM, STATUS_MPRV, , 1'b0,*/
/* STATUS_XS, STATUS_FS, /*STATUS_MPP, 8'b0, */
/*STATUS_SPP, STATUS_MPIE, 1'b0 2'b0, STATUS_SPIE,*/ STATUS_UPIE,
/*STATUS_MIE, 1'b0*/ 3'b0, /*STATUS_SIE, */STATUS_UIE};
end else begin: csrsr32 // RV32
assign MSTATUS_REGW = {STATUS_SD, 8'b0,
STATUS_TSR, STATUS_TW, STATUS_TVM, STATUS_MXR, STATUS_SUM, STATUS_MPRV,
@ -81,11 +76,6 @@ module csrsr (
STATUS_XS, STATUS_FS, /*STATUS_MPP, 2'b0*/ 4'b0,
STATUS_SPP, /*STATUS_MPIE, 1'b0*/ 2'b0, STATUS_SPIE, STATUS_UPIE,
/*STATUS_MIE, 1'b0*/ 2'b0, STATUS_SIE, STATUS_UIE};
assign USTATUS_REGW = {/*STATUS_SD, */ 27'b0, /*STATUS_SXL, STATUS_UXL, 9'b0, */
/*STATUS_TSR, STATUS_TW, STATUS_TVM, STATUS_MXR, STATUS_SUM, STATUS_MPRV, , 1'b0,*/
/*STATUS_XS, STATUS_FS, STATUS_MPP, 8'b0, */
/*STATUS_SPP, STATUS_MPIE, 1'b0 2'b0, STATUS_SPIE,*/ STATUS_UPIE,
/*STATUS_MIE, 1'b0*/ 3'b0, /*STATUS_SIE, */STATUS_UIE};
end
// harwired STATUS bits
@ -156,9 +146,6 @@ module csrsr (
STATUS_SPIE <= #1 `S_SUPPORTED;
STATUS_SPP <= #1 0; // Privileged 4.1.1
STATUS_MPRV_INT <= #1 0; // per 20210108 draft spec
end else if (uretM) begin
STATUS_UIE <= #1 STATUS_UPIE;
STATUS_UPIE <= #1 `U_SUPPORTED;
end else if (WriteMSTATUSM) begin
STATUS_TSR_INT <= #1 CSRWriteValM[22];
STATUS_TW_INT <= #1 CSRWriteValM[21];
@ -184,10 +171,6 @@ module csrsr (
STATUS_UPIE <= #1 `U_SUPPORTED & CSRWriteValM[4];
STATUS_SIE <= #1 `S_SUPPORTED & CSRWriteValM[1];
STATUS_UIE <= #1 `U_SUPPORTED & CSRWriteValM[0];
end else if (WriteUSTATUSM) begin // write a subset of the STATUS bits
STATUS_FS_INT <= #1 CSRWriteValM[14:13];
STATUS_UPIE <= #1 `U_SUPPORTED & CSRWriteValM[4];
STATUS_UIE <= #1 `U_SUPPORTED & CSRWriteValM[0];
end
end
end
endmodule

View File

@ -37,12 +37,11 @@ module privdec (
input logic [1:0] PrivilegeModeW,
input logic STATUS_TSR,
output logic IllegalInstrFaultM,
output logic uretM, sretM, mretM, ecallM, ebreakM, wfiM, sfencevmaM);
output logic sretM, mretM, ecallM, ebreakM, wfiM, sfencevmaM);
logic IllegalPrivilegedInstrM;
// xRET defined in Privileged Spect 3.2.2
assign uretM = PrivilegedM & (InstrM[31:20] == 12'b000000000010) & `N_SUPPORTED;
assign sretM = PrivilegedM & (InstrM[31:20] == 12'b000100000010) & `S_SUPPORTED &
PrivilegeModeW[0] & ~STATUS_TSR;
assign mretM = PrivilegedM & (InstrM[31:20] == 12'b001100000010) & (PrivilegeModeW == `M_MODE);
@ -51,7 +50,7 @@ module privdec (
assign ebreakM = PrivilegedM & (InstrM[31:20] == 12'b000000000001);
assign wfiM = PrivilegedM & (InstrM[31:20] == 12'b000100000101);
assign sfencevmaM = PrivilegedM & (InstrM[31:25] == 7'b0001001);
assign IllegalPrivilegedInstrM = PrivilegedM & ~(uretM|sretM|mretM|ecallM|ebreakM|wfiM|sfencevmaM);
assign IllegalPrivilegedInstrM = PrivilegedM & ~(sretM|mretM|ecallM|ebreakM|wfiM|sfencevmaM);
assign IllegalInstrFaultM = (IllegalIEUInstrFaultM & IllegalFPUInstrM) | IllegalPrivilegedInstrM | IllegalCSRAccessM | TrappedSRETM; // *** generalize this for other instructions
// *** initially, wfi is nop

View File

@ -85,11 +85,10 @@ module privileged (
logic [1:0] NextPrivilegeModeM;
logic [`XLEN-1:0] CauseM, NextFaultMtvalM;
logic [`XLEN-1:0] MEPC_REGW, SEPC_REGW, UEPC_REGW, UTVEC_REGW, STVEC_REGW, MTVEC_REGW;
// logic [11:0] MEDELEG_REGW, MIDELEG_REGW, SEDELEG_REGW, SIDELEG_REGW;
logic [`XLEN-1:0] MEDELEG_REGW, MIDELEG_REGW, SEDELEG_REGW, SIDELEG_REGW;
logic [`XLEN-1:0] MEPC_REGW, SEPC_REGW, STVEC_REGW, MTVEC_REGW;
logic [`XLEN-1:0] MEDELEG_REGW, MIDELEG_REGW;
logic uretM, sretM, mretM, ecallM, ebreakM, wfiM, sfencevmaM;
logic sretM, mretM, ecallM, ebreakM, wfiM, sfencevmaM;
logic IllegalCSRAccessM;
logic IllegalIEUInstrFaultE, IllegalIEUInstrFaultM;
logic IllegalFPUInstrM;
@ -103,7 +102,7 @@ module privileged (
logic STATUS_SPP, STATUS_TSR, STATUS_TW;
logic STATUS_MIE, STATUS_SIE;
logic [11:0] MIP_REGW, MIE_REGW, SIP_REGW, SIE_REGW;
logic md, sd;
logic md;
logic StallMQ;
@ -112,36 +111,28 @@ module privileged (
///////////////////////////////////////////
// get bits of DELEG registers based on CAUSE
// assign md = CauseM[`XLEN-1] ? MIDELEG_REGW[CauseM[3:0]] : MEDELEG_REGW[CauseM[3:0]];
// assign sd = CauseM[`XLEN-1] ? SIDELEG_REGW[CauseM[3:0]] : SEDELEG_REGW[CauseM[3:0]]; // depricated
assign md = CauseM[`XLEN-1] ? MIDELEG_REGW[CauseM[`LOG_XLEN-1:0]] : MEDELEG_REGW[CauseM[`LOG_XLEN-1:0]];
assign sd = CauseM[`XLEN-1] ? SIDELEG_REGW[CauseM[`LOG_XLEN-1:0]] : SEDELEG_REGW[CauseM[`LOG_XLEN-1:0]]; // depricated
// PrivilegeMode FSM
always_comb begin
TrappedSRETM = 0;
if (mretM) NextPrivilegeModeM = STATUS_MPP;
if (mretM) NextPrivilegeModeM = STATUS_MPP;
else if (sretM)
if (STATUS_TSR & PrivilegeModeW == `S_MODE) begin
TrappedSRETM = 1;
NextPrivilegeModeM = PrivilegeModeW;
end else NextPrivilegeModeM = {1'b0, STATUS_SPP};
else if (uretM) NextPrivilegeModeM = `U_MODE;
NextPrivilegeModeM = PrivilegeModeW;
end else NextPrivilegeModeM = {1'b0, STATUS_SPP};
else if (TrapM) begin // Change privilege based on DELEG registers (see 3.1.8)
if (PrivilegeModeW == `U_MODE)
if (`N_SUPPORTED & `U_SUPPORTED & md & sd) NextPrivilegeModeM = `U_MODE;
else if (`S_SUPPORTED & md) NextPrivilegeModeM = `S_MODE;
else NextPrivilegeModeM = `M_MODE;
else if (PrivilegeModeW == `S_MODE)
if (`S_SUPPORTED & md) NextPrivilegeModeM = `S_MODE;
else NextPrivilegeModeM = `M_MODE;
else NextPrivilegeModeM = `M_MODE;
end else NextPrivilegeModeM = PrivilegeModeW;
if (`S_SUPPORTED & md & (PrivilegeModeW == `U_MODE | PrivilegeModeW == `S_MODE))
NextPrivilegeModeM = `S_MODE;
else NextPrivilegeModeM = `M_MODE;
end else NextPrivilegeModeM = PrivilegeModeW;
end
// *** WFI could be implemented here and depends on TW
flopenl #(2) privmodereg(clk, reset, ~StallW, NextPrivilegeModeM, `M_MODE, PrivilegeModeW);
// *** WFI could be implemented here and depends on TW
///////////////////////////////////////////
// decode privileged instructions
///////////////////////////////////////////
@ -149,7 +140,7 @@ module privileged (
privdec pmd(.InstrM(InstrM[31:20]),
.PrivilegedM, .IllegalIEUInstrFaultM, .IllegalCSRAccessM, .IllegalFPUInstrM, .TrappedSRETM,
.PrivilegeModeW, .STATUS_TSR, .IllegalInstrFaultM,
.uretM, .sretM, .mretM, .ecallM, .ebreakM, .wfiM, .sfencevmaM);
.sretM, .mretM, .ecallM, .ebreakM, .wfiM, .sfencevmaM);
///////////////////////////////////////////
// Control and Status Registers
@ -158,7 +149,7 @@ module privileged (
.FlushE, .FlushM, .FlushW,
.StallE, .StallM, .StallW,
.InstrM, .PCM, .SrcAM,
.CSRReadM, .CSRWriteM, .TrapM, .MTrapM, .STrapM, .UTrapM, .mretM, .sretM, .uretM,
.CSRReadM, .CSRWriteM, .TrapM, .MTrapM, .STrapM, .UTrapM, .mretM, .sretM,
.TimerIntM, .ExtIntM, .SwIntM,
.MTIME_CLINT,
.InstrValidM, .FRegWriteM, .LoadStallD,
@ -167,8 +158,8 @@ module privileged (
.NextPrivilegeModeM, .PrivilegeModeW,
.CauseM, .NextFaultMtvalM, .STATUS_MPP,
.STATUS_SPP, .STATUS_TSR,
.MEPC_REGW, .SEPC_REGW, .UEPC_REGW, .UTVEC_REGW, .STVEC_REGW, .MTVEC_REGW,
.MEDELEG_REGW, .MIDELEG_REGW, .SEDELEG_REGW, .SIDELEG_REGW,
.MEPC_REGW, .SEPC_REGW, .STVEC_REGW, .MTVEC_REGW,
.MEDELEG_REGW, .MIDELEG_REGW,
.SATP_REGW,
.MIP_REGW, .MIE_REGW, .SIP_REGW, .SIE_REGW,
.STATUS_MIE, .STATUS_SIE,
@ -216,9 +207,9 @@ module privileged (
.BreakpointFaultM, .LoadMisalignedFaultM, .StoreAmoMisalignedFaultM,
.LoadAccessFaultM, .StoreAmoAccessFaultM, .EcallFaultM, .InstrPageFaultM,
.LoadPageFaultM, .StoreAmoPageFaultM,
.mretM, .sretM, .uretM,
.mretM, .sretM,
.PrivilegeModeW, .NextPrivilegeModeM,
.MEPC_REGW, .SEPC_REGW, .UEPC_REGW, .UTVEC_REGW, .STVEC_REGW, .MTVEC_REGW,
.MEPC_REGW, .SEPC_REGW, .STVEC_REGW, .MTVEC_REGW,
.MIP_REGW, .MIE_REGW, .SIP_REGW, .SIE_REGW,
.STATUS_MIE, .STATUS_SIE,
.PCM,

View File

@ -38,9 +38,9 @@ module trap (
(* mark_debug = "true" *) input logic BreakpointFaultM, LoadMisalignedFaultM, StoreAmoMisalignedFaultM,
(* mark_debug = "true" *) input logic LoadAccessFaultM, StoreAmoAccessFaultM, EcallFaultM, InstrPageFaultM,
(* mark_debug = "true" *) input logic LoadPageFaultM, StoreAmoPageFaultM,
(* mark_debug = "true" *) input logic mretM, sretM, uretM,
(* 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, UEPC_REGW, UTVEC_REGW, STVEC_REGW, MTVEC_REGW,
(* 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,
input logic STATUS_MIE, STATUS_SIE,
input logic [`XLEN-1:0] PCM,
@ -84,15 +84,13 @@ module trap (
assign TrapM = ExceptionM | InterruptM; // *** clean this up later DH
assign MTrapM = TrapM & (NextPrivilegeModeM == `M_MODE);
assign STrapM = TrapM & (NextPrivilegeModeM == `S_MODE) & `S_SUPPORTED;
assign UTrapM = TrapM & (NextPrivilegeModeM == `U_MODE) & `N_SUPPORTED;
assign RetM = mretM | sretM | uretM;
assign RetM = mretM | sretM;
always_comb
if (NextPrivilegeModeM == `U_MODE) PrivilegedTrapVector = UTVEC_REGW;
else if (NextPrivilegeModeM == `S_MODE) PrivilegedTrapVector = STVEC_REGW;
else PrivilegedTrapVector = MTVEC_REGW;
if (NextPrivilegeModeM == `S_MODE) PrivilegedTrapVector = STVEC_REGW;
else PrivilegedTrapVector = MTVEC_REGW;
// Handle vectored traps (when mtvec/stvec/utvec csr value has bits [1:0] == 01)
// Handle vectored traps (when mtvec/stvec csr value has bits [1:0] == 01)
// For vectored traps, set program counter to _tvec value + 4 times the cause code
//
// POSSIBLE OPTIMIZATION:
@ -115,7 +113,6 @@ module trap (
always_comb
if (mretM) PrivilegedNextPCM = MEPC_REGW;
else if (sretM) PrivilegedNextPCM = SEPC_REGW;
else if (uretM) PrivilegedNextPCM = UEPC_REGW;
else PrivilegedNextPCM = PrivilegedVectoredTrapVector;
// Cause priority defined in table 3.7 of 20190608 privileged spec

1
pipelined/srt/lint-srt Executable file
View File

@ -0,0 +1 @@
verilator --lint-only --top-module srt srt.sv -I../config/rv64gc -I../config/shared ../src/generic/*.sv ../src/generic/flop/*.sv

View File

@ -1 +1 @@
vsim -c -do srt.do
vsim -c -do "do srt.do"

View File

@ -17,7 +17,7 @@ if [file exists work] {
}
vlib work
vlog +incdir+../config/rv64gc +incdir+../config/shared srt.sv ../src/generic/flop/flop*.sv ../src/generic/mux.sv
vlog +incdir+../config/rv64gc +incdir+../config/shared srt.sv testbench.sv ../src/generic/flop/flop*.sv ../src/generic/mux.sv ../src/fpu/unpacking.sv
vopt +acc work.testbench -o workopt
vsim workopt

View File

@ -273,135 +273,3 @@ module finaladd(
assign #1 r = diff[54] ? diff[53:2] : diff[52:1];
endmodule
/////////////
// counter //
/////////////
module counter(input logic clk,
input logic req,
output logic done);
logic [5:0] count;
// This block of control logic sequences the divider
// through its iterations. You may modify it if you
// build a divider which completes in fewer iterations.
// You are not responsible for the (trivial) circuit
// design of the block.
always @(posedge clk)
begin
if (count == 54) done <= #1 1;
else if (done | req) done <= #1 0;
if (req) count <= #1 0;
else count <= #1 count+1;
end
endmodule
///////////
// clock //
///////////
module clock(clk);
output clk;
// Internal clk signal
logic clk;
endmodule
//////////
// testbench //
//////////
module testbench;
logic clk;
logic req;
logic done;
logic [51:0] a;
logic [51:0] b;
logic [51:0] r;
logic [54:0] rp, rm; // positive quotient digits
// Test parameters
parameter MEM_SIZE = 40000;
parameter MEM_WIDTH = 52+52+52;
`define memr 51:0
`define memb 103:52
`define mema 155:104
// Test logicisters
logic [MEM_WIDTH-1:0] Tests [0:MEM_SIZE]; // Space for input file
logic [MEM_WIDTH-1:0] Vec; // Verilog doesn't allow direct access to a
// bit field of an array
logic [51:0] correctr, nextr, diffn, diffp;
integer testnum, errors;
// Divider
srt #(52) srt(.clk, .Start(req),
.Stall(1'b0), .Flush(1'b0),
.SrcXFrac(a), .SrcYFrac(b),
.SrcA('0), .SrcB('0), .Fmt(2'b00),
.W64(1'b0), .Signed(1'b0), .Int(1'b0), .Sqrt(1'b0),
.Quot(r), .Rem(), .Flags());
// Counter
counter counter(clk, req, done);
initial
forever
begin
clk = 1; #17;
clk = 0; #16;
end
// Read test vectors from disk
initial
begin
testnum = 0;
errors = 0;
$readmemh ("testvectors", Tests);
Vec = Tests[testnum];
a = Vec[`mema];
b = Vec[`memb];
nextr = Vec[`memr];
req <= #5 1;
end
// Apply directed test vectors read from file.
always @(posedge clk)
begin
if (done)
begin
req <= #5 1;
diffp = correctr - r;
diffn = r - correctr;
if (($signed(diffn) > 1) | ($signed(diffp) > 1)) // check if accurate to 1 ulp
begin
errors = errors+1;
$display("result was %h, should be %h %h %h\n", r, correctr, diffn, diffp);
$display("failed\n");
$stop;
end
if (a === 52'hxxxxxxxxxxxxx)
begin
$display("%d Tests completed successfully", testnum);
$stop;
end
end
if (req)
begin
req <= #5 0;
correctr = nextr;
testnum = testnum+1;
Vec = Tests[testnum];
$display("a = %h b = %h",a,b);
a = Vec[`mema];
b = Vec[`memb];
nextr = Vec[`memr];
end
end
endmodule

View File

@ -11,7 +11,52 @@
// This Verilog file models a radix 2 SRT divider which
// produces one quotient digit per cycle. The divider
// keeps the partial remainder in carry-save form.
`include "wally-config.vh"
// will also be used for integer division so keep in mind when naming modules/signals
/////////////////
// srt_divide //
////////////////
module srt_divide(input logic clk,
input logic req,
input logic sqrt, // 1 to compute sqrt(a), 0 to compute a/b
input logic [63:0] a, b, // input numbers
output logic [54:0] rp, rm,
output logic [10:0] expE);
// output logic from Unpackers
logic XSgnE, YSgnE, ZSgnE;
logic [10:0] XExpE, YExpE, ZExpE; // exponent
logic [52:0] XManE, YManE, ZManE;
logic XNormE;
logic XNaNE, YNaNE, ZNaNE;
logic XSNaNE, YSNaNE, ZSNaNE;
logic XDenormE, YDenormE, ZDenormE; // denormals
logic XZeroE, YZeroE, ZZeroE;
logic [10:0] BiasE; // currrently hardcoded, will probs be removed
logic XInfE, YInfE, ZInfE;
logic XExpMaxE; // says exponent is all ones, can ignore
// have Unpackers
// have mantissa divider
// exponent divider
// hopefully having the .* here works for unpacker --- nope it doesn't
unpack unpacking(a, b, 0, 1'b1, 0, XSgnE, YSgnE, ZSgnE, XExpE, YExpE, ZExpE, XManE, YManE, ZManE, XNormE,XNaNE, YNaNE, ZNaNE,XSNaNE, YSNaNE, ZSNaNE,XDenormE, YDenormE, ZDenormE,XZeroE, YZeroE, ZZeroE,BiasE,XInfE, YInfE, ZInfE,XExpMaxE);
srt srt(clk, req, XManE[51:0], YManE[51:0], rp, rm);
exp exp(XexpE, YExpE, expE);
endmodule
// exponent module
// first iteration
module exp(input [10:0] e1, e2,
output [10:0] e); // for a 64 bit number, exponent section is 11 bits
assign e = (e1 - e2) + 11'd1023; // bias is hardcoded
endmodule
/////////
// srt //
/////////
@ -39,12 +84,12 @@ module srt(input logic clk,
// When start is asserted, the inputs are loaded into the divider.
// Otherwise, the divisor is retained and the partial remainder
// is fed back for the next iteration.
mux2 psmux({psa[54:0], 1'b0}, {4'b0001, a}, req, psn);
flop psflop(clk, psn, ps);
mux2 pcmux({pca[54:0], 1'b0}, 56'b0, req, pcn);
flop pcflop(clk, pcn, pc);
mux2 dmux(d, {4'b0001, b}, req, dn);
flop dflop(clk, dn, d);
mux2_special psmux({psa[54:0], 1'b0}, {4'b0001, a}, req, psn);
flop_special psflop(clk, psn, ps);
mux2_special pcmux({pca[54:0], 1'b0}, 56'b0, req, pcn);
flop_special pcflop(clk, pcn, pc);
mux2_special dmux(d, {4'b0001, b}, req, dn);
flop_special dflop(clk, dn, d);
// Quotient Selection logic
// Given partial remainder, select quotient of +1, 0, or -1 (qp, qz, pm)
@ -54,7 +99,7 @@ module srt(input logic clk,
// Divisor Selection logic
inv dinv(d, d_b);
mux3 divisorsel(d_b, 56'b0, d, qp, qz, qm, dsel);
mux3_special divisorsel(d_b, 56'b0, d, qp, qz, qm, dsel);
// Partial Product Generation
csa csa(ps, pc, dsel, qp, psa, pca);
@ -63,7 +108,7 @@ endmodule
//////////
// mux2 //
//////////
module mux2(input logic [55:0] in0, in1,
module mux2_special(input logic [55:0] in0, in1,
input logic sel,
output logic [55:0] out);
@ -73,7 +118,7 @@ endmodule
//////////
// flop //
//////////
module flop(clk, in, out);
module flop_special(clk, in, out);
input clk;
input [55:0] in;
output [55:0] out;
@ -159,9 +204,9 @@ module inv(input logic [55:0] in,
endmodule
//////////
// mux3 //
// mux3_special //
//////////
module mux3(in0, in1, in2, sel0, sel1, sel2, out);
module mux3_special(in0, in1, in2, sel0, sel1, sel2, out);
input [55:0] in0;
input [55:0] in1;
input [55:0] in2;
@ -271,6 +316,24 @@ module testbench;
logic [51:0] b;
logic [51:0] r;
logic [54:0] rp, rm; // positive quotient digits
//input logic [63:0] X, Y, Z, - numbers
//input logic FmtE, ---- format, 1 is for double precision, 0 is single
//input logic [2:0] FOpCtrlE, ---- controling operations for FPU, 1 is sqrt, 0 is divide
// all variables are commented in fpu.sv
// output logic from Unpackers
logic XSgnE, YSgnE, ZSgnE;
logic [10:0] XExpE, YExpE, ZExpE; // exponent
logic [52:0] XManE, YManE, ZManE;
logic XNormE;
logic XNaNE, YNaNE, ZNaNE;
logic XSNaNE, YSNaNE, ZSNaNE;
logic XDenormE, YDenormE, ZDenormE; // denormals
logic XZeroE, YZeroE, ZZeroE;
logic [10:0] BiasE; // currrently hardcoded, will probs be removed
logic XInfE, YInfE, ZInfE;
logic XExpMaxE; // says exponent is all ones, can ignore
// Test parameters
parameter MEM_SIZE = 40000;
@ -287,8 +350,15 @@ module testbench;
logic [51:0] correctr, nextr;
integer testnum, errors;
// Unpackers
unpacking unpack(.X({12'b100010000010,a}), .Y({12'b100010000001,b}), .Z(0), .FmtE(1'b1), .FOpCtrlE(0), .*);
// Divider
srt srt(clk, req, a, b, rp, rm);
srt srt(.clk(clk), .req(req), .sqrt(1'b0), .a(XManE[51:0]), .b(YManE[51:0]), .rp(rp),.rm(rm));
//srt srt(.clk(clk), .req(req), .sqrt(1'b0), .a(a), .b(b), .rp(rp),.rm(rm));
// Divider + unpacker
// Final adder converts quotient digits to 2's complement & normalizes
finaladd finaladd(rp, rm, r);
@ -326,7 +396,9 @@ module testbench;
begin
req <= #5 1;
$display("result was %h, should be %h\n", r, correctr);
if ((correctr - r) > 1) // check if accurate to 1 ulp
//if (abs(correctr - r) > 1) // check if accurate to 1 ulp
// giving error "srt_stanford.sv(395): (vopt-7063) Failed to find 'abs' in hierarchical name 'abs'."
if (correctr - r > 1) // check if accurate to 1 ulp
begin
errors = errors+1;
$display("failed\n");

132
pipelined/srt/testbench.sv Normal file
View File

@ -0,0 +1,132 @@
/////////////
// counter //
/////////////
module counter(input logic clk,
input logic req,
output logic done);
logic [5:0] count;
// This block of control logic sequences the divider
// through its iterations. You may modify it if you
// build a divider which completes in fewer iterations.
// You are not responsible for the (trivial) circuit
// design of the block.
always @(posedge clk)
begin
if (count == 54) done <= #1 1;
else if (done | req) done <= #1 0;
if (req) count <= #1 0;
else count <= #1 count+1;
end
endmodule
///////////
// clock //
///////////
module clock(clk);
output clk;
// Internal clk signal
logic clk;
endmodule
//////////
// testbench //
//////////
module testbench;
logic clk;
logic req;
logic done;
logic [51:0] a;
logic [51:0] b;
logic [51:0] r;
logic [54:0] rp, rm; // positive quotient digits
// Test parameters
parameter MEM_SIZE = 40000;
parameter MEM_WIDTH = 52+52+52;
`define memr 51:0
`define memb 103:52
`define mema 155:104
// Test logicisters
logic [MEM_WIDTH-1:0] Tests [0:MEM_SIZE]; // Space for input file
logic [MEM_WIDTH-1:0] Vec; // Verilog doesn't allow direct access to a
// bit field of an array
logic [51:0] correctr, nextr, diffn, diffp;
integer testnum, errors;
// Divider
srt #(52) srt(.clk, .Start(req),
.Stall(1'b0), .Flush(1'b0),
.SrcXFrac(a), .SrcYFrac(b),
.SrcA('0), .SrcB('0), .Fmt(2'b00),
.W64(1'b0), .Signed(1'b0), .Int(1'b0), .Sqrt(1'b0),
.Quot(r), .Rem(), .Flags());
// Counter
counter counter(clk, req, done);
initial
forever
begin
clk = 1; #17;
clk = 0; #16;
end
// Read test vectors from disk
initial
begin
testnum = 0;
errors = 0;
$readmemh ("testvectors", Tests);
Vec = Tests[testnum];
a = Vec[`mema];
b = Vec[`memb];
nextr = Vec[`memr];
req <= #5 1;
end
// Apply directed test vectors read from file.
always @(posedge clk)
begin
if (done)
begin
req <= #5 1;
diffp = correctr - r;
diffn = r - correctr;
if (($signed(diffn) > 1) | ($signed(diffp) > 1)) // check if accurate to 1 ulp
begin
errors = errors+1;
$display("result was %h, should be %h %h %h\n", r, correctr, diffn, diffp);
$display("failed\n");
$stop;
end
if (a === 52'hxxxxxxxxxxxxx)
begin
$display("%d Tests completed successfully", testnum);
$stop;
end
end
if (req)
begin
req <= #5 0;
correctr = nextr;
testnum = testnum+1;
Vec = Tests[testnum];
$display("a = %h b = %h",a,b);
a = Vec[`mema];
b = Vec[`memb];
nextr = Vec[`memr];
end
end
endmodule

View File

@ -28,7 +28,7 @@ double random_input(void);
void main(void)
{
FILE *fptr;
double a, b, r;
double x1, x2, a, b, r;
double list[ENTRIES] = {1, 1.5, 1.25, 1.125, 1.0625,
1.75, 1.875, 1.99999,
1.1, 1.2, 1.01, 1.001, 1.0001,
@ -63,6 +63,7 @@ void main(void)
void output(FILE *fptr, double a, double b, double r)
{
printhex(fptr, a);
fprintf(fptr, "_");
printhex(fptr, b);

View File

@ -102,7 +102,6 @@ module instrNameDecTB(
10'b1101111_???: name = "JAL";
10'b1110011_000: if (imm == 0) name = "ECALL";
else if (imm == 1) name = "EBREAK";
else if (imm == 2) name = "URET";
else if (imm == 258) name = "SRET";
else if (imm == 770) name = "MRET";
else if (funct7 == 9) name = "SFENCE.VMA";

View File

@ -1483,13 +1483,13 @@ string imperas32f[] = '{
string wally64priv[] = '{
`WALLYTEST,
"rv64i_m/privilege/WALLY-MMU-SV39", "30A0",
"rv64i_m/privilege/WALLY-MMU-SV48", "30A0",
"rv64i_m/privilege/WALLY-PMP", "30A0",
"rv64i_m/privilege/WALLY-PMA", "30A0",
"rv64i_m/privilege/WALLY-minfo-01", "30A0",
"rv64i_m/privilege/WALLY-CSR-permission-s-01", "40A0",
"rv64i_m/privilege/WALLY-CSR-permission-u-01", "40A0"
"rv64i_m/privilege/WALLY-MMU-SV39", "40A0",
"rv64i_m/privilege/WALLY-MMU-SV48", "40A0",
"rv64i_m/privilege/WALLY-PMP", "40A0",
"rv64i_m/privilege/WALLY-PMA", "40A0",
"rv64i_m/privilege/WALLY-minfo-01", "40A0",
"rv64i_m/privilege/WALLY-CSR-permission-s-01", "50A0",
"rv64i_m/privilege/WALLY-CSR-permission-u-01", "50A0"
};
string wally64periph[] = '{
@ -1548,9 +1548,11 @@ string wally32i[] = '{
string wally32priv[] = '{
`WALLYTEST,
"rv32i_m/privilege/WALLY-MMU-SV32", "3080",
"rv32i_m/privilege/WALLY-PMP", "3080",
"rv32i_m/privilege/WALLY-PMA", "3080"
"rv32i_m/privilege/WALLY-MMU-SV32", "4080",
"rv32i_m/privilege/WALLY-PMP", "4080",
"rv32i_m/privilege/WALLY-CSR-permission-s-01", "5080",
"rv32i_m/privilege/WALLY-CSR-permission-u-01", "5080",
"rv32i_m/privilege/WALLY-minfo-01", "4080"
};
string wally32periph[] = '{

View File

@ -7,7 +7,14 @@ NAME := synth
export DESIGN ?= wallypipelinedcore
export FREQ ?= 500
export CONFIG ?= rv32e
# sky130 and sky90 presently supported
export TECH ?= sky130
# MAXCORES allows parallel compilation, which is faster but less CPU-efficient
# Avoid when doing sweeps of many optimization points in parallel
export MAXCORES ?= 4
# MAXOPT turns on flattening, boundary optimization, and retiming
# The output netlist is hard to interpret, but significantly better PPA
export MAXOPT ?= 0
time := $(shell date +%F-%H-%M)
hash := $(shell git rev-parse --short HEAD)

View File

@ -10,6 +10,9 @@ suppress_message {VER-130}
suppress_message {VER-281}
suppress_message {VER-173}
# Enable Multicore
set_host_options -max_cores $::env(MAXCORES)
# get outputDir from environment (Makefile)
set outputDir $::env(OUTPUTDIR)
set cfgName $::env(CONFIG)
@ -17,6 +20,7 @@ set cfgName $::env(CONFIG)
set hdl_src "../pipelined/src"
set cfg "${hdl_src}/../config/${cfgName}/wally-config.vh"
set saifpower $::env(SAIFPOWER)
set maxopt $::env(MAXOPT)
eval file copy -force ${cfg} {hdl/}
eval file copy -force ${cfg} $outputDir
@ -65,7 +69,7 @@ if { $saifpower == 1 } {
# Set reset false path
set_false_path -from [get_ports reset]
# Set Frequency in [MHz] or [ps]
# Set Frequency in [MHz] or period in [ns]
set my_clock_pin clk
set my_uncertainty 0.0
set my_clk_freq_MHz $::env(FREQ)
@ -84,13 +88,20 @@ if { $find_clock != [list] } {
create_clock -period $my_period -name $my_clk
}
# Optimize paths that are close to critical
set_critical_range [expr $my_period*0.05] $current_design
# Partitioning - flatten or hierarchically synthesize
# ungroup -all -flatten -simple_names
if { $maxopt == 1 } {
ungroup -all -flatten -simple_names
}
# Set input pins except clock
set all_in_ex_clk [remove_from_collection [all_inputs] [get_ports $my_clk]]
# Specifies delays be propagated through the clock network
# This is getting optimized poorly in the current flow, causing a lot of clock skew
# and unrealistic bad timing results.
# set_propagated_clock [get_clocks $my_clk]
# Setting constraints on input ports
@ -101,8 +112,8 @@ if {$tech == "sky130"} {
}
# Set input/output delay
set_input_delay 0.0 -max -clock $my_clk $all_in_ex_clk
set_output_delay 0.0 -max -clock $my_clk [all_outputs]
set_input_delay 0.1 -max -clock $my_clk $all_in_ex_clk
set_output_delay 0.1 -max -clock $my_clk [all_outputs]
# Setting load constraint on output ports
if {$tech == "sky130"} {
@ -120,7 +131,7 @@ set_wire_load_mode "top"
# Set fanout
set_max_fanout 6 $all_in_ex_clk
# Fix hold time violations
# Fix hold time violations (DH: this doesn't seem to be working right now)
#set_fix_hold [all_clocks]
# Deal with constants and buffers to isolate ports
@ -132,11 +143,16 @@ set_fix_multiple_port_nets -all -buffer_constants
# group_path -name COMBO -from [all_inputs] -to [all_outputs]
# Save Unmapped Design
set filename [format "%s%s%s%s" $outputDir "/unmapped/" $my_toplevel ".ddc"]
write_file -format ddc -hierarchy -o $filename
#set filename [format "%s%s%s%s" $outputDir "/unmapped/" $my_toplevel ".ddc"]
#write_file -format ddc -hierarchy -o $filename
# Compile statements
compile_ultra -no_seq_output_inversion -no_boundary_optimization
if { $maxopt == 1 } {
compile_ultra -retime
optimize_registers
} else {
compile_ultra -no_seq_output_inversion -no_boundary_optimization
}
# Eliminate need for assign statements (yuck!)
set verilogout_no_tri true
@ -178,14 +194,17 @@ redirect $filename { report_qor }
# Report Timing
set filename [format "%s%s%s%s" $outputDir "/reports/" $my_toplevel "_reportpath.rep"]
redirect $filename { report_path_group }
#redirect $filename { report_path_group }
set filename [format "%s%s%s%s" $outputDir "/reports/" $my_toplevel "_report_clock.rep"]
redirect $filename { report_clock }
# redirect $filename { report_clock }
set filename [format "%s%s%s%s" $outputDir "/reports/" $my_toplevel "_timing.rep"]
redirect $filename { report_timing -capacitance -transition_time -nets -nworst 1 }
set filename [format "%s%s%s%s" $outputDir "/reports/" $my_toplevel "_mindelay.rep"]
redirect $filename { report_timing -capacitance -transition_time -nets -delay_type min -nworst 1 }
set filename [format "%s%s%s%s" $outputDir "/reports/" $my_toplevel "_per_module_timing.rep"]
redirect -append $filename { echo "\n\n\n//// Critical paths through ifu ////\n\n\n" }
redirect -append $filename { report_timing -capacitance -transition_time -nets -through {ifu/*} -nworst 1 }
@ -265,20 +284,14 @@ redirect -append $filename { echo "\n\n\n//// Critical path through FlushW ////\
redirect -append $filename { report_timing -capacitance -transition_time -nets -through {ieu/FlushW} -nworst 1 }
set filename [format "%s%s%s%s" $outputDir "/reports/" $my_toplevel "_ieu_timing.rep"]
redirect -append $filename { echo "\n\n\n//// Critical path through datapath/RD1D ////\n\n\n" }
redirect -append $filename { report_timing -capacitance -transition_time -nets -through {ieu/dp/RD1D} -nworst 1 }
redirect -append $filename { echo "\n\n\n//// Critical path through datapath/RD2D ////\n\n\n" }
redirect -append $filename { report_timing -capacitance -transition_time -nets -through {ieu/dp/RD2D} -nworst 1 }
redirect -append $filename { echo "\n\n\n//// Critical path through datapath/PreSrcAE ////\n\n\n" }
redirect -append $filename { report_timing -capacitance -transition_time -nets -through {ieu/dp/PreSrcAE} -nworst 1 }
redirect -append $filename { echo "\n\n\n//// Critical path through datapath/R1D ////\n\n\n" }
redirect -append $filename { report_timing -capacitance -transition_time -nets -through {ieu/dp/R1D} -nworst 1 }
redirect -append $filename { echo "\n\n\n//// Critical path through datapath/R2D ////\n\n\n" }
redirect -append $filename { report_timing -capacitance -transition_time -nets -through {ieu/dp/R2D} -nworst 1 }
redirect -append $filename { echo "\n\n\n//// Critical path through datapath/SrcAE ////\n\n\n" }
redirect -append $filename { report_timing -capacitance -transition_time -nets -through {ieu/dp/SrcAE} -nworst 1 }
redirect -append $filename { echo "\n\n\n//// Critical path through datapath/ALUResultE ////\n\n\n" }
redirect -append $filename { report_timing -capacitance -transition_time -nets -through {ieu/dp/ALUResultE} -nworst 1 }
redirect -append $filename { echo "\n\n\n//// Critical path through datapath/WriteDataE ////\n\n\n" }
redirect -append $filename { report_timing -capacitance -transition_time -nets -through {ieu/dp/WriteDataE} -nworst 1 }
redirect -append $filename { echo "\n\n\n//// Critical path through dataphath/ResultM ////\n\n\n" }
redirect -append $filename { report_timing -capacitance -transition_time -nets -through {ieu/dp/ResultM} -nworst 1 }
redirect -append $filename { echo "\n\n\n//// Critical path through datapath/WriteDataW ////\n\n\n" }
redirect -append $filename { report_timing -capacitance -transition_time -nets -through {ieu/dp/WriteDataW} -nworst 1 }
redirect -append $filename { echo "\n\n\n//// Critical path through datapath/ReadDataM ////\n\n\n" }
@ -323,7 +336,7 @@ set filename [format "%s%s%s%s" $outputDir "/reports/" $my_toplevel "_area.rep"
redirect $filename { report_area -hierarchy -nosplit -physical -designware}
set filename [format "%s%s%s%s" $outputDir "/reports/" $my_toplevel "_cell.rep"]
redirect $filename { report_cell [get_cells -hier *] }
# redirect $filename { report_cell [get_cells -hier *] }
set filename [format "%s%s%s%s" $outputDir "/reports/" $my_toplevel "_power.rep"]
redirect $filename { report_power -hierarchy -levels 1 }
@ -332,6 +345,6 @@ set filename [format "%s%s%s%s" $outputDir "/reports/" $my_toplevel "_constrain
redirect $filename { report_constraint }
set filename [format "%s%s%s%s" $outputDir "/reports/" $my_toplevel "_hier.rep"]
redirect $filename { report_hierarchy }
# redirect $filename { report_hierarchy }
quit

View File

@ -28,15 +28,15 @@ do
echo -e "Check $(printf %-24s ${stub}) \e[33m ... IGNORE \e[39m"
continue
fi
# KMG: changed diff snippet to a grep that will strip comments with '//' and '#' out of the reference file
diff --ignore-case --ignore-trailing-space --strip-trailing-cr <(grep -o '^[^//#]*' ${ref}) ${sig} &> /dev/null
# KMG: changed diff snippet to a grep that will strip comments with '#' out of the reference file
diff --ignore-case --ignore-trailing-space --strip-trailing-cr <(grep -o '^[^#]*' ${ref}) ${sig} &> /dev/null
if [ $? == 0 ]
then
echo -e "\e[32m ... OK \e[39m"
else
echo -e "\e[31m ... FAIL \e[39m"
FAIL=$((${FAIL} + 1))
sdiff ${ref} ${sig} > ${dif}
sdiff <(grep -o '^[^#]*' ${ref}) ${sig} > ${dif}
fi
done

View File

@ -63,9 +63,8 @@ copy:
$(info !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!)
$(info <<<<<<<<<<<<<<<<<<<<<<<<<<<< COPYING REFERENCES WITHOUT SIMULATING >>>>>>>>>>>>>>>>>>>>>>>>>>>>)
$(info !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!)
$(V) echo "Copying References without simulating for the following tests:"
$(V) echo $(target_tests_nosim)
$(V) for test in $(target_tests_nosim); do grep -o '^[^//#]*' $(ref_dir)/$$test.reference_output > $(work_dir_isa)/$$test.signature.output; done
$(V) echo "Copying References without simulating for the following tests: $(target_tests_nosim)"
$(V) for test in $(target_tests_nosim); do grep -o '^[^#]*' $(ref_dir)/$$test.reference_output > $(work_dir_isa)/$$test.signature.output; done
compile: $(combined_elf)
run: $(target_log)

View File

@ -29,7 +29,10 @@
rv32i_sc_tests = \
WALLY-MMU-SV32 \
WALLY-PMP
WALLY-PMP \
WALLY-CSR-permission-s-01 \
WALLY-CSR-permission-u-01 \
WALLY-minfo-01
target_tests_nosim = WALLY-PMA \

View File

@ -0,0 +1,195 @@
///////////////////////////////////////////
//
// WALLY-CSR-permissions
//
// Author: Kip Macsai-Goren <kmacsaigoren@g.hmc.edu>
//
// Created 2022-02-05
//
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
//
// 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-TEST-LIB-32.h"
INIT_TESTS
s_file_begin:
# Test 5.2.3.6: Test that all the machine mode CSR's are innaccessible for reads and writes in S mode.
# *** several of these appear not to be implemented in the assembler?
# I get "assembler messages: error: unkown CSR" with many of them.
GOTO_S_MODE 0x0, 0x0
# Attempt to write 0xbad to each of these CSRs and read the value back
# should result in an illegal instruction for the write and read, respectively
# High-bit versions storing the upper 32 bits of some CSRs for RV32
# WRITE_READ_CSR mstatush 0xbad # *** these appear not to be implemented in GCC
# WRITE_READ_CSR menvcfgh 0xbad
# WRITE_READ_CSR mseccfgh 0xbad
WRITE_READ_CSR pmpcfg1 0xbad
WRITE_READ_CSR pmpcfg3 0xbad
WRITE_READ_CSR mcycleh 0xbad
WRITE_READ_CSR minstreth 0xbad
WRITE_READ_CSR mhpmcounter3h 0xbad
WRITE_READ_CSR mhpmcounter4h 0xbad
WRITE_READ_CSR mhpmcounter5h 0xbad
WRITE_READ_CSR mhpmcounter6h 0xbad
WRITE_READ_CSR mhpmcounter7h 0xbad
WRITE_READ_CSR mhpmcounter8h 0xbad
WRITE_READ_CSR mhpmcounter9h 0xbad
WRITE_READ_CSR mhpmcounter10h 0xbad
WRITE_READ_CSR mhpmcounter11h 0xbad
WRITE_READ_CSR mhpmcounter12h 0xbad
WRITE_READ_CSR mhpmcounter13h 0xbad
WRITE_READ_CSR mhpmcounter14h 0xbad
WRITE_READ_CSR mhpmcounter15h 0xbad
WRITE_READ_CSR mhpmcounter16h 0xbad
WRITE_READ_CSR mhpmcounter17h 0xbad
WRITE_READ_CSR mhpmcounter18h 0xbad
WRITE_READ_CSR mhpmcounter19h 0xbad
WRITE_READ_CSR mhpmcounter20h 0xbad
WRITE_READ_CSR mhpmcounter21h 0xbad
WRITE_READ_CSR mhpmcounter22h 0xbad
WRITE_READ_CSR mhpmcounter23h 0xbad
WRITE_READ_CSR mhpmcounter24h 0xbad
WRITE_READ_CSR mhpmcounter25h 0xbad
WRITE_READ_CSR mhpmcounter26h 0xbad
WRITE_READ_CSR mhpmcounter27h 0xbad
WRITE_READ_CSR mhpmcounter28h 0xbad
WRITE_READ_CSR mhpmcounter29h 0xbad
WRITE_READ_CSR mhpmcounter30h 0xbad
WRITE_READ_CSR mhpmcounter31h 0xbad
# Machine information Registers
WRITE_READ_CSR mvendorid, 0xbad
WRITE_READ_CSR marchid, 0xbad
WRITE_READ_CSR mimpid, 0xbad
WRITE_READ_CSR mhartid, 0xbad
# WRITE_READ_CSR mconfigptr, 0xbad # mconfigptr unimplemented in spike as of 31 Jan 22
# Machine Trap Setup
WRITE_READ_CSR mstatus, 0xbad
WRITE_READ_CSR misa, 0xbad
WRITE_READ_CSR medeleg, 0xbad
WRITE_READ_CSR mideleg, 0xbad
WRITE_READ_CSR mie, 0xbad
WRITE_READ_CSR mtvec, 0xbad
WRITE_READ_CSR mcounteren, 0xbad
# Machine Trap Handling
WRITE_READ_CSR mscratch, 0xbad
WRITE_READ_CSR mepc, 0xbad
WRITE_READ_CSR mcause, 0xbad
WRITE_READ_CSR mtval, 0xbad
WRITE_READ_CSR mip, 0xbad
# WRITE_READ_CSR mtinst, 0xbad # *** these appear not to be implemented in GCC
# WRITE_READ_CSR mtval2, 0xbad
# Machine Configuration
# WRITE_READ_CSR menvcfg, 0xbad # *** these appear not to be implemented in GCC
# WRITE_READ_CSR mseccgf, 0xbad
# Machine Memory Protection
WRITE_READ_CSR pmpcfg0, 0xbad
WRITE_READ_CSR pmpcfg2, 0xbad # there's 1 pmpcfg reg per 8 pmpaddr regs
WRITE_READ_CSR pmpaddr0, 0xbad
WRITE_READ_CSR pmpaddr1, 0xbad
WRITE_READ_CSR pmpaddr2, 0xbad
WRITE_READ_CSR pmpaddr3, 0xbad
WRITE_READ_CSR pmpaddr4, 0xbad
WRITE_READ_CSR pmpaddr5, 0xbad
WRITE_READ_CSR pmpaddr6, 0xbad
WRITE_READ_CSR pmpaddr7, 0xbad
WRITE_READ_CSR pmpaddr8, 0xbad
WRITE_READ_CSR pmpaddr9, 0xbad
WRITE_READ_CSR pmpaddr10, 0xbad
WRITE_READ_CSR pmpaddr11, 0xbad
WRITE_READ_CSR pmpaddr12, 0xbad
WRITE_READ_CSR pmpaddr13, 0xbad
WRITE_READ_CSR pmpaddr14, 0xbad
WRITE_READ_CSR pmpaddr15, 0xbad # only pmpcfg0...15 are enabled in our config
# Machine Counter/Timers
WRITE_READ_CSR mcycle, 0xbad
WRITE_READ_CSR minstret, 0xbad
WRITE_READ_CSR mhpmcounter3, 0xbad
WRITE_READ_CSR mhpmcounter4, 0xbad
WRITE_READ_CSR mhpmcounter5, 0xbad
WRITE_READ_CSR mhpmcounter6, 0xbad
WRITE_READ_CSR mhpmcounter7, 0xbad
WRITE_READ_CSR mhpmcounter8, 0xbad
WRITE_READ_CSR mhpmcounter9, 0xbad
WRITE_READ_CSR mhpmcounter10, 0xbad
WRITE_READ_CSR mhpmcounter11, 0xbad
WRITE_READ_CSR mhpmcounter12, 0xbad
WRITE_READ_CSR mhpmcounter13, 0xbad
WRITE_READ_CSR mhpmcounter14, 0xbad
WRITE_READ_CSR mhpmcounter15, 0xbad
WRITE_READ_CSR mhpmcounter16, 0xbad
WRITE_READ_CSR mhpmcounter17, 0xbad
WRITE_READ_CSR mhpmcounter18, 0xbad
WRITE_READ_CSR mhpmcounter19, 0xbad
WRITE_READ_CSR mhpmcounter20, 0xbad
WRITE_READ_CSR mhpmcounter21, 0xbad
WRITE_READ_CSR mhpmcounter22, 0xbad
WRITE_READ_CSR mhpmcounter23, 0xbad
WRITE_READ_CSR mhpmcounter24, 0xbad
WRITE_READ_CSR mhpmcounter25, 0xbad
WRITE_READ_CSR mhpmcounter26, 0xbad
WRITE_READ_CSR mhpmcounter27, 0xbad
WRITE_READ_CSR mhpmcounter28, 0xbad
WRITE_READ_CSR mhpmcounter29, 0xbad
WRITE_READ_CSR mhpmcounter30, 0xbad
WRITE_READ_CSR mhpmcounter31, 0xbad
# Machine Counter Setup
WRITE_READ_CSR mcountinhibit, 0xbad
WRITE_READ_CSR mhpmevent3, 0xbad
WRITE_READ_CSR mhpmevent4, 0xbad
WRITE_READ_CSR mhpmevent5, 0xbad
WRITE_READ_CSR mhpmevent6, 0xbad
WRITE_READ_CSR mhpmevent7, 0xbad
WRITE_READ_CSR mhpmevent8, 0xbad
WRITE_READ_CSR mhpmevent9, 0xbad
WRITE_READ_CSR mhpmevent10, 0xbad
WRITE_READ_CSR mhpmevent11, 0xbad
WRITE_READ_CSR mhpmevent12, 0xbad
WRITE_READ_CSR mhpmevent13, 0xbad
WRITE_READ_CSR mhpmevent14, 0xbad
WRITE_READ_CSR mhpmevent15, 0xbad
WRITE_READ_CSR mhpmevent16, 0xbad
WRITE_READ_CSR mhpmevent17, 0xbad
WRITE_READ_CSR mhpmevent18, 0xbad
WRITE_READ_CSR mhpmevent19, 0xbad
WRITE_READ_CSR mhpmevent20, 0xbad
WRITE_READ_CSR mhpmevent21, 0xbad
WRITE_READ_CSR mhpmevent22, 0xbad
WRITE_READ_CSR mhpmevent23, 0xbad
WRITE_READ_CSR mhpmevent24, 0xbad
WRITE_READ_CSR mhpmevent25, 0xbad
WRITE_READ_CSR mhpmevent26, 0xbad
WRITE_READ_CSR mhpmevent27, 0xbad
WRITE_READ_CSR mhpmevent28, 0xbad
WRITE_READ_CSR mhpmevent29, 0xbad
WRITE_READ_CSR mhpmevent30, 0xbad
WRITE_READ_CSR mhpmevent31, 0xbad
END_TESTS
TEST_STACK_AND_DATA

View File

@ -0,0 +1,173 @@
///////////////////////////////////////////
//
// WALLY-CSR-permissions
//
// Author: Kip Macsai-Goren <kmacsaigoren@g.hmc.edu>
//
// Created 2022-02-05
//
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
//
// 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-TEST-LIB-32.h"
INIT_TESTS
s_file_begin:
# Test 5.2.3.6: Test that all the machine mode CSR's are innaccessible for reads and writes in R mode.
GOTO_U_MODE 0x0, 0x0
# Attempt to write 0xbad to each of these CSRs and read the value back
# should result in an illegal instruction for the write and read, respectively
# Supervisor Trap Setup
WRITE_READ_CSR sstatus, 0xbad
WRITE_READ_CSR sie, 0xbad
WRITE_READ_CSR stvec, 0xbad
WRITE_READ_CSR scounteren, 0xbad
# Supervisor Configuration
# WRITE_READ_CSR senvcfg, 0xbad # *** these appear not to be implemented in the compile step of make???
# Supervisor Trap Handling
WRITE_READ_CSR sscratch, 0xbad
WRITE_READ_CSR sepc, 0xbad
WRITE_READ_CSR scause, 0xbad
WRITE_READ_CSR stval, 0xbad
WRITE_READ_CSR sip, 0xbad
# Supervisor Protection and Translation
WRITE_READ_CSR satp, 0xbad
# Machine information Registers
WRITE_READ_CSR mvendorid, 0xbad
WRITE_READ_CSR marchid, 0xbad
WRITE_READ_CSR mimpid, 0xbad
WRITE_READ_CSR mhartid, 0xbad
# WRITE_READ_CSR mconfigptr, 0xbad # mconfigptr unimplemented in spike as of 31 Jan 22
# Machine Trap Setup
WRITE_READ_CSR mstatus, 0xbad
WRITE_READ_CSR misa, 0xbad
WRITE_READ_CSR medeleg, 0xbad
WRITE_READ_CSR mideleg, 0xbad
WRITE_READ_CSR mie, 0xbad
WRITE_READ_CSR mtvec, 0xbad
WRITE_READ_CSR mcounteren, 0xbad
# Machine Trap Handling
WRITE_READ_CSR mscratch, 0xbad
WRITE_READ_CSR mepc, 0xbad
WRITE_READ_CSR mcause, 0xbad
WRITE_READ_CSR mtval, 0xbad
WRITE_READ_CSR mip, 0xbad
# WRITE_READ_CSR mtinst, 0xbad # *** these appear not to be implemented in GCC
# WRITE_READ_CSR mtval2, 0xbad
# Machine Configuration
# WRITE_READ_CSR menvcfg, 0xbad # *** these appear not to be implemented in GCC
# WRITE_READ_CSR mseccgf, 0xbad
# Machine Memory Protection
WRITE_READ_CSR pmpcfg0, 0xbad
WRITE_READ_CSR pmpcfg2, 0xbad # pmpcfg 1 and 3 dont exist in rv64. there's 1 pmpcfg reg per 8 pmpaddr regs
WRITE_READ_CSR pmpaddr0, 0xbad
WRITE_READ_CSR pmpaddr1, 0xbad
WRITE_READ_CSR pmpaddr2, 0xbad
WRITE_READ_CSR pmpaddr3, 0xbad
WRITE_READ_CSR pmpaddr4, 0xbad
WRITE_READ_CSR pmpaddr5, 0xbad
WRITE_READ_CSR pmpaddr6, 0xbad
WRITE_READ_CSR pmpaddr7, 0xbad
WRITE_READ_CSR pmpaddr8, 0xbad
WRITE_READ_CSR pmpaddr9, 0xbad
WRITE_READ_CSR pmpaddr10, 0xbad
WRITE_READ_CSR pmpaddr11, 0xbad
WRITE_READ_CSR pmpaddr12, 0xbad
WRITE_READ_CSR pmpaddr13, 0xbad
WRITE_READ_CSR pmpaddr14, 0xbad
WRITE_READ_CSR pmpaddr15, 0xbad # only pmpcfg0...15 are enabled in our config
# Machine Counter/Timers
WRITE_READ_CSR mcycle, 0xbad
WRITE_READ_CSR minstret, 0xbad
WRITE_READ_CSR mhpmcounter3, 0xbad
WRITE_READ_CSR mhpmcounter4, 0xbad
WRITE_READ_CSR mhpmcounter5, 0xbad
WRITE_READ_CSR mhpmcounter6, 0xbad
WRITE_READ_CSR mhpmcounter7, 0xbad
WRITE_READ_CSR mhpmcounter8, 0xbad
WRITE_READ_CSR mhpmcounter9, 0xbad
WRITE_READ_CSR mhpmcounter10, 0xbad
WRITE_READ_CSR mhpmcounter11, 0xbad
WRITE_READ_CSR mhpmcounter12, 0xbad
WRITE_READ_CSR mhpmcounter13, 0xbad
WRITE_READ_CSR mhpmcounter14, 0xbad
WRITE_READ_CSR mhpmcounter15, 0xbad
WRITE_READ_CSR mhpmcounter16, 0xbad
WRITE_READ_CSR mhpmcounter17, 0xbad
WRITE_READ_CSR mhpmcounter18, 0xbad
WRITE_READ_CSR mhpmcounter19, 0xbad
WRITE_READ_CSR mhpmcounter20, 0xbad
WRITE_READ_CSR mhpmcounter21, 0xbad
WRITE_READ_CSR mhpmcounter22, 0xbad
WRITE_READ_CSR mhpmcounter23, 0xbad
WRITE_READ_CSR mhpmcounter24, 0xbad
WRITE_READ_CSR mhpmcounter25, 0xbad
WRITE_READ_CSR mhpmcounter26, 0xbad
WRITE_READ_CSR mhpmcounter27, 0xbad
WRITE_READ_CSR mhpmcounter28, 0xbad
WRITE_READ_CSR mhpmcounter29, 0xbad
WRITE_READ_CSR mhpmcounter30, 0xbad
WRITE_READ_CSR mhpmcounter31, 0xbad
# Machine Counter Setup
WRITE_READ_CSR mcountinhibit, 0xbad
WRITE_READ_CSR mhpmevent3, 0xbad
WRITE_READ_CSR mhpmevent4, 0xbad
WRITE_READ_CSR mhpmevent5, 0xbad
WRITE_READ_CSR mhpmevent6, 0xbad
WRITE_READ_CSR mhpmevent7, 0xbad
WRITE_READ_CSR mhpmevent8, 0xbad
WRITE_READ_CSR mhpmevent9, 0xbad
WRITE_READ_CSR mhpmevent10, 0xbad
WRITE_READ_CSR mhpmevent11, 0xbad
WRITE_READ_CSR mhpmevent12, 0xbad
WRITE_READ_CSR mhpmevent13, 0xbad
WRITE_READ_CSR mhpmevent14, 0xbad
WRITE_READ_CSR mhpmevent15, 0xbad
WRITE_READ_CSR mhpmevent16, 0xbad
WRITE_READ_CSR mhpmevent17, 0xbad
WRITE_READ_CSR mhpmevent18, 0xbad
WRITE_READ_CSR mhpmevent19, 0xbad
WRITE_READ_CSR mhpmevent20, 0xbad
WRITE_READ_CSR mhpmevent21, 0xbad
WRITE_READ_CSR mhpmevent22, 0xbad
WRITE_READ_CSR mhpmevent23, 0xbad
WRITE_READ_CSR mhpmevent24, 0xbad
WRITE_READ_CSR mhpmevent25, 0xbad
WRITE_READ_CSR mhpmevent26, 0xbad
WRITE_READ_CSR mhpmevent27, 0xbad
WRITE_READ_CSR mhpmevent28, 0xbad
WRITE_READ_CSR mhpmevent29, 0xbad
WRITE_READ_CSR mhpmevent30, 0xbad
WRITE_READ_CSR mhpmevent31, 0xbad
END_TESTS
TEST_STACK_AND_DATA

View File

@ -22,9 +22,18 @@
///////////////////////////////////////////
#include "WALLY-TEST-LIB-32.h"
// Test library includes and handler for each type of test, a trap handler, imperas compliance instructions
// Ideally this should mean that a test can be written by simply adding .8byte statements as below.
INIT_TESTS
s_file_begin:
j test_loop_setup // begin test loop/table tests instead of executing inline code.
INIT_TEST_TABLE
TEST_STACK_AND_DATA
.align 2
test_cases:
# ---------------------------------------------------------------------------------------------
# Test Contents
#

View File

@ -35,9 +35,18 @@
#define PLIC_RANGE 0x03FFFFFF
#include "WALLY-TEST-LIB-32.h"
// Test library includes and handler for each type of test, a trap handler, imperas compliance instructions
// Ideally this should mean that a test can be written by simply adding .4byte statements as below.
INIT_TESTS
s_file_begin:
j test_loop_setup // begin test loop/table tests instead of executing inline code.
INIT_TEST_TABLE
TEST_STACK_AND_DATA
.align 2
test_cases:
# ---------------------------------------------------------------------------------------------
# Test Contents
#

View File

@ -22,9 +22,18 @@
///////////////////////////////////////////
#include "WALLY-TEST-LIB-32.h"
// Test library includes and handler for each type of test, a trap handler, imperas compliance instructions
// Ideally this should mean that a test can be written by simply adding .4byte statements as below.
INIT_TESTS
s_file_begin:
j test_loop_setup // begin test loop/table tests instead of executing inline code.
INIT_TEST_TABLE
TEST_STACK_AND_DATA
.align 2
test_cases:
# ---------------------------------------------------------------------------------------------
# Test Contents
#
@ -45,22 +54,22 @@
# Test 12.3.2.2.1 Config: Write known values and set PMP config according to table 12.4 in the *** riscv book, copied below
# write pmpaddr regs
# | Reg | pmpaddr | pmpcfg | L | A | X | W | R | Comments |
.4byte 0x0, 0x0FFFFFFF, write_pmpaddr_0 # | 0 | 0x0FFFFFFF | 1F | 0 | NAPOT | 0 | 1 | 1 | I/O 00000000-7FFFFFFF RW |
.4byte 0x1, 0x20040000, write_pmpaddr_0 # | 1 | 0x20040000 | 00 | 0 | OFF | 0 | 0 | 0 | |
.4byte 0x2, 0x2004003F, write_pmpaddr_0 # | 2 | 0x2004003F | 09 | 0 | TOR | 0 | 0 | 1 | 80100000-801000FF R |
.4byte 0x3, 0x20040080, write_pmpaddr_0 # | 3 | 0x20040080 | 00 | 0 | OFF | 0 | 0 | 0 | |
.4byte 0x4, 0x20040084, write_pmpaddr_0 # | 4 | 0x20040084 | 0C | 0 | TOR | 1 | 0 | 0 | 80100200-80100210 X |
.4byte 0x5, 0x200400C0, write_pmpaddr_0 # | 5 | 0x200400C0 | 90 | 1 | NA4 | 0 | 0 | 0 | 80100300-80100303 locked out |
.4byte 0x6, 0x2004013F, write_pmpaddr_0 # | 6 | 0x2004013F | 18 | 0 | NAPOT | 0 | 0 | 0 | 80100400-801004FF no access |
# | Reg | pmpaddr | pmpcfg | L | A | X | W | R | Comments |
.4byte 0x0, 0x0FFFFFFF, write_pmpaddr_0 # | 0 | 0x0FFFFFFF | 1F | 0 | NAPOT | 0 | 1 | 1 | I/O 00000000-7FFFFFFF RW |
.4byte 0x1, 0x20040000, write_pmpaddr_1 # | 1 | 0x20040000 | 00 | 0 | OFF | 0 | 0 | 0 | |
.4byte 0x2, 0x2004003F, write_pmpaddr_2 # | 2 | 0x2004003F | 09 | 0 | TOR | 0 | 0 | 1 | 80100000-801000FF R |
.4byte 0x3, 0x20040080, write_pmpaddr_3 # | 3 | 0x20040080 | 00 | 0 | OFF | 0 | 0 | 0 | |
.4byte 0x4, 0x20040084, write_pmpaddr_4 # | 4 | 0x20040084 | 0C | 0 | TOR | 1 | 0 | 0 | 80100200-80100210 X |
.4byte 0x5, 0x200400C0, write_pmpaddr_5 # | 5 | 0x200400C0 | 90 | 1 | NA4 | 0 | 0 | 0 | 80100300-80100303 locked out |
.4byte 0x6, 0x2004013F, write_pmpaddr_6 # | 6 | 0x2004013F | 18 | 0 | NAPOT | 0 | 0 | 0 | 80100400-801004FF no access |
# Pmpaddr 7-14 are all zeroed out in this test, so they don't need writes.
.4byte 0xF, 0x2FFFFFFF, write_pmpaddr_0 # | 15 | 0x2FFFFFFF | 1F | 0 | NAPOT | 1 | 1 | 1 | Main mem 80000000-FFFFFFFF RWX|
.4byte 0xF, 0x2FFFFFFF, write_pmpaddr_15 # | 15 | 0x2FFFFFFF | 1F | 0 | NAPOT | 1 | 1 | 1 | Main mem 80000000-FFFFFFFF RWX|
# write pmpcfg regs with the information in the table above. this should also write the value of these registers to the output.
.4byte 0x0, 0x0009001F, write_pmpcfg_0 # write pmpcfg0, output 0x0009001F
.4byte 0x1, 0x0018900C, write_pmpcfg_0 # write pmpcfg1, output 0x0018900C
.4byte 0x1, 0x0018900C, write_pmpcfg_1 # write pmpcfg1, output 0x0018900C
# pmpcfg2 is zeroed out, so it doesn't need a write
.4byte 0x3, 0x1F000000, write_pmpcfg_0 # write pmpcfg3, output 0x1F000000
.4byte 0x3, 0x1F000000, write_pmpcfg_3 # write pmpcfg3, output 0x1F000000
# write known values to memory where W=0. This should be possible since we're in machine mode.
.4byte 0x80100010, 0x600DAA, write32_test # write to pmpaddr 1-2 range
@ -74,9 +83,9 @@
# attempt to write to pmpaddr5 and pmp5cfg after lockout
.4byte 0x1, 0x0018FF0C, write_pmpcfg_0 # attempt to edit only pmp5cfg (pmpcfg1[8:15]) after lockout.
.4byte 0x1, 0x0018FF0C, write_pmpcfg_1 # attempt to edit only pmp5cfg (pmpcfg1[8:15]) after lockout.
# instruction ignored, output is 0x0018900C, NOT 0x0018FF0C
.4byte 0x5, 0xFFFFFFFF, write_pmpaddr_0 # attempt to edit pmpaddr5 after lockout.
.4byte 0x5, 0xFFFFFFFF, write_pmpaddr_5 # attempt to edit pmpaddr5 after lockout.
# instruction ignored, output is 0x200400C0, NOT 0xFFFFFFFF
# Test 12.3.2.2.2 Machine mode access

View File

@ -4,7 +4,7 @@
//
// Author: Kip Macsai-Goren <kmacsaigoren@g.hmc.edu>
//
// Created 2021-07-20
// Created 2021-07-19
//
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
//
@ -23,6 +23,9 @@
#include "model_test.h"
#include "arch_test.h"
.macro INIT_TESTS
RVTEST_ISA("RV32I")
.section .text.init
@ -31,7 +34,7 @@ rvtest_entry_point:
RVMODEL_BOOT
RVTEST_CODE_BEGIN
// ---------------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------------
// Initialization Overview:
//
// Initialize x6 as a virtual pointer to the test results
@ -56,9 +59,9 @@ RVTEST_CODE_BEGIN
li a1, 0
li a2, 0 // reset trap handler inputs to zero
// go to first test!
j test_setup
// go to beginning of S file where we can decide between using the test data loop
// or using the macro inline code insertion
j s_file_begin
// ---------------------------------------------------------------------------------------------
// General traps Handler
@ -225,12 +228,16 @@ ecallhandler_changetousermode:
j trapreturn
instrfault:
lw x1, -4(sp) // load return address int x1 (the address after the jal into faulting page)
lw x1, -4(sp) // load return address int x1 (the address AFTER the jal into faulting page)
j trapreturn_finished // puts x1 into mepc, restores stack and returns to program (outside of faulting page)
illegalinstr:
j trapreturn // return to the code after recording the mcause
accessfault:
// *** What do I have to do here?
j trapreturn
// Table of trap behavior
// lists what to do on each exception (not interrupts)
// unexpected exceptions should cause segfaults for easy detection
@ -239,13 +246,13 @@ accessfault:
.align 2 // aligns this data table to an 4 byte boundary
trap_handler_vector_table:
.4byte segfault // 0: instruction address misaligned
.4byte instrfault // 1: instruction access fault
.4byte segfault // 2: illegal instruction
.4byte instrfault // 1: instruction access fault
.4byte illegalinstr // 2: illegal instruction
.4byte segfault // 3: breakpoint
.4byte segfault // 4: load address misaligned
.4byte accessfault // 5: load access fault
.4byte accessfault // 5: load access fault
.4byte segfault // 6: store address misaligned
.4byte accessfault // 7: store access fault
.4byte accessfault // 7: store access fault
.4byte ecallhandler // 8: ecall from U-mode
.4byte ecallhandler // 9: ecall from S-mode
.4byte segfault // 10: reserved
@ -260,6 +267,220 @@ trap_return_pagetype_table:
.4byte 0xC // 0: kilopage has 12 offset bits
.4byte 0x16 // 1: megapage has 22 offset bits
.endm
// Test Summary table!
// Test Name : Description : Fault output value : Normal output values
// ---------------------:-------------------------------------------:-------------------------------------------:------------------------------------------------------
// write64_test : Write 64 bits to address : 0x6, 0x7, or 0xf : None
// write32_test : Write 32 bits to address : 0x6, 0x7, or 0xf : None
// write16_test : Write 16 bits to address : 0x6, 0x7, or 0xf : None
// write08_test : Write 8 bits to address : 0x6, 0x7, or 0xf : None
// read64_test : Read 64 bits from address : 0x4, 0x5, or 0xd, then 0xbad : readvalue in hex
// read32_test : Read 32 bitsfrom address : 0x4, 0x5, or 0xd, then 0xbad : readvalue in hex
// read16_test : Read 16 bitsfrom address : 0x4, 0x5, or 0xd, then 0xbad : readvalue in hex
// read08_test : Read 8 bitsfrom address : 0x4, 0x5, or 0xd, then 0xbad : readvalue in hex
// executable_test : test executable on virtual page : 0x0, 0x1, or 0xc, then 0xbad : value of x7 modified by exectuion code (usually 0x111)
// terminate_test : terminate tests : mcause value for fault : from M 0xb, from S 0x9, from U 0x8
// goto_baremetal : satp.MODE = bare metal : None : None
// goto_sv32 : satp.MODE = sv32 : None : None
// goto_m_mode : go to mahcine mode : mcause value for fault : from M 0xb, from S 0x9, from U 0x8
// goto_s_mode : go to supervisor mode : mcause value for fault : from M 0xb, from S 0x9, from U 0x8
// goto_u_mode : go to user mode : mcause value for fault : from M 0xb, from S 0x9, from U 0x8
// write_read_csr : write to specified CSR : old CSR value, 0x2, depending on perms : value written to CSR
// csr_r_access : test read-only permissions on CSR : 0xbad : 0x2, then 0x11
// *** TESTS TO ADD: execute inline, read unknown value out, read CSR unknown value, just read CSR value
.macro WRITE32 ADDR VAL
// attempt to write VAL to ADDR
// Success outputs:
// None
// Fault outputs:
// 0x6: misaligned address
// 0x7: access fault
// 0xf: page fault
li x29, \VAL
li x30, \ADDR
sw x29, 0(x30)
.endm
.macro WRITE16 ADDR VAL
// all write tests have the same description/outputs as write64
li x29, \VAL
li x30, \ADDR
sh x29, 0(x30)
.endm
.macro WRITE08 ADDR VAL
// all write tests have the same description/outputs as write64
li x29, \VAL
li x30, \ADDR
sb x29, 0(x30)
.endm
.macro READ32 ADDR
// Attempt read at ADDR. Write the value read out to the output *** Consider adding specific test for reading a non known value
// Success outputs:
// value read out from ADDR
// Fault outputs:
// One of the following followed by 0xBAD
// 0x4: misaligned address
// 0x5: access fault
// 0xD: page fault
li x7, 0xBAD // bad value that will be overwritten on good reads.
li x29, \ADDR
lw x7, 0(x29)
sw x7, 0(x6)
addi x6, x6, 4
addi x16, x16, 4
.endm
.macro READ16 ADDR
// All reads have the same description/outputs as read32.
// They will store the sign extended value of what was read out at ADDR
li x7, 0xBAD // bad value that will be overwritten on good reads.
li x29, \ADDR
lh x7, 0(x29)
sw x7, 0(x6)
addi x6, x6, 4
addi x16, x16, 4
.endm
.macro READ08 ADDR
// All reads have the same description/outputs as read64.
// They will store the sign extended value of what was read out at ADDR
li x7, 0xBAD // bad value that will be overwritten on good reads.
li x29, \ADDR
lb x7, 0(x29)
sw x7, 0(x6)
addi x6, x6, 4
addi x16, x16, 4
.endm
// These goto_x_mode tests all involve invoking the trap handler,
// So their outputs are inevitably:
// 0x8: test called from U mode
// 0x9: test called from S mode
// 0xB: test called from M mode
// they generally do not fault or cause issues as long as these modes are enabled
// *** add functionality to check if modes are enabled before jumping? maybe cause a fault if not?
.macro GOTO_M_MODE RETURN_VPN RETURN_PAGETYPE
li a0, 2 // determine trap handler behavior (go to machine mode)
li a1, \RETURN_VPN // return VPN
li a2, \RETURN_PAGETYPE // return page types
ecall // writes mcause to the output.
// now in S mode
.endm
.macro GOTO_S_MODE RETURN_VPN RETURN_PAGETYPE
li a0, 3 // determine trap handler behavior (go to supervisor mode)
li a1, \RETURN_VPN // return VPN
li a2, \RETURN_PAGETYPE // return page types
ecall // writes mcause to the output.
// now in S mode
.endm
.macro GOTO_U_MODE RETURN_VPN RETURN_PAGETYPE
li a0, 4 // determine trap handler behavior (go to user mode)
li a1, \RETURN_VPN // return VPN
li a2, \RETURN_PAGETYPE // return page types
ecall // writes mcause to the output.
// now in S mode
.endm
// These tests change virtual memory settings, turning it on/off and changing between types.
// They don't have outputs as any error with turning on virtual memory should reveal itself in the tests *** Consider changing this policy?
.macro GOTO_BAREMETAL
// Turn translation off
li x7, 0 // satp.MODE value for bare metal (0)
slli x7, x7, 31
li x28, 0x8000D // Base Pagetable physical page number, satp.PPN field. *** add option for different pagetable location
add x7, x7, x28
csrw satp, x7
sfence.vma x0, x0 // *** flushes global pte's as well
.endm
.macro GOTO_SV32
// Turn on sv39 virtual memory
li x7, 1 // satp.MODE value for Sv32 (1)
slli x7, x7, 31
li x28, 0x8000D // Base Pagetable physical page number, satp.PPN field. *** add option for different pagetable location
add x7, x7, x28
csrw satp, x7
sfence.vma x0, x0 // *** flushes global pte's as well
.endm
.macro WRITE_READ_CSR CSR VAL
// attempt to write CSR with VAL. Note: this also tests read access to CSR
// Success outputs:
// value read back out from CSR after writing
// Fault outputs:
// The previous CSR value before write attempt
// *** Most likely 0x2, the mcause for illegal instruction if we don't have write or read access
li x30, 0xbad // load bad value to be overwritten by csrr
li x29, \VAL
csrw \CSR\(), x29
csrr x30, \CSR
sw x30, 0(x6)
addi x6, x6, 4
addi x16, x16, 4
.endm
.macro CSR_R_ACCESS CSR
// verify that a csr is accessible to read but not to write
// Success outputs:
// 0x2, then
// 0x11 *** consider changing to something more meaningful
// Fault outputs:
// 0xBAD *** consider changing this one as well. in general, do we need the branching if it hould cause an illegal instruction fault?
csrr x29, \CSR
csrwi \CSR\(), 0xA // Attempt to write a 'random' value to the CSR
csrr x30, \CSR
bne x30, x29, 1f // 1f represents write_access
li x30, 0x11 // Write failed, confirming read only permissions.
j 2f // j r_access_end
1: // w_access (write succeeded, violating read-only)
li x30, 0xBAD
2: // r_access end
sw x30, 0(x6)
addi x6, x6, 4
addi x16, x16, 4
.endm
.macro EXECUTE_AT_ADDRESS ADDR
// Execute the code already written to ADDR, returning the value in x7.
// *** Note: this test itself doesn't write the code to ADDR because it might be callled at a point where we dont have write access to ADDR
// Assumes the code modifies x7, usually to become 0x111.
// Sample code: 0x11100393 (li x7, 0x111), 0x00008067 (ret)
// Success outputs:
// modified value of x7. (0x111 if you use the sample code)
// Fault outputs:
// One of the following followed by 0xBAD
// 0x0: misaligned address
// 0x1: access fault
// 0xC: page fault
fence.i // forces caches and main memory to sync so execution code written to ADDR can run.
li x7, 0xBAD
li x28, \ADDR
jalr x28 // jump to executable test code
sw x7, 0(x6)
addi x6, x6, 4
addi x16, x16, 4
.endm
.macro END_TESTS
// invokes one final ecall to return to machine mode then terminates this program, so the output is
// 0x8: termination called from U mode
// 0x9: termination called from S mode
// 0xB: termination called from M mode
j terminate_test
.endm
// ---------------------------------------------------------------------------------------------
// Test Handler
//
@ -269,17 +490,18 @@ trap_return_pagetype_table:
// Input parameters:
//
// x28:
// Address input for the test taking place (think address to read/write, new address to return to, etc...)
// Address input for the test taking place (think: address to read/write, new address to return to, etc...)
//
// x29:
// Value input for the test taking place (think value to write, any other extra info needed)
// Value input for the test taking place (think: value to write, any other extra info needed)
//
// x30:
// Test type input that determines which kind of test will take place. Encoding for this input is in the table/case statements below
//
// Label for the location of the test that's about to take place
// ------------------------------------------------------------------------------------------------------------------------------------
test_setup:
.macro INIT_TEST_TABLE // *** Consider renaming this test. to what???
test_loop_setup:
la x5, test_cases
test_loop:
@ -298,25 +520,25 @@ test_loop:
jr x30
// Test Name : Description : Fault output value : Normal output values
// ----------------------:---------------------------------------:------------------------:------------------------------------------------------
// write32_test : Write 32 bits to address : 0xf : None
// write16_test : Write 16 bits to address : 0xf : None
// write08_test : Write 8 bits to address : 0xf : None
// read32_test : Read 32 bits from address : 0xd, 0xbad : readvalue in hex
// read16_test : Read 16 bits from address : 0xd, 0xbad : readvalue in hex
// read08_test : Read 8 bits from address : 0xd, 0xbad : readvalue in hex
// executable_test : test executable at address : 0xc, 0xbad : leading 12 bits of the li instr written to address. In general this is 0x111. (be sure to also write a return instruction)
// terminate_test : terminate tests : mcause value for fault : from M 0xb, from S 0x9, from U 0x8
// goto_baremetal : satp.MODE = bare metal : None : None
// goto_sv32 : satp.MODE = sv32 : None : None
// write_mxr_sum : write sstatus.[19:18] = MXR, SUM bits : None : None
// goto_m_mode : go to mahcine mode : mcause value for fault : from M 0xb, from S 0x9, from U 0x8
// goto_s_mode : go to supervisor mode : mcause value for fault : from M 0xb, from S 0x9, from U 0x8
// goto_u_mode : go to user mode : mcause value for fault : from M 0xb, from S 0x9, from U 0x8
// write_pmpcfg_x : Write one of the pmpcfg csr's : mstatuses?, 0xD : readback of pmpcfg value
// write_pmpaddr_x : Write one of the pmpaddr csr's : None : readback of pmpaddr value
// Test Name : Description : Fault output value : Normal output values
// ----------------------:-------------------------------------------:------------------------:------------------------------------------------------
// write32_test : Write 32 bits to address : 0xf : None
// write16_test : Write 16 bits to address : 0xf : None
// write08_test : Write 8 bits to address : 0xf : None
// read32_test : Read 32 bits from address : 0xd, 0xbad : readvalue in hex
// read16_test : Read 16 bits from address : 0xd, 0xbad : readvalue in hex
// read08_test : Read 8 bits from address : 0xd, 0xbad : readvalue in hex
// executable_test : test executable on virtual page : 0xc, 0xbad : value of x7 modified by exectuion code (usually 0x111)
// terminate_test : terminate tests : mcause value for fault : from M 0xb, from S 0x9, from U 0x8
// goto_baremetal : satp.MODE = bare metal : None : None
// goto_sv39 : satp.MODE = sv39 : None : None
// goto_sv48 : satp.MODE = sv48 : None : None
// write_mxr_sum : write sstatus.[19:18] = MXR, SUM bits : None : None
// goto_m_mode : go to mahcine mode : mcause value for fault : from M 0xb, from S 0x9, from U 0x8
// goto_s_mode : go to supervisor mode : mcause value for fault : from M 0xb, from S 0x9, from U 0x8
// goto_u_mode : go to user mode : mcause value for fault : from M 0xb, from S 0x9, from U 0x8
// write_pmpcfg_x : Write one of the pmpcfg csr's : mstatuses?, 0xD : readback of pmpcfg value
// write_pmpaddr_x : Write one of the pmpaddr csr's : None : readback of pmpaddr value
write32_test:
// address to write in x28, word value in x29
@ -360,9 +582,9 @@ read08_test:
addi x16, x16, 4
j test_loop // go to next test case
goto_s_mode:
li a0, 3 // Trap handler behavior (go to machine mode)
// return to address in x28,
li a0, 3 // Trap handler behavior (go to supervisor mode)
mv a1, x28 // return VPN
mv a2, x29 // return page types
ecall // writes mcause to the output.
@ -385,21 +607,11 @@ goto_u_mode:
goto_baremetal:
// Turn translation off
li x7, 0 // satp.MODE value for bare metal (0)
slli x7, x7, 31
li x28, 0x8000D // Base Pagetable physical page number, satp.PPN field.
add x7, x7, x28
csrw satp, x7
sfence.vma x0, x0 // *** flushes global pte's as well. Be careful
GOTO_BAREMETAL
j test_loop // go to next test case
goto_sv32:
li x7, 1 // satp.MODE value for Sv39 (1)
slli x7, x7, 31
li x28, 0x8000D // Base Pagetable physical page number, satp.PPN field.
add x7, x7, x28
csrw satp, x7
sfence.vma x0, x0 // *** flushes global pte's as well. Be careful
GOTO_SV32
j test_loop // go to next test case
write_mxr_sum:
@ -415,25 +627,26 @@ write_mxr_sum:
write_pmpcfg_0:
// writes the value in x29 to the pmpcfg register specified in x28.
li x7, 0x0
bne x7, x28, write_pmpcfg_1
// then writes the final value of pmpcfgX to the output.
csrw pmpcfg0, x29
csrr x30, pmpcfg0
j write_pmpcfg_end
write_pmpcfg_1:
li x7, 0x1
bne x7, x28, write_pmpcfg_2
csrw pmpcfg1, x29
csrr x30, pmpcfg1
csrr x30, pmpcfg1
j write_pmpcfg_end
write_pmpcfg_2:
li x7, 0x2
bne x7, x28, write_pmpcfg_3
csrw pmpcfg2, x29
csrr x30, pmpcfg2
j write_pmpcfg_end
write_pmpcfg_3:
li x7, 0x3
bne x7, x28, write_pmpcfg_end
csrw pmpcfg3, x29
csrr x30, pmpcfg3
j write_pmpcfg_end
write_pmpcfg_end:
sw x30, 0(x6)
addi x6, x6, 4
@ -441,103 +654,88 @@ write_pmpcfg_end:
j test_loop
write_pmpaddr_0:
// write_read_csr pmpaddr0, x29
// writes the value in x29 to the pmpaddr register specified in x28.
// then writes the final value of pmpaddrX to the output.
li x7, 0x0
bne x7, x28, write_pmpaddr_1
csrw pmpaddr0, x29
csrr x30, pmpaddr0
j write_pmpaddr_end
write_pmpaddr_1:
li x7, 0x1
bne x7, x28, write_pmpaddr_2
csrw pmpaddr1, x29
csrr x30, pmpaddr1
j write_pmpaddr_end
write_pmpaddr_2:
li x7, 0x2
bne x7, x28, write_pmpaddr_3
csrw pmpaddr2, x29
csrr x30, pmpaddr2
j write_pmpaddr_end
write_pmpaddr_3:
li x7, 0x3
bne x7, x28, write_pmpaddr_4
csrw pmpaddr3, x29
csrr x30, pmpaddr3
j write_pmpaddr_end
write_pmpaddr_4:
li x7, 0x4
bne x7, x28, write_pmpaddr_5
csrw pmpaddr4, x29
csrr x30, pmpaddr4
j write_pmpaddr_end
write_pmpaddr_5:
li x7, 0x5
bne x7, x28, write_pmpaddr_6
csrw pmpaddr5, x29
csrr x30, pmpaddr5
j write_pmpaddr_end
write_pmpaddr_6:
li x7, 0x6
bne x7, x28, write_pmpaddr_7
csrw pmpaddr6, x29
csrr x30, pmpaddr6
j write_pmpaddr_end
write_pmpaddr_7:
li x7, 0x7
bne x7, x28, write_pmpaddr_8
csrw pmpaddr7, x29
csrr x30, pmpaddr7
j write_pmpaddr_end
write_pmpaddr_8:
li x7, 0x8
bne x7, x28, write_pmpaddr_9
csrw pmpaddr8, x29
csrr x30, pmpaddr8
j write_pmpaddr_end
write_pmpaddr_9:
li x7, 0x9
bne x7, x28, write_pmpaddr_10
csrw pmpaddr9, x29
csrr x30, pmpaddr9
j write_pmpaddr_end
write_pmpaddr_10:
li x7, 0xA
bne x7, x28, write_pmpaddr_11
csrw pmpaddr10, x29
csrr x30, pmpaddr10
j write_pmpaddr_end
write_pmpaddr_11:
li x7, 0xB
bne x7, x28, write_pmpaddr_12
csrw pmpaddr11, x29
csrr x30, pmpaddr11
j write_pmpaddr_end
write_pmpaddr_12:
li x7, 0xC
bne x7, x28, write_pmpaddr_13
csrw pmpaddr12, x29
csrr x30, pmpaddr12
j write_pmpaddr_end
write_pmpaddr_13:
li x7, 0xD
bne x7, x28, write_pmpaddr_14
csrw pmpaddr13, x29
csrr x30, pmpaddr13
j write_pmpaddr_end
write_pmpaddr_14:
li x7, 0xE
bne x7, x28, write_pmpaddr_15
csrw pmpaddr14, x29
csrr x30, pmpaddr14
j write_pmpaddr_end
write_pmpaddr_15:
li x7, 0xF
bne x7, x28, write_pmpaddr_end
csrw pmpaddr15, x29
csrr x30, pmpaddr15
j write_pmpaddr_end
write_pmpaddr_end:
sw x30, 0(x6)
addi x6, x6, 4
@ -555,18 +753,21 @@ executable_test:
addi x16, x16, 4
j test_loop
.endm
// notably, terminate_test is not a part of the test table macro because it needs to be defined
// in any type of test, macro or test table, for the trap handler to work
terminate_test:
li a0, 2 // Trap handler behavior (go to machine mode)
ecall // writes mcause to the output.
csrw mtvec, x4 // restore original trap handler to halt program
RVTEST_CODE_END
RVMODEL_HALT
.macro TEST_STACK_AND_DATA
RVTEST_DATA_BEGIN
.align 4
rvtest_data:
@ -575,14 +776,12 @@ RVTEST_DATA_END
.align 2 // align stack to 4 byte boundary
bottom_of_stack:
.fill 1024, 4, 0xdeadbeef
.fill 1024, 4, 0xdeadbeef
top_of_stack:
RVMODEL_DATA_BEGIN
// next lines through test cases copied over from old framework
test_1_res:
.fill 1024, 4, 0xdeadbeef
@ -602,6 +801,4 @@ gpr_save:
#endif
.align 2
test_cases:
.endm

View File

@ -0,0 +1,39 @@
///////////////////////////////////////////
//
// WALLY-MMU
//
// Author: Kip Macsai-Goren <kmacsaigoren@g.hmc.edu>
//
// Created 2022-01-25
//
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
//
// 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-TEST-LIB-32.h"
INIT_TESTS
s_file_begin:
// Test 5.2.3.1: testing Read-only access to Machine info CSRs
CSR_R_ACCESS mvendorid
CSR_R_ACCESS marchid
CSR_R_ACCESS mimpid
CSR_R_ACCESS mhartid
# CSR_R_ACCESS mconfigptr # Unimplemented in spike as of 31 Jan 22
END_TESTS
TEST_STACK_AND_DATA

View File

@ -21,133 +21,137 @@
// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
///////////////////////////////////////////
#include "WALLY-TEST-MACROS-64.h"
#include "WALLY-TEST-LIB-64.h"
INIT_TESTS
s_file_begin:
# Test 5.2.3.6: Test that all the machine mode CSR's are innaccessible for reads and writes in S mode.
# *** several of these appear not to be implemented in the assembler?
# I get "assembler messages: error: unkown CSR" with many of them.
goto_s_mode 0x0, 0x0
GOTO_S_MODE 0x0, 0x0
# Attempt to write 0xbad to each of these CSRs and read the value back
# should result in an illegal instruction for the write and read, respectively
# Machine information Registers
write_read_csr mvendorid, 0xbad
write_read_csr marchid, 0xbad
write_read_csr mimpid, 0xbad
write_read_csr mhartid, 0xbad
# write_read_csr mconfigptr, 0xbad # mconfigptr unimplemented in spike as of 31 Jan 22
WRITE_READ_CSR mvendorid, 0xbad
WRITE_READ_CSR marchid, 0xbad
WRITE_READ_CSR mimpid, 0xbad
WRITE_READ_CSR mhartid, 0xbad
# WRITE_READ_CSR mconfigptr, 0xbad # mconfigptr unimplemented in spike as of 31 Jan 22
# Machine Trap Setup
write_read_csr mstatus, 0xbad
write_read_csr misa, 0xbad
write_read_csr medeleg, 0xbad
write_read_csr mideleg, 0xbad
write_read_csr mie, 0xbad
write_read_csr mtvec, 0xbad
write_read_csr mcounteren, 0xbad
WRITE_READ_CSR mstatus, 0xbad
WRITE_READ_CSR misa, 0xbad
WRITE_READ_CSR medeleg, 0xbad
WRITE_READ_CSR mideleg, 0xbad
WRITE_READ_CSR mie, 0xbad
WRITE_READ_CSR mtvec, 0xbad
WRITE_READ_CSR mcounteren, 0xbad
# Machine Trap Handling
write_read_csr mscratch, 0xbad
write_read_csr mepc, 0xbad
write_read_csr mcause, 0xbad
write_read_csr mtval, 0xbad
write_read_csr mip, 0xbad
# write_read_csr mtinst, 0xbad # *** these appear not to be implemented in the compile step of make???
# write_read_csr mtval2, 0xbad
WRITE_READ_CSR mscratch, 0xbad
WRITE_READ_CSR mepc, 0xbad
WRITE_READ_CSR mcause, 0xbad
WRITE_READ_CSR mtval, 0xbad
WRITE_READ_CSR mip, 0xbad
# WRITE_READ_CSR mtinst, 0xbad # *** these appear not to be implemented in GCC
# WRITE_READ_CSR mtval2, 0xbad
# Machine Configuration
# write_read_csr menvcfg, 0xbad # *** these appear not to be implemented in the compile step of make???
# write_read_csr mseccgf, 0xbad
# WRITE_READ_CSR menvcfg, 0xbad # *** these appear not to be implemented in GCC
# WRITE_READ_CSR mseccgf, 0xbad
# Machine Memory Protection
write_read_csr pmpcfg0, 0xbad
write_read_csr pmpcfg2, 0xbad # pmpcfg 1 and 3 dont exist in rv64. there's 1 pmpcfg reg per 8 pmpaddr regs
WRITE_READ_CSR pmpcfg0, 0xbad
WRITE_READ_CSR pmpcfg2, 0xbad # pmpcfg 1 and 3 dont exist in rv64. there's 1 pmpcfg reg per 8 pmpaddr regs
write_read_csr pmpaddr0, 0xbad
write_read_csr pmpaddr1, 0xbad
write_read_csr pmpaddr2, 0xbad
write_read_csr pmpaddr3, 0xbad
write_read_csr pmpaddr4, 0xbad
write_read_csr pmpaddr5, 0xbad
write_read_csr pmpaddr6, 0xbad
write_read_csr pmpaddr7, 0xbad
write_read_csr pmpaddr8, 0xbad
write_read_csr pmpaddr9, 0xbad
write_read_csr pmpaddr10, 0xbad
write_read_csr pmpaddr11, 0xbad
write_read_csr pmpaddr12, 0xbad
write_read_csr pmpaddr13, 0xbad
write_read_csr pmpaddr14, 0xbad
write_read_csr pmpaddr15, 0xbad # only pmpcfg0...15 are enabled in our config
WRITE_READ_CSR pmpaddr0, 0xbad
WRITE_READ_CSR pmpaddr1, 0xbad
WRITE_READ_CSR pmpaddr2, 0xbad
WRITE_READ_CSR pmpaddr3, 0xbad
WRITE_READ_CSR pmpaddr4, 0xbad
WRITE_READ_CSR pmpaddr5, 0xbad
WRITE_READ_CSR pmpaddr6, 0xbad
WRITE_READ_CSR pmpaddr7, 0xbad
WRITE_READ_CSR pmpaddr8, 0xbad
WRITE_READ_CSR pmpaddr9, 0xbad
WRITE_READ_CSR pmpaddr10, 0xbad
WRITE_READ_CSR pmpaddr11, 0xbad
WRITE_READ_CSR pmpaddr12, 0xbad
WRITE_READ_CSR pmpaddr13, 0xbad
WRITE_READ_CSR pmpaddr14, 0xbad
WRITE_READ_CSR pmpaddr15, 0xbad # only pmpcfg0...15 are enabled in our config
# Machine Counter/Timers
write_read_csr mcycle, 0xbad
write_read_csr minstret, 0xbad
write_read_csr mhpmcounter3, 0xbad
write_read_csr mhpmcounter4, 0xbad
write_read_csr mhpmcounter5, 0xbad
write_read_csr mhpmcounter6, 0xbad
write_read_csr mhpmcounter7, 0xbad
write_read_csr mhpmcounter8, 0xbad
write_read_csr mhpmcounter9, 0xbad
write_read_csr mhpmcounter10, 0xbad
write_read_csr mhpmcounter11, 0xbad
write_read_csr mhpmcounter12, 0xbad
write_read_csr mhpmcounter13, 0xbad
write_read_csr mhpmcounter14, 0xbad
write_read_csr mhpmcounter15, 0xbad
write_read_csr mhpmcounter16, 0xbad
write_read_csr mhpmcounter17, 0xbad
write_read_csr mhpmcounter18, 0xbad
write_read_csr mhpmcounter19, 0xbad
write_read_csr mhpmcounter20, 0xbad
write_read_csr mhpmcounter21, 0xbad
write_read_csr mhpmcounter22, 0xbad
write_read_csr mhpmcounter23, 0xbad
write_read_csr mhpmcounter24, 0xbad
write_read_csr mhpmcounter25, 0xbad
write_read_csr mhpmcounter26, 0xbad
write_read_csr mhpmcounter27, 0xbad
write_read_csr mhpmcounter28, 0xbad
write_read_csr mhpmcounter29, 0xbad
write_read_csr mhpmcounter30, 0xbad
write_read_csr mhpmcounter31, 0xbad
WRITE_READ_CSR mcycle, 0xbad
WRITE_READ_CSR minstret, 0xbad
WRITE_READ_CSR mhpmcounter3, 0xbad
WRITE_READ_CSR mhpmcounter4, 0xbad
WRITE_READ_CSR mhpmcounter5, 0xbad
WRITE_READ_CSR mhpmcounter6, 0xbad
WRITE_READ_CSR mhpmcounter7, 0xbad
WRITE_READ_CSR mhpmcounter8, 0xbad
WRITE_READ_CSR mhpmcounter9, 0xbad
WRITE_READ_CSR mhpmcounter10, 0xbad
WRITE_READ_CSR mhpmcounter11, 0xbad
WRITE_READ_CSR mhpmcounter12, 0xbad
WRITE_READ_CSR mhpmcounter13, 0xbad
WRITE_READ_CSR mhpmcounter14, 0xbad
WRITE_READ_CSR mhpmcounter15, 0xbad
WRITE_READ_CSR mhpmcounter16, 0xbad
WRITE_READ_CSR mhpmcounter17, 0xbad
WRITE_READ_CSR mhpmcounter18, 0xbad
WRITE_READ_CSR mhpmcounter19, 0xbad
WRITE_READ_CSR mhpmcounter20, 0xbad
WRITE_READ_CSR mhpmcounter21, 0xbad
WRITE_READ_CSR mhpmcounter22, 0xbad
WRITE_READ_CSR mhpmcounter23, 0xbad
WRITE_READ_CSR mhpmcounter24, 0xbad
WRITE_READ_CSR mhpmcounter25, 0xbad
WRITE_READ_CSR mhpmcounter26, 0xbad
WRITE_READ_CSR mhpmcounter27, 0xbad
WRITE_READ_CSR mhpmcounter28, 0xbad
WRITE_READ_CSR mhpmcounter29, 0xbad
WRITE_READ_CSR mhpmcounter30, 0xbad
WRITE_READ_CSR mhpmcounter31, 0xbad
# Machine Counter Setup
write_read_csr mcountinhibit, 0xbad
write_read_csr mhpmevent3, 0xbad
write_read_csr mhpmevent4, 0xbad
write_read_csr mhpmevent5, 0xbad
write_read_csr mhpmevent6, 0xbad
write_read_csr mhpmevent7, 0xbad
write_read_csr mhpmevent8, 0xbad
write_read_csr mhpmevent9, 0xbad
write_read_csr mhpmevent10, 0xbad
write_read_csr mhpmevent11, 0xbad
write_read_csr mhpmevent12, 0xbad
write_read_csr mhpmevent13, 0xbad
write_read_csr mhpmevent14, 0xbad
write_read_csr mhpmevent15, 0xbad
write_read_csr mhpmevent16, 0xbad
write_read_csr mhpmevent17, 0xbad
write_read_csr mhpmevent18, 0xbad
write_read_csr mhpmevent19, 0xbad
write_read_csr mhpmevent20, 0xbad
write_read_csr mhpmevent21, 0xbad
write_read_csr mhpmevent22, 0xbad
write_read_csr mhpmevent23, 0xbad
write_read_csr mhpmevent24, 0xbad
write_read_csr mhpmevent25, 0xbad
write_read_csr mhpmevent26, 0xbad
write_read_csr mhpmevent27, 0xbad
write_read_csr mhpmevent28, 0xbad
write_read_csr mhpmevent29, 0xbad
write_read_csr mhpmevent30, 0xbad
write_read_csr mhpmevent31, 0xbad
WRITE_READ_CSR mcountinhibit, 0xbad
WRITE_READ_CSR mhpmevent3, 0xbad
WRITE_READ_CSR mhpmevent4, 0xbad
WRITE_READ_CSR mhpmevent5, 0xbad
WRITE_READ_CSR mhpmevent6, 0xbad
WRITE_READ_CSR mhpmevent7, 0xbad
WRITE_READ_CSR mhpmevent8, 0xbad
WRITE_READ_CSR mhpmevent9, 0xbad
WRITE_READ_CSR mhpmevent10, 0xbad
WRITE_READ_CSR mhpmevent11, 0xbad
WRITE_READ_CSR mhpmevent12, 0xbad
WRITE_READ_CSR mhpmevent13, 0xbad
WRITE_READ_CSR mhpmevent14, 0xbad
WRITE_READ_CSR mhpmevent15, 0xbad
WRITE_READ_CSR mhpmevent16, 0xbad
WRITE_READ_CSR mhpmevent17, 0xbad
WRITE_READ_CSR mhpmevent18, 0xbad
WRITE_READ_CSR mhpmevent19, 0xbad
WRITE_READ_CSR mhpmevent20, 0xbad
WRITE_READ_CSR mhpmevent21, 0xbad
WRITE_READ_CSR mhpmevent22, 0xbad
WRITE_READ_CSR mhpmevent23, 0xbad
WRITE_READ_CSR mhpmevent24, 0xbad
WRITE_READ_CSR mhpmevent25, 0xbad
WRITE_READ_CSR mhpmevent26, 0xbad
WRITE_READ_CSR mhpmevent27, 0xbad
WRITE_READ_CSR mhpmevent28, 0xbad
WRITE_READ_CSR mhpmevent29, 0xbad
WRITE_READ_CSR mhpmevent30, 0xbad
WRITE_READ_CSR mhpmevent31, 0xbad
END_TESTS
END_TESTS
TEST_STACK_AND_DATA

View File

@ -21,149 +21,153 @@
// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
///////////////////////////////////////////
#include "WALLY-TEST-MACROS-64.h"
#include "WALLY-TEST-LIB-64.h"
INIT_TESTS
s_file_begin:
# Test 5.2.3.6: Test that all the machine mode CSR's are innaccessible for reads and writes in R mode.
goto_u_mode 0x0, 0x0
GOTO_U_MODE 0x0, 0x0
# Attempt to write 0xbad to each of these CSRs and read the value back
# should result in an illegal instruction for the write and read, respectively
# Supervisor Trap Setup
write_read_csr sstatus, 0xbad
write_read_csr sie, 0xbad
write_read_csr stvec, 0xbad
write_read_csr scounteren, 0xbad
WRITE_READ_CSR sstatus, 0xbad
WRITE_READ_CSR sie, 0xbad
WRITE_READ_CSR stvec, 0xbad
WRITE_READ_CSR scounteren, 0xbad
# Supervisor Configuration
# write_read_csr senvcfg, 0xbad # *** these appear not to be implemented in the compile step of make???
# WRITE_READ_CSR senvcfg, 0xbad # *** these appear not to be implemented in GCC
# Supervisor Trap Handling
write_read_csr sscratch, 0xbad
write_read_csr sepc, 0xbad
write_read_csr scause, 0xbad
write_read_csr stval, 0xbad
write_read_csr sip, 0xbad
WRITE_READ_CSR sscratch, 0xbad
WRITE_READ_CSR sepc, 0xbad
WRITE_READ_CSR scause, 0xbad
WRITE_READ_CSR stval, 0xbad
WRITE_READ_CSR sip, 0xbad
# Supervisor Protection and Translation
write_read_csr satp, 0xbad
WRITE_READ_CSR satp, 0xbad
# Machine information Registers
write_read_csr mvendorid, 0xbad
write_read_csr marchid, 0xbad
write_read_csr mimpid, 0xbad
write_read_csr mhartid, 0xbad
# write_read_csr mconfigptr, 0xbad # mconfigptr unimplemented in spike as of 31 Jan 22
WRITE_READ_CSR mvendorid, 0xbad
WRITE_READ_CSR marchid, 0xbad
WRITE_READ_CSR mimpid, 0xbad
WRITE_READ_CSR mhartid, 0xbad
# WRITE_READ_CSR mconfigptr, 0xbad # mconfigptr unimplemented in spike as of 31 Jan 22
# Machine Trap Setup
write_read_csr mstatus, 0xbad
write_read_csr misa, 0xbad
write_read_csr medeleg, 0xbad
write_read_csr mideleg, 0xbad
write_read_csr mie, 0xbad
write_read_csr mtvec, 0xbad
write_read_csr mcounteren, 0xbad
WRITE_READ_CSR mstatus, 0xbad
WRITE_READ_CSR misa, 0xbad
WRITE_READ_CSR medeleg, 0xbad
WRITE_READ_CSR mideleg, 0xbad
WRITE_READ_CSR mie, 0xbad
WRITE_READ_CSR mtvec, 0xbad
WRITE_READ_CSR mcounteren, 0xbad
# Machine Trap Handling
write_read_csr mscratch, 0xbad
write_read_csr mepc, 0xbad
write_read_csr mcause, 0xbad
write_read_csr mtval, 0xbad
write_read_csr mip, 0xbad
# write_read_csr mtinst, 0xbad # *** these appear not to be implemented in the compile step of make???
# write_read_csr mtval2, 0xbad
WRITE_READ_CSR mscratch, 0xbad
WRITE_READ_CSR mepc, 0xbad
WRITE_READ_CSR mcause, 0xbad
WRITE_READ_CSR mtval, 0xbad
WRITE_READ_CSR mip, 0xbad
# WRITE_READ_CSR mtinst, 0xbad # *** these appear not to be implemented in GCC
# WRITE_READ_CSR mtval2, 0xbad
# Machine Configuration
# write_read_csr menvcfg, 0xbad # *** these appear not to be implemented in the compile step of make???
# write_read_csr mseccgf, 0xbad
# WRITE_READ_CSR menvcfg, 0xbad # *** these appear not to be implemented in GCC
# WRITE_READ_CSR mseccgf, 0xbad
# Machine Memory Protection
write_read_csr pmpcfg0, 0xbad
write_read_csr pmpcfg2, 0xbad # pmpcfg 1 and 3 dont exist in rv64. there's 1 pmpcfg reg per 8 pmpaddr regs
WRITE_READ_CSR pmpcfg0, 0xbad
WRITE_READ_CSR pmpcfg2, 0xbad # pmpcfg 1 and 3 dont exist in rv64. there's 1 pmpcfg reg per 8 pmpaddr regs
write_read_csr pmpaddr0, 0xbad
write_read_csr pmpaddr1, 0xbad
write_read_csr pmpaddr2, 0xbad
write_read_csr pmpaddr3, 0xbad
write_read_csr pmpaddr4, 0xbad
write_read_csr pmpaddr5, 0xbad
write_read_csr pmpaddr6, 0xbad
write_read_csr pmpaddr7, 0xbad
write_read_csr pmpaddr8, 0xbad
write_read_csr pmpaddr9, 0xbad
write_read_csr pmpaddr10, 0xbad
write_read_csr pmpaddr11, 0xbad
write_read_csr pmpaddr12, 0xbad
write_read_csr pmpaddr13, 0xbad
write_read_csr pmpaddr14, 0xbad
write_read_csr pmpaddr15, 0xbad # only pmpcfg0...15 are enabled in our config
WRITE_READ_CSR pmpaddr0, 0xbad
WRITE_READ_CSR pmpaddr1, 0xbad
WRITE_READ_CSR pmpaddr2, 0xbad
WRITE_READ_CSR pmpaddr3, 0xbad
WRITE_READ_CSR pmpaddr4, 0xbad
WRITE_READ_CSR pmpaddr5, 0xbad
WRITE_READ_CSR pmpaddr6, 0xbad
WRITE_READ_CSR pmpaddr7, 0xbad
WRITE_READ_CSR pmpaddr8, 0xbad
WRITE_READ_CSR pmpaddr9, 0xbad
WRITE_READ_CSR pmpaddr10, 0xbad
WRITE_READ_CSR pmpaddr11, 0xbad
WRITE_READ_CSR pmpaddr12, 0xbad
WRITE_READ_CSR pmpaddr13, 0xbad
WRITE_READ_CSR pmpaddr14, 0xbad
WRITE_READ_CSR pmpaddr15, 0xbad # only pmpcfg0...15 are enabled in our config
# Machine Counter/Timers
write_read_csr mcycle, 0xbad
write_read_csr minstret, 0xbad
write_read_csr mhpmcounter3, 0xbad
write_read_csr mhpmcounter4, 0xbad
write_read_csr mhpmcounter5, 0xbad
write_read_csr mhpmcounter6, 0xbad
write_read_csr mhpmcounter7, 0xbad
write_read_csr mhpmcounter8, 0xbad
write_read_csr mhpmcounter9, 0xbad
write_read_csr mhpmcounter10, 0xbad
write_read_csr mhpmcounter11, 0xbad
write_read_csr mhpmcounter12, 0xbad
write_read_csr mhpmcounter13, 0xbad
write_read_csr mhpmcounter14, 0xbad
write_read_csr mhpmcounter15, 0xbad
write_read_csr mhpmcounter16, 0xbad
write_read_csr mhpmcounter17, 0xbad
write_read_csr mhpmcounter18, 0xbad
write_read_csr mhpmcounter19, 0xbad
write_read_csr mhpmcounter20, 0xbad
write_read_csr mhpmcounter21, 0xbad
write_read_csr mhpmcounter22, 0xbad
write_read_csr mhpmcounter23, 0xbad
write_read_csr mhpmcounter24, 0xbad
write_read_csr mhpmcounter25, 0xbad
write_read_csr mhpmcounter26, 0xbad
write_read_csr mhpmcounter27, 0xbad
write_read_csr mhpmcounter28, 0xbad
write_read_csr mhpmcounter29, 0xbad
write_read_csr mhpmcounter30, 0xbad
write_read_csr mhpmcounter31, 0xbad
WRITE_READ_CSR mcycle, 0xbad
WRITE_READ_CSR minstret, 0xbad
WRITE_READ_CSR mhpmcounter3, 0xbad
WRITE_READ_CSR mhpmcounter4, 0xbad
WRITE_READ_CSR mhpmcounter5, 0xbad
WRITE_READ_CSR mhpmcounter6, 0xbad
WRITE_READ_CSR mhpmcounter7, 0xbad
WRITE_READ_CSR mhpmcounter8, 0xbad
WRITE_READ_CSR mhpmcounter9, 0xbad
WRITE_READ_CSR mhpmcounter10, 0xbad
WRITE_READ_CSR mhpmcounter11, 0xbad
WRITE_READ_CSR mhpmcounter12, 0xbad
WRITE_READ_CSR mhpmcounter13, 0xbad
WRITE_READ_CSR mhpmcounter14, 0xbad
WRITE_READ_CSR mhpmcounter15, 0xbad
WRITE_READ_CSR mhpmcounter16, 0xbad
WRITE_READ_CSR mhpmcounter17, 0xbad
WRITE_READ_CSR mhpmcounter18, 0xbad
WRITE_READ_CSR mhpmcounter19, 0xbad
WRITE_READ_CSR mhpmcounter20, 0xbad
WRITE_READ_CSR mhpmcounter21, 0xbad
WRITE_READ_CSR mhpmcounter22, 0xbad
WRITE_READ_CSR mhpmcounter23, 0xbad
WRITE_READ_CSR mhpmcounter24, 0xbad
WRITE_READ_CSR mhpmcounter25, 0xbad
WRITE_READ_CSR mhpmcounter26, 0xbad
WRITE_READ_CSR mhpmcounter27, 0xbad
WRITE_READ_CSR mhpmcounter28, 0xbad
WRITE_READ_CSR mhpmcounter29, 0xbad
WRITE_READ_CSR mhpmcounter30, 0xbad
WRITE_READ_CSR mhpmcounter31, 0xbad
# Machine Counter Setup
write_read_csr mcountinhibit, 0xbad
write_read_csr mhpmevent3, 0xbad
write_read_csr mhpmevent4, 0xbad
write_read_csr mhpmevent5, 0xbad
write_read_csr mhpmevent6, 0xbad
write_read_csr mhpmevent7, 0xbad
write_read_csr mhpmevent8, 0xbad
write_read_csr mhpmevent9, 0xbad
write_read_csr mhpmevent10, 0xbad
write_read_csr mhpmevent11, 0xbad
write_read_csr mhpmevent12, 0xbad
write_read_csr mhpmevent13, 0xbad
write_read_csr mhpmevent14, 0xbad
write_read_csr mhpmevent15, 0xbad
write_read_csr mhpmevent16, 0xbad
write_read_csr mhpmevent17, 0xbad
write_read_csr mhpmevent18, 0xbad
write_read_csr mhpmevent19, 0xbad
write_read_csr mhpmevent20, 0xbad
write_read_csr mhpmevent21, 0xbad
write_read_csr mhpmevent22, 0xbad
write_read_csr mhpmevent23, 0xbad
write_read_csr mhpmevent24, 0xbad
write_read_csr mhpmevent25, 0xbad
write_read_csr mhpmevent26, 0xbad
write_read_csr mhpmevent27, 0xbad
write_read_csr mhpmevent28, 0xbad
write_read_csr mhpmevent29, 0xbad
write_read_csr mhpmevent30, 0xbad
write_read_csr mhpmevent31, 0xbad
WRITE_READ_CSR mcountinhibit, 0xbad
WRITE_READ_CSR mhpmevent3, 0xbad
WRITE_READ_CSR mhpmevent4, 0xbad
WRITE_READ_CSR mhpmevent5, 0xbad
WRITE_READ_CSR mhpmevent6, 0xbad
WRITE_READ_CSR mhpmevent7, 0xbad
WRITE_READ_CSR mhpmevent8, 0xbad
WRITE_READ_CSR mhpmevent9, 0xbad
WRITE_READ_CSR mhpmevent10, 0xbad
WRITE_READ_CSR mhpmevent11, 0xbad
WRITE_READ_CSR mhpmevent12, 0xbad
WRITE_READ_CSR mhpmevent13, 0xbad
WRITE_READ_CSR mhpmevent14, 0xbad
WRITE_READ_CSR mhpmevent15, 0xbad
WRITE_READ_CSR mhpmevent16, 0xbad
WRITE_READ_CSR mhpmevent17, 0xbad
WRITE_READ_CSR mhpmevent18, 0xbad
WRITE_READ_CSR mhpmevent19, 0xbad
WRITE_READ_CSR mhpmevent20, 0xbad
WRITE_READ_CSR mhpmevent21, 0xbad
WRITE_READ_CSR mhpmevent22, 0xbad
WRITE_READ_CSR mhpmevent23, 0xbad
WRITE_READ_CSR mhpmevent24, 0xbad
WRITE_READ_CSR mhpmevent25, 0xbad
WRITE_READ_CSR mhpmevent26, 0xbad
WRITE_READ_CSR mhpmevent27, 0xbad
WRITE_READ_CSR mhpmevent28, 0xbad
WRITE_READ_CSR mhpmevent29, 0xbad
WRITE_READ_CSR mhpmevent30, 0xbad
WRITE_READ_CSR mhpmevent31, 0xbad
END_TESTS
TEST_STACK_AND_DATA

View File

@ -22,8 +22,18 @@
///////////////////////////////////////////
#include "WALLY-TEST-LIB-64.h"
// Test library includes and handler for each type of test, a trap handler, imperas compliance instructions
// Ideally this should mean that a test can be written by simply adding .8byte statements as below.
INIT_TESTS
s_file_begin:
j test_loop_setup // begin test loop/table tests instead of executing inline code.
INIT_TEST_TABLE
TEST_STACK_AND_DATA
.align 3
test_cases:
# ---------------------------------------------------------------------------------------------
# Test Contents

View File

@ -22,8 +22,19 @@
///////////////////////////////////////////
#include "WALLY-TEST-LIB-64.h"
// Test library includes and handler for each type of test, a trap handler, imperas compliance instructions
// Ideally this should mean that a test can be written by simply adding .8byte statements as below.
INIT_TESTS
s_file_begin:
j test_loop_setup // begin test loop/table tests instead of executing inline code.
INIT_TEST_TABLE
TEST_STACK_AND_DATA
# These tests follow the testing plan in Chapter 12 of the riscv-wally textbook
.align 3
test_cases:
# ---------------------------------------------------------------------------------------------
# Test Contents
@ -39,7 +50,6 @@
#
# ---------------------------------------------------------------------------------------------
# These tests follow the testing plan in Chapter 12 of the riscv-wally textbook
# =========== test 12.3.1.1 Page Table Translation ===========

View File

@ -35,8 +35,19 @@
#define PLIC_RANGE 0x03FFFFFF
#include "WALLY-TEST-LIB-64.h"
// Test library includes and handler for each type of test, a trap handler, imperas compliance instructions
// Ideally this should mean that a test can be written by simply adding .8byte statements as below.
INIT_TESTS
s_file_begin:
j test_loop_setup // begin test loop/table tests instead of executing inline code.
INIT_TEST_TABLE
TEST_STACK_AND_DATA
# These tests follow the testing plan in Chapter 12 of the riscv-wally textbook
.align 3
test_cases:
# ---------------------------------------------------------------------------------------------
# Test Contents

View File

@ -22,8 +22,19 @@
///////////////////////////////////////////
#include "WALLY-TEST-LIB-64.h"
// Test library includes and handler for each type of test, a trap handler, imperas compliance instructions
// Ideally this should mean that a test can be written by simply adding .8byte statements as below.
INIT_TESTS
s_file_begin:
j test_loop_setup // begin test loop/table tests instead of executing inline code.
INIT_TEST_TABLE
TEST_STACK_AND_DATA
# These tests follow the testing plan in Chapter 12 of the riscv-wally textbook
.align 3
test_cases:
# ---------------------------------------------------------------------------------------------
# Test Contents

View File

@ -23,6 +23,9 @@
#include "model_test.h"
#include "arch_test.h"
.macro INIT_TESTS
RVTEST_ISA("RV64I")
.section .text.init
@ -56,9 +59,9 @@ RVTEST_CODE_BEGIN
li a1, 0
li a2, 0 // reset trap handler inputs to zero
// go to first test!
j test_setup
// go to beginning of S file where we can decide between using the test data loop
// or using the macro inline code insertion
j s_file_begin
// ---------------------------------------------------------------------------------------------
// General traps Handler
@ -230,6 +233,9 @@ instrfault:
ld x1, -8(sp) // load return address int x1 (the address AFTER the jal into faulting page)
j trapreturn_finished // puts x1 into mepc, restores stack and returns to program (outside of faulting page)
illegalinstr:
j trapreturn // return to the code after recording the mcause
accessfault:
// *** What do I have to do here?
j trapreturn
@ -243,7 +249,7 @@ accessfault:
trap_handler_vector_table:
.8byte segfault // 0: instruction address misaligned
.8byte instrfault // 1: instruction access fault
.8byte segfault // 2: illegal instruction
.8byte illegalinstr // 2: illegal instruction
.8byte segfault // 3: breakpoint
.8byte segfault // 4: load address misaligned
.8byte accessfault // 5: load access fault
@ -265,6 +271,249 @@ trap_return_pagetype_table:
.8byte 0x1E // 2: gigapage has 30 offset bits
.8byte 0x27 // 3: terapage has 39 offset bits
.endm
// Test Summary table!
// Test Name : Description : Fault output value : Normal output values
// ---------------------:-------------------------------------------:-------------------------------------------:------------------------------------------------------
// write64_test : Write 64 bits to address : 0x6, 0x7, or 0xf : None
// write32_test : Write 32 bits to address : 0x6, 0x7, or 0xf : None
// write16_test : Write 16 bits to address : 0x6, 0x7, or 0xf : None
// write08_test : Write 8 bits to address : 0x6, 0x7, or 0xf : None
// read64_test : Read 64 bits from address : 0x4, 0x5, or 0xd, then 0xbad : readvalue in hex
// read32_test : Read 32 bits from address : 0x4, 0x5, or 0xd, then 0xbad : readvalue in hex
// read16_test : Read 16 bits from address : 0x4, 0x5, or 0xd, then 0xbad : readvalue in hex
// read08_test : Read 8 bits from address : 0x4, 0x5, or 0xd, then 0xbad : readvalue in hex
// executable_test : test executable on virtual page : 0x0, 0x1, or 0xc, then 0xbad : value of x7 modified by exectuion code (usually 0x111)
// terminate_test : terminate tests : mcause value for fault : from M 0xb, from S 0x9, from U 0x8
// goto_baremetal : satp.MODE = bare metal : None : None
// goto_sv39 : satp.MODE = sv39 : None : None
// goto_sv48 : satp.MODE = sv48 : None : None
// goto_m_mode : go to mahcine mode : mcause value for fault : from M 0xb, from S 0x9, from U 0x8
// goto_s_mode : go to supervisor mode : mcause value for fault : from M 0xb, from S 0x9, from U 0x8
// goto_u_mode : go to user mode : mcause value for fault : from M 0xb, from S 0x9, from U 0x8
// write_read_csr : write to specified CSR : old CSR value, 0x2, depending on perms : value written to CSR
// csr_r_access : test read-only permissions on CSR : 0xbad : 0x2, then 0x11
// *** TESTS TO ADD: execute inline, read unknown value out, read CSR unknown value, just read CSR value
.macro WRITE64 ADDR VAL
// attempt to write VAL to ADDR
// Success outputs:
// None
// Fault outputs:
// 0x6: misaligned address
// 0x7: access fault
// 0xf: page fault
li x29, \VAL
li x30, \ADDR
sd x29, 0(x30)
.endm
.macro WRITE32 ADDR VAL
// all write tests have the same description/outputs as write64
li x29, \VAL
li x30, \ADDR
sw x29, 0(x30)
.endm
.macro WRITE16 ADDR VAL
// all write tests have the same description/outputs as write64
li x29, \VAL
li x30, \ADDR
sh x29, 0(x30)
.endm
.macro WRITE08 ADDR VAL
// all write tests have the same description/outputs as write64
li x29, \VAL
li x30, \ADDR
sb x29, 0(x30)
.endm
.macro READ64 ADDR
// Attempt read at ADDR. Write the value read out to the output *** Consider adding specific test for reading a non known value
// Success outputs:
// value read out from ADDR
// Fault outputs:
// One of the following followed by 0xBAD
// 0x4: misaligned address
// 0x5: access fault
// 0xD: page fault
li x7, 0xBAD // bad value that will be overwritten on good reads.
li x29, \ADDR
ld x7, 0(x29)
sd x7, 0(x6)
addi x6, x6, 8
addi x16, x16, 8
.endm
.macro READ32 ADDR
// All reads have the same description/outputs as read64.
// They will store the sign extended value of what was read out at ADDR
li x7, 0xBAD // bad value that will be overwritten on good reads.
li x29, \ADDR
lw x7, 0(x29)
sd x7, 0(x6)
addi x6, x6, 8
addi x16, x16, 8
.endm
.macro READ16 ADDR
// All reads have the same description/outputs as read64.
// They will store the sign extended value of what was read out at ADDR
li x7, 0xBAD // bad value that will be overwritten on good reads.
li x29, \ADDR
lh x7, 0(x29)
sd x7, 0(x6)
addi x6, x6, 8
addi x16, x16, 8
.endm
.macro READ08 ADDR
// All reads have the same description/outputs as read64.
// They will store the sign extended value of what was read out at ADDR
li x7, 0xBAD // bad value that will be overwritten on good reads.
li x29, \ADDR
lb x7, 0(x29)
sd x7, 0(x6)
addi x6, x6, 8
addi x16, x16, 8
.endm
// These goto_x_mode tests all involve invoking the trap handler,
// So their outputs are inevitably:
// 0x8: test called from U mode
// 0x9: test called from S mode
// 0xB: test called from M mode
// they generally do not fault or cause issues as long as these modes are enabled
// *** add functionality to check if modes are enabled before jumping? maybe cause a fault if not?
.macro GOTO_M_MODE RETURN_VPN RETURN_PAGETYPE
li a0, 2 // determine trap handler behavior (go to machine mode)
li a1, \RETURN_VPN // return VPN
li a2, \RETURN_PAGETYPE // return page types
ecall // writes mcause to the output.
// now in S mode
.endm
.macro GOTO_S_MODE RETURN_VPN RETURN_PAGETYPE
li a0, 3 // determine trap handler behavior (go to supervisor mode)
li a1, \RETURN_VPN // return VPN
li a2, \RETURN_PAGETYPE // return page types
ecall // writes mcause to the output.
// now in S mode
.endm
.macro GOTO_U_MODE RETURN_VPN RETURN_PAGETYPE
li a0, 4 // determine trap handler behavior (go to user mode)
li a1, \RETURN_VPN // return VPN
li a2, \RETURN_PAGETYPE // return page types
ecall // writes mcause to the output.
// now in S mode
.endm
// These tests change virtual memory settings, turning it on/off and changing between types.
// They don't have outputs as any error with turning on virtual memory should reveal itself in the tests *** Consider changing this policy?
.macro GOTO_BAREMETAL
// Turn translation off
li x7, 0 // satp.MODE value for bare metal (0)
slli x7, x7, 60
li x28, 0x8000D // Base Pagetable physical page number, satp.PPN field. *** add option for different pagetable location
add x7, x7, x28
csrw satp, x7
sfence.vma x0, x0 // *** flushes global pte's as well
.endm
.macro GOTO_SV39
// Turn on sv39 virtual memory
li x7, 8 // satp.MODE value for Sv39 (8)
slli x7, x7, 60
li x28, 0x8000D // Base Pagetable physical page number, satp.PPN field. *** add option for different pagetable location
add x7, x7, x28
csrw satp, x7
sfence.vma x0, x0 // *** flushes global pte's as well
.endm
.macro GOTO_SV48
// Turn on sv48 virtual memory
li x7, 9 // satp.MODE value for Sv39 (8)
slli x7, x7, 60
li x28, 0x8000D // Base Pagetable physical page number, satp.PPN field. *** add option for different pagetable location
add x7, x7, x28
csrw satp, x7
sfence.vma x0, x0 // *** flushes global pte's as well
.endm
.macro WRITE_READ_CSR CSR VAL
// attempt to write CSR with VAL. Note: this also tests read access to CSR
// Success outputs:
// value read back out from CSR after writing
// Fault outputs:
// The previous CSR value before write attempt
// *** Most likely 0x2, the mcause for illegal instruction if we don't have write or read access
li x30, 0xbad // load bad value to be overwritten by csrr
li x29, \VAL
csrw \CSR\(), x29
csrr x30, \CSR
sd x30, 0(x6)
addi x6, x6, 8
addi x16, x16, 8
.endm
.macro CSR_R_ACCESS CSR
// verify that a csr is accessible to read but not to write
// Success outputs:
// 0x2, then
// 0x11 *** consider changing to something more meaningful
// Fault outputs:
// 0xBAD *** consider changing this one as well. in general, do we need the branching if it hould cause an illegal instruction fault?
csrr x29, \CSR
csrwi \CSR\(), 0xA // Attempt to write a 'random' value to the CSR
csrr x30, \CSR
bne x30, x29, 1f // 1f represents write_access
li x30, 0x11 // Write failed, confirming read only permissions.
j 2f // j r_access_end
1: // w_access (write succeeded, violating read-only)
li x30, 0xBAD
2: // r_access end
sd x30, 0(x6)
addi x6, x6, 8
addi x16, x16, 8
.endm
.macro EXECUTE_AT_ADDRESS ADDR
// Execute the code already written to ADDR, returning the value in x7.
// *** Note: this test itself doesn't write the code to ADDR because it might be callled at a point where we dont have write access to ADDR
// Assumes the code modifies x7, usually to become 0x111.
// Sample code: 0x11100393 (li x7, 0x111), 0x00008067 (ret)
// Success outputs:
// modified value of x7. (0x111 if you use the sample code)
// Fault outputs:
// One of the following followed by 0xBAD
// 0x0: misaligned address
// 0x1: access fault
// 0xC: page fault
fence.i // forces caches and main memory to sync so execution code written to ADDR can run.
li x7, 0xBAD
li x28, \ADDR
jalr x28 // jump to executable test code
sd x7, 0(x6)
addi x6, x6, 8
addi x16, x16, 8
.endm
.macro END_TESTS
// invokes one final ecall to return to machine mode then terminates this program, so the output is
// 0x8: termination called from U mode
// 0x9: termination called from S mode
// 0xB: termination called from M mode
j terminate_test
.endm
// ---------------------------------------------------------------------------------------------
// Test Handler
//
@ -274,17 +523,18 @@ trap_return_pagetype_table:
// Input parameters:
//
// x28:
// Address input for the test taking place (think address to read/write, new address to return to, etc...)
// Address input for the test taking place (think: address to read/write, new address to return to, etc...)
//
// x29:
// Value input for the test taking place (think value to write, any other extra info needed)
// Value input for the test taking place (think: value to write, any other extra info needed)
//
// x30:
// Test type input that determines which kind of test will take place. Encoding for this input is in the table/case statements below
//
// Label for the location of the test that's about to take place
// ------------------------------------------------------------------------------------------------------------------------------------
test_setup:
.macro INIT_TEST_TABLE // *** Consider renaming this test. to what???
test_loop_setup:
la x5, test_cases
test_loop:
@ -407,30 +657,15 @@ goto_u_mode:
goto_baremetal:
// Turn translation off
li x7, 0 // satp.MODE value for bare metal (0)
slli x7, x7, 60
li x28, 0x8000D // Base Pagetable physical page number, satp.PPN field.
add x7, x7, x28
csrw satp, x7
sfence.vma x0, x0 // *** flushes global pte's as well
GOTO_BAREMETAL
j test_loop // go to next test case
goto_sv39:
li x7, 8 // satp.MODE value for Sv39 (8)
slli x7, x7, 60
li x28, 0x8000D // Base Pagetable physical page number, satp.PPN field.
add x7, x7, x28
csrw satp, x7
sfence.vma x0, x0 // *** flushes global pte's as well
GOTO_SV39
j test_loop // go to next test case
goto_sv48:
li x7, 9 // satp.MODE value for Sv48
slli x7, x7, 60
li x28, 0x8000D // Base Pagetable physical page number, satp.PPN field.
add x7, x7, x28
csrw satp, x7
sfence.vma x0, x0 // *** flushes global pte's as well
GOTO_SV48
j test_loop // go to next test case
write_mxr_sum:
@ -447,15 +682,15 @@ write_mxr_sum:
write_pmpcfg_0:
// writes the value in x29 to the pmpcfg register specified in x28.
// then writes the final value of pmpcfgX to the output.
li x7, 0x0
bne x7, x28, write_pmpcfg_2
csrw pmpcfg0, x29
csrr x30, pmpcfg0
j write_pmpcfg_end
write_pmpcfg_2:
li x7, 0x2
bne x7, x28, write_pmpcfg_end
csrw pmpcfg2, x29
csrr x30, pmpcfg2 // I would use csrrw but we need the value AFTER the csr has been written
j write_pmpcfg_end
write_pmpcfg_end:
sd x30, 0(x6)
addi x6, x6, 8
@ -463,103 +698,88 @@ write_pmpcfg_end:
j test_loop
write_pmpaddr_0:
// write_read_csr pmpaddr0, x29
// writes the value in x29 to the pmpaddr register specified in x28.
// then writes the final value of pmpaddrX to the output.
li x7, 0x0
bne x7, x28, write_pmpaddr_1
csrw pmpaddr0, x29
csrr x30, pmpaddr0
j write_pmpaddr_end
write_pmpaddr_1:
li x7, 0x1
bne x7, x28, write_pmpaddr_2
csrw pmpaddr1, x29
csrr x30, pmpaddr1
j write_pmpaddr_end
write_pmpaddr_2:
li x7, 0x2
bne x7, x28, write_pmpaddr_3
csrw pmpaddr2, x29
csrr x30, pmpaddr2
j write_pmpaddr_end
write_pmpaddr_3:
li x7, 0x3
bne x7, x28, write_pmpaddr_4
csrw pmpaddr3, x29
csrr x30, pmpaddr3
j write_pmpaddr_end
write_pmpaddr_4:
li x7, 0x4
bne x7, x28, write_pmpaddr_5
csrw pmpaddr4, x29
csrr x30, pmpaddr4
j write_pmpaddr_end
write_pmpaddr_5:
li x7, 0x5
bne x7, x28, write_pmpaddr_6
csrw pmpaddr5, x29
csrr x30, pmpaddr5
j write_pmpaddr_end
write_pmpaddr_6:
li x7, 0x6
bne x7, x28, write_pmpaddr_7
csrw pmpaddr6, x29
csrr x30, pmpaddr6
j write_pmpaddr_end
write_pmpaddr_7:
li x7, 0x7
bne x7, x28, write_pmpaddr_8
csrw pmpaddr7, x29
csrr x30, pmpaddr7
j write_pmpaddr_end
write_pmpaddr_8:
li x7, 0x8
bne x7, x28, write_pmpaddr_9
csrw pmpaddr8, x29
csrr x30, pmpaddr8
j write_pmpaddr_end
write_pmpaddr_9:
li x7, 0x9
bne x7, x28, write_pmpaddr_10
csrw pmpaddr9, x29
csrr x30, pmpaddr9
j write_pmpaddr_end
write_pmpaddr_10:
li x7, 0xA
bne x7, x28, write_pmpaddr_11
csrw pmpaddr10, x29
csrr x30, pmpaddr10
j write_pmpaddr_end
write_pmpaddr_11:
li x7, 0xB
bne x7, x28, write_pmpaddr_12
csrw pmpaddr11, x29
csrr x30, pmpaddr11
j write_pmpaddr_end
write_pmpaddr_12:
li x7, 0xC
bne x7, x28, write_pmpaddr_13
csrw pmpaddr12, x29
csrr x30, pmpaddr12
j write_pmpaddr_end
write_pmpaddr_13:
li x7, 0xD
bne x7, x28, write_pmpaddr_14
csrw pmpaddr13, x29
csrr x30, pmpaddr13
j write_pmpaddr_end
write_pmpaddr_14:
li x7, 0xE
bne x7, x28, write_pmpaddr_15
csrw pmpaddr14, x29
csrr x30, pmpaddr14
j write_pmpaddr_end
write_pmpaddr_15:
li x7, 0xF
bne x7, x28, write_pmpaddr_end
csrw pmpaddr15, x29
csrr x30, pmpaddr15
j write_pmpaddr_end
write_pmpaddr_end:
sd x30, 0(x6)
addi x6, x6, 8
@ -577,6 +797,10 @@ executable_test:
addi x16, x16, 8
j test_loop
.endm
// notably, terminate_test is not a part of the test table macro because it needs to be defined
// in any type of test, macro or test table, for the trap handler to work
terminate_test:
li a0, 2 // Trap handler behavior (go to machine mode)
@ -586,6 +810,8 @@ terminate_test:
RVTEST_CODE_END
RVMODEL_HALT
.macro TEST_STACK_AND_DATA
RVTEST_DATA_BEGIN
.align 4
rvtest_data:
@ -619,6 +845,4 @@ gpr_save:
#endif
.align 3
test_cases:
.endm

View File

@ -21,17 +21,19 @@
// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
///////////////////////////////////////////
#include "WALLY-TEST-MACROS-64.h"
#include "WALLY-TEST-LIB-64.h"
INIT_TESTS
s_file_begin:
// Test 5.2.3.1: testing Read-only access to Machine info CSRs
CSR_R_ACCESS mvendorid
CSR_R_ACCESS marchid
CSR_R_ACCESS mimpid
CSR_R_ACCESS mhartid
# CSR_R_ACCESS mconfigptr # Unimplemented in spike as of 31 Jan 22
csr_r_access mvendorid
csr_r_access marchid
csr_r_access mimpid
csr_r_access mhartid
# csr_r_access mconfigptr # Unimplemented in spike as of 31 Jan 22
END_TESTS
END_TESTS
TEST_STACK_AND_DATA