diff options
Diffstat (limited to 'riscv/riscv_step.sail')
| -rw-r--r-- | riscv/riscv_step.sail | 31 |
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; + } } } } |
