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 IBUS 1
`define VIRTMEM_SUPPORTED 1 `define VIRTMEM_SUPPORTED 1
`define VECTORED_INTERRUPTS_SUPPORTED 1 `define VECTORED_INTERRUPTS_SUPPORTED 1
`define BIGENDIAN_SUPPORTED 1
// TLB configuration. Entries should be a power of 2 // TLB configuration. Entries should be a power of 2
`define ITLB_ENTRIES 32 `define ITLB_ENTRIES 32

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -54,6 +54,7 @@ module lsu (
output logic [`XLEN-1:0] ReadDataM, output logic [`XLEN-1:0] ReadDataM,
// cpu privilege // cpu privilege
input logic [1:0] PrivilegeModeW, input logic [1:0] PrivilegeModeW,
input logic BigEndianM,
input logic DTLBFlushM, input logic DTLBFlushM,
// faults // faults
output logic LoadPageFaultM, StoreAmoPageFaultM, output logic LoadPageFaultM, StoreAmoPageFaultM,
@ -77,7 +78,7 @@ module lsu (
input logic InstrDAPageFaultF, input logic InstrDAPageFaultF,
output logic [`XLEN-1:0] PTE, output logic [`XLEN-1:0] PTE,
output logic [1:0] PageType, 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 [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. 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 CPUBusy;
logic DCacheStallM; logic DCacheStallM;
logic CacheableM; logic CacheableM;
logic SelHPTW;
logic BusStall; logic BusStall;
logic InterlockStall; logic InterlockStall;
logic IgnoreRequestTLB, IgnoreRequestTrapM; logic IgnoreRequestTLB, IgnoreRequestTrapM;
@ -182,8 +182,8 @@ module lsu (
// Memory System // Memory System
// Either Data Cache or Data Tightly Integrated Memory or just bus interface // Either Data Cache or Data Tightly Integrated Memory or just bus interface
///////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////
logic [`XLEN-1:0] AMOWriteDataM, FinalWriteDataM; logic [`XLEN-1:0] AMOWriteDataM, FinalWriteDataM, LittleEndianWriteDataM;
logic [`XLEN-1:0] ReadDataWordM; logic [`XLEN-1:0] ReadDataWordM, LittleEndianReadDataWordM;
logic [`XLEN-1:0] ReadDataWordMuxM; logic [`XLEN-1:0] ReadDataWordMuxM;
logic IgnoreRequest; logic IgnoreRequest;
logic SelUncachedAdr; logic SelUncachedAdr;
@ -220,7 +220,7 @@ module lsu (
.SelUncachedAdr, .IgnoreRequest, .LSURWM, .CPUBusy, .CacheableM, .SelUncachedAdr, .IgnoreRequest, .LSURWM, .CPUBusy, .CacheableM,
.BusStall, .BusCommittedM); .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)); .s(SelUncachedAdr), .y(ReadDataWordMuxM));
mux2 #(`XLEN) LsuBushwdataMux(.d0(ReadDataWordM), .d1(FinalWriteDataM), mux2 #(`XLEN) LsuBushwdataMux(.d0(ReadDataWordM), .d1(FinalWriteDataM),
.s(SelUncachedAdr), .y(LSUBusHWDATA)); .s(SelUncachedAdr), .y(LSUBusHWDATA));
@ -244,12 +244,9 @@ module lsu (
end end
end else begin: nobus // block: bus end else begin: nobus // block: bus
assign {LSUBusHWDATA, SelUncachedAdr} = '0; assign {LSUBusHWDATA, SelUncachedAdr} = '0;
assign ReadDataWordMuxM = ReadDataWordM; assign ReadDataWordMuxM = LittleEndianReadDataWordM;
end end
subwordread subwordread(.ReadDataWordMuxM, .LSUPAdrM(LSUPAdrM[2:0]),
.Funct3M(LSUFunct3M), .ReadDataM);
///////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////
// Atomic operations // Atomic operations
///////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////
@ -261,8 +258,25 @@ module lsu (
assign SquashSCW = 0; assign LSURWM = PreLSURWM; assign AMOWriteDataM = LSUWriteDataM; assign SquashSCW = 0; assign LSURWM = PreLSURWM; assign AMOWriteDataM = LSUWriteDataM;
end end
/////////////////////////////////////////////////////////////////////////////////////////////
// Subword Accesses
/////////////////////////////////////////////////////////////////////////////////////////////
subwordwrite subwordwrite(.LSUPAdrM(LSUPAdrM[2:0]), 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 endmodule

View File

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

View File

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

View File

@ -33,31 +33,34 @@
module csrsr ( module csrsr (
input logic clk, reset, StallW, input logic clk, reset, StallW,
input logic WriteMSTATUSM, WriteSSTATUSM, input logic WriteMSTATUSM, WriteMSTATUSHM, WriteSSTATUSM,
input logic TrapM, FRegWriteM, input logic TrapM, FRegWriteM,
input logic [1:0] NextPrivilegeModeM, PrivilegeModeW, input logic [1:0] NextPrivilegeModeM, PrivilegeModeW,
input logic mretM, sretM, input logic mretM, sretM,
input logic WriteFRMM, WriteFFLAGSM, input logic WriteFRMM, WriteFFLAGSM,
input logic [`XLEN-1:0] CSRWriteValM, input logic [`XLEN-1:0] CSRWriteValM,
input logic SelHPTW,
output logic [`XLEN-1:0] MSTATUS_REGW, SSTATUS_REGW, MSTATUSH_REGW, output logic [`XLEN-1:0] MSTATUS_REGW, SSTATUS_REGW, MSTATUSH_REGW,
output logic [1:0] STATUS_MPP, output logic [1:0] STATUS_MPP,
output logic STATUS_SPP, STATUS_TSR, STATUS_TW, output logic STATUS_SPP, STATUS_TSR, STATUS_TW,
output logic STATUS_MIE, STATUS_SIE, output logic STATUS_MIE, STATUS_SIE,
output logic STATUS_MXR, STATUS_SUM, output logic STATUS_MXR, STATUS_SUM,
output logic STATUS_MPRV, STATUS_TVM, 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 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 [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 STATUS_MPIE, STATUS_SPIE, STATUS_UBE, STATUS_SBE, STATUS_MBE;
logic nextMBE, nextSBE;
// STATUS REGISTER FIELD // STATUS REGISTER FIELD
// See Privileged Spec Section 3.1.6 // See Privileged Spec Section 3.1.6
// Lower privilege status registers are a subset of the full status register // Lower privilege status registers are a subset of the full status register
// *** consider adding MBE, SBE, UBE fields, parameterized to be fixed or adjustable // *** consider adding MBE, SBE, UBE fields, parameterized to be fixed or adjustable
if (`XLEN==64) begin: csrsr64 // RV64 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_TSR, STATUS_TW, STATUS_TVM, STATUS_MXR, STATUS_SUM, STATUS_MPRV,
STATUS_XS, STATUS_FS, STATUS_MPP, 2'b0, STATUS_XS, STATUS_FS, STATUS_MPP, 2'b0,
STATUS_SPP, STATUS_MPIE, STATUS_UBE, STATUS_SPIE, 1'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}; /*1'b0, STATUS_MIE, 1'b0*/ 3'b0, STATUS_SIE, 1'b0};
end 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 // harwired STATUS bits
assign STATUS_TSR = `S_SUPPORTED & STATUS_TSR_INT; // override reigster with 0 if supervisor mode not supported 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_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_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_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_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 // 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_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 assign STATUS_UXL = `U_SUPPORTED ? 2'b10 : 2'b00; // 10 if user mode supported
@ -102,6 +114,28 @@ module csrsr (
else if (CSRWriteValM[12:11] == `S_MODE & `S_SUPPORTED) STATUS_MPP_NEXT = `S_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 // registers for STATUS bits
// complex register with reset, write enable, and the ability to update other bits in certain cases // complex register with reset, write enable, and the ability to update other bits in certain cases
always_ff @(posedge clk) //, posedge reset) always_ff @(posedge clk) //, posedge reset)
@ -113,12 +147,15 @@ module csrsr (
STATUS_SUM_INT <= #1 0; STATUS_SUM_INT <= #1 0;
STATUS_MPRV_INT <= #1 0; // Per Priv 3.3 STATUS_MPRV_INT <= #1 0; // Per Priv 3.3
STATUS_FS_INT <= #1 `F_SUPPORTED ? 2'b01 : 2'b00; STATUS_FS_INT <= #1 `F_SUPPORTED ? 2'b01 : 2'b00;
STATUS_MPP <= #1 0; //`M_MODE; STATUS_MPP <= #1 0;
STATUS_SPP <= #1 0; //1'b1; STATUS_SPP <= #1 0;
STATUS_MPIE <= #1 0; //1; STATUS_MPIE <= #1 0;
STATUS_SPIE <= #1 0; //`S_SUPPORTED; STATUS_SPIE <= #1 0;
STATUS_MIE <= #1 0; // Per Priv 3.3 STATUS_MIE <= #1 0;
STATUS_SIE <= #1 0; //`S_SUPPORTED; STATUS_SIE <= #1 0;
STATUS_MBE <= #1 0;
STATUS_SBE <= #1 0;
STATUS_UBE <= #1 0;
end else if (~StallW) begin 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; 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_SPIE <= #1 `S_SUPPORTED & CSRWriteValM[5];
STATUS_MIE <= #1 CSRWriteValM[3]; STATUS_MIE <= #1 CSRWriteValM[3];
STATUS_SIE <= #1 `S_SUPPORTED & CSRWriteValM[1]; 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 end else if (WriteSSTATUSM) begin // write a subset of the STATUS bits
STATUS_MXR_INT <= #1 CSRWriteValM[19]; STATUS_MXR_INT <= #1 CSRWriteValM[19];
STATUS_SUM_INT <= #1 CSRWriteValM[18]; STATUS_SUM_INT <= #1 CSRWriteValM[18];
@ -168,6 +211,7 @@ module csrsr (
STATUS_SPP <= #1 `S_SUPPORTED & CSRWriteValM[8]; STATUS_SPP <= #1 `S_SUPPORTED & CSRWriteValM[8];
STATUS_SPIE <= #1 `S_SUPPORTED & CSRWriteValM[5]; STATUS_SPIE <= #1 `S_SUPPORTED & CSRWriteValM[5];
STATUS_SIE <= #1 `S_SUPPORTED & CSRWriteValM[1]; STATUS_SIE <= #1 `S_SUPPORTED & CSRWriteValM[1];
STATUS_UBE <= #1 CSRWriteValM[6] & `U_SUPPORTED & `BIGENDIAN_SUPPORTED;
end end
end end
endmodule endmodule

View File

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

View File

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