mirror of
https://github.com/openhwgroup/cvw
synced 2025-01-24 05:24:49 +00:00
Preliminary support for big endian modes. Regression passes but no big endian tests written yet.
This commit is contained in:
parent
2792d77e4e
commit
8066ba45e8
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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(
|
||||
|
Loading…
Reference in New Issue
Block a user