hierarchical signal name as argument to verilog task

Guest
Hi

I am doing a testbench on a design that has multiple sub-blocks. Each
sub-block has a "trig" input, a "done" output and a "data" output. When
trig is asserted for one clock cycle, the done is asserted for one
cycle after a variable number of cycles. During that cycle, "data" has
a valid data. I need to trigger each sub-block multiple times and I am
expecting a fixed sequence of data. I want to verfiy that I am getting
that data.

My plan is to write a generic task that will work for all the
sub-blocks. I want to pass on the hierarchial name e.g
u_subblock1.trig, u_subblock1.done into the following task.

task checkdata;
input trig;
inout(??) done;
inout (??) data;
input refdata;

begin
force trig = 1;
@ ( posedge clk );
force trig = 0;
@ ( posedge clk );
while (!done) @ ( posedge clk );
if ( data !== refdata )
$display ("test failed");
else
$display ("test ok");
end
endtask

I am calling this task from the testbench as follows

checkdata (u_subblock1.trig, u_subblock1.done, u_subblock1.data,
subblk1_refdata1 );
checkdata (u_subblock1.trig, u_subblock1.done, u_subblock1.data,
subblk1_refdata2 );
....
....
checkdata (u_subblock2.trig, u_subblock2.done, u_subblock2.data,
subblk2_refdata1 );
checkdata (u_subblock2.trig, u_subblock2.done, u_subblock2.data,
subblk2_refdata2 );
....
....

Is something like this possible with verilog? Can I use some form of
`define or parameter to achieve this?

Thanks.

-Dipankar
 
This is not possible the way you are trying to do it.

When you pass an argument into a task, you are just copying the current
value
of the actual argument into the formal argument, which is a variable
local to the
task. If the task changes that argument, it is just changing the local
variable. It
has no immediate effect on the actual argument that you passed. If the
argument
is an output or inout, then when you return from the task, the value of
the formal
argument will be copied back out to the actual argument.

To put it another way:
An inout argument uses copy-in-copy-out semantics. Changes to the
formal
argument inside the task will have no effect on the actual argument
until
the task returns. Also, since the argument passing each way is
equivalent
to a procedural blocking assignment, the actual argument must be a
variable.
It cannot be a net, since you cannot assign to a net from procedural
code.

For the same reasons, checking the values of done and data won't work.
They will continue to be copies of the values passed in when the task
was
called. They will not change value when the actuals change value. So
you will never see them change.

The obvious way to do what you are trying to do is to put your task
checkdata into the module definition for u_subblock1 and u_subblock2.
I assume that they are instances of the same module, which makes this
simple, since it is still just a single task declaration. Then the
task can
directly reference the trig, done and data signals in the module
without
passing them as parameters. Your testbench can call a specific
instance
of the task using a hierarchical reference, such as

u_subblock1.checkdata(subblk1_refdata1);
u_subblock1.checkdata(subblk1_refdata2);
....
u_subblock2.checkdata(subblk2_refdata1);
 

Welcome to EDABoard.com

Sponsor

Back
Top