Preliminary support for big endian modes. Regression passes but no big endian tests written yet.

This commit is contained in:
David Harris 2022-05-08 06:46:35 +00:00
parent 2792d77e4e
commit 8066ba45e8
20 changed files with 140 additions and 64 deletions

View File

@ -53,6 +53,7 @@
`define IBUS 1
`define VIRTMEM_SUPPORTED 1
`define VECTORED_INTERRUPTS_SUPPORTED 1
`define BIGENDIAN_SUPPORTED 1
// TLB configuration. Entries should be a power of 2
`define ITLB_ENTRIES 32

View File

@ -55,6 +55,7 @@
`define IBUS 1
`define VIRTMEM_SUPPORTED 1
`define VECTORED_INTERRUPTS_SUPPORTED 1
`define BIGENDIAN_SUPPORTED 1
// TLB configuration. Entries should be a power of 2
`define ITLB_ENTRIES 32

View File

@ -56,6 +56,7 @@
`define IBUS 1
`define VIRTMEM_SUPPORTED 0
`define VECTORED_INTERRUPTS_SUPPORTED 0
`define BIGENDIAN_SUPPORTED 0
// TLB configuration. Entries should be a power of 2
`define ITLB_ENTRIES 0

View File

@ -54,6 +54,7 @@
`define IBUS 1
`define VIRTMEM_SUPPORTED 1
`define VECTORED_INTERRUPTS_SUPPORTED 1
`define BIGENDIAN_SUPPORTED 1
// TLB configuration. Entries should be a power of 2
`define ITLB_ENTRIES 32

View File

@ -56,6 +56,7 @@
`define IBUS 1
`define VIRTMEM_SUPPORTED 1
`define VECTORED_INTERRUPTS_SUPPORTED 1
`define BIGENDIAN_SUPPORTED 0
// TLB configuration. Entries should be a power of 2
`define ITLB_ENTRIES 32

View File

@ -54,6 +54,7 @@
`define IBUS 0
`define VIRTMEM_SUPPORTED 0
`define VECTORED_INTERRUPTS_SUPPORTED 1
`define BIGENDIAN_SUPPORTED 0
// TLB configuration. Entries should be a power of 2
`define ITLB_ENTRIES 0

View File

@ -56,6 +56,7 @@
`define IBUS 1
`define VIRTMEM_SUPPORTED 1
`define VECTORED_INTERRUPTS_SUPPORTED 1
`define BIGENDIAN_SUPPORTED 0
// TLB configuration. Entries should be a power of 2
`define ITLB_ENTRIES 32

View File

@ -53,6 +53,7 @@
`define IMEM `MEM_CACHE
`define VIRTMEM_SUPPORTED 1
`define VECTORED_INTERRUPTS_SUPPORTED 1
`define BIGENDIAN_SUPPORTED 0
// TLB configuration. Entries should be a power of 2
`define ITLB_ENTRIES 32

View File

@ -55,6 +55,7 @@
`define IBUS 1
`define VIRTMEM_SUPPORTED 1
`define VECTORED_INTERRUPTS_SUPPORTED 1
`define BIGENDIAN_SUPPORTED 1
// TLB configuration. Entries should be a power of 2
`define ITLB_ENTRIES 32

View File

@ -55,6 +55,7 @@
`define IBUS 1
`define VIRTMEM_SUPPORTED 1
`define VECTORED_INTERRUPTS_SUPPORTED 1
`define BIGENDIAN_SUPPORTED 0
// TLB configuration. Entries should be a power of 2
`define ITLB_ENTRIES 32

View File

@ -55,6 +55,7 @@
`define IBUS 0
`define VIRTMEM_SUPPORTED 0
`define VECTORED_INTERRUPTS_SUPPORTED 1
`define BIGENDIAN_SUPPORTED 0
// TLB configuration. Entries should be a power of 2
`define ITLB_ENTRIES 0

View File

