Closed rod-chapman closed 3 years ago
How to organise the source of this package? The package spec is simple, and common to both RV32 and RV64.
The body needs to be implemented in assembler and is different for RV32 and RV64.
What is the best way to organise this and make sure the right version gets compiled, assebled and linked?
Is there a scalar constant defined by the BSP that tells me whether a target is RV32 or RV64 perhaps?
Actually, a static scalar constant (not a string!) would be good so I could write a case statement over its value, and expect the compiler to optimize away the "wrong" branch for any particular target...
Hi @rod-chapman,
I opened #363 to implement performance CSR on both RV32 and RV64. The API is the same for RV32 or RV64 so you don't have to worry about that in this case.
For the mtime
counter the situation is a bit more difficult. mtime
is a memory mapped register not a CSR, the reason is to allow mtime
to be in a different clock domain than the CPU and therefore keep ticking when the CPU is halted.
Unfortunately the address of mtime
is not fixed in the standard, so it can be different for every board.
For the HiFive1 you can use these definitions:
CLINT_Addr : constant := 16#02000000#;
CLINT_Mtime_Offset : constant := 16#BFF8#;
Mtime_Lo_Addr : Address := To_Address (CLINT_Addr + CLINT_Mtime_Offset);
Mtime_Hi_Addr : Address := To_Address (CLINT_Addr + CLINT_Mtime_Offset + 4);
Mtime_Lo : UInt32 with Volatile_Full_Access, Address => Mtime_Lo_Addr;
Mtime_Hi : UInt32 with Volatile_Full_Access, Address => Mtime_Hi_Addr;
It would be helpful to offer a standard Ada API to read the values of the standard RISC-V performance counters, specifically the CSRs CYCLE, INSTRET and TIME.
These are always 64-bit unsigned values on both RV32 and RV64, but the implementation differs, since (on RV32) they have to be read as 2 32-bit values and checked for (non-)overflow.