1. Channels & Bus Interfaces Introduction

    Channels & Bus Interfaces Introduction

    Several synthesis and modeling problems become apparent when attempting to use C function calls to describe a hierarchical system. The purpose of channel class is to simplify both synthesis and modeling with a minimal impact on coding style and C simulation performance.

    The first problem is primarily a synthesis problem. To build a streaming interface, you need to be able to guarantee that the data communicated between two blocks is read and written in the same order. Since a channel enforces a FIFO discipline, it guarantees that the hardware can build for streaming interfaces.

    The second problem is that systems are often made up of blocks that run using different amounts of data. The first block in a system might produce data 100 values at a time, while the reader may have been written to consume data 128 elements at a time. Channels automate the connection of these blocks.

    Finally, many systems have feedback and the length of the feedback path must be defined in the C source. Changing the feedback path length during synthesis would result in a design that simulates differently, which would violate the most fundamental rule of Algorithmic Synthesis. Channels provide a way to define a feedback path so it can be easily simulated and synthesized.

    Channel Class Definition

    The fundamental operation that High-Level Synthesis performs is to convert a single-threaded C++ model into a high-performance, multiple-process RTL model. Each hierarchical function in the C++ model becomes a process in the RTL model. To allow for more efficient synchronization of the data among processes, the channel class may be used. The restrictions are necessary to ensure that the C++ model and the RTL model have the same functionality while allowing the RTL to be efficiently implemented.

    The channel class is a C++ template class that enforces a FIFO discipline (reads occur in the same order as writes.) From a modeling perspective, a channel is implemented as a simple interface to the C++ standard queue (std::deque). That is, for modeling purposes, a channel is infinite in length (writes always succeed) and attempting to read from an empty channel generates an assertion failure (reads are non-blocking).

    Within the C++ model, an instance of a channel may be written by a single hierarchical function and read by a single, different, hierarchical function. In the resulting hardware, the FIFO corresponding to a channel will be written from a single process and read by a single process - thus implementing point-to-point communication. For purposes of this discussion, the external world counts as a process. If a channel appears in the top-level interface of a design and is only written by the design, then the external environment is assumed to be the unique reader. Likewise, the external environment is assumed to be the writer of a channel which is only read.

    The channel constructor includes the ability to add a set of values that are read before the inputs to the channel are read. This is most commonly used to set the size of the feedback path, but also has other applications in the feed-forward path to control the ramp-up of the system.

    Example

    Consider an example where we have a simple block function that that reads the data from an input stream, and simply writes it back to an output stream. The function defines two channels of datatype int. Member functions are used to perform channel read and channel write operations.

    #include <ac_channel.h>
    void block(ac_channel<int > &din, ac_channel<int > &dout)
    {
     int temp = din.read();
     dout.write(temp);
    }

    These functions can be synthesized into hardware. All constructor member functions are also synthesizable.

    Bus Interfaces

    HLS enables implementation of various bus protocols and interfaces such as AXI, AXI4, PCIe etc. to ensure seamless integration of hardware accelerators with existing software systems. The bus protocols and interfaces are defined using #pragmas and directives.

    AXI4 Streaming Interface

    HLS provides streaming interfaces that implement AXI4-Stream protocol as master to slave connections. Interface signals include the primary data signal TDATA, the sideband signal TUSER, the handshake signals TREADY/TVALID and the end-of-packet signal TLAST. Structs are used to represent AXI4 data.

    AXI4 Master Interface

    HLS provides components that implement a limited AXI4 Master protocol as Master to Slave connections. Data is read and/or written to properly implement AXI4 slave memory as the system interface. These components provide a variety of mechanisms to configure system address space and burst sizes.

    AXI4 Slave Memory Interface

    HLS provides components that implement parameterized memory which interfaces with an AXI4 bus. Data is read and/or written using a properly implemented AXI4 master as the system interface. The component uses compile-time parameters to configure system address space and bus sizes.

    AXI4 Register Interface and DMA

    HLS IO components allow AXI4-Lite slave protocol access to configuration and status interface variables that are simple scalars. Data valid handshaking is used with external output interrupt for notification of new output data.