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.
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.
// 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
}
}// 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
endmoduleSame 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.