3.5.1.17 Struct Support
(Ask a Question)A C++ struct
is a user-defined data type that is used to group several fields, possibly with different data types. Using struct
allows passing a set of variables around the design together while retaining the readability and accessibility of each of these variables. In this section, we will discuss how interfaces and memories with struct
types are handled in SmartHLS™ including partitioning, packing, and returning by value.
Example
This example will be used in the following sub-sections to show the different interfaces. There are three struct
types in the code below:
Account
: represents a bank account with checking and savings balances.Client
: represents a bank client with an IDid
and an accountacc
. Note thatid
has a 6-bit unsigned integer type to demonstratestruct
packing.UpdateResult
: used as a return type for the top-level functionupdate
to report if the update was completed and the final account balance.
The top-level function update
of the example takes a clients' list clients
, an ID id
and an account balance acc
to be added to the client's balance. It returns UpdateResult
with updated = 1
and the final balance acc
if an account with ID id
is found in the client's list clients
, otherwise it returns updated = 0
.
To demonstrate another advantage of using struct
, Account
has a member function add
that is used to update the balances which makes the code more readable in update
function.
Another function find
is used to search for an account with ID id
in the clients' list. Notice that this function has noinline
attribute. This is intended to demonstrate how struct
types are passed through RTL modules after synthesizing the design.
#include <hls/ap_int.hpp> #include <stdint.h> #include <stdio.h> #include <string.h> #define N 4 using namespace hls; struct Account { uint64_t checking; uint64_t savings; void add(const Account &acc) { checking += acc.checking; savings += acc.savings; } }; struct Client { ap_uint<6> id; Account acc; }; struct UpdateResult { ap_uint<1> updated; Account acc; }; int find(Client clients[N], ap_uint<6> id) { #pragma HLS function noinline for (int i = 0; i < N; i++) if (clients[i].id == id) return i; return -1; } UpdateResult update(Client clients[N], ap_uint<6> id, Account acc) { #pragma HLS function top UpdateResult ret{}; int idx = find(clients, id); if (idx != -1) { clients[idx].acc.add(acc); ret.acc = clients[idx].acc; ret.updated = 1; } return ret; } Client clients[N]; int main() { for (int i = 0; i < N; i++) { clients[i].id = i; clients[i].acc.checking = 0; clients[i].acc.savings = 0; } Account test_acc{100, 100}; int passes = 0; UpdateResult test_ret{}; for (int j = 0; j < N; j++) { test_ret = update(clients, j, test_acc); if (test_ret.updated == 1) { if (clients[j].acc.checking == 100 && clients[j].acc.savings == 100) passes++; } } // Should return 0 if passes == N return (passes != N); }