sysprog21 / rv32emu

Compact and Efficient RISC-V RV32I[MAFC] emulator
MIT License
382 stars 91 forks source link

Implement performance counters and timers #33

Closed jserv closed 1 year ago

jserv commented 2 years ago

RISC-V ISAs provide a set of up to 32×64-bit performance counters and timers.

RV32I provides a number of 64-bit read-only user-level counters, which are mapped into the 12-bit CSR address space and accessed in 32-bit pieces using CSRRS instructions. In RV64I, the CSR instructions can manipulate 64-bit CSRs. In particular, the RDCYCLE, RDTIME, and RDINSTRET pseudo-instructions read the full 64 bits of the cycle, time, and instret counters. Hence, the RDCYCLEH, RDTIMEH, and RDINSTRETH instructions are RV32I-only.

jserv commented 1 year ago

Check the following materials in advance:

jserv commented 1 year ago

fastrv32 is another reference for implementing timer stuff.

jserv commented 1 year ago

Writing my first assembly code.

Alternatively, you can check riscv-csr-access for inline assembly based routines.

jserv commented 1 year ago

Suppose that we are going to utilize a function getcycles:

uint64_t getcycles();

It can be implemented:

.text

.globl getcycles
.align 2
getcycles:
    csrr a1, mcycleh
    csrr a0, mcycle
    csrr a2, mcycleh
    bne a1, a2, getcycles
    ret
.size getcycles,.-getcycles

Similarly, function getinstret can be implemented as following:

.text

.globl getinstret
.align 2
getinstret:
    csrr a1, minstreth
    csrr a0, minstret
    csrr a2, minstreth
    bne a1, a2, getinstret
    ret
.size getinstret,.-getinstret