Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add general purpose timer GPTMR #195

Merged
merged 14 commits into from
Nov 3, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ defined by the `hw_version_c` constant in the main VHDL package file [`rtl/core/

| Date (*dd.mm.yyyy*) | Version | Comment |
|:----------:|:-------:|:--------|
| 03.11.2021 | 1.6.3.1 | :sparkles: added new peripheral module - general purpose 32-bit timer `GPTMR` ([see PR #195](https://github.com/stnolting/neorv32/pull/195)) |
| 02.11.2021 |[**:rocket:1.6.3**](https://github.com/stnolting/neorv32/releases/tag/v1.6.3) | **New release** |
| 01.11.2021 | 1.6.2.13 | added new top generics to explicitly control implementation of `Zicntr` (CPU base counters) and `Zihpm` (hardware performance monitors, see [PR #192](https://github.com/stnolting/neorv32/pull/192) |
| 30.10.2021 | 1.6.2.12 | :sparkles: :lock: added memory-mapped register to BUSKEEPER module - software can now retrieve the actual cause of an instruction / data-load / data-store bus access fault exception (access timeout or device error); see [PR #191](https://github.com/stnolting/neorv32/pull/191) |
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,8 @@ cache ([iCACHE](https://stnolting.github.io/neorv32/#_processor_internal_instruc

**Timers**

* machine system timer ([MTIME](https://stnolting.github.io/neorv32/#_machine_system_timer_mtime)), RISC-V spec. compatible
* machine system timer, 64-bit ([MTIME](https://stnolting.github.io/neorv32/#_machine_system_timer_mtime)), RISC-V spec. compatible
* general purpose 32-bit timer ([GPTMR](https://stnolting.github.io/neorv32/#_general_purpose_timer_gptmr))
* watchdog timer ([WDT](https://stnolting.github.io/neorv32/#_watchdog_timer_wdt))

**IO**
Expand Down
4 changes: 4 additions & 0 deletions docs/datasheet/overview.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -226,19 +226,22 @@ neorv32_top.vhd - NEORV32 Processor top entity
├neorv32_debug_dtm.vhd - on-chip debugger: debug transfer module
├neorv32_dmem.entity.vhd - Processor-internal data memory (entity-only!)
├neorv32_gpio.vhd - General purpose input/output port unit
├neorv32_gptmr.vhd - General purpose 32-bit timer
├neorv32_icache.vhd - Processor-internal instruction cache
├neorv32_imem.entity.vhd - Processor-internal instruction memory (entity-only!)
│└neor32_application_image.vhd - IMEM application initialization image
├neorv32_mtime.vhd - Machine system timer
├neorv32_neoled.vhd - NeoPixel (TM) compatible smart LED interface
├neorv32_pwm.vhd - Pulse-width modulation controller
├neorv32_slink.vhd - Stream link controller
├neorv32_spi.vhd - Serial peripheral interface controller
├neorv32_sysinfo.vhd - System configuration information memory
├neorv32_trng.vhd - True random number generator
├neorv32_twi.vhd - Two wire serial interface controller
├neorv32_uart.vhd - Universal async. receiver/transmitter
├neorv32_wdt.vhd - Watchdog timer
├neorv32_wishbone.vhd - External (Wishbone) bus interface
├neorv32_xirq.vhd - External interrupt controller
├mem/neorv32_dmem.default.vhd - _Default_ data memory (architecture-only!)
└mem/neorv32_imem.default.vhd - _Default_ instruction memory (architecture-only!)
Expand Down Expand Up @@ -332,6 +335,7 @@ https://stnolting.github.io/neorv32/ug/#_application_specific_processor_configur
| WDT | Watchdog timer | 53 | 43 | 0 | 0
| WISHBONE | External memory interface | 114 | 110 | 0 | 0
| XIRQ | External interrupt controller (32 channels) | 241 | 201 | 0 | 0
| GPTMR | General Purpose Timer | 153 | 107 | 0 | 0
|=======================


Expand Down
20 changes: 17 additions & 3 deletions docs/datasheet/soc.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ image::neorv32_processor.png[align=center]
* _optional_ custom functions subsystem for custom co-processor extensions (<<_custom_functions_subsystem_cfs,**CFS**>>)
* _optional_ NeoPixel(TM)/WS2812-compatible smart LED interface (<<_smart_led_interface_neoled,**NEOLED**>>)
* _optional_ external interrupt controller with up to 32 channels (<<_external_interrupt_controller_xirq,**XIRQ**>>)
* _optional_ general purpose 32-bit timer (<<_general_purpose_timer_gptmr,**GPTMR**>>)
* _optional_ on-chip debugger with JTAG TAP (<<_on_chip_debugger_ocd,**OCD**>>)
* bus keeper to monitor processor-internal bus transactions (<<_internal_bus_monitor_buskeeper,**BUSKEEPER**>>)
* system configuration information memory to check HW configuration via software (<<_system_configuration_information_memory_sysinfo,**SYSINFO**>>)
Expand Down Expand Up @@ -1016,6 +1017,18 @@ See section <<_smart_led_interface_neoled>> for more information.
|======


:sectnums!:
===== _IO_GPTMR_EN_

[cols="4,4,2"]
[frame="all",grid="none"]
|======
| **IO_GPTMR_EN** | _boolean_ | false
3+| Implement general purpose 32-bit timer (GPTMR) when _true_.
See section <<_general_purpose_timer_gptmr>> for more information.
|======



<<<
// ####################################################################################################################
Expand Down Expand Up @@ -1098,7 +1111,8 @@ the according FIRQ priority; 0 = highest, 15 = lowest):
| 9 | <<_smart_led_interface_neoled,NEOLED>> | NEOLED TX buffer interrupt
| 10 | <<_stream_link_interface_slink,SLINK>> | RX data buffer interrupt
| 11 | <<_stream_link_interface_slink,SLINK>> | TX data buffer interrupt
| 12:15 | - | _reserved_, will never fire
| 12 | <<_general_purpose_timer_gptmr,GPTMR>> | General purpose timer interrupt
| 13:15 | - | _reserved_, will never fire
|=======================

.Trigger type
Expand Down Expand Up @@ -1488,6 +1502,6 @@ include::soc_neoled.adoc[]

include::soc_xirq.adoc[]

include::soc_sysinfo.adoc[]

include::soc_gptmr.adoc[]

include::soc_sysinfo.adoc[]
68 changes: 68 additions & 0 deletions docs/datasheet/soc_gptmr.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<<<
:sectnums:
==== General Purpose Timer (GPTMR)

[cols="<3,<3,<4"]
[frame="topbot",grid="none"]
|=======================
| Hardware source file(s): | neorv32_gptmr.vhd |
| Software driver file(s): | neorv32_gptmr.c |
| | neorv32_gptmr.h |
| Top entity port: | none |
| Configuration generics: | _IO_GPTMR_EN_ | implement timer when _true_
| CPU interrupts: | fast IRQ channel 12 | transmission done interrupt (see <<_processor_interrupts>>)
|=======================


**Theory of Operation**

The general purpose timer module provides a simple yet universal 32-bit timer. The timer is implemented if
_IO_GPTMR_EN_ top generic is set _true_. It provides a 32-bit counter register (`COUNT`) and a 32-bit threshold
register (`THRES`). An interrupt is generated whenever the value of the counter registers matches the one from
threshold register.

The timer is enabled by setting the _GPTMR_CTRL_EN_ bit in the device's control register `CTRL`. The `COUNT`
register will start incrementing at a programmable rate, which scales the main processor clock. The
pre-scaler value is configured via the three _GPTMR_CTRL_PRSCx_ control register bits:

.GPTMR prescaler configuration
[cols="<4,^1,^1,^1,^1,^1,^1,^1,^1"]
[options="header",grid="rows"]
|=======================
| **`GPTMR_CTRL_PRSCx`** | `0b000` | `0b001` | `0b010` | `0b011` | `0b100` | `0b101` | `0b110` | `0b111`
| Resulting `clock_prescaler` | 2 | 4 | 8 | 64 | 128 | 1024 | 2048 | 4096
|=======================

The timer provides two operation modes that are configured by the _GPTMR_CTRL_MODE_ control register bit:
if _GPTMR_CTRL_MODE_ is cleared (`0`) the timer operates in _single-shot mode_. As soon as `COUNT` matches
`THRES` an interrupt request is generated and the timer stops operation (i.e. it stops incrementing). If
_GPTMR_CTRL_MODE_ is set (`1`) the timer operates in _continuous mode_. When `COUNT` matches `THRES` an interrupt
request is generated and `COUNT` is automatically reset to all-zero before continuing to increment.

[NOTE]
Disabling the timer will not clear the `COUNT` register. However, it can be manually reset at any time by
writing zero to it.


**Timer Interrupt**

The timer interrupt gets pending when the timer is enabled and `COUNT` matches `THRES`. The interrupt
request is indicated via the _GPTMR_CTRL_ALARM_ control register bit. This bit as well as the actual
interrupt keeps pending until the bit is explicitly cleared by application software or if the
timer is disabled.


.GPTMR register map (`struct NEORV32_GPTMR`)
[cols="<2,<2,<4,^1,<7"]
[options="header",grid="all"]
|=======================
| Address | Name [C] | Bit(s), Name [C] | R/W | Function
.6+<| `0xffffff60` .6+<| `NEORV32_GPTMR.CTRL` <|`0` _GPTMR_CTRL_EN_ ^| r/w <| Timer enable flag
<|`1` _GPTMR_CTRL_PRSC0_ ^| r/w .3+| 3-bit clock prescaler select
<|`2` _GPTMR_CTRL_PRSC1_ ^| r/w
<|`3` _GPTMR_CTRL_PRSC2_ ^| r/w
<|`4` _GPTMR_CTRL_MODE_ ^| r/w <| Counter mode: `0`=single-shot, `1`=continuous
<|`5` _GPTMR_CTRL_ALARM_ ^| r/c <| Pending interrupt/alarm, cleared by setting bit to zero
| `0xffffff64` | `NEORV32_GPTMR.THRES` |`31:0` | r/w | Threshold value register
| `0xffffff68` | `NEORV32_GPTMR.COUNT` |`31:0` | r/w | Counter register
|=======================
5 changes: 4 additions & 1 deletion docs/datasheet/software.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -61,20 +61,23 @@ files are currently part of the NEORV32 core library:
|=======================
| C source file | C header file | Description
| - | `neorv32.h` | main NEORV32 definitions and library file
| - | `neorv32_legacy.h` | legacy back-compatibility layer
| `neorv32_cfs.c` | `neorv32_cfs.h` | HW driver (stub)footnote:[This driver file only represents a stub, since the real CFS drivers are defined by the actual CFS implementation.] functions for the custom functions subsystem
| `neorv32_cpu.c` | `neorv32_cpu.h` | HW driver functions for the NEORV32 **CPU**
| `neorv32_gpio.c` | `neorv32_gpio.h` | HW driver functions for the **GPIO**
| `neorv32_gptmr.c` | `neorv32_gptmr.h` | HW driver functions for the **GPTRM**
| - | `neorv32_intrinsics.h` | macros for custom intrinsics/instructions
| - | `neorv32_legacy.h` | legacy back-compatibility layer
| `neorv32_mtime.c` | `neorv32_mtime.h` | HW driver functions for the **MTIME**
| `neorv32_neoled.c` | `neorv32_neoled.h` | HW driver functions for the **NEOLED**
| `neorv32_pwm.c` | `neorv32_pwm.h` | HW driver functions for the **PWM**
| `neorv32_rte.c` | `neorv32_rte.h` | NEORV32 **runtime environment** and helpers
| `neorv32_slink.c` | `neorv32_slink.h` | HW driver functions for the **SLINK**
| `neorv32_spi.c` | `neorv32_spi.h` | HW driver functions for the **SPI**
| `neorv32_trng.c` | `neorv32_trng.h` | HW driver functions for the **TRNG**
| `neorv32_twi.c` | `neorv32_twi.h` | HW driver functions for the **TWI**
| `neorv32_uart.c` | `neorv32_uart.h` | HW driver functions for the **UART0** and **UART1**
| `neorv32_wdt.c` | `neorv32_wdt.h` | HW driver functions for the **WDT**
| `neorv32_xirq.c` | `neorv32_xirq.h` | HW driver functions for the **XIRQ**
|=======================

.Documentation
Expand Down
Binary file modified docs/figures/neorv32_processor.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading