<<<
:sectnums:
==== Core-Local Interruptor (CLINT)

[cols="<3,<3,<4"]
[grid="none"]
|=======================
| Hardware source files:  | neorv32_clint.vhd |
| Software driver files:  | neorv32_clint.c   | link:https://stnolting.github.io/neorv32/sw/neorv32__clint_8c.html[Online software reference (Doxygen)]
|                         | neorv32_clint.h   | link:https://stnolting.github.io/neorv32/sw/neorv32__clint_8h.html[Online software reference (Doxygen)]
| Top entity ports:       | `irq_msi_i`       | RISC-V software IRQ if CLINT is **not** implemented
|                         | `irq_mti_i`       | RISC-V machine timer IRQ if CLINT is **not** implemented
|                         | `mtime_time_o`    | Current system time (from CLINT's MTIMER)
| Configuration generics: | `IO_CLINT_EN`     | implement core local interruptor when `true`
| CPU interrupts:         | `MTI`             | machine timer interrupt (see <<_processor_interrupts>>)
|                         | `MSI`             | machine software interrupt (see <<_processor_interrupts>>)
|=======================

**Key Features**

* Compatible to the RISC-V ACLINT specification
* Global 64-bit system time
* Timer and software interrupts for each CPU core


**Overview**

The core-local interruptor provides machine-level timer and software interrupts for a set of CPU cores ("harts").
It is compatible to the original SiFive(R) CLINT specifications and it is also backwards-compatible to the RISC-V
_Advanced Core-Local Interruptor (ACLINT)_ specifications. In terms of the ACLINT spec the NEORV32 CLINT implements three
_devices_ that are placed next to each other in the address space: an MTIMER including time-compares and an MSWI device.
The CLINT can support up to 4095 harts. However, the NEORV32 CLINT is configured for up to two harts only.
Hence, only the according registers are implemented while the remaining ones are hardwired to zero.

.RISC-V ACLINT Specs.
[TIP]
The original RISC-V ACLINT specifications are available online at https://github.com/riscvarchive/riscv-aclint.


**MTIMER Device**

The MTIMER device provides a global 64-bit machine timer (`NEORV32_CLINT->MTIME`) that increments with every main
processor clock tick. Upon reset the timer is reset to all zero. Each hart provides an individual 64-bit timer-compare
register (`NEORV32_CLINT->MTIMECMP[0]` for hart 0). Whenever `MTIMECMP >= MTIME` the according hart's machine timer
interrupt becomes pending.

.CSR Access
[NOTE]
The MTIME system time is also available as read-only shadow copy via the <<_timeh>> CSRs.


**MSWI Device**

The MSWI provides a software interrupt for each hart via hart-individual memory-mapped registers (e.g.
`NEORV32_CLINT->MSWI[0]` for hart 0). Setting bit 0 of this register will bring the machine software
interrupt for the specific hart into pending state.

.External Machine Timer and Software Interrupts
[NOTE]
If the NEORV32 CLINT module is **disabled** (`IO_CLINT_EN` = `false`) the core's machine timer interrupt and
machine software interrupt become available as processor-external signals (`irq_mti_i` and `irq_msi_i`, respectively).


**Register Map**

.CLINT register map (`struct NEORV32_CLINT`)
[cols="<3,<3,^1,^1,<6"]
[options="header",grid="all"]
|=======================
| Address      | Name [C]      | Bits | R/W | Function
.2+<| `0xfff40000` .2+<| `MSWI[0]` ^| 0    ^| r/w <| trigger machine software interrupt for hart 0 when set
                                   ^| 31:1 ^| r/- <| hardwired to zero
.2+<| `0xfff40004` .2+<| `MSWI[1]` ^| 0    ^| r/w <| trigger machine software interrupt for hart 1 when set
                                   ^| 31:1 ^| r/- <| hardwired to zero
| `0xfff44000` | `MTIMECMP[0]` | 63:0 | r/w | 64-bit time compare for hart 0
| `0xfff44008` | `MTIMECMP[1]` | 63:0 | r/w | 64-bit time compare for hart 1
| `0xfff4bff8` | `MTIME`       | 63:0 | r/w | 64-bit global machine timer
|=======================
