Information about the SysTick Register


I’m working in Rust on the GD32VF103 on my Longan Nano. Does anyone have any information about the systick register?

The datasheet, user manual, and firmware seem to be light on information. The header files seem to show the address at 0xd1000000, in the n200 timer (?)

If I find anything else I’ll update this thread.

Thanks! Chris

Couple of facts I’ve found:

  • SysTick is a 64-bit up counter clocked by CK_AHB divided by 4.
  • Accessible via register mapped at 0xD1000000 (LOW 32 bits) & 0xD1000004 (HIGH 32 bits).
  • Maskable system interrupt generation when the counter and comparison values are
  • 64-bit compare register at 0xD1000008
  • Compare interrupt vector CLIC_INT_TMR (0x0000_001C), handler eclic_mtip_handler

SysTick is an ARM register. Since the GD32VF103 doesn’t have an ARM core, it doesn’t have SysTick. Yes, I know that the User Manual references SysTick (v1.2, p63):

The RISCV System Timer (SysTick) external clock is clocked with the AHB clock (HCLK) divided by 4.

However, if you look at the GD32F103 User Manual, which the GD32VF103 User Manual was clearly based on, you see this (v2.2, p83):

The Cortex System Timer (SysTick) external clock is clocked with the AHB clock (HCLK) divided by 8.

GigaDevice probably just did a find-and-replace of “Cortex” for “RISCV” and forgot to update the rest of the passage. That’s not the only such mistake in the User Manual: earlier in that section, it says you can trigger a reset using the “RISC-V Application Interrupt and Reset Control Register.” That register doesn’t exist on RISC-V, but it does on ARM.

That being said, all hope is not lost. While RISC-V doesn’t have SysTick, it does have mtime which serves much the same purpose. I’m almost certain that GigaDevice hooked up the clock line labeled SysTick to mtime and just forgot to update the name in the User Manual. You can find full documentation of mtime in the RISC-V Privileged ISA Specification and also in the Bumblebee Core Architecture Manual[1].

Interestingly, neither the GD32VF103 User Manual nor the Bumblebee Architecture Manual say where mtime is mapped into memory. The latter at least makes some reference to it, but all it says (p62) is to “refer to the Datasheet of the Bumblebee Core.” The Bumblebee Datasheet[1] just says (p9) to “refer to the datasheet of the specific MCU chip.” Going off @loboris’s comment above, I’d guess that the base address for the timer registers is 0xD1000000 on the GD32VF103.


1 Like

Look at Machine Timer Registers (mtime and mtimecmp) in The RISC-V Instruction Set Manual.

Platforms provide a real-time counter, exposed as a memory-mapped machine-mode read-write
register, mtime. mtime must run at constant frequency, and the platform must provide a mechanism
for determining the timebase of mtime.

This counter is implementation dependant and on GD32VF103 is implemented as counter clocked at AHB/4 and memory mapped at 0xD1000000.

GD32VF103 also has a standard RISC-V mcycle CSR (see Hardware Performance Monitor in The RISC-V Instruction Set Manual) which counts the number of instructions.
CSR is not memory mapped and must be reead/written using the read_csr/write_csr macro (asm csrr/csrw).

Both counters have 64-bit precission and on 32-bit RISC-V must be read as two 32-bit registers (Lo & Hi).

Example of using both can be found in measure_cpu_freq function.

I’ve had no issues using those registers, so I don’t see any problem with them. There are some errors in GD32VF103 User Manual but they are probably to be corrected in the next release.


Thank you both for your help! I’ll post back when I have it reading. I don’t suspect any hardware troubles; i’m just using rust and having to learn rust and implement low level apis which is new for me.

There are two core timers/counters: mcycle and so-called SysTick 0xD1000000. First runs at the core frequency, second runs at HCLK/4
Counter at 0xD1000000 is documented in “Bumblebee core datasheet”

Do have have the page number for that?

Hmm, now I have no idea where I got this address from. Maybe from the SDK. SysTick timer itself is documented on pdf-page 144 (Bumblebee core datasheet_en.pdf)

I looked at that page, and it has a nice table giving the layout of the various timer registers. But it gives their location in terms of “intra-module offset address”. It also says “The base address of the TIMER unit in the Bumblebee kernel is described in the Bumblebee Kernel Concise Data Sheet.”.

THAT document then says “In the implementation of the Bumblebee kernel, mtime/mtimecmp is TIMER unit implementation, see the Bumblebee Kernel Instruction Architecture Handbook for details on the TIBR unit of the Bumblebee kernel.” Which is where I started.

There does however appear to be a clock at address 0xD1000000 incrementing at about 2 MHz (on my default board with an 8 MHz cpu clock). It is just that I would like to see the relevant documentation before relying on it.

Next time I am working on it I will see if there is all ones at address D1000008, which would be the default mtimecmp value according to table 6-1.

Timer frequency is AHB frequency divided by 4 (page 63 of GD32VF103_User_Manual_EN_V1.2.pdf)