6.3. Stream and Signal Interfaces
When processes written using the Impulse C libraries are compiled to hardware, HDL files are generated representing (as you have seen) the various processes, streams, and other elements described in the C source files. The generated hardware may represent a complete hardware system (as might be the case when streams connect to an external microprocessor) or may be interfaced to other hardware elements, such as high-speed serial interfaces, through the use of well-defined stream, signal, and memory interfaces.
Depending on the application requirements, stream and signal interfaces may be used to directly connect different hardware processes (for example, to create a system-level hardware pipeline) or may be used to connect hardware processes running in the FPGA with other processes running as software in an embedded FPGA processor. For hardware-to-hardware connections the stream and signal protocols are relatively straightforward and are described in this section. Hardware-to-software connections are somewhat more complex and are specific to the platform being targeted.
If you are using a predefined Impulse platform support package, the required hardware-to-software or hardware-to-hardware stream and signal interfaces will be generated automatically for you. If, however, you are interfacing Impulse C hardware processes to other components of your system (such as external VHDL hardware elements), you will need to study and understand the basic communication mechanisms used to implement streams and signals at a hardware level. Appendix B presents one such example, in which a stream is interfaced to an external hardware component.
Stream and Signal Protocols
The Impulse C compiler uses well-defined protocols when generating hardware interfaces for streams and signals. Figure 6-5 illustrates the relationship between the top-level system and a lower-level component with its associated stream and signal components. As shown in the figure, each stream is generated with one data line and three control lines on its input side and four corresponding lines on its output side. One of the control lines is controlled by the stream (the rdy signal), and one is controlled externally (the en signal) to allow a handshake method of control. The eos control line flows through the stream and indicates to the downstream process that the upstream process has closed the stream (typically by using the co_stream_close function). The data line, which has a width defined by the application programmer, accepts data on the input side of the stream and receives data on the output side.
Figure 6-5. Streams and signals are implemented as components at the top level of the generated HDL.
During operation, a stream generates indications on its rdy lines indicating that the stream is ready for reading (output side) or writing (input side). When rdy is active, the system or the connected process (depending on the direction of the stream) may read or write data from or to the stream by moving data from or to the data lines and then asserting the en signal.
Signals operate in a similar fashion, with the elimination of the eos control line and with different rules regarding how messages are posted. (Write operations on a signal component never block, even if an unserviced message has already been posted to the same signal.)
In the case of a hardware-to-hardware interface (as illustrated in Figure 6-6), the producer and consumer processes share a common stream or signal interface as shown.
Figure 6-6. Multiple hardware processes connected via a shared stream buffer.
Streams Used in Write Mode
When used in write mode (as indicated by the use of O_WRONLY in the co_stream_open function call), stream interfaces are generated with the following ports and corresponding signals:
<stream_name>_rdy : OUT -- Ready to accept data. <stream_name>_en : IN -- Enable write. <stream_name>_eos: IN -- Write is EOS. <stream_name>_data: IN -- Write data.
Streams Used in Read Mode
When used in read mode (as indicated by the use of O_RDONLY in the co_stream_open function call), stream interfaces are generated with these port names and corresponding signal names:
<stream_name>_rdy : OUT -- Data is available. <stream_name>_en : IN -- Enable read. <stream_name>_eos : OUT -- Read is EOS <stream_name>_data : OUT -- Read data.
Signals Used in Post (Write) Mode
When used in write mode (as indicated by the use of the co_signal_post function call), signal interfaces are generated with the following ports and corresponding signals:
<signal_name>_en : IN -- Enable write. <signal_name>_data: IN -- Write data.
Notice that there is no _rdy signal here, which reflects the fact that signal writes (using co_signal_post) are nonblocking operations.
Signals Used in Wait (Read) Mode
When used in wait mode (as indicated by the use of the co_signal_wait function call), signal interfaces are generated with the following ports and corresponding signals:
<signal_name>_rdy : OUT -- Signal is posted. <signal_name>_en : IN -- Enable read. <signal_name>_data : OUT -- Read data.