C⏚ v2.0.0Updated 2026-05-12·Language

Statements

Statements drive C⏚'s control flow and side effects. Where expressions compute values, statements change state.

Assignment

x = 15;
y[3] = (u4) z;

An assignment can also be a bare expression. The compiler still evaluates the right side, which is useful for reading and discarding a port:

msg.read();      // wait for data on msg, drop the value

if / else if / else

if (a > 0) {
  print("positive");
} else if (a < 0) {
  print("negative");
} else {
  print("zero");
}

if conditions can include port reads. The compiler treats those reads as peeked: the value is available inside the chosen branch without a second read causing a cycle break.

if (a.read() < b.read()) {
  min.write(a.read());     // does not cause a new cycle
}
// after the if, both a and b are consumed

for

for (u4 i = 0; i < 5; i++) {
  print("hello");
}

A for loop runs entirely within the current cycle when all three of these conditions hold:

  • The iteration variable is a local used only for iteration.
  • Bounds are compile-time constant.
  • The body contains no port reads or writes, no fence, no idle.

Otherwise each iteration takes at least one cycle.

The loop condition supports peeking, like if:

for (; cond.read(); count++) {
  // body runs while cond is true
}

while

while (keepGoing.read()) {
  count++;
}

while always introduces a cycle break per iteration. There is no compile-time form.

fence

End the current cycle and resume on the next:

print("cycle N");
fence;
print("cycle N+1");

idle

End the current cycle and stay idle for n cycles before resuming. n must be a compile-time constant.

print("cycle N");
idle(3);
print("cycle N+4");

print

Print to the simulator console. Arguments are concatenated; integers and booleans print in decimal.

print("count = ", count, "  mode = ", mode);

print has no effect in synthesis.

assert

Fail the simulation if the condition is false.

assert(count < MAX);

assert has no effect in synthesis. It is the primary verification tool inside monitor tasks.

write

Write a value to an output port.

answer.write(42);

A port may be written at most once per cycle. Writing the same port twice creates an implicit cycle break, as for read.

return

Return a value from a const function.

return factor << 1;

return is only valid at the end of a constant function. Tasks' setup and loop are void and return implicitly.