multiple task 'instances' 
Author Message
 multiple task 'instances'

Hi,

    I'm trying to use Verilog tasks to make my code more structured, but
    am running into a potential limitation - there seems to be no concept
    of multiple 'instances' of a task.  If this seems confusing, what I'm
    running up against is the way Verilog has only a single copy of all
    task-scoped variables - each caller shares those same variables.  I'm
    looking to have separate ('per-instance') copies of those variables.

    So my question is, is there a way to have multiple instances of a
    task, each with their own independent task variables?  Can one have a
    vector of tasks?  If not, then is there a conventional way to do this,
    say keeping external task 'state' in an array (per instance) and pass
    that state as an inout variable?

Regards,
Eric



Sat, 07 Jan 2006 00:48:38 GMT  
 multiple task 'instances'

Quote:

>     I'm trying to use Verilog tasks to make my code more structured, but
>     am running into a potential limitation - there seems to be no concept
>     of multiple 'instances' of a task.

Actually, there is a concept of multiple instances of a task: there is
a separate instance of the task in each instance of the module that
declares it (just as there is a separate instance of a reg in each
instance of the module that declares it).  But there is not a separate
instance of the task for each place that calls it within a module.
That means that multiple processes in the same module that call the same
task at overlapping times will be sharing the same variables.

Quote:
>     If this seems confusing, what I'm
>     running up against is the way Verilog has only a single copy of all
>     task-scoped variables - each caller shares those same variables.  I'm
>     looking to have separate ('per-instance') copies of those variables.

Understood.

Quote:
>     So my question is, is there a way to have multiple instances of a
>     task, each with their own independent task variables?  Can one have a
>     vector of tasks?  If not, then is there a conventional way to do this,
>     say keeping external task 'state' in an array (per instance) and pass
>     that state as an inout variable?

Verilog-2001 adds re-entrant tasks and functions, which allocate a new
copy of each variable whenever execution enters its scope, and deallocate
it when execution exits the scope.  These variables are initialized to the
default initialization value (X for most variables) when allocated.  Since
there is not guaranteed to be one instance of each variable, these variables
cannot be referenced by hierarchical names, unlike normal task variables.
There are also some other restrictions on what can be done with them.

Re-entrant tasks and functions are declared by putting the word "automatic"
after the keyword "task" or "function" in the declaration.  Whether you
can make use of this depends on whether your tools support this particular
Verilog-2001 feature.  NC-Verilog and BuildGates support it, and I believe
that VCS supports it by now also.

The "vector of tasks" approach could have been done by using a different
Verilog-2001 feature: the generate-for.  However, the standard specifically
made it illegal to put tasks and functions inside generate-for loops, for
no good reason.  At any rate, a tool that supports generates is likely to
support re-entrant tasks and functions already.

The most obvious approach to this using Verilog-1995 would be to put the
tasks into a module, and instantiate the module as many times as you
need instances of the task.  An array of instances could be used to do
this in one instantiation, like your vector of tasks.  Then call the task
using a hierarchical name for the appropriate instance.  This is less
convenient than a re-entrant task, especially if the task needs to access
variables in the instantiating module, but even that can be done by using
hierarchical names in the task (probably of the form of
parent_module_name.variable_name, rather than the more usual
parent_instance_name.variable_name, so that it doesn't care about the
instance name of the module using it).



Sat, 07 Jan 2006 06:36:27 GMT  
 multiple task 'instances'
