Chapter 2: Core Modeling

Datatypes and Bit-Accurate Modeling

When to use C++ integers, sc_int, sc_uint, sc_bigint, sc_bv, sc_lv, fixed-point types, and enums.

SystemC is C++, so the first datatype question is always: can a normal C++ type answer this modeling question? If yes, use it. If the model needs hardware-shaped behavior, use SystemC datatypes. In accordance with the LRM Section 7, SystemC provides a robust set of numeric and vector types.

Here is a complete, fully compilable example demonstrating how all these types are instantiated and used within a SystemC module:

#include <systemc>
// Include the specific headers for SystemC datatypes
#include <sysc/datatypes/int/sc_int.h>
#include <sysc/datatypes/int/sc_uint.h>
#include <sysc/datatypes/bit/sc_bv.h>
#include <sysc/datatypes/bit/sc_lv.h>
#include <sysc/datatypes/fx/sc_fixed.h>
 
using namespace sc_core;
 
enum class BusState {
  Idle,
  Address,
  Data,
  Response,
};
 
SC_MODULE(DatatypeDemo) {
  SC_CTOR(DatatypeDemo) {
    SC_THREAD(run);
  }
 
  void run() {
    // Native C++ Types: fast and familiar
    uint32_t address = 0x40001000;
    uint8_t byte = 0xff;
    bool irq_pending = false;
 
    // sc_int and sc_uint: EXACT small bit-widths (up to 64 bits)
    sc_dt::sc_uint<12> page_offset = address & 0x0FFF;
    sc_dt::sc_int<9> signed_delta = -7;
    std::cout << "Page offset: " << page_offset << ", signed delta: " << signed_delta << "\n";
 
    // sc_bigint and sc_biguint: Arbitrary precision (> 64 bits)
    sc_dt::sc_biguint<257> wide_accumulator = 0;
    wide_accumulator = wide_accumulator + 1;
    
    // sc_bv and sc_lv: Bit vectors and Logic vectors
    sc_dt::sc_bv<8> mask = "10101100";
    sc_dt::sc_lv<4> bus = "10ZX"; // Z = High impedance, X = Unknown
    std::cout << "Bit vector mask: " << mask << ", Logic vector bus: " << bus << "\n";
 
    // Fixed-Point Types: DSP and quantization
    // <Total word length, Integer word length>
    sc_dt::sc_fixed<16, 2> gain = 1.25;
    std::cout << "Fixed point gain: " << gain << "\n";
 
    // Enums
    BusState state = BusState::Idle;
    if (state == BusState::Idle) {
       std::cout << "Bus is idle.\n";
    }
  }
};
 
int sc_main(int argc, char* argv[]) {
  DatatypeDemo demo("demo");
  sc_start();
  return 0;
}

Choosing a Type

Use this practical rule:

  • Use native C++ types for fast functional state.
  • Use sc_uint and sc_int for exact small widths.
  • Use bit vectors (sc_bv) for bit slicing and packed fields when arithmetic isn't the primary goal.
  • Use logic vectors (sc_lv) when X or Z is meaningful for bus resolution (LRM Section 7.9).
  • Use fixed-point types (sc_fixed) for quantization and DSP modeling.
  • Use enums for readable control state.

The best type is the one that preserves the behavior you need without pretending the model is more detailed than it is.

Comments and Corrections