rv32emu icon indicating copy to clipboard operation
rv32emu copied to clipboard

Implement performance counters and timers

Open jserv opened this issue 3 years ago • 3 comments

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.

  • RDCYCLE: The execution environment should provide a means to determine the current rate (cycles/second) at which the cycle counter is incrementing.
  • RDTIME: The execution environment should provide a means of determining the period of the real-time counter (seconds/tick). The environment should provide a means to determine the accuracy of the clock.

jserv avatar Aug 05 '22 04:08 jserv

Check the following materials in advance:

  • PicoRV32: ENABLE_COUNTERS64 (default = 1) This parameter enables support for the RDCYCLEH, RDTIMEH, and RDINSTRETH instructions. If this parameter is set to 0, and ENABLE_COUNTERS is set to 1, then only the RDCYCLE, RDTIME, and RDINSTRET instructions are available.
  • Mike Field's emulate-risc-v

jserv avatar Sep 28 '22 02:09 jserv

fastrv32 is another reference for implementing timer stuff.

jserv avatar Oct 03 '22 06:10 jserv

Sample RISC-V assembly program using performance counter:

.section .text
.global _get_cycles
.type _get_cycles, @function

_get_cycles:
    csrr a0, minstret
    csrr a1, minstreth
    ret

jserv avatar Oct 31 '22 10:10 jserv

Thanks, Writing my first assembly code.

TheCloudlet avatar Oct 31 '22 15:10 TheCloudlet

Writing my first assembly code.

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

jserv avatar Oct 31 '22 19:10 jserv

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

jserv avatar Nov 03 '22 18:11 jserv