Scalar Memory Type

When the pointer argument is referencing a single element scalar, or the global variable is of a scalar type, this means the external memory has only one element. In these cases, the HLS module uses the scalar memory interface, which can be thought of as a special memory interface that has no address port and expects a 0-cycle read latency.

Note that specifying an array / struct data type to be partitioned into individual elements using #pragma HLS memory partition (see Memory Partitioning for details) can create scalar interfaces. The following example has an array interface array that is partitioned completely into 10 elements, each element is a scalar memory.

int kernel(int array[10]) {
#pragma HLS function top
#pragma HLS memory partition argument(array) type(complete)
  ...
}

The table below lists the associated RTL module ports for each scalar memory interface. Some signals are not available when the memory is read-only or write-only, i.e., when the top-level function (and its descendant functions) never write to or read from the memory.

Port NameDirectionDescription
<ARG_NAME>_read_dataINThe input value of the argument (n/a for write-only memory). The signal is not sampled at the start of circuit execution. The external logic needs to keep the signal stable and valid at any given time during the circuit execution.
<ARG_NAME>_write_dataOUTThe output value of the argument (n/a for read-only memory). The write_data port has valid value only when the write_en signal is high. This port is not available if the SmartHLS circuit never writes to the pointer argument (or global variable).
<ARG_NAME>_write_enOUTIndicates the write_data is valid (n/a for read-only memory). This port is not available if the SmartHLS circuit never writes to the pointer argument (or global variable).

Note that SmartHLS circuit expects a 0-cycle read latency. This is, the <ARG_NAME>_read_data port is expected to always hold the valid data for the pointer argument such that the SmartHLS circuit can use its value at any time.

One way of using the scalar memory interface is to connect the scalar memory interface to a register outside of the SmartHLS module. The read_data port can be connected to the register itself. The write_en and write_data ports will be used to update the register.

The timing diagram gives an example of how the scalar memory interface would behave when it is connected to an external register. Initially the external register is holding a value of "D0" and providing the value to the arg_read_data port. At Cycle a, the top-level module writes to the register by asserting arg_write_en and setting arg_write_data to "D1". Then at the next cycle, Cycle b, the register value is updated, and the arg_read_data is also immediately updated to the new value.

Note that the scalar memory interface does not always have to be connected to an external register. One use case of the scalar memory interface could be to connect the arg_read_data port to an input signal that is changing while the SmartHLS circuit runs, allowing the SmartHLS circuit to read the up-to-date value from the input. Typically, the pointer argument is read-only by the SmartHLS circuit in such case.

Similarly, the arg_write_data can be connected to an output that needs to be updated in real-time. In this case, the pointer argument is normally only written to by the SmartHLS circuit (with no read access).