tillitis-key/hw/application_fpga/core/timer
Daniel Jobson 6bdedf4f86
Fix bug in timer core, where it misses clock cycles
Remove redundant timer state. This fixes a bug where the timer misses a
clock cycle every time the prescaler counter reaches 1. This means if
one uses a large prescaler, like 18E6, it is barely noticeable, but if
one have a low prescaler and a high timer value it becomes significant.
This also yields the running_* registers redundant, which are removed.

Add clarity to the readme.

Update the timer to default to values of one, for prescaler and timer
count.
2024-11-27 08:10:15 +01:00
..
rtl Fix bug in timer core, where it misses clock cycles 2024-11-27 08:10:15 +01:00
tb Fix bug in timer core, where it misses clock cycles 2024-11-27 08:10:15 +01:00
toolruns Update Verilog version to 2005 for linting 2024-04-24 08:44:08 +02:00
README.md Fix bug in timer core, where it misses clock cycles 2024-11-27 08:10:15 +01:00

timer

A simple timer with prescaler.

Introduction

This core implements a simple timer with a prescaler. The prescaler can be used to divide the system clock frequency to yield a specific amount of clock frequency ticks for each timer tick. This allows measurement of time rather than cycles. If for example setting the prescaler to the clock frequency in Hertz, the timer will count seconds.

API

The following addresses define the API for the timer:

	ADDR_CTRL: 0x08
	CTRL_START_BIT: 0
	CTRL_STOP_BIT:  1

	ADDR_STATUS: 0x09
	STATUS_RUNNING_BIT: 0

	ADDR_PRESCALER: 0x0a
	ADDR_TIMER:     0x0b

Details

The core consists of the timer_core module (in timer_core.v) and a top level wrapper, timer (in timer.v). The top level wrapper implements the API, while the timer_core implements the timer functionality.

The timer counter and the prescaler counter are both 32 bits. Both the prescaler and the timer register can be set through the API above, and should be a non-zero value, the defaults are one. These values cannot be changed when the timer is running.

Bit zero of the status register shows if the timer is running, one indicates a running timer.

Start the timer by writing 1 to bit zero of the ctrl register, write 1 to bit one to stop it.

Time elapsed can be calculated using:

time = clock_freq / (prescaler * timer)