Skip to content

Kathryn

A cycle-accurate control-flow and resource-abstraction HDL framework. Describe control flow and hardware resources at a high level in Python — keep full cycle-accurate control, and emit clean Verilog from a Rust core.

A Framework-Assisted Approach that keeps cycle accuracy

Section titled “A Framework-Assisted Approach that keeps cycle accuracy”

Hardware modeling tools trade off two things: how much they abstract control flow and resources, and how much cycle-accurate control they leave you. Traditional HDLs (Verilog, VHDL) and framework-assisted approaches (Chisel) give you cycle accuracy but leave you writing structural RTL — every state machine and wire by hand. High-level synthesis abstracts the control away — and takes cycle accuracy with it.

Kathryn is a Framework-Assisted Approach (FAA) that refuses that trade-off. You construct the register-transfer-level model directly in Python — every register, wire, and control step is something you wrote — while three abstractions (below) remove the manual control-flow and routing burden. The Rust-powered compiler emits exactly that model as synthesizable Verilog. It is not high-level synthesis: it never guesses micro-architecture from algorithmic code.

flowchart LR
    subgraph HLS["High-Level Synthesis"]
      direction TB
      H1["High abstraction"]
      H2["✗ loses cycle accuracy"]
    end
    subgraph HDLFAA["HDL / classic FAA"]
      direction TB
      D1["Cycle-accurate"]
      D2["✗ structural RTL and routing"]
    end
    subgraph KAT["Kathryn (FAA)"]
      direction TB
      K1["Cycle-accurate"]
      K2["✓ abstracts control & routing"]
    end
    HLS -. "give up control" .-> K
    HDLFAA -. "give up abstraction" .-> K
    K(["Kathryn bridges the gap"])
    KAT --> K

All three abstractions exist in both implementations — the current Python DSL and the legacy C++ core; only the surface syntax differs.

Hybrid Design Flow (HDF)

An abstract model for hardware control flow. Sequential, parallel, and conditional blocks — seq, par, cif, sif, zif — and pipeline halves pip / zync are plain Python context managers that compile to explicit, cycle-accurate state machines. Comparable control to HDL, without the manual FSM bookkeeping. The legacy C++ core provides the same blocks as C++ macros.

Decentralized Update

Relax centralized control logic. Any block may update a hardware resource’s value; multiple writers to one register are legal and deterministic, because every assignment carries a priority and conflicts resolve exactly as declared — no hand-routed valid/select trees.

Hardware Aggregator

The Table & Slot abstraction bundles many hardware components into one entity: multi-dimensional arrays with named fields, static and dynamic indexing (binary or one-hot), spread writes, and hardware reduce trees — the machinery behind structures like a reservation station. Exposed as karray in Python, and as Table & Slot in the legacy C++ core.

Hardware as code — not high-level synthesis

Section titled “Hardware as code — not high-level synthesis”

You write Python

from kathryn import *
class counter_demo(Module):
@init
def declare(self):
self.x = reg(8, "x")
self.y = reg(8, "y")
self.simple_val = val(8, 48, "simple_val")
self.x.mark_output("my_x")
self.y.mark_output("my_y")
@flow
def my_flow(self):
with seq(): # one step per cycle
self.x |= self.simple_val
self.y |= self.x
reset()
build_model(counter_demo())
emit_verilog("out/")

Kathryn emits Verilog (excerpt)

module MODULE_counter_demo0_0(
output reg [7:0] my_x,
output reg [7:0] my_y,
input wire [0:0] clk,
input wire [0:0] mrst
);
always @(posedge WIRE_clk_12) begin
if (SR_ST_seq_state_4_0_ST_36) begin
REG_x_1[7:0] <= VAL_simple_val_3[7:0];
end
end
always @(posedge WIRE_clk_12) begin
if (SR_ST_seq_state_4_1_ST_40) begin
REG_y_2[7:0] <= REG_x_1[7:0];
end
end

The same model is written the same way in the legacy C++ implementation, where Kathryn began as a C++-embedded HDL — the Kathryn C++ book documents it in full:

class ExampleModule: public Module{
public:
mWire(i, 32);
mReg(a, 32);mReg(b, 32);
mReg(c, 32);mReg(d, 32);
ExampleModule(int x): Module(){ i.asInputGlob(); d.asOutputGlob();}
void flow() override{
seq{ /// all sub element run [seq]uentialy
a <<= i;
par{ /// all sub element run parallelly
cdowhile(a < 8){ /// do loop
a <<= a + 1;
c <<= c + 1;
}
cdowhile(b < 8){ /// do loop
b <<= b + 1;
d <<= d + 1;
}
}
d <<= c + d;
}
}
};

Structured pipelines

Build pipelines from pip and zync halves with stall, bubble, and flush behavior driven by a shared arbiter — no hand-rolled valid/ready wiring.

Plain-Python modules

Hierarchy is ordinary Python classes with @init and @flow methods — nest, inherit, and parameterize with the full language.

Rust core

A generational-arena model store in Rust: memory-safe, fast, and reachable from Python through lightweight copy-by-value handles.

Clean Verilog out

Deterministic elaboration, cross-module IO routing, and a backend that only reads the model — never redesigns it — so the emitted Verilog mirrors what you wrote.

Legacy C++ core

The original C++-embedded implementation ships its own toolbox: a cycle-accurate Hybrid Simulator with VCD waveforms and the ZEP cycle profiler, plus a synthesizable-Verilog generator — all documented in the Kathryn C++ book.

Kathryn is an academic research project on cycle-accurate, control-flow and resource-abstraction hardware design. Come build with us, or explore the original C++ edition.

AI tools assisted in drafting this documentation site. The maintainers have reviewed all of it and verified the content against the Kathryn source code.