What should be my approach verifying time constraints in the signals of a interface

I’ve got a HW block with the following interface:
Clock
Data
Pulse A
Pulse B

Now, I’ve already written the code (I’m using a UVM environment) to verify the functionality of a HW block with that interface. However, I now must check for the following timing requirements:

  1. Clock rising to Data Hold time should be at least 10 ns.
  2. Data to Clock rising setup time should be at least 10 ns.
  3. Pulse A should be at least 50 ns
  4. Pulse B should be at least 60 ns
  5. Pulse A rising to Pulse B falling should be at leas 40 ns.

I’ve been reading online and so far I’ve gotten the vague notions that I could use

A) SV functions $setup $hold $setuphold $recovery, etc
B) I could use “checkers” and “bind” them to the interface (Although I could not find any examples on how to write simple checkers or much theory in them)
C) Use (this is very generic) SVA (How, exactly?)

The only thing everything that I’ve read seems to agree on, is the fact that whatever it is I do, it should be in the interface itself. So that is clear.
Could someone, please, provide me with an idea of how I should go about implementing this, and where I can read about whatever SV tools I need for this?

Thanks in advance.

In reply to aarelovich:

You can use assertions for this, I can give you a small example:


  property p_check_hole_time;
   time t1, t2;
   @(posedge clk) (1, t1 = $time) |-> @(posedge clk) (1, t2 = $time) ##0 ((t1 - t2) == 2ns, pass_msg);

  endproperty

Here if you can see I have taken 2 variables t1, t2 inside a assertion and am using to store the time. You can it in a same way in writing a assertion.
Note: this is just a skeleton and its not compile free.

In reply to nikhil_c:

I’m just learning about assertions. Could you clarify, in your above example what ##0 is?

In reply to aarelovich:

The Main use of ##0 is it makes the execution on the sequence in the next region and makes us to remove the race conditions.