Function call nesting

From: Per Bojsen <bojsen_at_.....>
Date: Wed Aug 31 2005 - 20:38:41 PDT
Hi,

on the topic of potentially limiting function call nesting, I'd like
to understand what the fundamental difficulties in implementing higher
levels of nesting are.  I am having trouble seeing where the
difficulties are.  Consider:

  1) An imported function call can be seen as a message sent from
     the HW side to the SW side carrying the input arguments followed
     by a message from the SW side to the HW side carrying output
     arguments and return value.

  2) An exported function/task call can be seen as a message sent from
     the SW side to the HW side carrying the input arguments
     followed by a message from the HW side to the SW side carrying
     output arguments and return value (for functions).

Consider zero-time functions first.  Further consider function call
nesting that does not involve exported tasks/functions indirectly
calling themselves.  When an imported function call happens, the HW
side must stop the clocks until the return value is received.  The
clocks remain stopped for any nested calls, since all functions/tasks
are zero-time.  In this case, arbitrary nesting of function/task calls
should be straightforward to implement.  The implementation needs to
be able to distinguish HW->SW messages as return messages from
exported function/tasks and activation messages from imported function
calls.  Once this is in place, the implementation can support calling
an imported function from an exported function/task.  The converse,
i.e., calling an exported function/task from an imported function is
easier from the SW point of view: just send the exported function
activation message.  Any exported task or function on the HW side will
always be waiting to be triggered.

So, once imported functions can call exported ones and vice versa
any levels of nesting should follow trivially.  Of course, in practice
one will be limited by stack depth, but that is no different from
function nesting in any program.

Now, consider non-zero-time exported tasks.  I can see this case
being tricky.  Consider an imported function that calls a time
consuming exported task.  When the imported function call is
originated, the user clocks must stop.  But when the exported
task is called, the user clocks must be allowed to run, otherwise
the task could not consume time.  If it in turn calls an imported
function, the clocks must be stopped again until the call
returns or it calls another nested time consuming task.  While
the clock control involved here seems tricky, I think it follows
simple rules that should be fairly straightforward to implement.
The only issue is that care must be taken when SCE-MI 1.x clock
control is going on simultaneously.  SCE-MI 1.x clock control
must have higher priority such that a time consuming exported
task call won't turn on the clocks while SCE-MI 1.x clock control
is in effect.

Finally consider recursion in exported functions/tasks.  I think
this is where the real implementation difficulties are.  For
example, assume an exported function fe() is called and that this
function calls an imported function fi() which in turn calls fe().
The problem is that the second call of fe() needs its own copy
of fe()'s private variables and state or it would affect the
state of the parent call of fe().  Hardware has no stack.  To do
this the registers that contain fe()'s state would have to be
replicated in the hardware as many times as the maximum depth
the recursion would reach.  The infrastructure linker has no
chance to determine this because it does not look at the SW side
for one.
 
To summarize, I think arbitrary non-recursive (on the HW side)
nesting with non-time and time consuming tasks is possible to
implement fairly easily.  On the other hand, recursion of
exported tasks is harder to implement at would require user
hints as to how many nesting levels to generate hardware for.
This leads me to the following question: how does a SystemVerilog
simulator handle exported task recursion?  Is it even allowed?
How is the local variable state handled?

Per
Received on Wed Aug 31 20:38:53 2005

This archive was generated by hypermail 2.1.8 : Wed Aug 31 2005 - 20:39:56 PDT