diff --git a/src/Cpu/CSRs/CsrFile.bsv b/src/Cpu/CSRs/CsrFile.bsv index 06bb8f6..bfb3090 100644 --- a/src/Cpu/CSRs/CsrFile.bsv +++ b/src/Cpu/CSRs/CsrFile.bsv @@ -5,6 +5,7 @@ import Trap::*; import IsaCfg::*; import MachineInformation::*; +import MachineISA::*; import MachineStatus::*; import RV_ISA::*; @@ -18,15 +19,15 @@ typedef struct { } CsrWriteResult deriving(Bits, Eq, FShow); interface CsrReadPort#(numeric type xlen); - method ActionValue#(CsrReadResult#(xlen)) read(RVCsrIndex index); + method ActionValue#(CsrReadResult#(xlen)) read(RVCSRIndex index); endinterface interface CsrWritePort#(numeric type xlen); - method ActionValue#(CsrWriteResult) write(RVCsrIndex index, Bit#(xlen) value); + method ActionValue#(CsrWriteResult) write(RVCSRIndex index, Bit#(xlen) value); endinterface interface CsrWritePermission; - method Bool isWriteable(RVCsrIndex index); + method Bool isWriteable(RVCSRIndex index); endinterface interface CsrFile#(numeric type xlen); @@ -44,7 +45,11 @@ typedef struct { IsaCfg#(xlen) isa_cfg; } CsrFileCfg#(numeric type xlen); -module mkCsrFile#(CsrFileCfg#(xlen) cfg)(CsrFile#(xlen)); +module mkCsrFile#(CsrFileCfg#(xlen) cfg)(CsrFile#(xlen)) + provisos( + Add#(xlen, 0, 32), + Add#(xlen, 0, 64) + ); Reg#(RVPrivilegeLevel) currentPriv <- mkReg(priv_MACHINE); // Counters @@ -63,7 +68,8 @@ module mkCsrFile#(CsrFileCfg#(xlen) cfg)(CsrFile#(xlen)); mconfigptr: 0 }; - MachineStatusIfc#(xlen) mstatus <- mkMachineStatus(cfg); + MachineStatus_Ifc#(xlen) mstatus <- mkMachineStatus(cfg.isa_cfg); + MachineISA_Ifc#(xlen) misa <- mkMachineISA(cfg.isa_cfg); /* ReadOnly#(Bit#(xlen)) mcycle <- mkReadOnly(truncate(cycleCounter)); ReadOnly#(Bit#(xlen)) mtimer <- mkReadOnly(truncate(timeCounter)); @@ -90,7 +96,7 @@ module mkCsrFile#(CsrFileCfg#(xlen) cfg)(CsrFile#(xlen)); Reg#(Bit#(xlen)) sideleg <- mkReg(0); Reg#(Bit#(xlen)) sedeleg <- mkReg(0); - function Bool isWARLIgnore(RVCsrIndex index); + function Bool isWARLIgnore(RVCSRIndex index); Bool result = False; if ((index >= csr_PMPADDR0 && index <= csr_PMPADDR63) || (index >= csr_PMPCFG0 && index <= csr_PMPCFG15) || @@ -103,8 +109,8 @@ module mkCsrFile#(CsrFileCfg#(xlen) cfg)(CsrFile#(xlen)); return result; endfunction - function RVCsrIndex getIndex(RVPrivilegeLevel privilege_level, RVCsrIndexOffset offset); - RVCsrIndex index = 0; + function RVCSRIndex getIndex(RVPrivilegeLevel privilege_level, RVCSRIndexOffset offset); + RVCSRIndex index = 0; index[9:8] = privilege_level[1:0]; index[7:0] = offset; return index; @@ -115,7 +121,7 @@ module mkCsrFile#(CsrFileCfg#(xlen) cfg)(CsrFile#(xlen)); let trap_privilege_level = priv_MACHINE; if (currentPriv < priv_MACHINE) begin - if (cfg.s_mode_supported) begin // S mode supported? + if (cfg.isa_cfg.extS) begin // S mode supported? // See if this trap should be delegated to SUPERVISOR mode let delegated = (trap.isInterrupt ? (mideleg[trap.cause] == 0 ? False : True) : @@ -126,7 +132,7 @@ module mkCsrFile#(CsrFileCfg#(xlen) cfg)(CsrFile#(xlen)); // If the current priv mode is U, and user mode traps are supported, // then consult sedeleg/sideleg to determine if delegated to USER mode. - if (currentPriv == priv_USER && cfg.u_level_interrupts_supported) begin + if (currentPriv == priv_USER && cfg.isa_cfg.extU) begin delegated = (trap.isInterrupt ? (sideleg[trap.cause] == 0 ? False : True) : (sedeleg[trap.cause] == 0 ? False : True)); @@ -139,7 +145,7 @@ module mkCsrFile#(CsrFileCfg#(xlen) cfg)(CsrFile#(xlen)); end else begin // S mode *NOT* supported // If user mode traps are supported, then consult sedeleg/sideleg to determine // if delegated to USER mode. - if (cfg.u_level_interrupts_supported) begin + if (cfg.isa_cfg.extU) begin let delegated = (trap.isInterrupt ? (mideleg[trap.cause] == 0 ? False : True) : (medeleg[trap.cause] == 0 ? False : True)); @@ -157,9 +163,9 @@ module mkCsrFile#(CsrFileCfg#(xlen) cfg)(CsrFile#(xlen)); // // readInternal // - function ActionValue#(CsrReadResult#(xlen)) readInternal(RVCsrIndex index); + function ActionValue#(CsrReadResult#(xlen)) readInternal(RVCSRIndex index); actionvalue - let result = CsrReadResult { + CsrReadResult#(xlen) result = CsrReadResult { value: 0, denied: False }; @@ -174,7 +180,7 @@ module mkCsrFile#(CsrFileCfg#(xlen) cfg)(CsrFile#(xlen)); csr_MIMPID: result.value = machineInfoCfg.mimpid; csr_MHARTID: result.value = machineInfoCfg.mhartid; - csr_MISA: result.value = pack(cfg); + csr_MISA: result.value = misa.pack; csr_MCAUSE: result.value = mcause; csr_MTVEC: result.value = mtvec; @@ -183,10 +189,7 @@ module mkCsrFile#(CsrFileCfg#(xlen) cfg)(CsrFile#(xlen)); csr_MIDELEG: result.value = mideleg; csr_MEDELEG: result.value = medeleg; - csr_MSTATUS: begin - let mstatus_ <- mstatus.getMachineStatus.get; - result.value = pack(mstatus_); - end + csr_MSTATUS: result.value = mstatus.pack; /* csr_MCYCLE, csr_CYCLE: begin result.value = mcycle; @@ -216,7 +219,7 @@ module mkCsrFile#(CsrFileCfg#(xlen) cfg)(CsrFile#(xlen)); // // writeInternal // - function ActionValue#(CsrWriteResult) writeInternal(RVCsrIndex index, Bit#(xlen) value); + function ActionValue#(CsrWriteResult) writeInternal(RVCSRIndex index, Bit#(xlen) value); actionvalue let result = CsrWriteResult { denied: False @@ -252,14 +255,14 @@ module mkCsrFile#(CsrFileCfg#(xlen) cfg)(CsrFile#(xlen)); endactionvalue endfunction - function ActionValue#(CsrReadResult#(xlen)) readWithOffset1(RVPrivilegeLevel privilegeLevel, RVCsrIndexOffset offset); + function ActionValue#(CsrReadResult#(xlen)) readWithOffset1(RVPrivilegeLevel privilegeLevel, RVCSRIndexOffset offset); actionvalue let csrReadResult <- readInternal(getIndex(privilegeLevel, offset)); return csrReadResult; endactionvalue endfunction - function ActionValue#(CsrWriteResult) writeWithOffset1(RVPrivilegeLevel privilegeLevel, RVCsrIndexOffset offset, Bit#(xlen) value); + function ActionValue#(CsrWriteResult) writeWithOffset1(RVPrivilegeLevel privilegeLevel, RVCSRIndexOffset offset, Bit#(xlen) value); actionvalue let csrWriteResult <- writeInternal(getIndex(privilegeLevel, offset), value); return csrWriteResult; @@ -279,7 +282,7 @@ module mkCsrFile#(CsrFileCfg#(xlen) cfg)(CsrFile#(xlen)); // CsrReadport // interface CsrReadPort csrReadPort; - method ActionValue#(CsrReadResult#(xlen)) read(RVCsrIndex index); + method ActionValue#(CsrReadResult#(xlen)) read(RVCSRIndex index); let result = CsrReadResult { value: 0, denied: True @@ -297,7 +300,7 @@ module mkCsrFile#(CsrFileCfg#(xlen) cfg)(CsrFile#(xlen)); // CsrWritePort // interface CsrWritePort csrWritePort; - method ActionValue#(CsrWriteResult) write(RVCsrIndex index, Bit#(xlen) value); + method ActionValue#(CsrWriteResult) write(RVCSRIndex index, Bit#(xlen) value); let result = CsrWriteResult { denied: True }; @@ -314,7 +317,7 @@ module mkCsrFile#(CsrFileCfg#(xlen) cfg)(CsrFile#(xlen)); // CsrWritePermission // interface CsrWritePermission csrWritePermission; - method Bool isWriteable(RVCsrIndex index); + method Bool isWriteable(RVCSRIndex index); return (currentPriv >= index[9:8] && index[11:10] != 'b11); endmethod endinterface diff --git a/src/Cpu/CSRs/MachineISA.bsv b/src/Cpu/CSRs/MachineISA.bsv new file mode 100644 index 0000000..dc261d7 --- /dev/null +++ b/src/Cpu/CSRs/MachineISA.bsv @@ -0,0 +1,129 @@ +import IsaCfg::*; + +import GetPut::*; + +typedef Bit#(2) MXL; +MXL mxl_32bit = 2'b01; +MXL mxl_64bit = 2'b10; +MXL mxl_128bit = 2'b11; + +typedef struct { + Bool extZ; // ** RESERVED ** + Bool extY; // ** RESERVED ** + Bool extX; // Non-standard extensions present + Bool extW; // ** RESERVED ** + Bool extV; // Vector extension + Bool extU; // User mode implemented + Bool extT; // ** RESERVED ** + Bool extS; // Supervisor mode implemented + Bool extR; // ** RESERVED ** + Bool extQ; // Quad precision floating-point extension + Bool extP; // Packed-SIMD extension + Bool extO; // ** RESERVED ** + Bool extN; // User level interrupts extension + Bool extM; // Integer multiply/divide extension + Bool extL; // ** RESERVED ** + Bool extK; // ** RESERVED ** + Bool extJ; // Dynamically translated language extension + Bool extI; // RV32I/64I/128I base ISA + Bool extH; // Hypervisor extension + Bool extG; // ** RESERVED ** + Bool extF; // Single precision floating-point extension + Bool extE; // RV32E base ISA + Bool extD; // Double precision floating-point extension + Bool extC; // Compressed instruction extension + Bool extB; // Bit manipulation extension + Bool extA; // Atomic extension +} MachineISA deriving(Bits, Eq, FShow); + +instance DefaultValue#(MachineISA); + defaultValue = MachineISA { + extA: False, + extB: False, + extC: False, + extD: False, + extE: False, + extF: False, + extG: False, + extH: False, + extI: True, // RV32I/64I/128I base ISA + extJ: False, + extK: False, + extL: False, + extM: False, + extN: False, + extO: False, + extP: False, + extQ: False, + extR: False, + extS: False, + extT: False, + extU: False, + extV: False, + extW: False, + extX: False, + extY: False, + extZ: False + }; +endinstance + +interface MachineISA_Ifc#(numeric type xlen); + method Bit#(xlen) pack; + interface Get#(MachineISA) getMachineISA; + interface Put#(MachineISA) putMachineISA; +endinterface + +module mkMachineISA#(IsaCfg#(xlen) cfg)(MachineISA_Ifc#(xlen)) + provisos( + Add#(a__, 26, xlen), + Add#(b__, 2, xlen) + ); + function MachineISA getMISA; + MachineISA misa_ = defaultValue; + + // Check for user level interrupts + if (cfg.extN) begin + misa_.extN = True; + end + + // Check for supervisor mode support. + if (cfg.extS) begin + misa_.extS = True; + end + + // Check for user mode support. + if (cfg.extU) begin + misa_.extU = True; + end + + return misa_; + endfunction + + function MXL getMXL; + MXL mxl = fromInteger((log2(valueof(xlen))) - 4); + return mxl; + endfunction + + method Bit#(xlen) pack; + Bit#(xlen) misa = 0; + + misa[valueof(xlen)-1:valueof(xlen)-2] = getMXL; + + Bit#(26) extensions = pack(getMISA); + misa[25:0] = extensions; + + return misa; + endmethod + + interface Get getMachineISA; + method ActionValue#(MachineISA) get; + return getMISA; + endmethod + endinterface + + interface Put putMachineISA; + method Action put(MachineISA misa); + // Writing to MISA not supported + endmethod + endinterface +endmodule diff --git a/src/Cpu/CSRs/MachineISA.bsv.remove b/src/Cpu/CSRs/MachineISA.bsv.remove deleted file mode 100644 index 4218e85..0000000 --- a/src/Cpu/CSRs/MachineISA.bsv.remove +++ /dev/null @@ -1,179 +0,0 @@ -import IsaCfg::*; - -import GetPut::*; - -typedef Bit#(2) MXL; -MXL mxl_32bit = 2'b01; -MXL mxl_64bit = 2'b10; -MXL mxl_128bit = 2'b11; - -typedef struct { - Bool extA; // Atomic extension - Bool extB; // Bit manipulation extension - Bool extC; // Compressed instruction extension - Bool extD; // Double precision floating-point extension - Bool extE; // RV32E base ISA - Bool extF; // Single precision floating-point extension - Bool extG; // ** RESERVED ** - Bool extH; // Hypervisor extension - Bool extI; // RV32I/64I/128I base ISA - Bool extJ; // Dynamically translated language extension - Bool extK; // ** RESERVED ** - Bool extL; // ** RESERVED ** - Bool extM; // Integer multiply/divide extension - Bool extN; // User level interrupts extension - Bool extO; // ** RESERVED ** - Bool extP; // Packed-SIMD extension - Bool extQ; // Quad precision floating-point extension - Bool extR; // ** RESERVED ** - Bool extS; // Supervisor mode implemented - Bool extT; // ** RESERVED ** - Bool extU; // User mode implemented - Bool extV; // Vector extension - Bool extW; // ** RESERVED ** - Bool extX; // Non-standard extensions present - Bool extY; // ** RESERVED ** - Bool extZ; // ** RESERVED ** -} MachineISA#(numeric type xlen); - -instance DefaultValue#(MachineISA#(xlen)); - defaultValue = MachineISA { - extA: False, - extB: False, - extC: False, - extD: False, - extE: False, - extF: False, - extG: False, - extH: False, - extI: True, // RV32I/64I/128I base ISA - extJ: False, - extK: False, - extL: False, - extM: False, - extN: False, - extO: False, - extP: False, - extQ: False, - extR: False, - extS: False, - extT: False, - extU: False, - extV: False, - extW: False, - extX: False, - extY: False, - extZ: False - }; -endinstance - -instance Bits#(MachineISA#(64), 64); - function Bit#(64) pack(MachineISA#(64) misa); - MXL mxl = mxl_64bit; - return { - mxl, - 36'b0, - pack(misa.extZ), - pack(misa.extY), - pack(misa.extX), - pack(misa.extW), - pack(misa.extV), - pack(misa.extU), - pack(misa.extT), - pack(misa.extS), - pack(misa.extR), - pack(misa.extQ), - pack(misa.extP), - pack(misa.extO), - pack(misa.extN), - pack(misa.extM), - pack(misa.extL), - pack(misa.extK), - pack(misa.extJ), - pack(misa.extI), - pack(misa.extH), - pack(misa.extH), - pack(misa.extF), - pack(misa.extE), - pack(misa.extD), - pack(misa.extC), - pack(misa.extB), - pack(misa.extA) - }; - endfunction - - function MachineISA#(64) unpack(Bit#(64) value); - return defaultValue; - endfunction -endinstance - -instance Bits#(MachineISA#(32), 32); - function Bit#(32) pack(MachineISA#(32) misa); - MXL mxl = mxl_32bit; - return { - mxl, - 4'b0, - pack(misa.extZ), - pack(misa.extY), - pack(misa.extX), - pack(misa.extW), - pack(misa.extV), - pack(misa.extU), - pack(misa.extT), - pack(misa.extS), - pack(misa.extR), - pack(misa.extQ), - pack(misa.extP), - pack(misa.extO), - pack(misa.extN), - pack(misa.extM), - pack(misa.extL), - pack(misa.extK), - pack(misa.extJ), - pack(misa.extI), - pack(misa.extH), - pack(misa.extH), - pack(misa.extF), - pack(misa.extE), - pack(misa.extD), - pack(misa.extC), - pack(misa.extB), - pack(misa.extA) - }; - endfunction - - function MachineISA#(32) unpack(Bit#(32) value); - return defaultValue; - endfunction -endinstance - -interface MachineISAIfc#(numeric type xlen); - interface Get#(MachineISA#(xlen)) getMachineISA; - interface Put#(MachineISA#(xlen)) putMachineISA; -endinterface - -module mkMachineISA#(IsaCfg#(xlen) cfg)(MachineISAIfc#(xlen)); - interface Get getMachineISA; - method ActionValue#(MachineISA#(xlen)) get; - MachineISA#(xlen) misa_ = defaultValue; - - // Check for user mode support. - if (cfg.u_mode_supported) begin - misa_.extU = True; - end - - // Check for supervisor mode support. - if (cfg.s_mode_supported) begin - misa_.extS = True; - end - - return misa_; - endmethod - endinterface - - interface Put putMachineISA; - method Action put(MachineISA#(xlen) misa); - // Writing to MISA not supported - endmethod - endinterface -endmodule diff --git a/src/Cpu/CSRs/MachineISA_tb.bsv b/src/Cpu/CSRs/MachineISA_tb.bsv new file mode 100644 index 0000000..c602a0d --- /dev/null +++ b/src/Cpu/CSRs/MachineISA_tb.bsv @@ -0,0 +1,50 @@ +import DecodeStage::*; +import IsaCfg::*; +import MachineISA::*; + +import Assert::*; + +module mkTopModule(Empty); + Reg#(Bit#(20)) stepNumber <- mkReg(0); + + IsaCfg#(32) rv32i_cfg = IsaCfg { + extN: False, + extS: False, + extU: False + }; + MachineISA_Ifc#(32) rv32i <- mkMachineISA(rv32i_cfg); + + IsaCfg#(64) rv64i_cfg = IsaCfg { + extN: False, + extS: False, + extU: False + }; + MachineISA_Ifc#(64) rv64i <- mkMachineISA(rv64i_cfg); + + (* no_implicit_conditions *) + rule test; + case(stepNumber) + 0: begin + let misa = rv32i.pack; + dynamicAssert(misa == 32'b01_0000_00000000000000000100000000, "MachineISA RV32I invalid"); + end + + 1: begin + let misa = rv64i.pack; + $display("MISA: %b", misa); + dynamicAssert(misa == 64'b10_000000000000000000000000000000000000_00000000000000000100000000, "MachineISA RV64I invalid"); + end + + default: begin + dynamicAssert(stepNumber == 2, "MachineISA - not all tests run"); + $display(">>>PASS"); + $finish(); + end + endcase + endrule + + + rule increment_step_number; + stepNumber <= stepNumber + 1; + endrule +endmodule diff --git a/src/Cpu/CSRs/MachineStatus copy.bsv b/src/Cpu/CSRs/MachineStatus copy.bsv deleted file mode 100644 index 66a99d9..0000000 --- a/src/Cpu/CSRs/MachineStatus copy.bsv +++ /dev/null @@ -1,180 +0,0 @@ -import GetPut::*; - -import IsaCfg::*; -import RV_ISA::*; - -typedef Bit#(2) XLENEncoding; -XLENEncoding xlen_32 = 2'b01; -XLENEncoding xlen_64 = 2'b10; -XLENEncoding xlen_128 = 2'b11; - -typedef Bit#(2) FSVSState; -FSVSState fsvs_OFF = 2'b00; -FSVSState fsvs_INITIAL = 2'b01; -FSVSState fsvs_CLEAN = 2'b10; -FSVSState fsvs_DIRTY = 2'b11; - -typedef Bit#(2) XSState; -XSState xs_ALL_OFF = 2'b00; -XSState xs_NONE_DIRTY_OR_CLEAN = 2'b01; -XSState xs_NONE_DIRTY_SOME_CLEAN = 2'b10; -XSState xs_SOME_DIRTY = 2'b11; - -typedef struct { - Bool sie; // Supervisor Interrupt Enable - Bool mie; // Machine Interrupt Enable - Bool spie; // Supervisor Mode Interupts Enabled During Trap - Bool ube; // User Mode Data Accesses are Big Endian - Bool mpie; // Machine Mode Interrupts Enabled During Trap - Bool spp; // Supervisor Previous Privilege Mode - FSVSState vs; // Vector Extension State - RVPrivilegeLevel mpp; // Machine Previous Privilege Level - FSVSState fs; // Floating Point Status - XSState xs; // User Mode Extension Status - Bool mprv; // Modify Privilege Mode For Loads/Stores - Bool sum; // Permit Supervisor User Memory Access - Bool mxr; // Make Executable Pages Readable - Bool tvm; // Trap Virtual Memory Management Accesses - Bool tw; // Timeout-Wait - Bool tsr; // Trap SRET Instruction - - XLENEncoding uxl; // User Mode XLEN value (RV64 only) - XLENEncoding sxl; // Supervisor Mode XLEN value (RV64 only) - - Bool sbe; // Supervisor Mode Data Accesses are Big Endian - Bool mbe; // Machine Mode Data Accesses are Big Endian -} MachineStatus#(numeric type xlen) deriving(Bits, Eq); - -instance DefaultValue#(MachineStatus#(xlen)); - defaultValue = MachineStatus { - sie: False, - mie: False, - spie: False, - ube: False, - mpie: False, - spp: False, - vs: fsvs_OFF, - mpp: priv_MACHINE, - fs: fsvs_OFF, - xs: xs_ALL_OFF, - mprv: False, - sum: False, - mxr: False, - tvm: False, - tw: False, - tsr: False, - - uxl: xlen_64, // RV64 only - sxl: xlen_64, // RV64 only - - sbe: False, - mbe: False - }; -endinstance - -instance Bits#(MachineStatus#(64), 64); - function Bit#(64) pack(MachineStatus#(64) mstatus); - Bit#(1) sd = ((mstatus.vs | mstatus.fs | mstatus.xs) == 0 ? 0 : 1); - return { - sd, - 25'b0, - pack(mstatus.mbe), - pack(mstatus.sbe), - pack(mstatus.sxl), - pack(mstatus.uxl), - 9'b0, - pack(mstatus.tsr), - pack(mstatus.tw), - pack(mstatus.tvm), - pack(mstatus.mxr), - pack(mstatus.sum), - pack(mstatus.mprv), - pack(mstatus.xs), - pack(mstatus.fs), - pack(mstatus.mpp), - pack(mstatus.vs), - pack(mstatus.spp), - pack(mstatus.mpie), - pack(mstatus.ube), - pack(mstatus.spie), - 1'b0, - pack(mstatus.mie), - 1'b0, - pack(mstatus.sie), - 1'b0 - }; - endfunction - - function MachineStatus#(64) unpack(Bit#(64) value); - return defaultValue; - endfunction -endinstance - -instance Bits#(MachineStatus#(32), 32); - function Bit#(32) pack(MachineStatus#(32) mstatus); - Bit#(1) sd = ((mstatus.vs | mstatus.fs | mstatus.xs) == 0 ? 0 : 1); - return { - sd, - 8'b0, - pack(mstatus.tsr), - pack(mstatus.tw), - pack(mstatus.tvm), - pack(mstatus.mxr), - pack(mstatus.sum), - pack(mstatus.mprv), - pack(mstatus.xs), - pack(mstatus.fs), - pack(mstatus.mpp), - pack(mstatus.vs), - pack(mstatus.spp), - pack(mstatus.mpie), - pack(mstatus.ube), - pack(mstatus.spie), - 1'b0, - pack(mstatus.mie), - 1'b0, - pack(mstatus.sie), - 1'b0 - }; - endfunction - - function MachineStatus#(32) unpack(Bit#(32) value); - return defaultValue; - endfunction -endinstance - -interface MachineStatusIfc#(numeric type xlen); - interface Get#(MachineStatus#(xlen)) getMachineStatus; - interface Put#(MachineStatus#(xlen)) putMachineStatus; -endinterface - -module mkMachineStatus#(IsaCfg#(xlen) cfg)(MachineStatusIfc#(xlen)); - Reg#(MachineStatus#(xlen)) mstatus <- mkReg(defaultValue); - - interface Get getMachineStatus = toGet(mstatus); - interface Put putMachineStatus; - method Action put(MachineStatus#(xlen) value); - // - // Only MPP, MIE, and MIE are writable. The rest - // are written with defaults - // - MachineStatus#(xlen) mstatus_ = defaultValue; - - if (cfg.extS) begin - mstatus_.mpp = value.mpp; - end else begin - // Supervisor mode not supported, ensure only USER and MACHINE - // mode are set in MPP. - RVPrivilegeLevel requestedMPP = value.mpp; - if (requestedMPP == priv_USER || requestedMPP == priv_MACHINE) begin - mstatus_.mpp = requestedMPP; - end - end - - mstatus_.mpie = value.mpie; - mstatus_.mie = value.mie; - - mstatus <= mstatus_; - endmethod - endinterface -endmodule diff --git a/src/Cpu/CSRs/MachineStatus.bsv b/src/Cpu/CSRs/MachineStatus.bsv index 6c3afaa..09d0ada 100644 --- a/src/Cpu/CSRs/MachineStatus.bsv +++ b/src/Cpu/CSRs/MachineStatus.bsv @@ -43,7 +43,7 @@ typedef struct { Bool sbe; // Supervisor Mode Data Accesses are Big Endian Bool mbe; // Machine Mode Data Accesses are Big Endian -} MachineStatus; +} MachineStatus deriving(Bits, Eq, FShow); instance DefaultValue#(MachineStatus); defaultValue = MachineStatus { @@ -72,12 +72,22 @@ instance DefaultValue#(MachineStatus); }; endinstance -instance Bits#(MachineStatus, 32); - function Bit#(32) pack(MachineStatus mstatus); - Bit#(1) sd = ((mstatus.vs | mstatus.fs | mstatus.xs) == 0 ? 0 : 1); +interface MachineStatus_Ifc#(numeric type xlen); + method Bit#(xlen) pack; + method Action unpack(Bit#(xlen) bits); + interface Get#(MachineStatus) getMachineStatus; + interface Put#(MachineStatus) putMachineStatus; +endinterface + +module mkMachineStatus#(IsaCfg#(xlen) cfg)(MachineStatus_Ifc#(xlen)) + provisos( + Add#(a__, 32, xlen) + ); + Reg#(MachineStatus) mstatus <- mkReg(defaultValue); + + function Bit#(32) packLower; return { - sd, - 8'b0, + 9'b0, pack(mstatus.tsr), pack(mstatus.tw), pack(mstatus.tvm), @@ -100,57 +110,34 @@ instance Bits#(MachineStatus, 32); }; endfunction - function MachineStatus unpack(Bit#(32) value); - return defaultValue; - endfunction -endinstance - -instance Bits#(MachineStatus, 64); - function Bit#(64) pack(MachineStatus mstatus); - Bit#(1) sd = ((mstatus.vs | mstatus.fs | mstatus.xs) == 0 ? 0 : 1); + function Bit#(32) packUpper; return { - sd, - 25'b0, + 26'b0, pack(mstatus.mbe), pack(mstatus.sbe), pack(mstatus.sxl), - pack(mstatus.uxl), - 9'b0, - pack(mstatus.tsr), - pack(mstatus.tw), - pack(mstatus.tvm), - pack(mstatus.mxr), - pack(mstatus.sum), - pack(mstatus.mprv), - pack(mstatus.xs), - pack(mstatus.fs), - pack(mstatus.mpp), - pack(mstatus.vs), - pack(mstatus.spp), - pack(mstatus.mpie), - pack(mstatus.ube), - pack(mstatus.spie), - 1'b0, - pack(mstatus.mie), - 1'b0, - pack(mstatus.sie), - 1'b0 - }; + pack(mstatus.uxl) + }; endfunction - function MachineStatus unpack(Bit#(64) value); - return defaultValue; - endfunction -endinstance + method Bit#(xlen) pack; + Bit#(32) lower = packLower; + Bit#(xlen) mstatus_ = 0; -interface MachineStatus_Ifc; - interface Get#(MachineStatus) getMachineStatus; - interface Put#(MachineStatus) putMachineStatus; -endinterface + Bit#(1) sd = ((mstatus.vs | mstatus.fs | mstatus.xs) == 0 ? 0 : 1); + mstatus_[valueof(xlen)-1] = sd; + mstatus_[31:0] = lower; -module mkMachineStatus#(IsaCfg#(xlen) cfg)(MachineStatus_Ifc); - Reg#(MachineStatus) mstatus <- mkReg(defaultValue); + if (valueof(xlen) == 64) begin + mstatus_[valueof(xlen)-2:32] = packUpper; + end + return mstatus_; + endmethod + + method Action unpack(Bit#(xlen) bits); + endmethod + interface Get getMachineStatus = toGet(mstatus); interface Put putMachineStatus; method Action put(MachineStatus value); diff --git a/src/Cpu/DecodeStage.bsv b/src/Cpu/DecodeStage.bsv new file mode 100644 index 0000000..462eff6 --- /dev/null +++ b/src/Cpu/DecodeStage.bsv @@ -0,0 +1,123 @@ +import CsrFile::*; +import IsaCfg::*; +import GprFile::*; +import PipelineRegisters::*; +import RV_ISA::*; +import Trap::*; + +interface DecodeStage_Ifc#(numeric type xlen); + method ActionValue#(ID_EX#(xlen)) step( + IF_ID#(xlen) if_id, + GprReadPort#(xlen) gprReadPort1, + GprReadPort#(xlen) gprReadPort2, + CsrReadPort#(xlen) csrReadPort + ); +endinterface + +module mkDecodeStage#(IsaCfg#(xlen) cfg)(DecodeStage_Ifc#(xlen)) + provisos( + Add#(a__, 20, xlen), + Add#(b__, 5, xlen), + Add#(c__, 13, xlen), + Add#(d__, 21, xlen), + Add#(e__, 12, xlen) + ); + function RVGPRIndex extractRs1(Instruction inst); + return inst.value[19:15]; + endfunction + + function RVGPRIndex extractRs2(Instruction inst); + return inst.value[24:20]; + endfunction + + function RVCSRIndex extractCsrIndex(Instruction inst); + return inst.value[31:20]; + endfunction + + function Bit#(xlen) decodeImmediate(Instruction inst); + return case(inst.value[6:0]) + 7'b0110111: begin // LUI + signExtend(inst.value[31:12]); + end + + 7'b0010111: begin // AUIPC + signExtend(inst.value[31:12]); + end + + 7'b1101111: begin // JAL + signExtend({ + inst.value[31], + inst.value[19:12], + inst.value[20], + inst.value[30:21], + 1'b0 + }); + end + + 7'b1100111: begin // JALR + signExtend(inst.value[31:20]); + end + + 7'b1100011: begin // BRANCH + signExtend({ + inst.value[31], + inst.value[7], + inst.value[30:25], + inst.value[11:8], + 1'b0 + }); + end + + 7'b0000011: begin // LOAD + signExtend(inst.value[31:20]); + end + + 7'b0100011: begin // STORE + signExtend({ + inst.value[31:25], + inst.value[11:7] + }); + end + + 7'b0010011: begin // OPIMM + signExtend(inst.value[31:20]); + end + + 7'b1110011: begin // SYSTEM (CSR) + zeroExtend(inst.value[19:15]); // UIMM stored in RS1 + end + + default: begin + 0; + end + endcase; + endfunction + + method ActionValue#(ID_EX#(xlen)) step( + IF_ID#(xlen) if_id, + GprReadPort#(xlen) gprReadPort1, + GprReadPort#(xlen) gprReadPort2, + CsrReadPort#(xlen) csrReadPort + ); + ID_EX#(xlen) id_ex = defaultValue; + + id_ex.common = if_id.common; + id_ex.epoch = if_id.epoch; + id_ex.npc = if_id.npc; + + // Read GPRs + let rs1 = extractRs1(if_id.common.ir); + let rs2 = extractRs2(if_id.common.ir); + id_ex.a = gprReadPort1.read(rs1); + id_ex.b = gprReadPort2.read(rs2); + + // Decode immediate + id_ex.imm = decodeImmediate(if_id.common.ir); + + // CSR read + let csrIndex = extractCsrIndex(if_id.common.ir); + id_ex.csr <- csrReadPort.read(csrIndex); + + return id_ex; + endmethod +endmodule diff --git a/src/Cpu/DecodeStage_tb.bsv b/src/Cpu/DecodeStage_tb.bsv new file mode 100644 index 0000000..4fda280 --- /dev/null +++ b/src/Cpu/DecodeStage_tb.bsv @@ -0,0 +1,44 @@ +import DecodeStage::*; +import GprFile::*; +import IsaCfg::*; +import PipelineRegisters::*; +import RV_ISA::*; +import Trap::*; + +import Assert::*; + +module mkTopModule(Empty); + Reg#(Bit#(20)) stepNumber <- mkReg(0); + + // 32 bit + IsaCfg#(32) rv32 = IsaCfg{ + extN: False, + extS: False, + extU: False + }; + DecodeStage_Ifc#(32) decodeStage32 <- mkDecodeStage(rv32); + + // + // GPR + // + GprFileCfg#(32) gprFileCfg32 = GprFileCfg { + }; + GprFile#(32) gprFile32 <- mkGprFile(gprFileCfg32); + + (* no_implicit_conditions *) + rule test; + IF_ID#(32) if_id = defaultValue; + + case(stepNumber) + default: begin + dynamicAssert(stepNumber == 0, "Decode - not all tests run"); + $display(">>>PASS"); + $finish(); + end + endcase + endrule + + rule increment_step_number; + stepNumber <= stepNumber + 1; + endrule +endmodule diff --git a/src/Cpu/FetchStage_tb.bsv b/src/Cpu/FetchStage_tb.bsv index bcf8ec3..8067b67 100644 --- a/src/Cpu/FetchStage_tb.bsv +++ b/src/Cpu/FetchStage_tb.bsv @@ -42,7 +42,7 @@ module mkTopModule(Empty); dynamicAssert(if_id.npc == defaultValue, "Fetch - Misaligned instruction trap check - NPC incorrect"); end - // Memory request denied trap (request submit) + // Memory request denied trap (step 1 - request submit) 1: begin pc_if.pc = 'h100; @@ -51,7 +51,7 @@ module mkTopModule(Empty); dynamicAssert(if_id == defaultValue, "Fetch - Memory request denied trap check - request should return a bubble"); end - // Memory request denied trap (request receipt) + // Memory request denied trap (step 2 - request receipt) 2: begin pc_if.pc = 'h100; @@ -70,7 +70,7 @@ module mkTopModule(Empty); }); end - // Memory request denied trap (return trap check) + // Memory request denied trap (step 3 - return trap check) 3: begin pc_if.pc = 'h100; @@ -83,7 +83,7 @@ module mkTopModule(Empty); dynamicAssert(if_id.epoch == defaultValue, "Fetch - Misaligned instruction trap check - Verify epoch unchanged"); end - // Normal memory request (request submit) + // Normal memory request (step 1 - request submit) 4: begin pc_if.pc = 'h100; @@ -92,7 +92,7 @@ module mkTopModule(Empty); dynamicAssert(if_id == defaultValue, "Fetch - Normal request - request should return a bubble"); end - // Normal memory request (request receipt) + // Normal memory request (step 2 - request receipt) 5: begin pc_if.pc = 'h100; @@ -111,7 +111,7 @@ module mkTopModule(Empty); }); end - // Normal memory request (return value check) + // Normal memory request (step 3 - return value check) 6: begin pc_if.pc = 'h100; @@ -123,7 +123,7 @@ module mkTopModule(Empty); dynamicAssert(if_id.epoch == defaultValue, "Fetch - Normal request - Verify epoch unchanged"); end - // Redirect handling check + // Redirect handling check (step 1 - request submit) 7: begin pc_if.pc = 'h100; pc_if.redirection = tagged Valid 'h8000; @@ -133,6 +133,7 @@ module mkTopModule(Empty); dynamicAssert(if_id == defaultValue, "Fetch - Redirect check - request should return a bubble"); end + // Redirect handling check (step 2 - request receipt) 8: begin pc_if.pc = 'h100; @@ -151,10 +152,10 @@ module mkTopModule(Empty); }); end + // Redirect handling check (step 3 - return value check) 9: begin pc_if.pc = 'h100; - // The fetch should proceed and return a bubble. let if_id <- fetchStage32.step(pc_if); dynamicAssert(if_id.common.pc == 'h8000, "Fetch - Redirect check - common.pc"); dynamicAssert(!isValid(if_id.common.trap), "Fetch - Redirect check - contains no trap"); diff --git a/src/Cpu/GprFile.bsv b/src/Cpu/GprFile.bsv index 3cee4b5..3cd2d8d 100644 --- a/src/Cpu/GprFile.bsv +++ b/src/Cpu/GprFile.bsv @@ -1,15 +1,15 @@ +import RV_ISA::*; + import ClientServer::*; import GetPut::*; import Vector::*; -typedef Bit#(5) GprIndex; - interface GprReadPort#(numeric type xlen); - method Bit#(xlen) read(GprIndex index); + method Bit#(xlen) read(RVGPRIndex index); endinterface interface GprWritePort#(numeric type xlen); - method Action write(GprIndex index, Bit#(xlen) value); + method Action write(RVGPRIndex index, Bit#(xlen) value); endinterface interface GprFile#(numeric type xlen); @@ -26,19 +26,19 @@ module mkGprFile#(GprFileCfg#(xlen) cfg)(GprFile#(xlen)); Vector#(32, Reg#(Bit#(xlen))) reg_file <- replicateM(mkReg(0)); interface GprReadPort gprReadPort1; - method Bit#(xlen) read(GprIndex index); + method Bit#(xlen) read(RVGPRIndex index); return reg_file[index]; endmethod endinterface interface GprReadPort gprReadPort2; - method Bit#(xlen) read(GprIndex index); + method Bit#(xlen) read(RVGPRIndex index); return reg_file[index]; endmethod endinterface interface GprWritePort gprWritePort; - method Action write(GprIndex index, Bit#(xlen) value); + method Action write(RVGPRIndex index, Bit#(xlen) value); if (index != 0) begin reg_file[index] <= value; end diff --git a/src/Cpu/PipelineRegisters.bsv b/src/Cpu/PipelineRegisters.bsv index f1999e9..d35aa1a 100644 --- a/src/Cpu/PipelineRegisters.bsv +++ b/src/Cpu/PipelineRegisters.bsv @@ -1,3 +1,4 @@ +import CsrFile::*; import Trap::*; import DefaultValue::*; @@ -81,11 +82,11 @@ endinstance typedef struct { PipelineRegisterCommon#(xlen) common; Epoch epoch; - ProgramCounter#(xlen) npc; // Next program counter - Bit#(xlen) a; // Operand 1 - Bit#(xlen) b; // Operand 2 - Bool isBValid; // In the case of a CSR, this will indicate if 'b' is valid - Bit#(xlen) imm; // Sign extended immediate + ProgramCounter#(xlen) npc; // Next program counter + Bit#(xlen) a; // Operand 1 + Bit#(xlen) b; // Operand 2 + Bit#(xlen) imm; // Sign extended immediate + CsrReadResult#(xlen) csr; // CSR read result } ID_EX#(numeric type xlen) deriving(Bits, Eq, FShow); instance DefaultValue #(ID_EX#(xlen)); @@ -95,8 +96,11 @@ instance DefaultValue #(ID_EX#(xlen)); npc: defaultValue, a: 'h-1, b: 'h-1, - isBValid: True, - imm: 'h-1 + imm: 'h-1, + csr: CsrReadResult { + value: 'h-1, + denied: False + } }; endinstance diff --git a/src/Cpu/RV_ISA.bsv b/src/Cpu/RV_ISA.bsv index ef4e2d2..2d8b593 100644 --- a/src/Cpu/RV_ISA.bsv +++ b/src/Cpu/RV_ISA.bsv @@ -43,102 +43,102 @@ RVBranchOperator branch_BLTU = 3'b110; RVBranchOperator branch_BGEU = 3'b111; // -// RVCsrIndex +// RVCSRIndex // -typedef Bit#(12) RVCsrIndex; +typedef Bit#(12) RVCSRIndex; // Supervisor Trap Setup -RVCsrIndex csr_SSTATUS = 12'h100; // Supervisor Status Register (SRW) -RVCsrIndex csr_SIE = 12'h104; // Supervisor Interrupt Enable Register (SRW) -RVCsrIndex csr_STVEC = 12'h105; // Supervisor Trap-Handler base address (SRW) -RVCsrIndex csr_SCOUNTEREN = 12'h106; // Supervisor Counter Enable Register (SRW) +RVCSRIndex csr_SSTATUS = 12'h100; // Supervisor Status Register (SRW) +RVCSRIndex csr_SIE = 12'h104; // Supervisor Interrupt Enable Register (SRW) +RVCSRIndex csr_STVEC = 12'h105; // Supervisor Trap-Handler base address (SRW) +RVCSRIndex csr_SCOUNTEREN = 12'h106; // Supervisor Counter Enable Register (SRW) // Supervisor Configuration -RVCsrIndex csr_SENVCFG = 12'h10A; // Supervisor environment configuration register (SRW) +RVCSRIndex csr_SENVCFG = 12'h10A; // Supervisor environment configuration register (SRW) // Supervisor Trap Handling -RVCsrIndex csr_SSCRATCH = 12'h140; // Scratch register for supervisor trap handlers (SRW) -RVCsrIndex csr_SEPC = 12'h141; // Supervisor exception program counter (SRW) -RVCsrIndex csr_SCAUSE = 12'h142; // Supervisor trap cause (SRW) -RVCsrIndex csr_STVAL = 12'h143; // Supervisor bad address or instruction (SRW) -RVCsrIndex csr_SIP = 12'h144; // Supervisor interrupt pending (SRW) +RVCSRIndex csr_SSCRATCH = 12'h140; // Scratch register for supervisor trap handlers (SRW) +RVCSRIndex csr_SEPC = 12'h141; // Supervisor exception program counter (SRW) +RVCSRIndex csr_SCAUSE = 12'h142; // Supervisor trap cause (SRW) +RVCSRIndex csr_STVAL = 12'h143; // Supervisor bad address or instruction (SRW) +RVCSRIndex csr_SIP = 12'h144; // Supervisor interrupt pending (SRW) // Supervisor Protection and Translation -RVCsrIndex csr_SATP = 12'h180; // Supervisor address translation and protection (SRW) +RVCSRIndex csr_SATP = 12'h180; // Supervisor address translation and protection (SRW) // Machine Trap Setup -RVCsrIndex csr_MSTATUS = 12'h300; // Machine Status Register (MRW) -RVCsrIndex csr_MISA = 12'h301; // Machine ISA and Extensions Register (MRW) -RVCsrIndex csr_MEDELEG = 12'h302; // Machine Exception Delegation Register (MRW) -RVCsrIndex csr_MIDELEG = 12'h303; // Machine Interrupt Delegation Register (MRW) -RVCsrIndex csr_MIE = 12'h304; // Machine Interrupt Enable Register (MRW) -RVCsrIndex csr_MTVEC = 12'h305; // Machine Trap-Handler base address (MRW) -RVCsrIndex csr_MCOUNTEREN = 12'h306; // Machine Counter Enable Register (MRW) -RVCsrIndex csr_MSTATUSH = 12'h310; // Additional machine status register, RV32 only (MRW) +RVCSRIndex csr_MSTATUS = 12'h300; // Machine Status Register (MRW) +RVCSRIndex csr_MISA = 12'h301; // Machine ISA and Extensions Register (MRW) +RVCSRIndex csr_MEDELEG = 12'h302; // Machine Exception Delegation Register (MRW) +RVCSRIndex csr_MIDELEG = 12'h303; // Machine Interrupt Delegation Register (MRW) +RVCSRIndex csr_MIE = 12'h304; // Machine Interrupt Enable Register (MRW) +RVCSRIndex csr_MTVEC = 12'h305; // Machine Trap-Handler base address (MRW) +RVCSRIndex csr_MCOUNTEREN = 12'h306; // Machine Counter Enable Register (MRW) +RVCSRIndex csr_MSTATUSH = 12'h310; // Additional machine status register, RV32 only (MRW) // Machine Trap Handling -RVCsrIndex csr_MSCRATCH = 12'h340; // Scratch register for machine trap handlers (MRW) -RVCsrIndex csr_MEPC = 12'h341; // Machine exception program counter (MRW) -RVCsrIndex csr_MCAUSE = 12'h342; // Machine trap cause (MRW) -RVCsrIndex csr_MTVAL = 12'h343; // Machine bad address or instruction (MRW) -RVCsrIndex csr_MIP = 12'h344; // Machine interrupt pending (MRW) -RVCsrIndex csr_MTINST = 12'h34A; // Machine trap instruction (transformed) (MRW) -RVCsrIndex csr_MTVAL2 = 12'h34B; // Machine bad guest physical address (MRW) +RVCSRIndex csr_MSCRATCH = 12'h340; // Scratch register for machine trap handlers (MRW) +RVCSRIndex csr_MEPC = 12'h341; // Machine exception program counter (MRW) +RVCSRIndex csr_MCAUSE = 12'h342; // Machine trap cause (MRW) +RVCSRIndex csr_MTVAL = 12'h343; // Machine bad address or instruction (MRW) +RVCSRIndex csr_MIP = 12'h344; // Machine interrupt pending (MRW) +RVCSRIndex csr_MTINST = 12'h34A; // Machine trap instruction (transformed) (MRW) +RVCSRIndex csr_MTVAL2 = 12'h34B; // Machine bad guest physical address (MRW) // Machine Memory Protection -RVCsrIndex csr_PMPCFG0 = 12'h3A0; // Physical memory protection configuration (MRW) -RVCsrIndex csr_PMPCFG15 = 12'h3AF; -RVCsrIndex csr_PMPADDR0 = 12'h3B0; // Physical memory protection address register (MRW) -RVCsrIndex csr_PMPADDR63 = 12'h3EF; +RVCSRIndex csr_PMPCFG0 = 12'h3A0; // Physical memory protection configuration (MRW) +RVCSRIndex csr_PMPCFG15 = 12'h3AF; +RVCSRIndex csr_PMPADDR0 = 12'h3B0; // Physical memory protection address register (MRW) +RVCSRIndex csr_PMPADDR63 = 12'h3EF; // Debug/Trace Registers -RVCsrIndex csr_TSELECT = 12'h7A0; // Debug/Trace trigger register select (MRW) -RVCsrIndex csr_TDATA1 = 12'h7A1; // First Debug/Trace trigger data register (MRW) -RVCsrIndex csr_TDATA2 = 12'h7A2; // Second Debug/Trace trigger data register (MRW) -RVCsrIndex csr_TDATA3 = 12'h7A3; // Third Debug/Trace trigger data register (MRW) -RVCsrIndex csr_MCONTEXT = 12'h7A8; // Machine-mode context register (MRW) +RVCSRIndex csr_TSELECT = 12'h7A0; // Debug/Trace trigger register select (MRW) +RVCSRIndex csr_TDATA1 = 12'h7A1; // First Debug/Trace trigger data register (MRW) +RVCSRIndex csr_TDATA2 = 12'h7A2; // Second Debug/Trace trigger data register (MRW) +RVCSRIndex csr_TDATA3 = 12'h7A3; // Third Debug/Trace trigger data register (MRW) +RVCSRIndex csr_MCONTEXT = 12'h7A8; // Machine-mode context register (MRW) // Debug Mode Registers -RVCsrIndex csr_DCSR = 12'h7B0; // Debug Control and Status -RVCsrIndex csr_DPC = 12'h7B1; // Debug Program Counter -RVCsrIndex csr_DSCRATCH0 = 12'h7B2; // Debug Scratch Register 0 -RVCsrIndex csr_DSCRATCH1 = 12'h7B3; // Debug Scratch Register 1 +RVCSRIndex csr_DCSR = 12'h7B0; // Debug Control and Status +RVCSRIndex csr_DPC = 12'h7B1; // Debug Program Counter +RVCSRIndex csr_DSCRATCH0 = 12'h7B2; // Debug Scratch Register 0 +RVCSRIndex csr_DSCRATCH1 = 12'h7B3; // Debug Scratch Register 1 // Machine Counters/Timers -RVCsrIndex csr_MCYCLE = 12'hB00; // Cycle counter for RDCYCLE instruction (MRW) -RVCsrIndex csr_MINSTRET = 12'hB02; // Machine instructions-retired counter (MRW) -RVCsrIndex csr_MHPMCOUNTER3 = 12'hB03; // Machine performance-monitoring counter (MRW) -RVCsrIndex csr_MHPMCOUNTER4 = 12'hB04; // Machine performance-monitoring counter (MRW) -RVCsrIndex csr_MHPMCOUNTER5 = 12'hB05; // Machine performance-monitoring counter (MRW) -RVCsrIndex csr_MHPMCOUNTER6 = 12'hB06; // Machine performance-monitoring counter (MRW) -RVCsrIndex csr_MHPMCOUNTER7 = 12'hB07; // Machine performance-monitoring counter (MRW) -RVCsrIndex csr_MHPMCOUNTER8 = 12'hB08; // Machine performance-monitoring counter (MRW) -RVCsrIndex csr_MHPMCOUNTER9 = 12'hB09; // Machine performance-monitoring counter (MRW) -RVCsrIndex csr_MCYCLEH = 12'hB80; // Upper 32 bits of mcycle, RV32I only (MRW) -RVCsrIndex csr_MINSTRETH = 12'hB82; // Upper 32 bits of minstret, RV32I only (MRW) -RVCsrIndex csr_MHPMCOUNTER3H = 12'hB83; // Machine performance-monitoring counter (upper 32 bits) (MRW) -RVCsrIndex csr_MHPMCOUNTER4H = 12'hB84; // Machine performance-monitoring counter (upper 32 bits) (MRW) -RVCsrIndex csr_MHPMCOUNTER5H = 12'hB85; // Machine performance-monitoring counter (upper 32 bits) (MRW) -RVCsrIndex csr_MHPMCOUNTER6H = 12'hB86; // Machine performance-monitoring counter (upper 32 bits) (MRW) -RVCsrIndex csr_MHPMCOUNTER7H = 12'hB87; // Machine performance-monitoring counter (upper 32 bits) (MRW) -RVCsrIndex csr_MHPMCOUNTER8H = 12'hB88; // Machine performance-monitoring counter (upper 32 bits) (MRW) -RVCsrIndex csr_MHPMCOUNTER9H = 12'hB89; // Machine performance-monitoring counter (upper 32 bits) (MRW) -RVCsrIndex csr_CYCLE = 12'hC00; // Read only mirror of MCYCLE +RVCSRIndex csr_MCYCLE = 12'hB00; // Cycle counter for RDCYCLE instruction (MRW) +RVCSRIndex csr_MINSTRET = 12'hB02; // Machine instructions-retired counter (MRW) +RVCSRIndex csr_MHPMCOUNTER3 = 12'hB03; // Machine performance-monitoring counter (MRW) +RVCSRIndex csr_MHPMCOUNTER4 = 12'hB04; // Machine performance-monitoring counter (MRW) +RVCSRIndex csr_MHPMCOUNTER5 = 12'hB05; // Machine performance-monitoring counter (MRW) +RVCSRIndex csr_MHPMCOUNTER6 = 12'hB06; // Machine performance-monitoring counter (MRW) +RVCSRIndex csr_MHPMCOUNTER7 = 12'hB07; // Machine performance-monitoring counter (MRW) +RVCSRIndex csr_MHPMCOUNTER8 = 12'hB08; // Machine performance-monitoring counter (MRW) +RVCSRIndex csr_MHPMCOUNTER9 = 12'hB09; // Machine performance-monitoring counter (MRW) +RVCSRIndex csr_MCYCLEH = 12'hB80; // Upper 32 bits of mcycle, RV32I only (MRW) +RVCSRIndex csr_MINSTRETH = 12'hB82; // Upper 32 bits of minstret, RV32I only (MRW) +RVCSRIndex csr_MHPMCOUNTER3H = 12'hB83; // Machine performance-monitoring counter (upper 32 bits) (MRW) +RVCSRIndex csr_MHPMCOUNTER4H = 12'hB84; // Machine performance-monitoring counter (upper 32 bits) (MRW) +RVCSRIndex csr_MHPMCOUNTER5H = 12'hB85; // Machine performance-monitoring counter (upper 32 bits) (MRW) +RVCSRIndex csr_MHPMCOUNTER6H = 12'hB86; // Machine performance-monitoring counter (upper 32 bits) (MRW) +RVCSRIndex csr_MHPMCOUNTER7H = 12'hB87; // Machine performance-monitoring counter (upper 32 bits) (MRW) +RVCSRIndex csr_MHPMCOUNTER8H = 12'hB88; // Machine performance-monitoring counter (upper 32 bits) (MRW) +RVCSRIndex csr_MHPMCOUNTER9H = 12'hB89; // Machine performance-monitoring counter (upper 32 bits) (MRW) +RVCSRIndex csr_CYCLE = 12'hC00; // Read only mirror of MCYCLE // Machine Information Registers -RVCsrIndex csr_MVENDORID = 12'hF11; // Vendor ID (MRO) -RVCsrIndex csr_MARCHID = 12'hF12; // Architecture ID (MRO) -RVCsrIndex csr_MIMPID = 12'hF13; // Implementation ID (MRO) -RVCsrIndex csr_MHARTID = 12'hF14; // Hardware thread ID (MRO) -RVCsrIndex csr_MCONFIGPTR = 12'hF15; // Pointer to configuration data structure (MRO) +RVCSRIndex csr_MVENDORID = 12'hF11; // Vendor ID (MRO) +RVCSRIndex csr_MARCHID = 12'hF12; // Architecture ID (MRO) +RVCSRIndex csr_MIMPID = 12'hF13; // Implementation ID (MRO) +RVCSRIndex csr_MHARTID = 12'hF14; // Hardware thread ID (MRO) +RVCSRIndex csr_MCONFIGPTR = 12'hF15; // Pointer to configuration data structure (MRO) // -// RVCsrIndexOffset +// RVCSRIndexOffset // -typedef Bit#(8) RVCsrIndexOffset; +typedef Bit#(8) RVCSRIndexOffset; // Trap Setup -RVCsrIndexOffset csr_STATUS = 8'h00; // Status -RVCsrIndexOffset csr_EDELEG = 8'h02; // Exception Delegation -RVCsrIndexOffset csr_IDELEG = 8'h03; // Interrupt Delegation -RVCsrIndexOffset csr_IE = 8'h04; // Interrupt Enable -RVCsrIndexOffset csr_TVEC = 8'h05; // Vector Table -RVCsrIndexOffset csr_COUNTEREN = 8'h06; // Counter Enable +RVCSRIndexOffset csr_STATUS = 8'h00; // Status +RVCSRIndexOffset csr_EDELEG = 8'h02; // Exception Delegation +RVCSRIndexOffset csr_IDELEG = 8'h03; // Interrupt Delegation +RVCSRIndexOffset csr_IE = 8'h04; // Interrupt Enable +RVCSRIndexOffset csr_TVEC = 8'h05; // Vector Table +RVCSRIndexOffset csr_COUNTEREN = 8'h06; // Counter Enable // Trap Handling -RVCsrIndexOffset csr_SCRATCH = 8'h40; // Scratch Register -RVCsrIndexOffset csr_EPC = 8'h41; // Exception Program Counter -RVCsrIndexOffset csr_CAUSE = 8'h42; // Exception/Interrupt Cause -RVCsrIndexOffset csr_TVAL = 8'h43; // Bad address or instruction -RVCsrIndexOffset csr_IP = 8'h44; // Interrupt Pending +RVCSRIndexOffset csr_SCRATCH = 8'h40; // Scratch Register +RVCSRIndexOffset csr_EPC = 8'h41; // Exception Program Counter +RVCSRIndexOffset csr_CAUSE = 8'h42; // Exception/Interrupt Cause +RVCSRIndexOffset csr_TVAL = 8'h43; // Bad address or instruction +RVCSRIndexOffset csr_IP = 8'h44; // Interrupt Pending // // RVCSROperator(s)