Synthesizable Datatypes
Understanding which SystemC datatypes are supported by HLS tools.
How to Read This Lesson
Synthesizable Datatypes
When targeting High-Level Synthesis (HLS), choosing the right datatype is critical. In hardware, every bit costs area, power, and routing resources. Using a 32-bit int to store a value that only goes from 0 to 5 is a massive waste of silicon.
The SystemC Synthesizable Subset strictly defines which types are allowed and encouraged.
Standard and source context
Supported SystemC Types
The following SystemC-specific types are fully supported for synthesis:
sc_int<W>andsc_uint<W>: Limited precision (1 to 64 bits) integer types. These are the workhorses of HLS because they synthesize extremely efficiently.sc_bigint<W>andsc_biguint<W>: Arbitrary precision integer types (greater than 64 bits). These are synthesizable, but arithmetic operations on very wide buses will result in massive logic gates and slow clock speeds.sc_logicandsc_bv<W>: Bit-vector and logic types. These are supported, but modern HLS flows often prefersc_uintfor arithmetic.- Fixed Point Types (
sc_fixed,sc_ufixed): Fully synthesizable and highly recommended for DSP applications where floating-point math is too expensive.
Native C++ Types
Native C++ integer types are synthesizable, but their hardware size depends on the compiler standard (usually 32 bits for int).
bool(synthesizes to a 1-bit wire or flip-flop)char,short,int,long,long long(and their unsigned variants).
[!WARNING] Floating Point
floatanddoubleare technically synthesizable by modern advanced HLS tools, but they instantiate massive, slow IEEE-754 compliant floating-point arithmetic units (FPU). Unless you specifically intend to build a hardware FPU, usesc_fixedinstead.
Unsupported Types
std::string: Strings cannot be synthesized. Hardware does not process dynamic text.- STL Containers:
std::vector,std::list,std::maprely on dynamic heap allocation. They are completely unsynthesizable. - Pointers to functions: Not supported.
When writing synthesizable SystemC, always constrain your bit-widths. Use sc_uint<3> for a counter that counts to 7, rather than a generic int.
Under the Hood: sc_int and sc_dt::sc_uint_base
Standard C++ int is typically 32-bit. SystemC provides arbitrary precision types like sc_int<W> and sc_biguint<W>.
In sysc/datatypes/int/sc_uint_base.h, an sc_uint<W> (where W <= 64) is simply stored as a standard uint64_t. The class overloads the mathematical and bitwise operators to apply a bit-mask (m_mask) after every operation, ensuring the value wraps around according to the custom bit-width W.
For sc_biguint<W> (W > 64), the value is stored as an array of 32-bit integers (sc_digit). Operations on big types require loops over these arrays with carry propagation, which is why they are significantly slower to simulate than native uint64_t.
Source-reading checkpoint
For synthesis-oriented datatype choices, inspect the sc_cthread, reset, and wait examples beside the subset LRM. The source view is useful only after the hardware intent is clear.
Can you answer these clearly?
Keep moving when you can answer each question without looking back at the lesson.
Comments and Corrections