Hi John, I am glad to see your updated proposal moving in the right direction in accommodating some of the feedback at the face to face meeting. Yet I see several important issues we need to address. I inserted my comments and questions below. Let's discuss these at the next meeting. Shabtay ________________________________ From: owner-itc@eda.org [mailto:owner-itc@eda.org] On Behalf Of John Stickley Sent: Tuesday, February 21, 2006 9:49 AM To: 'itc@eda.org' Cc: brian_bailey@acm.org Subject: updates to pipes proposal: merging of of fifo and pipe interfaces into unified pipe interface Greetings ITC Techies, As a follow up to the face-to-face two weeks ago, I've been busy incorporating some of the good suggestions at that meeting. One major thing I heard was some disappointment that the non-blocking fifo interface was not congruent with the pipes interface in terms of handling data shaping, variable length messaging. Initially I had thought there were some complications with combining data shaping in non-blocking interfaces. However, the more I thought about it the more I realized that we can Plus I agree that unifying the two would remove the complication of two separate use models - one for TLM/FIFO applications and the other for streaming/PIPE applications. We can still have two use models but at least a unified interface. [Shabtay] Glad to see that you reached these conclusions in line with the feedback provided at the meeting. Toward that end, I've made some improvements to the current proposal and have been able to qualify these in the prototype. Here is a summary of the changes: 1. Merging of FIFO and PIPE interfaces I've merged dpi_fifo non-blocking calls into dpi_pipe calls. Now the dpi_pipe interface supports the full blocking streaming calls and data shaping features just as it had before. Plus it now has a thread-neutral non-blocking interface as well. The non-blocking send() and receive() calls take the same argument profiles as the blocking ones so that data shaping is still supported. ---------------------------------------------------- Blocking (thread-aware calls): ---------------- C side Data transfer ops: dpi_pipe_c_send() dpi_pipe_c_receive() dpi_pipe_c_flush() ---------------- HDL side Data transfer ops: dpi_pipe_hdl_send() dpi_pipe_hdl_receive() dpi_pipe_hdl_flush() ---------------------------------------------------- Non-blocking (thread-neutral calls): ---------------- C side Data transfer ops: dpi_pipe_c_try_send() dpi_pipe_c_try_receive() dpi_pipe_c_try_flush() [Shabtay] You placed the last try_flush call under data transfer operation, but it is not clear that this call is doing anything. What are the semantics that you see for dpi_pipe_c_try_flush()? Do you distinguish between "can flush be issued' and "has the buffer been flushed"? More on that in item 4. Query ops: dpi_pipe_c_can_send() dpi_pipe_c_can_receive() Notify ops: (dpi_pipe_notify_ok_to_send)() (dpi_pipe_notify_ok_to_receive)() ---------------- HDL side Data transfer ops: dpi_pipe_hdl_try_send() dpi_pipe_hdl_try_receive() dpi_pipe_hdl_try_flush() Query ops: dpi_pipe_hdl_can_send() dpi_pipe_hdl_can_receive() Notify ops: dpi_pipe_hdl_notify_ok_to_send() dpi_pipe_hdl_notify_ok_to_receive() 2. Notify callbacks now dynamic on the C side Per had commented at the face-to-face that the notify callbacks were hard coded function names and questioned if we should make them function pointers instead. After exploring this more, it became clear that the fixed named callbacks do not allow much flexibility in terms of implementing higher thread-aware interfaces on top of the thread-neutral calls. For example you might want one function if you're using TLM proxies but another if you're using blocking DPI ops directly. To accommodate this, it turns out to be a lot more flexible if the notify callback can be changed to different functions on a pipe by pipe basis. For this reason I've changed the notify callback to be programmable on the C side. User's will never really need to deal with these complications since they will tend to use higher level blocking calls or TLM interfaces. So this is a complication that can be potentially limited to the implementor not the user. Nonetheless I think it makes sense to make the underlying API a clear part of the standard for the implementor. To support the programmable notify callbacks two functions were added to set a callback pointer and context and to retrieve context: typedef void (*dpi_pipe_notify_callback)( void *context ); // input: C model context void *dpi_pipe_get_notify_context( void *pipe_handle ); // input: pipe handle void dpi_pipe_set_notify_callback( void *pipe_handle, // input: pipe handle dpi_pipe_notify_callback notify_callback, // input: notify callback function void *notify_context ); // input: notify context The notify callback itself is now passed the context directly which is more efficient (no longer has to do a lookup using svGetScope()/svGetUserData()). The attached examples show how these calls are used. 3. Pipe handles used in place of pipe IDs on the C side Another comment that was made a few weeks ago is that it is somewhat awkward to set the scope before each call to a pipe on the C side. It turns out, this requirement also can make implementations less efficient. I'm now proposing that we replace the pipe-id argument to all C-side calls with a pipe_handle argument instead. The pipe handle can be derived once at initialization time and reused many times without having to set scope each time and requiring the internal implementation to do a lookup based on the scope and the pipe ID to retrieve the internal data structure associated with a pipe. Doing this not only made the user application code a lot cleaner looking but made the implementation more efficient as well (fewer lookups and pointer indirections on each call). To faciliate pipe handles, a new call is added to retrieve a pipe handle for a given DPI scope and pipe ID: void *dpi_pipe_c_handle( // return: pipe handle svScope hdl_context, // input: HDL context int pipe_id, // input: intra-module pipe identifier svBit input_or_output ); // input: 1 for input pipe, // 0 for output pipe [Shabtay] The handle idea is good and I agree with your considerations for providing it. However, I am trying to figure out how the test can obtain a handle unless it was provided by the proxy model to the test. If the proxy model did not provide a method returning a handle to the test, I don't see how the test could obtain one. Do you agree and do you have a suggestion to address this? 4. Thread-neutral calls to support blocking flush op We may want to re-think this a bit but this is what I have for now. Since flush is, by definition, a blocking operation, it is thread-aware. To be consistent with providing thread-neutral API support for implementation of all blocking calls, it stands to reason we need dpi_c/hdl_try_flush() calls to compliment the dpi_c/hdl_flush() calls. So I've added this to the API. There are a couple of other possible options for this. [Shabtay] This area indeed requires some thought as I am not sure that one method addresses what is needed. In addition, flush was defined as global function. I am not clear if your intent that dpi_c/hdl_try_flush() will only be implemented at a single pipe granularity of if you intent that it will monitor status on issue command that will apply to multiple pipes. Again, please clarify the semantics of dpi_c/hdl_try_flush() in the context of single and multiple pipes. 5. Automatic flush-on-eom Cadence suggested that, on a pipe-by-pipe basis, that there be a means to enable automatic flush when eom is specified. The committee agreed that this would be useful. A new call is added to specify automatic flush-on-eom mode for a pipe designated by a given handle. This mode configuration call is always initiated only on the C side (at initialization) for both input and output pipes: void dpi_pipe_set_eom_auto_flush( void *pipe_handle, // input: pipe handle svBit enabled ); // input: enable/disable [Shabtay] Your suggestion using the handle is in line with our thinking and specifically it simplifies things quite a bit (hopefully addressing Duain's concern expressed at the meeting). We need to settle several issues: 1. The default setting during bring up. My recommendation is for eom_auto_flush to be enabled by default to insure correct functionality. 2. We need to provide control to the test to set this mode w/o relying on the proxy model. It can yet be done using handles that should be obtained by the test. This coincides with my comment embedded in 3. 3. Need to define: what are the synchronization semantics in eom_auto_flush mode wrt to buffer size? I would expect that HW side buffer full/empty will not yield an implicit flush in this mode. Only explicit call of flush will be honored in this mode. Is this how you see it? 6. Limitless transaction sizes on the C side for data shaping At the face-to-face Shabtay expressed some disappointment that for data shaping funnels, the input transaction from the C side is limited in size to the width of the pipe as statically specified on the HDL side. Happily it turns out this is not true ! Since svBitVecVal arrays can be essentially unbounded, using data shaping (funnel) an arbitrarily large number of elements can be sent from or received to the C side in a single call. [Shabtay] I don't recall raising an issue about SW side wrt HDL side limitation, (did I??), but in any case this is a useful clarification. Only on the HDL side do we have a practical limitation on the number of elements that can be received or sent on any given call. As before, this is equal to the size of the statically declared data arguments on the HDL side. [Shabtay] The following comment still triggers the following issues: 1. Assume we agree that the buffer size on the HDL side is larger than the largest element, but yet smaller than 2 elements. Assume the SW side producer delivered a transaction (by Cadence definition..) composed of two elements. Assume the consumer call dpi_pipe_hdl_receive is asking for 2 elements. Will the function return with one element or 2 elements in this case? 2. Assume the HW side producer is delivering a variable length transaction composed of n elements, where n is determined at runtime. Once the last element is sent it issues eom. How would the consumer know how many elements it should read given that it doesn't know the length of the transaction upfront when calling dpi_pipe_c_receive? 3. Assume I have enabled Automatic flush-on-eom on a pipe. Shouldn't we offer an option for the consumer to block until eom is issued? The fundamental issue that I yet see missing in the proposal is native variable length message support using reactive semantics. The simplest use model it will address is transaction level exchange (start -> eom) w/o the consumer having to deal with aggregation of elements and w/o having to consider any HW side buffer allocation limitation. I've attached header files for the new calls for both the HDL and C sides. I've attached a simple example of blocking call implementations for both the C and HDL side using the thread-neutral interfaces described above. (For HDL side example see dpi_pipes.vh, for C side example see dpi_pipes_sysc.cxx). I've also attached the revised example of the TLM proxy model that is currently in the appendix of the working document. I'm ready to make these detailed updates to the working document but I want to make sure I have some degree of buyin. I can also update the distributed example to reflect the latest changes. I really think with this proposal I've addressed many of the concerns raised about pipes at the face-to-face and, with the committee's cooperation, I'd like incorporate these changes into the working document ASAP. -- johnS This email may contain material that is confidential, privileged and/or attorney work product for the sole use of the intended recipient. Any review, reliance or distribution by others or forwarding without express permission /\ is strictly prohibited. If you are /\ | \ not the intended recipient please | \ / | contact the sender and delete / \ \ all copies. /\_/ K2 \_ \_ ______________________________/\/ \ \ John Stickley \ \ \ Principal Engineer \ \________________ Mentor Graphics - MED \_ 17 E. Cedar Place \ john_stickley@mentor.com Ramsey, NJ 07446 \ Phone: (201) 818-2585 ________________________________________________________________Received on Tue Feb 28 15:13:24 2006
This archive was generated by hypermail 2.1.8 : Tue Feb 28 2006 - 15:14:19 PST