Chapter 11: Advanced Core Semantics

Source Deep Dive: sc_clock and Reset Implementation

How clocks schedule edges, how reset policies attach to processes, and why reset behaves like controlled process unwinding.

How to Read This Lesson

Clocks and resets look simple in examples, but they are where simulation semantics meet hardware intuition. Read this lesson slowly: the source explains why reset is not just an if statement around your thread body.

Source and LRM Trail

Use Docs/LRMs/SystemC_LRM_1666-2023.pdf for clocks, events, processes, and reset semantics. Use Docs/LRMs/SystemC_Synthesis_Subset_1_4_7.pdf when the reset must synthesize. In source, inspect .codex-src/systemc/src/sysc/communication/sc_clock.*, .codex-src/systemc/src/sysc/kernel/sc_reset.*, sc_process.*, and sc_except.*.

How sc_clock Behaves

sc_clock is a predefined channel that produces periodic value changes. It is useful because it combines:

  • a Boolean signal-like value
  • positive and negative edge events
  • period, duty cycle, start time, and edge scheduling
  • integration with the kernel's timed event queue

When a process is sensitive to clk.pos(), it is really sensitive to an event finder associated with the clock's positive edge event.

SC_METHOD(tick);
sensitive << clk.pos();
dont_initialize();

The process runs when the clock channel updates and the positive edge event is notified.

Reset Is Attached to a Process

Reset declarations such as:

SC_CTHREAD(run, clk.pos());
reset_signal_is(rst, true);

do not simply store a Boolean in your module. They attach reset metadata to the process object created most recently by the process macro.

That is why ordering matters: the reset call configures the process registration, not an arbitrary C++ function.

How the Source Makes Reset Work

The Accellera implementation tracks reset targets through kernel-side reset structures. When reset becomes active, the process is marked for reset. For thread-like processes, the kernel may need to unwind the coroutine stack and restart the process function from its reset point.

That unwinding is represented through a special exception mechanism. It is not an error exception in the normal application sense. It is controlled kernel flow used to stop the current coroutine execution and return to a known process state.

Why This Matters for User Code

This is why destructors and local objects inside a thread can matter during reset. If reset unwinds the stack, normal C++ cleanup rules may run. If your thread owns nontrivial local state across waits, reset behavior must be reviewed.

Better pattern:

void run() {
  state = IDLE;
  out.write(false);
  wait();
 
  while (true) {
    // normal clocked behavior
    wait();
  }
}

The reset section is explicit and repeatable.

Review Checklist

  • Is reset attached immediately after the intended process registration?
  • Does reset behavior match the process type?
  • Are local objects inside resettable threads safe to unwind?
  • Is synthesis reset style checked separately from simulation reset behavior?
  • Are clock periods and time resolution chosen deliberately?

Comments and Corrections