C⏚ language

Hardware that reads like software

C⏚ ("C-Ground") gives you C-like syntax with real hardware semantics, and compiles to clean, standard Verilog. Describe what your hardware does - the compiler builds the FSMs, counters and handshakes.

C-like syntax·bit-accurate types·compiles to Verilog·not HLS

Why C⏚ exists

Forty years of software lessons, finally applied to hardware

Verilog was designed in 1984, VHDL in 1983. They were revolutionary - but HDLs still force you to think at the wire level. C⏚ lets you think at the architecture level instead.

This is not High-Level Synthesis. HLS tools are black boxes that emit RTL you can't read or debug. C⏚ compiles to clean Verilog at the right level of abstraction - code you can review, hand-tweak, and would be happy to have written yourself.

See the difference

Half the code, and you still own the Verilog

The same stream-scaler - in C⏚, and in the hand-written Verilog you'd otherwise maintain. You write the intent; the compiler wires the valid/ready handshake, the skid buffer and the reset.

C⏚ - what you write
// Scale a stream of samples by a constant
task StreamScale {
  in stream u8 sample;
  out stream u8 scaled;

  const u8 GAIN = 3;

  void loop() {
    u8 x = sample.read;          // blocks until valid
    scaled.write((u8)(x * GAIN)); // back-pressures when full
  }
}
Verilog - what you'd write by hand
// Equivalent hand-written Verilog
module stream_scale (
  input  wire        clk,
  input  wire        rst_n,
  input  wire [7:0]  sample,
  input  wire        sample_valid,
  output reg         sample_ready,
  output reg  [7:0]  scaled,
  output reg         scaled_valid,
  input  wire        scaled_ready
);
  localparam [7:0] GAIN = 8'd3;

  // You wire the valid/ready handshake,
  // the skid buffer and the reset by hand:
  always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
      scaled       <= 8'd0;
      scaled_valid <= 1'b0;
    end else if (sample_valid && sample_ready) begin
      scaled       <= sample * GAIN;
      scaled_valid <= 1'b1;
    end else if (scaled_valid && scaled_ready) begin
      scaled_valid <= 1'b0;
    end
  end
  // ...plus the sample_ready back-pressure logic
endmodule

Same function. Half the code. And C⏚ generates that Verilog for you.

Core features

The primitives that make hardware feel like software

C-like control flow, bit-accurate types, concurrent tasks and stream handshakes - each one a language primitive, so the compiler builds the FSMs, counters and back-pressure for you.

C-like syntax

If you know C, you already know most of C⏚ - familiar control flow, operators and structure. The learning curve is hours, not months.

if (count > THRESHOLD) {
  enable = true;
  status = READY;
}

Strong, bit-accurate typing

Bit-accurate types catch width mismatches before synthesis - flagged live in the editor, not after hours of simulation.

u8 byte_data;
u16 word_data;
bool flag;

Readable concurrency

Tasks describe concurrent hardware; ports connect them. No sensitivity lists, no races from a typo.

in push u8 input;
out push u16 output;

output.write(data);

Built-in hardware constructs

Typed ports, stream handshakes and loop-driven state machines are language primitives - the compiler builds the FSMs, counters and back-pressure.

in stream u8 src;
out stream u8 dst;

void loop() {
  dst.write(src.read);
}

In practice

What it looks like on a real design

Readable source, live type checking, generated state machines and the actual Verilog - the whole loop, on real code from the editor.

Clean, maintainable code

No thousand-line case statements, no hunting for signal definitions across modules. C⏚ reads like modern software - and readable code is debuggable code. A rising-edge detector is one register and three lines:

// One-cycle pulse on every 0 -> 1 transition of the line.
task RisingEdge {
  in  stream bool signal;   // sampled input line
  out stream bool pulse;    // high for one cycle on a rising edge

  bool prev;                // previous sample

  void loop() {
    bool now = signal.read;
    pulse.write(now && !prev);
    prev = now;
  }
}

Type safety at hardware scale

Bit-accurate types mean the compiler catches width mismatches, sign errors and type incompatibilities - live in the editor, not in simulation or, worse, on silicon.

Cycle-accurate, naturally

Each blocking port read is one clock cycle - the compiler turns your loop() into a cycle-accurate state machine. You write the algorithm; the FSM, counters and handshakes are generated.

Concurrency without chaos

Tasks execute in parallel; ports manage communication. Synchronous and asynchronous channels handle data flow, so you build concurrent systems without fighting the language.

Transparent compilation, not HLS magic

C⏚ compiles to readable Verilog at the right abstraction level - no black-box RTL. The generated HDL is clean, reviewable and debuggable: exactly what Verilog should have been.

Technical details

Built on a real semantic model, not regex

A static type system, a concurrency model, first-class clock domains and transparent compilation - the foundations that make the high-level syntax safe to trust.

Type system

Bit-accurate types - u8, u32, i16, bool - plus arbitrary widths like u17 or u127. Static type checking catches width and sign errors at compile time, live in the editor.

Concurrency model

Tasks run concurrently and communicate over typed ports; synchronous and asynchronous channels are built in. Express parallelism without always-blocks or sensitivity lists.

Clock domains

First-class clock-domain support with cross-domain communication that is safe by default - no metastability bugs from a forgotten synchronizer.

Transparent compilation

Compiles to clean, readable Verilog at the right level of abstraction. Review it, debug it, hand-tweak it, or drop it into an existing flow. You always know what you are getting.

Try C⏚ on a real project

Full language reference, tutorials and example projects - and a 14-day free trial, no credit card.