Section 4.9. Using Input Streams


4.9. Using Input Streams

Two operations may be performed on an input stream: an end-of-stream test and a stream read. The end-of-stream test checks to see whether a "close" operation was performed on the stream by the stream writer. It does this by checking the current element at the head of the stream. If this element is determined to be an end-of-stream token, a true value is returned; otherwise, a false value is returned indicating that the stream is open. The co_stream_eos function is nonblocking, and a return value of false does not imply that there is, or will be, more data available.

The co_stream_read function attempts to read the next stream element and blocks if the stream is empty. A read operation on a closed stream returns the value TRue. Thus, the preferred sequence of operations is to describe a stream reading loop:

 err = co_stream_open(input_stream, O_RDONLY, INT_TYPE(32)); while(co_stream_read(input_stream) == co_err_none) { . . . // Process the data here } co_stream_close(input_stream); 

When an input stream is closed using co_stream_close, all the unread data in the stream is flushed, and the EOS token is consumed. If there is no EOS in the stream (for example, the writer hasn't closed it yet), co_stream_close blocks until an EOS is detected. Note also that co_stream_close writes the EOS token only when called from the writer process, so it is important not to close a stream from the read side unless the EOS token has been detected.

Checking for End of Stream

The co_stream_eos function returns TRue to indicate that the writer has closed the stream. Once co_stream_eos returns false, all subsequent calls to co_stream_eos return false until the reader closes the stream. Similarly, all subsequent calls to co_stream_read fail with co_err_eos until the stream is closed and reopened for reading.

Efficient Use of Stream Reads

The efficient processing of stream-related data is a key part of programming using Impulse C. There are three possible methods of reading data from streams:

Method 1 (preferred method)
 while(co_stream_read(input_stream) == co_err_none) { ...  // Process the data here } 

Method 2 (acceptable method)
 do {  if (co_stream_read(input_stream,&i,sizeof(i)) == co_err_none) {     ...  // Process the data here  } }  while(!co_stream_eos(input_stream)); 

or the following derivative:

 while ( ! co_stream_eos(input_stream) ) {   if ( co_stream_read(input_Stream, &i, sizeof(i)) == co_err_none ) {      . . .   } } 

Method 3 (less acceptable)
 while(!co_stream_eos(input_stream)) {   co_stream_read(input_stream,&i,sizeof(i));   ...  // Process the data here } 

or the following derivative (which is also less acceptable):

 do {  co_stream_read(input_stream,&i,sizeof(i));    ...  // Process the data here }while(!co_stream_eos(input_stream)); 

As indicated, the first two methods are acceptable, but the third may result in problems during simulation and/or in the generated VHDL and should not be used. (The reason? It's possible that between the call to co_stream_eos and co_stream_read, the stream may be closed by the upstream process. Since method 3 does not check the return value of co_stream_read, the read buffer could contain invalid data.)

Which method you will use depends on the nature of your application, but there are significant trade-offs for processes that will be compiled to hardware. Because each control point in a hardware process will require a full cycle, method 1 is strongly preferred for efficient hardware synthesis. Also, when testing for a condition on the return value from co_stream_read, the condition must be (co_stream_read(...) == co_err_none) as shown.

The best strategy is almost always the first of these three methods. Eliminating the explicit call to co_stream_eos will result in the loop waiting (possibly forever) for the the first data element to appear on the stream and will not result in an additional wasted cycle. If, however, you need to perform conditional read operations or are operating on multiple streams simultaneously, the second method is acceptable as an alternative.



    Practical FPGA Programming in C
    Practical FPGA Programming in C
    ISBN: 0131543180
    EAN: 2147483647
    Year: 2005
    Pages: 208

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net