Search code examples
fpgaxilinxvivado-hls

How can I convert an HLS arbitrary precision type into a composite type


I am writing an HLS unit with an AXI4 Stream input. Several words in the stream comprise a struct that I would like to access. For example:

struct eth_header {
    ap_uint<48> dest;
    ap_uint<48> source;
    ap_uint<16> proto;
}

I can easily buffer the stream's words and concatenate them to a big ap_uint<112>. However, I would very much like to convert the ap_uint<112> into a nice struct like the eth_header above that I can access with the field syntax. I can't find a nice way to do that. I cannot cast or use a union because the ap_uint class is not a POD.

Is it possible to convert the types somehow (without writing explicit code for each field)?

EDIT: it wasn't clear that the struct needs to be converted from several words from the stream.


Solution

  • I ended up writing explicit code to do the conversion. For example:

    struct eth_header {
        ap_uint<48> dest;
        ap_uint<48> source;
        ap_uint<16> proto;
    
        static const int width = 112;
    
        eth_header(const ap_uint<width>& d) :
            dest  (d( 47,  0)),
            source(d( 95, 48)),
            proto (d(111, 96))
        {}
    
        operator ap_uint<width>()
        {
            return (hls_helpers::swap16(proto), source, dest);
        }
    };
    

    This is very ugly, but its the only thing that worked for me.