Expand rvcpp counter CSR implementation
This commit is contained in:
parent
af08c0becd
commit
32f65fb142
|
@ -5,6 +5,7 @@
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
|
#include <array>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "rv_opcodes.h"
|
#include "rv_opcodes.h"
|
||||||
|
@ -145,6 +146,10 @@ class RVCSR {
|
||||||
uint priv;
|
uint priv;
|
||||||
|
|
||||||
ux_t mcycle;
|
ux_t mcycle;
|
||||||
|
ux_t mcycleh;
|
||||||
|
ux_t minstret;
|
||||||
|
ux_t minstreth;
|
||||||
|
ux_t mcountinhibit;
|
||||||
ux_t mstatus;
|
ux_t mstatus;
|
||||||
ux_t mie;
|
ux_t mie;
|
||||||
ux_t mip;
|
ux_t mip;
|
||||||
|
@ -153,6 +158,8 @@ class RVCSR {
|
||||||
ux_t mepc;
|
ux_t mepc;
|
||||||
ux_t mcause;
|
ux_t mcause;
|
||||||
|
|
||||||
|
std::optional<ux_t> addr_written_this_step;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
@ -164,6 +171,10 @@ public:
|
||||||
RVCSR() {
|
RVCSR() {
|
||||||
priv = 3;
|
priv = 3;
|
||||||
mcycle = 0;
|
mcycle = 0;
|
||||||
|
mcycleh = 0;
|
||||||
|
minstret = 0;
|
||||||
|
minstreth = 0;
|
||||||
|
mcountinhibit = 0;
|
||||||
mstatus = 0;
|
mstatus = 0;
|
||||||
mie = 0;
|
mie = 0;
|
||||||
mip = 0;
|
mip = 0;
|
||||||
|
@ -171,9 +182,32 @@ public:
|
||||||
mscratch = 0;
|
mscratch = 0;
|
||||||
mepc = 0;
|
mepc = 0;
|
||||||
mcause = 0;
|
mcause = 0;
|
||||||
|
addr_written_this_step = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void step() {++mcycle;}
|
void step() {
|
||||||
|
uint64_t mcycle_64 = ((uint64_t)mcycleh << 32) | mcycle;
|
||||||
|
uint64_t minstret_64 = ((uint64_t)minstreth << 32) | minstret;
|
||||||
|
if (!(mcountinhibit & 0x1u)) {
|
||||||
|
++mcycle_64;
|
||||||
|
}
|
||||||
|
if (!(mcountinhibit & 0x4u)) {
|
||||||
|
++minstret_64;
|
||||||
|
}
|
||||||
|
if (!(addr_written_this_step && *addr_written_this_step == CSR_MCYCLEH)) {
|
||||||
|
mcycleh = mcycle_64 >> 32;
|
||||||
|
}
|
||||||
|
if (!(addr_written_this_step && *addr_written_this_step == CSR_MCYCLE)) {
|
||||||
|
mcycle = mcycle_64 & 0xffffffffu;
|
||||||
|
}
|
||||||
|
if (!(addr_written_this_step && *addr_written_this_step == CSR_MINSTRETH)) {
|
||||||
|
minstreth = minstret_64 >> 32;
|
||||||
|
}
|
||||||
|
if (!(addr_written_this_step && *addr_written_this_step == CSR_MINSTRET)) {
|
||||||
|
minstret = minstret_64 & 0xffffffffu;
|
||||||
|
}
|
||||||
|
addr_written_this_step = {};
|
||||||
|
}
|
||||||
|
|
||||||
// Returns None on permission/decode fail
|
// Returns None on permission/decode fail
|
||||||
std::optional<ux_t> read(uint16_t addr, bool side_effect=true) {
|
std::optional<ux_t> read(uint16_t addr, bool side_effect=true) {
|
||||||
|
@ -181,30 +215,35 @@ public:
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
switch (addr) {
|
switch (addr) {
|
||||||
case CSR_MISA: return 0x40101105; // RV32IMAC + U
|
case CSR_MISA: return 0x40901105; // RV32IMACX + U
|
||||||
case CSR_MHARTID: return 0;
|
case CSR_MHARTID: return 0;
|
||||||
case CSR_MARCHID: return 0;
|
case CSR_MARCHID: return 0x1b; // Hazard3
|
||||||
case CSR_MIMPID: return 0;
|
case CSR_MIMPID: return 0x12345678u; // Match testbench value
|
||||||
case CSR_MVENDORID: return 0;
|
case CSR_MVENDORID: return 0xdeadbeefu; // Match testbench value
|
||||||
|
case CSR_MCONFIGPTR: return 0x9abcdef0u; // Match testbench value
|
||||||
|
|
||||||
case CSR_MSTATUS: return mstatus;
|
case CSR_MSTATUS: return mstatus;
|
||||||
case CSR_MIE: return mie;
|
case CSR_MIE: return mie;
|
||||||
case CSR_MIP: return mip;
|
case CSR_MIP: return mip;
|
||||||
case CSR_MTVEC: return mtvec;
|
case CSR_MTVEC: return mtvec;
|
||||||
case CSR_MSCRATCH: return mscratch;
|
case CSR_MSCRATCH: return mscratch;
|
||||||
case CSR_MEPC: return mepc;
|
case CSR_MEPC: return mepc;
|
||||||
case CSR_MCAUSE: return mcause;
|
case CSR_MCAUSE: return mcause;
|
||||||
case CSR_MTVAL: return 0;
|
case CSR_MTVAL: return 0;
|
||||||
|
|
||||||
case CSR_MCYCLE: return mcycle;
|
case CSR_MCOUNTINHIBIT: return mcountinhibit;
|
||||||
case CSR_MINSTRET: return mcycle;
|
case CSR_MCYCLE: return mcycle;
|
||||||
|
case CSR_MCYCLEH: return mcycleh;
|
||||||
|
case CSR_MINSTRET: return minstret;
|
||||||
|
case CSR_MINSTRETH: return minstreth;
|
||||||
|
|
||||||
default: return {};
|
default: return {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns false on permission/decode fail
|
// Returns false on permission/decode fail
|
||||||
bool write(uint16_t addr, ux_t data, uint op=WRITE) {
|
bool write(uint16_t addr, ux_t data, uint op=WRITE) {
|
||||||
|
addr_written_this_step = addr;
|
||||||
if (addr >= 1u << 12 || GETBITS(addr, 9, 8) > priv)
|
if (addr >= 1u << 12 || GETBITS(addr, 9, 8) > priv)
|
||||||
return false;
|
return false;
|
||||||
if (addr >= 1u << 12)
|
if (addr >= 1u << 12)
|
||||||
|
@ -219,23 +258,25 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (addr) {
|
switch (addr) {
|
||||||
case CSR_MISA: break;
|
case CSR_MISA: break;
|
||||||
case CSR_MHARTID: break;
|
case CSR_MHARTID: break;
|
||||||
case CSR_MARCHID: break;
|
case CSR_MARCHID: break;
|
||||||
case CSR_MIMPID: break;
|
case CSR_MIMPID: break;
|
||||||
|
|
||||||
case CSR_MSTATUS: mstatus = data; break;
|
case CSR_MSTATUS: mstatus = data; break;
|
||||||
case CSR_MIE: mie = data; break;
|
case CSR_MIE: mie = data; break;
|
||||||
case CSR_MIP: break;
|
case CSR_MIP: break;
|
||||||
case CSR_MTVEC: mtvec = data & 0xfffffffdu; break;
|
case CSR_MTVEC: mtvec = data & 0xfffffffdu; break;
|
||||||
case CSR_MSCRATCH: mscratch = data; break;
|
case CSR_MSCRATCH: mscratch = data; break;
|
||||||
case CSR_MEPC: mepc = data & 0xfffffffeu; break;
|
case CSR_MEPC: mepc = data & 0xfffffffeu; break;
|
||||||
case CSR_MCAUSE: mcause = data & 0x800000ffu; break;
|
case CSR_MCAUSE: mcause = data & 0x800000ffu; break;
|
||||||
case CSR_MTVAL: break;
|
case CSR_MTVAL: break;
|
||||||
|
|
||||||
case CSR_MCYCLE: mcycle = data; break;
|
|
||||||
case CSR_MINSTRET: mcycle = data; break;
|
|
||||||
|
|
||||||
|
case CSR_MCYCLE: mcycle = data; break;
|
||||||
|
case CSR_MCYCLEH: mcycleh = data; break;
|
||||||
|
case CSR_MINSTRET: minstret = data; break;
|
||||||
|
case CSR_MINSTRETH: minstreth = data; break;
|
||||||
|
case CSR_MCOUNTINHIBIT: mcountinhibit = data & 0x7u; break;
|
||||||
default: return false;
|
default: return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -324,6 +324,7 @@
|
||||||
#define CSR_MHPMCOUNTER29 0xb1d
|
#define CSR_MHPMCOUNTER29 0xb1d
|
||||||
#define CSR_MHPMCOUNTER30 0xb1e
|
#define CSR_MHPMCOUNTER30 0xb1e
|
||||||
#define CSR_MHPMCOUNTER31 0xb1f
|
#define CSR_MHPMCOUNTER31 0xb1f
|
||||||
|
#define CSR_MCOUNTINHIBIT 0x320
|
||||||
#define CSR_MHPMEVENT3 0x323
|
#define CSR_MHPMEVENT3 0x323
|
||||||
#define CSR_MHPMEVENT4 0x324
|
#define CSR_MHPMEVENT4 0x324
|
||||||
#define CSR_MHPMEVENT5 0x325
|
#define CSR_MHPMEVENT5 0x325
|
||||||
|
@ -357,6 +358,7 @@
|
||||||
#define CSR_MARCHID 0xf12
|
#define CSR_MARCHID 0xf12
|
||||||
#define CSR_MIMPID 0xf13
|
#define CSR_MIMPID 0xf13
|
||||||
#define CSR_MHARTID 0xf14
|
#define CSR_MHARTID 0xf14
|
||||||
|
#define CSR_MCONFIGPTR 0xf15
|
||||||
#define CSR_CYCLEH 0xc80
|
#define CSR_CYCLEH 0xc80
|
||||||
#define CSR_TIMEH 0xc81
|
#define CSR_TIMEH 0xc81
|
||||||
#define CSR_INSTRETH 0xc82
|
#define CSR_INSTRETH 0xc82
|
||||||
|
|
Loading…
Reference in New Issue