Usage of string to force/probe singals of an instance

I need to check clock periods of various clocks of an instance in a verilog design through an OVM SV environment.

So i want to create a task that will just take clock name as input and calculate its clock and compare with expected clock period (also given as input to task) and flag an error in case of mismatch.

in this task if i want to probe the clock whose path is created as a string (path of instance in which clock is present) concatenated with the clock name (task’s input).

I created a task below but I get compiler error. Can you suggest any alternative way to achieve what i want ?

task(string clk_name, real expected_clk_period);
string str;
real period
str = {“top.insta.instb.instc.”, clk_name};
time start_time, end_time;
start_time = $time;
@ (posedge (str)); // compile error at this line **ncvlog EXPCPD : Expecting a valid compiler directive** @ (posedge (str)); // compile error at this line ncvlog EXPCPD : Expecting a valid compiler directive
end_time = $time;
period = end_time -start_time;

endtask

You cannot use a string to reference a signal. You can pass a reference to a signal using a ref argument.

task check_period(ref logic clk, input real expected_period);
real period;
real start_time, end_time;
  start_time = $time / 1ns; // normalize to ns;
  repeat (2) @(posedge clk);
  end_time = $time / 1ns; // normalize to ns;
  period = end_time - start_time;
  assert (period == expected_period*1ns); // may need to account for rounding errors
endtask

Then call the task as follows in your procedural code

period_check(top.insta.instb.instc.clk,10);

clk must be a variable, not a wire. if it is a wire, then you’ll need to assign it to a variable first.

logic clk;

assign clk =
top.insta.instb.instc.clk;

period_check(clk,10);

Thanks dave, it works fine. I actually wanted the task to be inteligent enough to not hang if the clock is either 0 or 1.
So i had used the following way

fork
begin
repeat(2) @(posedge clk);
end_time = $time / 1ns; // normalize to ns;
period = end_time -start_time;
ovm_info(....) end begin #50us; period = 0; ovm_error(…)
end
join_any

I get a syntax error for this saying that I can not have a reference variable inside a fork join block.
What would be alternate way of doing this ?

In reply to dave_59:

Hi Dave,

I am using such a task in which I pass the reference of a signal as you have passed in above example. Now, as an add-on I need to make this task as a library element, So that I can use it for several other variables. For that I need to make it independent of the bit width of the variable. which is 1 in the case you’ve mentioned.

What I mean is I can’t use above syntax for a task which I may be using to assign values to variables of different widths.

Is there anything that could be done.

Thanks in advance.

In reply to praav16:

You can wrap the task as a static method of a parameterized virtual class. See section 13.8 Parameterized tasks and functions of the 1800-2012 LRM.

In reply to dave_59:

Hi Dave, That did the trick. thanks :)