@ -53,7 +53,8 @@ module lsu (
input logic [`XLEN-1:0] WriteDataE,
output logic [`XLEN-1:0] ReadDataM,
// cpu privilege
input logic [1:0] PrivilegeModeW,
input logic [1:0] PrivilegeModeW,
input logic BigEndianM,
input logic DTLBFlushM,
// faults
output logic LoadPageFaultM, StoreAmoPageFaultM,
@ -77,7 +78,7 @@ module lsu (
input logic InstrDAPageFaultF,
output logic [`XLEN-1:0] PTE,
output logic [1:0] PageType,
output logic ITLBWriteF,
output logic ITLBWriteF, SelHPTW,
input var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0],
input var logic [`XLEN-1:0] PMPADDR_ARRAY_REGW[`PMP_ENTRIES-1:0] // *** this one especially has a large note attached to it in pmpchecker.
);
@ -96,7 +97,6 @@ module lsu (
logic CPUBusy;
logic DCacheStallM;
logic CacheableM;
logic SelHPTW;
logic BusStall;
logic InterlockStall;
logic IgnoreRequestTLB, IgnoreRequestTrapM;
@ -182,8 +182,8 @@ module lsu (
// Memory System
// Either Data Cache or Data Tightly Integrated Memory or just bus interface
/////////////////////////////////////////////////////////////////////////////////////////////
logic [`XLEN-1:0] AMOWriteDataM, FinalWriteDataM;
logic [`XLEN-1:0] ReadDataWordM;
logic [`XLEN-1:0] AMOWriteDataM, FinalWriteDataM, LittleEndianWriteDataM;
logic [`XLEN-1:0] ReadDataWordM, LittleEndianReadDataWordM;
logic [`XLEN-1:0] ReadDataWordMuxM;
logic IgnoreRequest;
logic SelUncachedAdr;
@ -220,7 +220,7 @@ module lsu (
.SelUncachedAdr, .IgnoreRequest, .LSURWM, .CPUBusy, .CacheableM,
.BusStall, .BusCommittedM);
mux2 #(`XLEN) UnCachedDataMux(.d0(ReadDataWordM), .d1(DCacheBusWriteData[`XLEN-1:0]),
mux2 #(`XLEN) UnCachedDataMux(.d0(LittleEndianReadDataWordM), .d1(DCacheBusWriteData[`XLEN-1:0]),
.s(SelUncachedAdr), .y(ReadDataWordMuxM));
mux2 #(`XLEN) LsuBushwdataMux(.d0(ReadDataWordM), .d1(FinalWriteDataM),
.s(SelUncachedAdr), .y(LSUBusHWDATA));
@ -244,12 +244,9 @@ module lsu (
end
end else begin: nobus // block: bus
assign {LSUBusHWDATA, SelUncachedAdr} = '0;
assign ReadDataWordMuxM = ReadDataWordM;
assign ReadDataWordMuxM = LittleEndianReadDataWordM;
end
subwordread subwordread(.ReadDataWordMuxM, .LSUPAdrM(LSUPAdrM[2:0]),
.Funct3M(LSUFunct3M), .ReadDataM);
/////////////////////////////////////////////////////////////////////////////////////////////
// Atomic operations
/////////////////////////////////////////////////////////////////////////////////////////////
@ -261,8 +258,25 @@ module lsu (
assign SquashSCW = 0; assign LSURWM = PreLSURWM; assign AMOWriteDataM = LSUWriteDataM;
end
/////////////////////////////////////////////////////////////////////////////////////////////
// Subword Accesses
/////////////////////////////////////////////////////////////////////////////////////////////
subwordwrite subwordwrite(.LSUPAdrM(LSUPAdrM[2:0]),
.LSUFunct3M, .AMOWriteDataM, .FinalWriteDataM, .ByteMaskM);
.LSUFunct3M, .AMOWriteDataM, .LittleEndianWriteDataM, .ByteMaskM);
subwordread subwordread(.ReadDataWordMuxM, .LSUPAdrM(LSUPAdrM[2:0]),
.Funct3M(LSUFunct3M), .ReadDataM);
/////////////////////////////////////////////////////////////////////////////////////////////
// Big Endian Byte Swapper
// hart works little-endian internally
// swap the bytes when read from big-endian memory
/////////////////////////////////////////////////////////////////////////////////////////////
if (`BIGENDIAN_SUPPORTED) begin:endian
bigendianswap storeswap(.BigEndianM, .a(LittleEndianWriteDataM), .y(FinalWriteDataM));
bigendianswap loadswap(.BigEndianM, .a(ReadDataWordM), .y(LittleEndianReadDataWordM));
end else begin
assign FinalWriteDataM = LittleEndianWriteDataM;
assign LittleEndianReadDataWordM = ReadDataWordM;
end
endmodule

View File

@ -34,7 +34,7 @@ module subwordwrite (
input logic [2:0] LSUPAdrM,
input logic [2:0] LSUFunct3M,
input logic [`XLEN-1:0] AMOWriteDataM,
output logic [`XLEN-1:0] FinalWriteDataM,
output logic [`XLEN-1:0] LittleEndianWriteDataM,
output logic [`XLEN/8-1:0] ByteMaskM
);
@ -45,18 +45,18 @@ module subwordwrite (
if (`XLEN == 64) begin:sww
always_comb
case(LSUFunct3M[1:0])
2'b00: FinalWriteDataM = {8{AMOWriteDataM[7:0]}}; // sb
2'b01: FinalWriteDataM = {4{AMOWriteDataM[15:0]}}; // sh
2'b10: FinalWriteDataM = {2{AMOWriteDataM[31:0]}}; // sw
2'b11: FinalWriteDataM = AMOWriteDataM; // sw
2'b00: LittleEndianWriteDataM = {8{AMOWriteDataM[7:0]}}; // sb
2'b01: LittleEndianWriteDataM = {4{AMOWriteDataM[15:0]}}; // sh
2'b10: LittleEndianWriteDataM = {2{AMOWriteDataM[31:0]}}; // sw
2'b11: LittleEndianWriteDataM = AMOWriteDataM; // sw
endcase
end else begin:sww // 32-bit
always_comb
case(LSUFunct3M[1:0])
2'b00: FinalWriteDataM = {4{AMOWriteDataM[7:0]}}; // sb
2'b01: FinalWriteDataM = {2{AMOWriteDataM[15:0]}}; // sh
2'b10: FinalWriteDataM = AMOWriteDataM; // sw
default: FinalWriteDataM = AMOWriteDataM; // shouldn't happen
2'b00: LittleEndianWriteDataM = {4{AMOWriteDataM[7:0]}}; // sb
2'b01: LittleEndianWriteDataM = {2{AMOWriteDataM[15:0]}}; // sh
2'b10: LittleEndianWriteDataM = AMOWriteDataM; // sw
default: LittleEndianWriteDataM = AMOWriteDataM; // shouldn't happen
endcase
end
endmodule

View File

@ -210,17 +210,17 @@ module hptw
// Initial state and misalignment for RV32/64
if (`XLEN == 32) begin
assign InitialWalkerState = L1_ADR;
assign MegapageMisaligned = |(CurrentPPN[9:0]); // must have zero PPN0
// *** Possible bug - should be L1_ADR?
assign Misaligned = ((WalkerState == L0_ADR) & MegapageMisaligned);
assign InitialWalkerState = L1_ADR;
assign MegapageMisaligned = |(CurrentPPN[9:0]); // must have zero PPN0
// *** Possible bug - should be L1_ADR?
assign Misaligned = ((WalkerState == L0_ADR) & MegapageMisaligned);
end else begin
logic GigapageMisaligned, TerapageMisaligned;
assign InitialWalkerState = (SvMode == `SV48) ? L3_ADR : L2_ADR;
assign TerapageMisaligned = |(CurrentPPN[26:0]); // must have zero PPN2, PPN1, PPN0
assign GigapageMisaligned = |(CurrentPPN[17:0]); // must have zero PPN1 and PPN0
assign MegapageMisaligned = |(CurrentPPN[8:0]); // must have zero PPN0
assign Misaligned = ((WalkerState == L2_ADR) & TerapageMisaligned) | ((WalkerState == L1_ADR) & GigapageMisaligned) | ((WalkerState == L0_ADR) & MegapageMisaligned);
logic GigapageMisaligned, TerapageMisaligned;
assign InitialWalkerState = (SvMode == `SV48) ? L3_ADR : L2_ADR;
assign TerapageMisaligned = |(CurrentPPN[26:0]); // must have zero PPN2, PPN1, PPN0
assign GigapageMisaligned = |(CurrentPPN[17:0]); // must have zero PPN1 and PPN0
assign MegapageMisaligned = |(CurrentPPN[8:0]); // must have zero PPN0
assign Misaligned = ((WalkerState == L2_ADR) & TerapageMisaligned) | ((WalkerState == L1_ADR) & GigapageMisaligned) | ((WalkerState == L0_ADR) & MegapageMisaligned);
end
// Page Table Walker FSM

View File

@ -56,6 +56,7 @@ module csr #(parameter
input logic ICacheAccess,
input logic [1:0] NextPrivilegeModeM, PrivilegeModeW,
input logic [`XLEN-1:0] CauseM, NextFaultMtvalM,
input logic SelHPTW,
output logic [1:0] STATUS_MPP,
output logic STATUS_SPP, STATUS_TSR, STATUS_TVM,
output logic [`XLEN-1:0] MEPC_REGW, SEPC_REGW, STVEC_REGW, MTVEC_REGW,
@ -72,7 +73,7 @@ module csr #(parameter
output logic [2:0] FRM_REGW,
// output logic [11:0] MIP_REGW, SIP_REGW, UIP_REGW, MIE_REGW, SIE_REGW, UIE_REGW,
output logic [`XLEN-1:0] CSRReadValW,
output logic IllegalCSRAccessM
output logic IllegalCSRAccessM, BigEndianM
);
localparam NOP = 32'h13;
@ -84,7 +85,7 @@ module csr #(parameter
(* mark_debug = "true" *) logic [`XLEN-1:0] MSTATUS_REGW, SSTATUS_REGW, MSTATUSH_REGW;
logic [31:0] MCOUNTINHIBIT_REGW, MCOUNTEREN_REGW, SCOUNTEREN_REGW;
logic WriteMSTATUSM, WriteSSTATUSM;
logic WriteMSTATUSM, WriteMSTATUSHM, WriteSSTATUSM;
logic CSRMWriteM, CSRSWriteM, CSRUWriteM;
logic WriteFRMM, WriteFFLAGSM;
@ -136,13 +137,13 @@ module csr #(parameter
.MExtIntM, .SExtIntM, .TimerIntM, .SwIntM,
.MIP_REGW, .MIE_REGW, .SIP_REGW, .SIE_REGW, .MIDELEG_REGW, .IP_REGW_writeable);
csrsr csrsr(.clk, .reset, .StallW,
.WriteMSTATUSM, .WriteSSTATUSM,
.WriteMSTATUSM, .WriteMSTATUSHM, .WriteSSTATUSM,
.TrapM, .FRegWriteM, .NextPrivilegeModeM, .PrivilegeModeW,
.mretM, .sretM, .WriteFRMM, .WriteFFLAGSM, .CSRWriteValM,
.mretM, .sretM, .WriteFRMM, .WriteFFLAGSM, .CSRWriteValM, .SelHPTW,
.MSTATUS_REGW, .SSTATUS_REGW, .MSTATUSH_REGW,
.STATUS_MPP, .STATUS_SPP, .STATUS_TSR, .STATUS_TW,
.STATUS_MIE, .STATUS_SIE, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_TVM,
.STATUS_FS);
.STATUS_FS, .BigEndianM);
csrc counters(.clk, .reset,
.StallE, .StallM, .StallW, .FlushE, .FlushM, .FlushW,
.InstrValidM, .LoadStallD, .CSRMWriteM,
@ -157,7 +158,7 @@ module csr #(parameter
.CSRWriteValM, .CSRMReadValM, .MTVEC_REGW,
.MEPC_REGW, .MCOUNTEREN_REGW, .MCOUNTINHIBIT_REGW,
.MEDELEG_REGW, .MIDELEG_REGW,.PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW,
.MIP_REGW, .MIE_REGW, .WriteMSTATUSM,
.MIP_REGW, .MIE_REGW, .WriteMSTATUSM, .WriteMSTATUSHM,
.IllegalCSRMAccessM, .IllegalCSRMWriteReadonlyM);
csrs csrs(.clk, .reset, .InstrValidNotFlushedM, .StallW,
.CSRSWriteM, .STrapM, .CSRAdrM,

View File

@ -86,7 +86,7 @@ module csrm #(parameter
output var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0],
output var logic [`XLEN-1:0] PMPADDR_ARRAY_REGW [`PMP_ENTRIES-1:0],
(* mark_debug = "true" *) input logic [11:0] MIP_REGW, MIE_REGW,
output logic WriteMSTATUSM,
output logic WriteMSTATUSM, WriteMSTATUSHM,
output logic IllegalCSRMAccessM, IllegalCSRMWriteReadonlyM
);
@ -134,7 +134,7 @@ module csrm #(parameter
// Write machine Mode CSRs
assign WriteMSTATUSM = CSRMWriteM & (CSRAdrM == MSTATUS) & InstrValidNotFlushedM;
// writes to MSTATUSH are not yet supported because the register is always 0
assign WriteMSTATUSHM = CSRMWriteM & (CSRAdrM == MSTATUSH) & InstrValidNotFlushedM & (`XLEN==32);
assign WriteMTVECM = CSRMWriteM & (CSRAdrM == MTVEC) & InstrValidNotFlushedM;
assign WriteMEDELEGM = CSRMWriteM & (CSRAdrM == MEDELEG) & InstrValidNotFlushedM;
assign WriteMIDELEGM = CSRMWriteM & (CSRAdrM == MIDELEG) & InstrValidNotFlushedM;

