Skip to content

Commit 2832234

Browse files
committed
improve timer performance
1 parent d10a2ad commit 2832234

File tree

2 files changed

+29
-16
lines changed

2 files changed

+29
-16
lines changed

cpu.py

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
from machine import MachineError, ExecutionTerminated, SetupError
1919
import random
2020

21-
# Helper functions
2221

2322
def signed32(val):
2423
return val if val < 0x80000000 else val - 0x100000000
@@ -237,6 +236,7 @@ def exec_SYSTEM(cpu, ram, inst, rd, funct3, rs1, rs2, funct7):
237236
cpu.mtime = (cpu.csrs[0x7C1] << 32) | cpu.csrs[0x7C0]
238237
cpu.mtime_lo_updated = False
239238
cpu.mtime_hi_updated = False
239+
cpu.mtip = (cpu.mtime >= cpu.mtimecmp)
240240

241241
# Atomic update of mtimecmp
242242
if csr in (0x7C2, 0x7C3):
@@ -246,7 +246,9 @@ def exec_SYSTEM(cpu, ram, inst, rd, funct3, rs1, rs2, funct7):
246246
cpu.mtimecmp = (cpu.csrs[0x7C3] << 32) | cpu.csrs[0x7C2]
247247
cpu.mtimecmp_lo_updated = False
248248
cpu.mtimecmp_hi_updated = False
249-
249+
cpu.mtime_countdown = cpu.mtimecmp - cpu.mtime
250+
cpu.mtip = (cpu.mtime >= cpu.mtimecmp)
251+
250252
elif funct3 in (0b010, 0b110): # CSRRS / CSRRSI
251253
if rs1_val != 0:
252254
cpu.csrs[csr] = old | rs1_val
@@ -335,6 +337,7 @@ def __init__(self, ram, init_regs=None, logger=None, args=None):
335337
self.mtime_hi_updated = False
336338
self.mtimecmp_lo_updated = False
337339
self.mtimecmp_hi_updated = False
340+
self.mtip = False
338341

339342
# name - ID register maps
340343
self.REG_NUM_NAME = {}
@@ -418,20 +421,30 @@ def bypassed_trap_return(self, cause, mtval=0):
418421
self.csrs[0x300] |= (1 << 7) # MPIE = 1
419422
# (MIE, bit 3, stays unchanged)
420423

424+
# Machine timer interrupt logic
421425
def timer_update(self):
422426
csrs = self.csrs
423-
self.mtime = (self.mtime + 1) & 0xFFFFFFFF_FFFFFFFF
427+
mtime = self.mtime
424428

425-
# trigger Machine Timer Interrupt
426-
if self.mtime >= self.mtimecmp:
427-
csrs[0x344] |= (1 << 7) # set MTIP (timer interrupt)
428-
else:
429-
csrs[0x344] &= ~(1 << 7) # clear MTIP
429+
self.mtime = (mtime + 1) # & 0xFFFFFFFF_FFFFFFFF # the counter should wrap, but it's unlikely to ever happen ;)
430+
mtip_asserted = (mtime >= self.mtimecmp)
430431

431-
if (csrs[0x300] & (1<<3)) and (csrs[0x304] & (1<<7)) and (csrs[0x344] & (1<<7)):
432-
self.trap(cause=0x80000007, sync=False) # fire interrupt as an asynchronous trap
432+
# Set interrupt pending flag
433+
if mtip_asserted != self.mtip:
434+
if mtip_asserted:
435+
csrs[0x344] |= (1 << 7) # set MTIP
436+
else:
437+
csrs[0x344] &= ~(1 << 7) # clear MTIP
438+
self.mtip = mtip_asserted
439+
440+
if not mtip_asserted:
441+
return
442+
443+
# Trigger Machine Timer Interrupt
444+
if (csrs[0x300] & (1<<3)) and (csrs[0x304] & (1<<7)):
445+
self.trap(cause=0x80000007, sync=False) # fire timer interrupt as an asynchronous trap
433446

434-
# CPU register initialization
447+
# CPU registers initialization
435448
def init_registers(self, mode='0x00000000'):
436449
self.registers[0] = 0
437450
if mode == 'random':

machine.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -207,17 +207,17 @@ def make_regformatter_lambda(self, regstring='pc,sp,ra,a0'):
207207

208208
getters = []
209209
for name in names:
210-
if name in cpu.REG_NAME_NUM:
210+
if name in cpu.REG_NAME_NUM: # registers
211211
idx = cpu.REG_NAME_NUM[name]
212212
getters.append( (name, lambda cpu, idx=idx: cpu.registers[idx]) )
213-
elif name in ['mtime_lo', 'mtimecmp_lo']:
213+
elif name in ['mtime_lo', 'mtimecmp_lo']: # mtime/mtimecmp
214214
getters.append( (name, lambda cpu, name=name: getattr(cpu, name[:-3]) & 0xFFFFFFFF) )
215-
elif name in ['mtime_hi', 'mtimecmp_hi']:
215+
elif name in ['mtime_hi', 'mtimecmp_hi']: # mtime/mtimecmp
216216
getters.append( (name, lambda cpu, name=name: getattr(cpu, name[:-3]) >> 32) )
217-
elif name in cpu.CSR_NAME_ADDR:
217+
elif name in cpu.CSR_NAME_ADDR: # CSRs
218218
addr = cpu.CSR_NAME_ADDR[name]
219219
getters.append( (name, lambda cpu, addr=addr: cpu.csrs[addr]) )
220-
elif name in ['pc']:
220+
elif name in ['pc']: #PC
221221
getters.append( (name, lambda cpu, name=name: getattr(cpu, name)) )
222222
else:
223223
raise SetupError(f"Unknown register/CSR while setting up register logging: '{name}'")

0 commit comments

Comments
 (0)