Hold Time Check Using a Procedure

A

Anand P Paralkar

Hi,

I am trying to implement a hold time check using a concurrent procedure
statement. In the procedure, I use a variable of type time
(last_clk_rising) to store the time value at which the previous rising
edge of clock has occurred.

If I specify a initial/default value for that variable (last_clk_rising)
(say to 0 ns), every time the procedure is executed, the variable
(last_clk_rising) is reset to the initial value (0 ns) so; I loose the
time value at which the previous rising edge of clock has occurred.

However, if I do not specify the initial/default value for that variable
(last_clk_rising), the first time the procedure executes, the variable has
a huge negative value and the statement:

now - last_clk_rising

gives rise to an integer overflow error in the simulator.

Either way, the procedure does not work correctly. Any suggestions on
how I could perform the hold time check in the procedure?

(Please see the code below for more specific details.)

Thanks,
Anand


-----------------------------------------------------------------------
library ieee; use ieee.std_logic_1164.all;

entity tb_hld_chk_proc is
end entity tb_hld_chk_proc;

architecture test of tb_hld_chk_proc is

procedure hld_chk_proc (signal clk : in std_logic;
signal data : in std_logic;
constant tH : in time) is
variable last_clk_rising : time; -- **** Do not set default value.
begin
if (clk'event and clk = '1') then
last_clk_rising := now;
end if;
if (data'event) then
report ("Clock rising edge at " & time'image(last_clk_rising));
report ("Data edge at " & time'image(now));
assert (now - last_clk_rising >= tH) -- **** First evaluation causes
report ("Hold time violation!") -- **** integer overflow.
severity warning;
end if;
end procedure hld_chk_proc;

signal datain, clkin : std_logic;
constant holdtime : time := 5 ns;
begin

stimulus : process is
begin
wait for 10 ns;
clkin <= '0'; datain <= '0';
wait for 10 ns;
clkin <= '1'; wait for 10 ns; datain <= '1';
clkin <= '0'; wait for 10 ns;
clkin <= '1'; wait for 4 ns; datain <= '0';
wait for 10 ns;
clkin <= '0';
wait;
end process stimulus;

chk_hld : hld_chk_proc (clkin, datain, holdtime);

end architecture test;
---------------------------------------------------------------------------
 
E

Egbert Molenkamp

Anand P Paralkar said:
Hi,

I am trying to implement a hold time check using a concurrent procedure
statement. In the procedure, I use a variable of type time
(last_clk_rising) to store the time value at which the previous rising
edge of clock has occurred.

If I specify a initial/default value for that variable (last_clk_rising)
(say to 0 ns), every time the procedure is executed, the variable
(last_clk_rising) is reset to the initial value (0 ns) so; I loose the
time value at which the previous rising edge of clock has occurred.

In your solution the procedure is executed if data or clk is changed and you
want to remember to value
of the variable in the procedure.

Remember that the concurrent procedure call:
chk_hld : hld_chk_proc (clkin, datain, holdtime);

is equal to:

process
begin
chk_hld : hld_chk_proc (clkin, datain, holdtime);
wait on clkin,datain;
end process;

This means that each time the procedure is executed the procedure is called
and space is created for the variable.
So a solution is only suspend execution of the procedure. That is easy!

procedure name (...)
variable last_clk_rising : time := 0 ns; -- YES !!!
begin
LOOP
your code here of the procedure
WAIT ON data, clk;
END LOOP;
end ;

After the procedure is executed it will suspend execution at the wait
statement. If data or clk is changed it will
resume excution and will indeed remember the value of the variable (only the
first time last_clk_rising is 0 ns)!
Give it a try.

Egbert Molenkamp

Maybe you could also use the attibute 'LAST_EVENT .
 
R

Renaud Pacalet

Anand said:
Hi,

I am trying to implement a hold time check using a concurrent procedure
statement. In the procedure, I use a variable of type time
(last_clk_rising) to store the time value at which the previous rising
edge of clock has occurred.

If I specify a initial/default value for that variable (last_clk_rising)
(say to 0 ns), every time the procedure is executed, the variable
(last_clk_rising) is reset to the initial value (0 ns) so; I loose the
time value at which the previous rising edge of clock has occurred.

However, if I do not specify the initial/default value for that variable
(last_clk_rising), the first time the procedure executes, the variable has
a huge negative value and the statement:

now - last_clk_rising

gives rise to an integer overflow error in the simulator.

Either way, the procedure does not work correctly. Any suggestions on
how I could perform the hold time check in the procedure?

You could use LAST_EVENT and LAST_VALUE attributes. In a process:

process(datain)
begin
assert clkin'last_event >= tH or clkin'last_value = '1'
report "Hold time violation!"
severity warning;
end process;

In a procedure it's more elegant but less efficient as you'll resume it
on clk events, which is useless:

procedure hld_chk_proc (signal clk : in std_logic;
signal data : in std_logic;
constant tH : in time) is
begin
if data'event then
assert clk'last_event >= tH or clkin'last_value = '1'
report "Hold time violation!"
severity warning;
end if;
end procedure hld_chk_proc;

Best regards,
--
Renaud Pacalet, GET/ENST/COMELEC/SoC
Institut Eurecom BP 193, 2229 route des Cretes
F-06904 Sophia-Antipolis Cedex
Tel : +33 (0) 4 9300 2770
Fax : +33 (0) 4 9300 2627
Fight Spam! Join EuroCAUCE: http://www.euro.cauce.org/
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,997
Messages
2,570,240
Members
46,828
Latest member
LauraCastr

Latest Threads

Top