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

⚠️ rework GPTMR #939

Merged
merged 10 commits into from
Jul 4, 2024
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 @@ -29,6 +29,7 @@ mimpid = 0x01040312 -> Version 01.04.03.12 -> v1.4.3.12

| Date | Version | Comment | Ticket |
|:----:|:-------:|:--------|:------:|
| 04.07.2024 | 1.10.0.10 | :warning: rework GPTMRM and remove capture mode | [#939](https://github.com/stnolting/neorv32/pull/939) |
| 03.07.2024 | 1.10.0.9 | :warning: remove `AMO_RVS_GRANULARITY` generic, reservation set granularity is now fixed to 4 bytes | [#938](https://github.com/stnolting/neorv32/pull/938) |
| 03.07.2024 | 1.10.0.8 | :test_tube: add XBUS to AHB3-lite bridge | [#937](https://github.com/stnolting/neorv32/pull/937) |
| 02.07.2024 | 1.10.0.7 | minor rtl and software edits and cleanups | [#936](https://github.com/stnolting/neorv32/pull/936) |
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ For example, the CPU ensures _all_ memory accesses are properly acknowledged and
instructions are always detected as such. Whenever an unexpected state occurs the application software is
informed via _precise_ and resumable hardware exceptions.

* :books: For detailed information see the [NEORV32 online documentation](https://stnolting.github.io/neorv32/).
* :recycle: Looking for an **all-Verilog** version? Have a look at [neorv32-verilog](https://github.com/stnolting/neorv32-verilog).
* :heavy_check_mark: [Continuous integration](#project-status) to check for regressions (including RISC-V ISA compatibility check using **RISCOF**).
* :open_file_folder: [Exemplary setups](https://github.com/stnolting/neorv32-setups) and
Expand All @@ -46,6 +45,7 @@ targeting various FPGA boards and toolchains to get started.
* :label: The project's change log is available in [CHANGELOG.md](https://github.com/stnolting/neorv32/blob/main/CHANGELOG.md).
* :rocket: Check out the [quick links below](#5-getting-started) and the
[*User Guide*](https://stnolting.github.io/neorv32/ug/) to get started setting up _your_ NEORV32 processor!
* :books: For detailed information see the [NEORV32 online documentation](https://stnolting.github.io/neorv32/).
* :interrobang: Want to know more? Check out the [project's rationale](https://stnolting.github.io/neorv32/#_rationale).

Feel free to open a new [issue](https://github.com/stnolting/neorv32/issues) or start a new
Expand Down Expand Up @@ -140,7 +140,7 @@ allows booting application code via UART or from external SPI flash
**Timers and Counters**

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

**Input / Output**
Expand Down
4 changes: 1 addition & 3 deletions docs/datasheet/soc.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,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**>>) with capture input
* _optional_ general purpose 32-bit timer (<<_general_purpose_timer_gptmr,**GPTMR**>>)
* _optional_ execute in-place module (<<_execute_in_place_module_xip,**XIP**>>)
* _optional_ 1-wire serial interface controller (<<_one_wire_serial_interface_controller_onewire,**ONEWIRE**>>), compatible to the 1-wire standard
* _optional_ autonomous direct memory access controller (<<_direct_memory_access_controller_dma,**DMA**>>)
Expand Down Expand Up @@ -151,8 +151,6 @@ Some interfaces (like the TWI and the 1-Wire bus) require tri-state drivers in t
| `neoled_o` | 1 | out | - | asynchronous serial data output
5+^| **<<_machine_system_timer_mtime>>**
| `mtime_time_o` | 64 | out | - | MTIME system time output
5+^| **<<_general_purpose_timer_gptmr>>**
| `gptmr_trig_i` | 1 | in | `'L'` | timer capture input
5+^| **<<_external_interrupt_controller_xirq>>**
| `xirq_i` | 32 | in | `'L'` | external interrupt requests
5+^| **RISC-V Machine-Mode <<_processor_interrupts>>**
Expand Down
72 changes: 25 additions & 47 deletions docs/datasheet/soc_gptmr.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
| Hardware source files: | neorv32_gptmr.vhd |
| Software driver files: | neorv32_gptmr.c |
| | neorv32_gptmr.h |
| Top entity ports: | `gptmr_trig_i` | timer capture input
| Top entity ports: | none |
| Configuration generics: | `IO_GPTMR_EN` | implement general purpose timer when `true`
| CPU interrupts: | fast IRQ channel 12 | timer interrupt (see <<_processor_interrupts>>)
|=======================
Expand All @@ -18,14 +18,13 @@

The general purpose timer module implements a simple yet universal 32-bit timer. It is implemented if the processor's
`IO_GPTMR_EN` top generic is set `true`. The timer provides a pre-scaled counter register that can trigger an interrupt
when reaching a programmable threshold value. Additionally, a timer-capture feature is implemented that copies the current
counter value to a dedicated register if a programmable edge occurs at the `gptmr_trig_i` input signal.
when reaching a programmable threshold value.l.

Four interface registers are available: a control register (`CTRL`), a 32-bit counter register (`COUNT`), a 32-bit
threshold register (`THRES`) and a 32-bit read-only capture register (`CAPTURE`). The timer is globally enabled by setting the
`GPTMR_CTRL_EN` bit in the device's control register `CTRL`. When the timer is enable 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:
The GPTMR provides three interface registers : a control register (`CTRL`), a 32-bit counter register (`COUNT`) and a
32-bit threshold register (`THRES`). The timer is globally enabled by setting the `GPTMR_CTRL_EN` bit in the module's
control register. When the timer is enable the `COUNT` register will start incrementing from zero at a programmable
rate that scales the main processor clock. this pre-scaler is configured via the three `GPTMR_CTRL_PRSCx`
control register bits:

.GPTMR prescaler configuration
[cols="<4,^1,^1,^1,^1,^1,^1,^1,^1"]
Expand All @@ -35,40 +34,24 @@ three `GPTMR_CTRL_PRSCx` control register bits:
| Resulting `clock_prescaler` | 2 | 4 | 8 | 64 | 128 | 1024 | 2048 | 4096
|=======================

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


**Interval Timer**

Whenever the counter register `COUNT` reaches the programmable threshold value `THRES` the counter register
is reset to zero and the _timer-match_ flag `GPTMR_CTRL_TRIGM` gets set. This flag has to be cleared manually
by writing zero to it. Optionally, an interrupt can be triggered if the `GPTMR_CTRL_IRQM` bit is set.
Whenever the counter register `COUNT` equals the programmable threshold value `THRES` the module's interrupt
signal becomes pending (indicated by `GPTMR_CTRL_IRQ_PND` being set). Note that a pending interrupt has to be
cleared manually by writing a `1` to `GPTMR_CTRL_IRQ_CLR`.

The control register's `GPTMR_CTRL_MODE` bit defines what will happen when `COUNT == THRES`.

**Timer Capture**
* `GPTMR_CTRL_MODE = 0`: **single-shot mode** - the `COUNT` register will stop incrementing
* `GPTMR_CTRL_MODE = 1`: **continuous mode** - the `COUNT` register is automatically reset and restarts incrementing from zero

In addition to the the internal timer, the GPTMR provides a timer-capture feature. Whenever an edge is detected
at the `gptmr_trig_i` input signal the current `COUNT` value is copied to the read-only `CAPTURE` register and the
_capture-trigger_ flag `GPTMR_CTRL_TRIGC` gets set. This flag has to be cleared manually by writing zero to it.
Optionally, an interrupt can be triggered if the `GPTMR_CTRL_IRQC` bit is set.

The triggering edge can be a rising-edge (if `GPTMR_CTRL_RISE` is set), a falling-edge (if `GPTMR_CTRL_FALL` is
set) or even both. By default, the `gptmr_trig_i` is sampled two times at the processor clock for checking for
edges. This simple edge detection is sufficient for trigger signals that are generated by (on-chip) digital logic.

For sampling chip-external signals an optional filtering mode is available that can be enabled by the
`GPTMR_CTRL_FILTER` bit. If this bit is set, the `gptmr_trig_i` is sampled at a reduced clock speed (1/4 of the
processor clock) and the signal has to be stable for at lest 4 sample clock in order to be considered high or low.
This stabilized signal is then fed to the edge detection logic.
.Resetting the Counter
[NOTE]
Disabling the GPTMR will also clear the `COUNT` register.


**Interrupt**

The GPTRM provides a single interrupt line that can be trigger by a timer-match event and/or by a timer-compare
event. Once triggered, the interrupt will stay active until explicitly cleared by writing zero to the according
interrupt flag (`GPTMR_CTRL_TRIGM` or `GPTMR_CTRL_TRIGC`).
The GPTRM provides a single interrupt line is triggered whenever `COUNT` equals `THRES`. Once triggered, the interrupt will
stay pending until explicitly cleared by writing a 1 to `GPTMR_CTRL_IRQ_CLR`.


**Register Map**
Expand All @@ -78,17 +61,12 @@ interrupt flag (`GPTMR_CTRL_TRIGM` or `GPTMR_CTRL_TRIGC`).
[options="header",grid="all"]
|=======================
| Address | Name [C] | Bit(s), Name [C] | R/W | Function
.10+<| `0xfffff100` .10+<| `CTRL` <|`0` `GPTMR_CTRL_EN` ^| r/w <| Timer enable flag
<|`3:1` `GPTMR_CTRL_PRSC2 : GPTMR_CTRL_PRSC0` ^| r/w <| 3-bit clock prescaler select
<|`4` `GPTMR_CTRL_IRQM` ^| r/w <| Enable interrupt on timer-match
<|`5` `GPTMR_CTRL_IRQC` ^| r/w <| Enable interrupt on capture-trigger
<|`6` `GPTMR_CTRL_RISE` ^| r/w <| Capture on rising edge
<|`7` `GPTMR_CTRL_FALL` ^| r/w <| Capture on falling edge
<|`8` `GPTMR_CTRL_FILTER` ^| r/w <| Filter capture input
<|`29:9` - ^| r/- <| _reserved_, read as zero
<|`30` `GPTMR_CTRL_TRIGM` ^| r/c <| Timer-match has fired, cleared by writing 0
<|`31` `GPTMR_CTRL_TRIGC` ^| r/c <| Capture-trigger has fired, cleared by writing 0
.6+<| `0xfffff100` .6+<| `CTRL` <|`0` `GPTMR_CTRL_EN` ^| r/w <| Timer enable flag
<|`3:1` `GPTMR_CTRL_PRSC2 : GPTMR_CTRL_PRSC0` ^| r/w <| 3-bit clock prescaler select
<|`4` `GPTMR_CTRL_MODE` ^| r/w <| Operation mode (0=single-shot, 1=continuous)
<|`29:5` - ^| r/- <| _reserved_, read as zero
<|`30` `GPTMR_CTRL_IRQ_CLR` ^| -/w <| Write `1` to clear timer-match interrupt; auto-clears
<|`31` `GPTMR_CTRL_IRQ_PND` ^| r/- <| Timer-match interrupt pending
| `0xfffff104` | `THRES` |`31:0` | r/w | Threshold value register
| `0xfffff108` | `COUNT` |`31:0` | r/w | Counter register
| `0xfffff10C` | `CAPTURE` |`31:0` | r/- | Capture register
| `0xfffff108` | `COUNT` |`31:0` | r/- | Counter register
|=======================
Loading