View File

@ -33,31 +33,34 @@
module csrsr (
input logic clk, reset, StallW,
input logic WriteMSTATUSM, WriteSSTATUSM,
input logic WriteMSTATUSM, WriteMSTATUSHM, WriteSSTATUSM,
input logic TrapM, FRegWriteM,
input logic [1:0] NextPrivilegeModeM, PrivilegeModeW,
input logic mretM, sretM,
input logic WriteFRMM, WriteFFLAGSM,
input logic [`XLEN-1:0] CSRWriteValM,
input logic SelHPTW,
output logic [`XLEN-1:0] MSTATUS_REGW, SSTATUS_REGW, MSTATUSH_REGW,
output logic [1:0] STATUS_MPP,
output logic STATUS_SPP, STATUS_TSR, STATUS_TW,
output logic STATUS_MIE, STATUS_SIE,
output logic STATUS_MXR, STATUS_SUM,
output logic STATUS_MPRV, STATUS_TVM,
output logic [1:0] STATUS_FS
output logic [1:0] STATUS_FS,
output logic BigEndianM
);
logic STATUS_SD, STATUS_TW_INT, STATUS_TSR_INT, STATUS_TVM_INT, STATUS_MXR_INT, STATUS_SUM_INT, STATUS_MPRV_INT;
logic [1:0] STATUS_SXL, STATUS_UXL, STATUS_XS, STATUS_FS_INT, STATUS_MPP_NEXT;
logic STATUS_MPIE, STATUS_SPIE, STATUS_UBE, STATUS_SBE, STATUS_MBE;
logic nextMBE, nextSBE;
// STATUS REGISTER FIELD
// See Privileged Spec Section 3.1.6
// Lower privilege status registers are a subset of the full status register
// *** consider adding MBE, SBE, UBE fields, parameterized to be fixed or adjustable
if (`XLEN==64) begin: csrsr64 // RV64
assign MSTATUS_REGW = {STATUS_SD, 25'b0, STATUS_MBE, STATUS_UBE, STATUS_SXL, STATUS_UXL, 9'b0,
assign MSTATUS_REGW = {STATUS_SD, 25'b0, STATUS_MBE, STATUS_SBE, STATUS_SXL, STATUS_UXL, 9'b0,
STATUS_TSR, STATUS_TW, STATUS_TVM, STATUS_MXR, STATUS_SUM, STATUS_MPRV,
STATUS_XS, STATUS_FS, STATUS_MPP, 2'b0,
STATUS_SPP, STATUS_MPIE, STATUS_UBE, STATUS_SPIE, 1'b0,
@ -80,14 +83,23 @@ module csrsr (
/*1'b0, STATUS_MIE, 1'b0*/ 3'b0, STATUS_SIE, 1'b0};
end
// extract values to write to upper status register on 64/32-bit access
if (`XLEN==64) begin:upperstatus
assign nextMBE = CSRWriteValM[37] & `BIGENDIAN_SUPPORTED;
assign nextSBE = CSRWriteValM[36] & `S_SUPPORTED & `BIGENDIAN_SUPPORTED;
end else begin:upperstatus
assign nextMBE = STATUS_MBE;
assign nextSBE = STATUS_SBE;
end
// harwired STATUS bits
assign STATUS_TSR = `S_SUPPORTED & STATUS_TSR_INT; // override reigster with 0 if supervisor mode not supported
assign STATUS_TW = (`S_SUPPORTED | `U_SUPPORTED) & STATUS_TW_INT; // override reigster with 0 if only machine mode supported
assign STATUS_TVM = `S_SUPPORTED & STATUS_TVM_INT; // override reigster with 0 if supervisor mode not supported
assign STATUS_MXR = `S_SUPPORTED & STATUS_MXR_INT; // override reigster with 0 if supervisor mode not supported
assign STATUS_UBE = 0; // little-endian
/* assign STATUS_UBE = 0; // little-endian
assign STATUS_SBE = 0; // little-endian
assign STATUS_MBE = 0; // little-endian
assign STATUS_MBE = 0; // little-endian */
// SXL and UXL bits only matter for RV64. Set to 10 for RV64 if mode is supported, or 0 if not
assign STATUS_SXL = `S_SUPPORTED ? 2'b10 : 2'b00; // 10 if supervisor mode supported
assign STATUS_UXL = `U_SUPPORTED ? 2'b10 : 2'b00; // 10 if user mode supported
@ -100,7 +112,29 @@ module csrsr (
always_comb
if (CSRWriteValM[12:11] == `U_MODE & `U_SUPPORTED) STATUS_MPP_NEXT = `U_MODE;
else if (CSRWriteValM[12:11] == `S_MODE & `S_SUPPORTED) STATUS_MPP_NEXT = `S_MODE;
else STATUS_MPP_NEXT = `M_MODE;
else STATUS_MPP_NEXT = `M_MODE;
///////////////////////////////////////////
// Endianness logic Privileged Spec 3.1.6.4
///////////////////////////////////////////
if (`BIGENDIAN_SUPPORTED) begin: endianmux
// determine whether bit endian accesses should be made
logic [1:0] EndiannessPrivMode;
always_comb begin
if (SelHPTW) EndiannessPrivMode = `S_MODE;
else if (PrivilegeModeW == `M_MODE & STATUS_MPRV) EndiannessPrivMode = STATUS_MPP;
else EndiannessPrivMode = PrivilegeModeW;
case (EndiannessPrivMode)
`M_MODE: BigEndianM = STATUS_MBE;
`S_MODE: BigEndianM = STATUS_SBE;
default: BigEndianM = STATUS_UBE;
endcase
end
end else begin: endianmux
assign BigEndianM = 0;
end
// registers for STATUS bits
// complex register with reset, write enable, and the ability to update other bits in certain cases
@ -113,12 +147,15 @@ module csrsr (
STATUS_SUM_INT <= #1 0;
STATUS_MPRV_INT <= #1 0; // Per Priv 3.3
STATUS_FS_INT <= #1 `F_SUPPORTED ? 2'b01 : 2'b00;
STATUS_MPP <= #1 0; //`M_MODE;
STATUS_SPP <= #1 0; //1'b1;
STATUS_MPIE <= #1 0; //1;
STATUS_SPIE <= #1 0; //`S_SUPPORTED;
STATUS_MIE <= #1 0; // Per Priv 3.3
STATUS_SIE <= #1 0; //`S_SUPPORTED;
STATUS_MPP <= #1 0;
STATUS_SPP <= #1 0;
STATUS_MPIE <= #1 0;
STATUS_SPIE <= #1 0;
STATUS_MIE <= #1 0;
STATUS_SIE <= #1 0;
STATUS_MBE <= #1 0;
STATUS_SBE <= #1 0;
STATUS_UBE <= #1 0;
end else if (~StallW) begin
if (FRegWriteM | WriteFRMM | WriteFFLAGSM) STATUS_FS_INT <= #1 2'b11; // mark Float State dirty *** this should happen in M stage, be part of if/else;
@ -161,6 +198,12 @@ module csrsr (
STATUS_SPIE <= #1 `S_SUPPORTED & CSRWriteValM[5];
STATUS_MIE <= #1 CSRWriteValM[3];
STATUS_SIE <= #1 `S_SUPPORTED & CSRWriteValM[1];
STATUS_UBE <= #1 CSRWriteValM[6] & `U_SUPPORTED & `BIGENDIAN_SUPPORTED;
STATUS_MBE <= #1 nextMBE;
STATUS_SBE <= #1 nextSBE;
end else if (WriteMSTATUSHM) begin
STATUS_MBE <= #1 CSRWriteValM[5] & `BIGENDIAN_SUPPORTED;
STATUS_SBE <= #1 CSRWriteValM[4] & `S_SUPPORTED & `BIGENDIAN_SUPPORTED;
end else if (WriteSSTATUSM) begin // write a subset of the STATUS bits
STATUS_MXR_INT <= #1 CSRWriteValM[19];
STATUS_SUM_INT <= #1 CSRWriteValM[18];
@ -168,6 +211,7 @@ module csrsr (
STATUS_SPP <= #1 `S_SUPPORTED & CSRWriteValM[8];
STATUS_SPIE <= #1 `S_SUPPORTED & CSRWriteValM[5];
STATUS_SIE <= #1 `S_SUPPORTED & CSRWriteValM[1];
STATUS_UBE <= #1 CSRWriteValM[6] & `U_SUPPORTED & `BIGENDIAN_SUPPORTED;
end
end
endmodule

View File

@ -67,6 +67,7 @@ module privileged (
input logic InstrAccessFaultF,
input logic LoadAccessFaultM,
input logic StoreAmoAccessFaultM,
input logic SelHPTW,
output logic ExceptionM,
output logic IllegalFPUInstrE,
@ -78,7 +79,7 @@ module privileged (
output var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0],
output var logic [`XLEN-1:0] PMPADDR_ARRAY_REGW [`PMP_ENTRIES-1:0],
output logic [2:0] FRM_REGW,
output logic BreakpointFaultM, EcallFaultM, wfiM, IntPendingM
output logic BreakpointFaultM, EcallFaultM, wfiM, IntPendingM, BigEndianM
);
logic [1:0] NextPrivilegeModeM;
@ -142,6 +143,7 @@ module privileged (
assign WFITimeoutM = ((STATUS_TW & PrivilegeModeW != `M_MODE) | (`S_SUPPORTED & PrivilegeModeW == `U_MODE)) & WFICount[`WFI_TIMEOUT_BIT];
end else assign WFITimeoutM = 0;
///////////////////////////////////////////
// decode privileged instructions
///////////////////////////////////////////
@ -165,7 +167,8 @@ module privileged (
.BPPredDirWrongM, .BTBPredPCWrongM, .RASPredPCWrongM,
.BPPredClassNonCFIWrongM, .InstrClassM, .DCacheMiss, .DCacheAccess, .ICacheMiss, .ICacheAccess,
.NextPrivilegeModeM, .PrivilegeModeW,
.CauseM, .NextFaultMtvalM, .STATUS_MPP,
.CauseM, .NextFaultMtvalM, .SelHPTW,
.STATUS_MPP,
.STATUS_SPP, .STATUS_TSR, .STATUS_TVM,
.MEPC_REGW, .SEPC_REGW, .STVEC_REGW, .MTVEC_REGW,
.MEDELEG_REGW,
@ -178,7 +181,7 @@ module privileged (
.SetFflagsM,
.FRM_REGW,
.CSRReadValW,
.IllegalCSRAccessM);
.IllegalCSRAccessM, .BigEndianM);
///////////////////////////////////////////
// Extract exceptions by name and handle them

View File

@ -118,12 +118,12 @@ module trap (
// Exceptions are of lower priority than all interrupts (3.1.9)
always_comb
if (reset) CauseM = 0; // hard reset 3.3
else if (ValidIntsM[11]) CauseM = (1 << (`XLEN-1)) + 11; // Machine External Int
else if (ValidIntsM[3]) CauseM = (1 << (`XLEN-1)) + 3; // Machine Sw Int
else if (ValidIntsM[7]) CauseM = (1 << (`XLEN-1)) + 7; // Machine Timer Int
else if (ValidIntsM[9]) CauseM = (1 << (`XLEN-1)) + 9; // Supervisor External Int
else if (ValidIntsM[1]) CauseM = (1 << (`XLEN-1)) + 1; // Supervisor Sw Int
else if (ValidIntsM[5]) CauseM = (1 << (`XLEN-1)) + 5; // Supervisor Timer Int
else if (ValidIntsM[11]) CauseM = (1 << (`XLEN-1)) + 11; // Machine External Int
else if (ValidIntsM[3]) CauseM = (1 << (`XLEN-1)) + 3; // Machine Sw Int
else if (ValidIntsM[7]) CauseM = (1 << (`XLEN-1)) + 7; // Machine Timer Int
else if (ValidIntsM[9]) CauseM = (1 << (`XLEN-1)) + 9; // Supervisor External Int
else if (ValidIntsM[1]) CauseM = (1 << (`XLEN-1)) + 1; // Supervisor Sw Int
else if (ValidIntsM[5]) CauseM = (1 << (`XLEN-1)) + 5; // Supervisor Timer Int
else if (InstrPageFaultM) CauseM = 12;
else if (InstrAccessFaultM) CauseM = 1;
else if (IllegalInstrFaultM) CauseM = 2;

View File

@ -113,6 +113,7 @@ module wallypipelinedcore (
logic [`XLEN-1:0] PTE;
logic [1:0] PageType;
logic wfiM, IntPendingM;
logic SelHPTW;
// PMA checker signals
var logic [`XLEN-1:0] PMPADDR_ARRAY_REGW [`PMP_ENTRIES-1:0];
@ -163,6 +164,7 @@ module wallypipelinedcore (
logic ICacheAccess;
logic BreakpointFaultM, EcallFaultM;
logic InstrDAPageFaultF;
logic BigEndianM;
ifu ifu(
.clk, .reset,
@ -257,7 +259,7 @@ module wallypipelinedcore (
.LSUBusHRDATA, .LSUBusHWDATA, .LSUBusSize,
// connect to csr or privilege and stay the same.
.PrivilegeModeW, // connects to csr
.PrivilegeModeW, .BigEndianM, // connects to csr
.PMPCFG_ARRAY_REGW, // connects to csr
.PMPADDR_ARRAY_REGW, // connects to csr
// hptw keep i/o
@ -276,7 +278,7 @@ module wallypipelinedcore (
.StoreAmoAccessFaultM, // connects to privilege
.InstrDAPageFaultF,
.PCF, .ITLBMissF, .PTE, .PageType, .ITLBWriteF,
.PCF, .ITLBMissF, .PTE, .PageType, .ITLBWriteF, .SelHPTW,
.LSUStallM); // change to LSUStallM
@ -336,12 +338,12 @@ module wallypipelinedcore (
// Trap signals from pmp/pma in mmu
// *** do these need to be split up into one for dmem and one for ifu?
// instead, could we only care about the instr and F pins that come from ifu and only care about the load/store and m pins that come from dmem?
.InstrAccessFaultF, .LoadAccessFaultM, .StoreAmoAccessFaultM,
.InstrAccessFaultF, .LoadAccessFaultM, .StoreAmoAccessFaultM, .SelHPTW,
.ExceptionM, .IllegalFPUInstrE,
.PrivilegeModeW, .SATP_REGW,
.STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .STATUS_FS,
.PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW,
.FRM_REGW,.BreakpointFaultM, .EcallFaultM, .wfiM, .IntPendingM
.FRM_REGW,.BreakpointFaultM, .EcallFaultM, .wfiM, .IntPendingM, .BigEndianM
);
end else begin
assign CSRReadValW = 0;
@ -351,6 +353,7 @@ module wallypipelinedcore (
assign wfiM = 0;
assign ITLBFlushF = 0;
assign DTLBFlushM = 0;
assign BigEndianM = 0;
end
if (`M_SUPPORTED) begin:mdu
muldiv mdu(