Implementation status (TBD)¶
Most of Pyrope is implemented in LiveHD
and exercised by its test suite. This page lists the documented features that
are not implemented yet; each is also marked "TBD" where it is described.
A feature on this list may parse (lhd elaborate is permissive) but does not
lower to working hardware.
The Task column names an existing task page in the LiveHD repo under todo/
where one is available; a dash means no separate task page exists.
| Feature | Documented in | Task | Notes |
|---|---|---|---|
fluid lambdas, valid/retry/fire elastic handshakes |
Fluid Blocks | 3f-fluid |
syntax parses; no lowering |
Temporal library: past(x, n), rose, fell, stable, changed, eventually(x, w), always(x, w) |
Extended Verification | 3f-temporal |
positional args only — there is no f[N](x) bracket form. The pipelining past[N](x) DOES work (design body only) and is a different operator. No edge attributes: .[rising]/.[falling]/.[changed]/.[stable] are not recognized. lhd formal verify must reject these calls with an explicit "not implemented" diagnostic |
Testbench extras: multi-match string-path refs, force/release, cpp(...) external models, unbounded tick { } |
Extended Verification | 3f-temporal |
the instance/step model runs via lhd sim: bare dotted DUT access READS any cell at any depth, and regref (dotted or single-cell string) DRIVES a register at any depth. peek/poke and sigref are removed — a bare dotted read is exactly what sigref was; waitfor/spawn/join/cancel are dropped |
regref — the SYNTHESIZABLE cross-scope register/memory attach by string path (zero-or-many matches) |
Type system, Memories | 3f-temporal |
still TBD. The test-block regref (single cell, dotted or string, writable) is a separate construct and is IMPLEMENTED |
Statements rejected inside a test block: .[rand]/.[crand], past[N], positional instantiation-by-call |
Testing | 3f-temporal |
dotted names, runtime (...) params, tick/step/break/continue, bare dotted DUT access, for loops and regref all work. sigref was REMOVED 2026-09-06 -- a bare dotted read is exactly it |
Standard library (import("prp")) |
Standard Library | — | wish-list chapter |
macro= memory-compiler binding |
Memories | 3f-macro |
|
cover, covercase, in-language lec()/lec_valid() |
Assertions | 3f-temporal |
assert/cassert/assume/assert_always work; cover does NOT exist in any context |
.[rand] / .[crand] random generation |
Random | 3f-temporal |
rejected in test blocks and design bodies; survives only where it constant-folds |
assert.[failed] (read/clear the accumulated failure flag in a test) |
Test | 3f-temporal |
|
always_assert / always_cassert / always_assume / always_cover / always_covercase; valid-based (.[valid]) gating of checks |
Reset and verification | 3f-temporal |
the implemented spelling is assert_always; no valid-based gating exists |
A ref self method used in a right-hand-side EXPRESSION (mut a_2 = a_1.f1(x=4), output named self) |
Functions, Struct types, Type system | — | the STATEMENT form and UFCS both work; only the expression form errors a method with a 'ref' parameter … cannot be used in a right-hand-side expression. Workaround: copy first, then mutate |
| A VECTOR io port — an unnamed/positional tuple or an array as a module port | Functions | — | no lowering in either direction; the NAMED tuple port works (tests/sim/tuple_io_ports.prp). Tracker: inou/prp/tests/fixme/vector_io_ports.prp |
Bit packing with #[..]: comptime unpack into an array, the exact-width check on unpack, ... splice of a declared [N]T when BUILDING a tuple |
Internals, Deprecated | 3f-bitpack |
Implemented: packing a tuple LITERAL ((a, b)#[..], (...stages, inp)#[..]) at comptime and at runtime, entry 0 at bit 0; packing a tuple/array VARIABLE (x#[..]); the declared-width guard, so an untyped or literal entry is rejected; the exact-width destination check (z:u16 = (b, a)#[..] on 12 bits errors, and an undeclared destination errors); the named-field rule, with the real diagnostic on a multi-field bundle and the one-field case still legal; reductions, sign extension, and sub-ranges over a packed tuple literal or an array/tuple variable; unpacking into a declared array at RUNTIME (const x:[2]u4 = b#[..] emits b[3:0], b[7:4]). concat is REMOVED and diagnoses its own replacement (concat-removed), which is the error to read first, because the argument order reverses. Still missing: comptime unpack does not split — const x:[2]u4 = b8#[..] folds BOTH entries to the whole word, a silent wrong value; the exact-width check on unpack, so b:u9 into [2]u4 silently drops bit 8; ... expands an unnamed tuple and an untyped array literal but not a declared const x:[2]u4 = (3,1) when building a tuple (as a PACKING entry it does expand); an array ELEMENT read is not a packing entry ((x, arr[2], arr[1])#[..] reports concat lane … has no declared bit width — bind each to a typed name first) |
Notes:
requires/ensureswere removed from the language. They parse today only to emit a "no obligation generated" warning; write anassumefor a precondition and anassertfor a postcondition.- A design-body
assertis checked bypass.formaland emitted into the Verilog netlist, but is not executed bylhd sim— the simulation runtime fallback is pending. Only assertions written inside atestblock are checked at simulation time. - A verification statement does not inherit an enclosing
ifguard:if c { assert(x) }is lowered as an unconditionalassert(x). Useassert(c implies x). - A refutable
assumeover free inputs is a hard build error at the top module and a deferred runtime check in an instantiated one. - Runtime
wrap/satlowering and enum-typed register resets are implemented (earlier limitations, since fixed). - Glob import patterns were removed from the language: the import string is
"file"or"file.pub_name"only (see import). - Removed 2026-09-06 (docs↔LiveHD consistency audit):
sigref(a bare dotteddut.xread is exactly it —regrefstays as the way to DRIVE a cell); the operator-overload hookseq/lt/to_string/to_bool(no dispatch ever existed —==is structural, comparisons are integer-only, andto_string/to_boolare ordinary explicit methods;initconstructor overload lists work and stay); strings as char tuples ("hi" == ('h','i'),..."h",string#[..],signed('cad'),"ab"#+[..]— strings are opaque,string(int)stays);pub wire;format(...); a type produced by a call (:Param_type(string)) and the computed widthu(W)— both use generics instead; the recursive-enum ADT (add:(Expr,Expr)+match does) — nested enums work and stay; and the tuple-LHS subset test forin. - Tuples are compile-time only, now and ever.
- An integer is not a condition: write
if i != 0, notif i. - The comptime
[...]test-parameter sweep (one test instance per swept value, the planned replacement for thefor { test ... }fan-out idiom) is reserved but not yet specified.