![Xilinx Virtex-II Pro PPC405 User Manual Download Page 218](http://html1.mh-extra.com/html/xilinx/virtex-ii-pro-ppc405/virtex-ii-pro-ppc405_user-manual_3410279218.webp)
526
March 2002 Release
1-800-255-7778
Virtex-II Pro™ Platform FPGA Documentation
Chapter 8:
Timer Resources
R
Computing Time of Day
Calculating the time-of-day from the current time-base value requires the following
information:
•
A fixed-reference time.
•
The equivalent time-base value corresponding to the fixed reference time.
•
The system-dependent time-base update frequency.
Following is an algorithm that calculates the time-of-day. Awkward 64-bit division is
avoided by assuming the algorithm is initiated by a time-keeping interrupt
at least
once per
second. This periodic interrupt can be triggered by the fixed-interval timer or some
external-interrupt device. The algorithm uses the following variables:
•
billion
—one billion (1,000,000,000).
•
posix_tb
—A 64-bit variable containing the last value read from the time base.
•
posix_sec
—A 32-bit variable containing the number of seconds that have elapsed since
the fixed-reference time. When timekeeping actually begins, this variable must be
initialized with the number of seconds that have elapsed from the fixed-reference
time. For example, assume:
-
The fixed-reference time is 12:00:00 AM, January 1, 2001
-
The equivalent time-base value for the fixed-reference time is 0.
-
Timekeeping begins at 12:00:00 AM, July 1, 2001.
Using these parameters, this variable is initialized with 0x00EE_9F80, which
represents the number of seconds that have elapsed since the fixed-reference time.
•
posix_ns
—A 32-bit variable containing the number of nanoseconds that have elapsed
since the last time-of-day calculation.
•
ticks_per_sec
—The number of times the time base increments per second. In this
example, the processor clock is 300 MHz and the time base is incremented once every
32 processor clocks. Thus, the variable is set to 0x8F_0D18 (300 MHz
÷
32
=
9,375,000).
•
ns_adj
—The number of nanoseconds per increment of the time base. In this example,
the variable is set to 0x6B (
billion
÷
ticks_per_sec
=
107).
The following code sequence implements the algorithm:
loop:
mftbu
r
x
! Read TBU.
mftb
r
y
! Read TBL.
mftbu
r
z
! Read TBU again.
cmpw
r
z,
r
x
! Check for TBU rollover by comparing old and new.
bne
loop
! Read the time base again if a rollover occurred.
! We now have a consistent 64-bit time base in
r
x and
r
y.
lwz
r
z, p4 ! Load
r
z with the low-32 bits of posix_tb.
sub
r
z,
r
y,
r
z
!
r
z = change in TB since last read.
lwz
r
w, ns_adj
! Load the number of ns per time-base increment.
mullw
r
z,
r
z,
r
w
!
r
z = number of elapsed ns since TB last read.
lwz
r
w, posix_ns
! Load elapsed ns since last computation.
add
r
z,
r
z,
r
w
!
r
z = new ns since last computation.
lwz
r
w billion
! A billion nanoseconds is 1 second.
cmpw
r
z,
r
w
! Are new elapsed ns more than 1 second?
blt
nochange
! Branch if not.
sub
r
z,
r
z,
r
w
! Subtract 1 second from elapsed nanoseconds.
lwz
r
w, posix_sec
! Load the number of elapsed seconds.
addi
r
w,
r
w, 1
! Add 1 second.
stw
r
w, posix_sec
! Store the number of elapsed seconds.
nochange:
stw
r
z, posix_ns
! Update elapsed ns.