Chapter 14: Synthesis Subset

Synthesizable Datatypes

Understanding which SystemC datatypes are supported by HLS tools.

How to Read This Lesson

For synthesis, the question changes from 'can C++ run this?' to 'can hardware be built from this?' Keep storage, timing, and static structure in your head as you read.

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.

Source and LRM Trail

For synthesis, use Docs/LRMs/SystemC_Synthesis_Subset_1_4_7.pdf as the primary contract and Docs/LRMs/SystemC_LRM_1666-2023.pdf for base SystemC semantics. Source internals explain simulation behavior, but synthesizability is a tool contract: focus on static structure, reset modeling, wait placement, and bounded loops.

Supported SystemC Types

The following SystemC-specific types are fully supported for synthesis:

  • sc_int<W> and sc_uint<W>: Limited precision (1 to 64 bits) integer types. These are the workhorses of HLS because they synthesize extremely efficiently.
  • sc_bigint<W> and sc_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_logic and sc_bv<W>: Bit-vector and logic types. These are supported, but modern HLS flows often prefer sc_uint for 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 float and double are 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, use sc_fixed instead.

Unsupported Types

  • std::string: Strings cannot be synthesized. Hardware does not process dynamic text.
  • STL Containers: std::vector, std::list, std::map rely 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.

Comments and Corrections