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? PerReceived 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