summaryrefslogtreecommitdiff
path: root/riscv/riscv_step.sail
diff options
context:
space:
mode:
Diffstat (limited to 'riscv/riscv_step.sail')
-rw-r--r--riscv/riscv_step.sail31
1 files changed, 16 insertions, 15 deletions
diff --git a/riscv/riscv_step.sail b/riscv/riscv_step.sail
index 2ac80cc6..2d074f27 100644
--- a/riscv/riscv_step.sail
+++ b/riscv/riscv_step.sail
@@ -1,6 +1,8 @@
+/* The emulator fetch-execute-interrupt dispatch loop. */
+
union FetchResult = {
- F_Base : word, /* Base ISA */
- F_RVC : half, /* Compressed ISA */
+ F_Base : word, /* Base ISA */
+ F_RVC : half, /* Compressed ISA */
F_Error : (ExceptionType, xlenbits) /* exception and PC */
}
@@ -8,7 +10,7 @@ function isRVC(h : half) -> bool =
~ (h[1 .. 0] == 0b11)
val fetch : unit -> FetchResult effect {escape, rmem, rreg, wmv, wreg}
-function fetch() -> FetchResult = {
+function fetch() -> FetchResult =
/* check for legal PC */
if (PC[0] != 0b0 | (PC[1] != 0b0 & (~ (haveRVC()))))
then F_Error(E_Fetch_Addr_Align, PC)
@@ -39,11 +41,10 @@ function fetch() -> FetchResult = {
}
}
}
-}
/* returns whether an instruction was retired, and whether to increment the step count in the trace */
val step : int -> (bool, bool) effect {barr, eamem, escape, exmem, rmem, rreg, wmv, wreg}
-function step(step_no) = {
+function step(step_no) =
match curInterrupt(cur_privilege, mip, mie, mideleg) {
Some(intr, priv) => {
print_bits("Handling interrupt: ", intr);
@@ -87,14 +88,13 @@ function step(step_no) = {
}
}
}
-}
val loop : unit -> unit effect {barr, eamem, escape, exmem, rmem, rreg, wmv, wreg}
function loop () = {
let insns_per_tick = plat_insns_per_tick();
i : int = 0;
step_no : int = 0;
- while true do {
+ while (~ (htif_done)) do {
minstret_written = false; /* see note for minstret */
let (retired, stepped) = step(step_no);
PC = nextPC;
@@ -107,14 +107,15 @@ function loop () = {
let exit_val = unsigned(htif_exit_code);
if exit_val == 0 then print("SUCCESS")
else print_int("FAILURE: ", exit_val);
- exit(());
- };
-
- /* update time */
- i = i + 1;
- if i == insns_per_tick then {
- tick_clock();
- i = 0;
+ } else {
+ /* update time */
+ i = i + 1;
+ if i == insns_per_tick then {
+ tick_clock();
+ /* for now, we drive the platform i/o at every clock tick. */
+ tick_platform();
+ i = 0;
+ }
}
}
}