Steven,

    Thank you for the suggestion - I used the latter one (an array of
    instances of modules, which contain tasks), but I must have done something
    wrong - it requires me to put a _literal_ number in to index the
    particular module instance:

    module HasProblems;     // much simplified
        integer i;

        // declare array of Channel modules
        Channel channels ['NUM_CHANNELS - 1:0](initializers);

        always begin
            for (i = 0 ; i < `NUM_CHANNELS ; i = i + 1) begin
                channels[i].rx(buf);        // Verilog complains here
            end
        end
    endmodule

    module Channel(initializers);
        reg rx_state; // this is the per-module variable

        task rx;
            output [31:0] buf;
            begin
                ...
            end
        endtask

    endmodule

    On the line that says 'Verilog complains here' - if I replace 'i' with a
    hard-coded number (e.g. 0), all works fine.  But the a big reason for the
    array was to allow me to put variable array indices in.  Am I doing
    something wrong here?

    The error spit out by NC-Verilog is 'Non-numeric expression in
    instance-select.'  Seems like an integer would be numeric enough for
    me...

    Maybe I should consider myself lucky, a few of the Verilog simulators I
    tried didn't even support arrays of modules :-)

Regards,
Eric

Quote:


>>     I'm trying to use Verilog tasks to make my code more structured, but
>>     am running into a potential limitation - there seems to be no concept
>>     of multiple 'instances' of a task.

[ deleted for brevity ]

[ your suggestion I took: ]

Quote:
> The most obvious approach to this using Verilog-1995 would be to put the
> tasks into a module, and instantiate the module as many times as you need
> instances of the task.  An array of instances could be used to do this in
> one instantiation, like your vector of tasks.  Then call the task using a
> hierarchical name for the appropriate instance.  This is less convenient
> than a re-entrant task, especially if the task needs to access variables in
> the instantiating module, but even that can be done by using hierarchical
> names in the task (probably of the form of parent_module_name.variable_name,
> rather than the more usual parent_instance_name.variable_name, so that it
> doesn't care about the instance name of the module using it).



Sun, 08 Jan 2006 12:39:46 GMT  
 multiple task 'instances'

Quote:

>     Thank you for the suggestion - I used the latter one (an array of
>     instances of modules, which contain tasks), but I must have done something
>     wrong - it requires me to put a _literal_ number in to index the
>     particular module instance:

I'm afraid that is a restriction of arrays of instances.  The standard
actually requires an unsized, unbased decimal number.  It should allow
any constant expression, and I am working on getting it extended.  But
variables cannot be allowed.

Arrays of instances aren't really arrays in the normal sense.  Normal
arrays are homogeneous, i.e. all of their elements are the same size
and type.  This allows them to be indexed by variables at runtime,
because it isn't important to know which one will be selected since
we still know at compile time what it will look like.  

Different instances in an instance "array" are not necessarily
homogeneous.  Defparams can customize each one with different parameter
values, resulting in different object sizes in each one.  Other kinds
of hierarchical references, or different connections to their ports can
also create internal differences between instances. This gets even
worse in Verilog-2001, since conditional generates can cause the
contents of different instances to be completely different.  These
differences make it impractical to wait until runtime to determine
which instance is being referenced.

In most cases, being unable to do this shouldn't affect a design
that needs multiple task instances.  A loop can only be used to
call multiple tasks sequentially, with one task returning before
the next one is called.  In this situation, there should be no
need for multiple task instances.  Multiple task instances are
needed when there are multiple processes executing the task at
the same time, which would interfere with each other by sharing
the same variables.  If there is no overlap in execution (as
there isn't with iterations of a loop), a single task should
suffice.

So I am not clear what your situation is, and what you are trying
to do here.  I assumed that you really needed multiple task
instances due to overlapping execution.  If you just need to have a
task operate on a different state variable in different calls,
you can pass an element of an array of state variables in and out
via an argument of the task.  I am guessing that this is the case,
since you chose to use the multiple-instance approach, rather than
the reentrant task solution.

Note that a Verilog-2001 generate-for loop could generate multiple
processes that could call a task at the same time.  But in that
case the loop index would be treated as a constant in each instance
of the loop body, and could be used as an index in an array of
instances (assuming the extension to allow any constant expression
as an instance array index).



Mon, 09 Jan 2006 08:12:08 GMT  
 
 [ 4 post ] 

 Relevant Pages 

1. ordering multiple instances of verilog task

2. use 'defparam' in a verilog task

3. Elegant 'abort' of sleeping task

4. Exception argument is of Type 'instance'?

5. Invoking a subclass's method on its superclass's instance

6. 'Dynamic' class instances

7. the 'in' operator and class instances

8. the 'in' operator and class instances

9. DerivVar instance has no attribute '__float__'

10. XmlprocDriver instance has no attribute 'feed'

11. SmalltalkV/Mac V.2 'Has Instances'

12. Using DLL's or CIN's to talk to multiple Ethernet cards

 

 
Powered by phpBB® Forum Software