summaryrefslogtreecommitdiff
path: root/riscv/riscv_sys.sail
diff options
context:
space:
mode:
authorPrashanth Mundkur2018-06-09 18:42:43 -0700
committerPrashanth Mundkur2018-06-09 19:27:24 -0700
commit4336409f923c10a8c5e4acc91fa7e6ef5551a88f (patch)
tree3f35100f9f4333033fb9b8cc7f50b060e76018da /riscv/riscv_sys.sail
parentee44f49cf6180734ecfb749a8868b4f146a4bc41 (diff)
Increment minstret on instruction retires, and handle the case when the minstret CSR is explicitly written to.
Diffstat (limited to 'riscv/riscv_sys.sail')
-rw-r--r--riscv/riscv_sys.sail19
1 files changed, 19 insertions, 0 deletions
diff --git a/riscv/riscv_sys.sail b/riscv/riscv_sys.sail
index b423b08f..8af1155a 100644
--- a/riscv/riscv_sys.sail
+++ b/riscv/riscv_sys.sail
@@ -265,7 +265,24 @@ function legalize_scounteren(c : Counteren, v : xlenbits) -> Counteren = {
register mcycle : xlenbits
register mtime : xlenbits
+
+/* minstret is an architectural register, and can be written to. The
+ spec says that minstret increments on instruction retires need to
+ occur before any explicit writes to instret. However, in our
+ simulation loop, we need to execute an instruction to find out
+ whether it retired, and hence can only increment instret after
+ execution. To avoid doing this in the case minstret was explicitly
+ written to, we track writes to it in a separate model-internal
+ register.
+*/
register minstret : xlenbits
+register minstret_written : bool
+
+function retire_instruction() -> unit = {
+ if minstret_written == true
+ then minstret_written = false
+ else minstret = minstret + 1
+}
/* informational registers */
register mvendorid : xlenbits
@@ -785,6 +802,8 @@ function init_sys() -> unit = {
mhartid = EXTZ(0b0);
mcounteren->bits() = EXTZ(0b0);
+ minstret = EXTZ(0b0);
+ minstret_written = false;
}
function tick_clock() -> unit = {