realazing a watch

M

Manfred Balik

Guest
Please can someone help me:

I have realized a watch viewing nanoseconds and seconds from a 31.611 MHz
clock (it's the only one in the design).
For high precision I count in femtoseconds - out of them, I calculate
nanoseconds and seconds.

Unfortunately the code I wrote is to slow in the Altera APEX 20KE I use

Please can someone help me to improve the code
Thanks, Manfred


LIBRARY ieee;
USE ieee.std_logic_1164.all;

ENTITY timestamp_counter IS
PORT
(
clk : IN STD_LOGIC;
reset : IN STD_LOGIC;
time_sec : OUT STD_LOGIC_VECTOR(0 to 30);
time_nanosec : OUT STD_LOGIC_VECTOR(0 to 29)
);
END timestamp_counter;

ARCHITECTURE timestamp_counter_architecture OF timestamp_counter IS

CONSTANT clock_cycle_femtosec : integer := 31_634_558; -- 1 clock cycle in
femto seconds
-- 31.611 MHz == 31,634 557 590 712 ... ns
-- => Error: -4.09288E-16 s/cycle
-- = -1.2938E-8 s/sec
-- = -7.7628E-7 s/min
-- = -4.65768E-5 s/h
-- = -1.1178432E-3 s/day
-- = -0,408012768 s/year (-0,4091306112 s/leap year ;-))

FUNCTION int2slvect(int_value : INTEGER; size : INTEGER) RETURN
std_logic_vector;
FUNCTION int2slvect(int_value : INTEGER; size : INTEGER) RETURN
std_logic_vector IS
VARIABLE result : std_logic_vector(0 TO size-1);
BEGIN
FOR i IN 0 TO size-1 LOOP
IF ((int_value/(2**i)) REM 2) = 0 THEN
result(i) := '0';
ELSE
result(i) := '1';
END IF;
END LOOP;
RETURN result;
END int2slvect;

BEGIN

timestamp_counter_process : PROCESS (clk,reset) IS
VARIABLE sec: integer RANGE 0 TO 2_147_483_647;
VARIABLE nanosec: integer RANGE 0 TO 1_000_000_050;
VARIABLE femtosec: integer RANGE 0 TO 33_000_000;
VARIABLE read_timespec_prev: std_logic;
BEGIN
IF reset = '1' THEN
sec := 0;
nanosec := 0;
femtosec := 0;
read_timespec_prev := '0';
timespec_sec <= (OTHERS => '0');
timespec_nanosec <= (OTHERS => '0');
time_sec <= (OTHERS => '0');
time_nanosec <= (OTHERS => '0');
ELSIF clk'event AND clk = '1' THEN
femtosec := femtosec + clock_cycle_femtosec;
IF femtosec > 31_999_999 THEN
nanosec := nanosec + 32;
femtosec := femtosec - 32_000_000;
ELSIF femtosec > 30_999_999 THEN
nanosec := nanosec + 31;
femtosec := femtosec - 31_000_000;
END IF;
IF nanosec > 999_999_999 THEN
sec := sec + 1;
nanosec := nanosec - 1_000_000_000;
END IF;
time_sec <= int2slvect(sec,31);
time_nanosec <= int2slvect(nanosec,30);
END IF;
END PROCESS timestamp_counter_process;

END timestamp_counter_architecture;
 
I have realized a watch viewing nanoseconds and seconds from a 31.611 MHz
clock (it's the only one in the design).
For high precision I count in femtoseconds - out of them, I calculate
nanoseconds and seconds.
You can make big adders/counters go as fast as you want. google for
carry-save-adder or carry-save-counter

If all you want is seconds, I'd make a big adder and bump it by X each
clock tick. The top bits would be seconds. Adjust X to give the right
answer. Pick the number of fractional bits to match the accuracy of
your crystal.

If you need seconds and nanoseconds things get more complicated. Are
you feeding a display? If so, it might be simplest overall to count/add
in decimal rather then binary. If you only need 10ths/100ths of a second,
I'd probably use a binary adder for the lower bits and a decimal
counter for the rest.

Note that with carry-save you have the possibility for things to get
out of phase. It will "count" 1.9 1.0 2.0. There is a carry pending
on the middle case, but you can't see it. It only lasts 1 clock tick.

You can fix that by adding a pipeline (delay) stage on the lower
digit. (and more delay stages as needed) Or ignore that if it
doesn't matter for your application. (If you are just driving
a display, your eye will never notice.)



ELSIF clk'event AND clk = '1' THEN
femtosec := femtosec + clock_cycle_femtosec;
IF femtosec > 31_999_999 THEN
nanosec := nanosec + 32;
femtosec := femtosec - 32_000_000;
ELSIF femtosec > 30_999_999 THEN
nanosec := nanosec + 31;
femtosec := femtosec - 31_000_000;
END IF;
IF nanosec > 999_999_999 THEN
sec := sec + 1;
nanosec := nanosec - 1_000_000_000;
END IF;
That looks like software rather than hardware. What do you expect
it to synthise into? I suggest designing the hardware (or at least
sketching it out) with pencil and paper. Then write the VHDL to
get what you want.

--
The suespammers.org mail server is located in California. So are all my
other mailboxes. Please do not send unsolicited bulk e-mail or unsolicited
commercial e-mail to my suespammers.org address or any of my other addresses.
These are my opinions, not necessarily my employer's. I hate spam.
 

Welcome to EDABoard.com

Sponsor

Back
Top