CDL Modules
|
Files | |
file | apb_target_rv_timer.cdl |
RISC-V compatible timer target for an APB bus. | |
module apb_target_rv_timer::apb_target_rv_timer | ( | clock | clk, |
input bit | reset_n, | ||
input t_timer_control | timer_control, | ||
input t_apb_request | apb_request, | ||
output t_apb_response | apb_response, | ||
output t_timer_value | timer_value | ||
) |
[in] | clk | System clock |
[in] | reset_n | Active low reset |
[in] | timer_control | Control of the timer |
[in] | apb_request | APB request |
[out] | apb_response | APB response |
[out] | timer_value | RISC-V compatible timer with an APB interface. |
This is a monotonically increasing 64-bit timer with a 64-bit comparator.
The timer has a fractional component to permit, for example, a 'nanosecond' timer that is clocked at, say, 600MHz; in this case the timer is ticked every 1.666ns, and so an addition in each cycle of 0xa to a 4-bit fractional component and a 1 integer component. The timer_control has, therfore, a fixed-point adder value with a 4-digit fractional component.
However, this would actually lead to a timer that would be only 99.61% accurate.
Hence a further subfraction capability is supported; this permits a further 1/16th of a nanosecond (or whatever the timer unit is) to be added for M out of every N cycles.
In the case of 600MHz a bonus 1/16th should be added for 2 out of every 3 cycles. This is set using a bonus_subfraction_numer of 0 and a bonus_subfraction_denom of 2 (meaning for 2 out of every 3 cycles add a further 1/16th).
Hence every three cycles the timer will have 0x1.b, 0x1.b, 0x1.a added to it - hence the timer will have gone up by an integer value of 5ns, which is correct for 3 600MHz clock cycles.
If the control values are tied off to zero then the extra fractional logic will be optimized out.
Some example values for 1ns timer values:
Clock | Period | Adder (Int/fraction) | Subfraction Numer/Denom |
---|---|---|---|
1GHz | 1ns | 1 / 0x0 | 0 / 0 |
800MHz | 1.25ns | 1 / 0x4 | 0 / 0 |
600MHz | 1.66ns | 1 / 0xa | 0 / 2 |
The period should be:
subfraction numer/denum=0/x: (Int + fraction/16)
subfraction numer/denum=M/N: (Int + (fraction+(N-M-1)/N)/16)