Skip to main content

ElaborateSession

Struct ElaborateSession 

Source
pub struct ElaborateSession { /* private fields */ }
Expand description

Session token holding the unfrozen circuit (AD-13).

Implementations§

Source§

impl ElaborateSession

Source

pub fn new(circuit_name: impl Into<String>) -> Self

Source

pub fn begin_module(&mut self, name: impl Into<String>, span: Span)

Source

pub fn bind_domain(&mut self, name: impl Into<String>, domain: u32)

Bind a phantom clock-domain id to a signal (AD-22).

Source

pub fn mark_cdc_bridge(&mut self, name: impl Into<String>)

Mark a CDC bridge signal that may legally cross domains.

Source

pub fn declare_double_flop_stages( &mut self, stem: impl Into<String>, ty: GroundType, dst_domain: u32, span: Span, ) -> (String, String)

Declare a synthesizable 2-stage CDC synchronizer register pair (FR79 / AD-29).

Creates {stem}_ff0 and {stem}_ff1, binds both to dst_domain, and marks {stem}_ff0 as a CDC bridge so Self::assign_reg_d_from / Self::assign_net may sample a source-domain din. Call Self::connect_double_flop inside a sequential process to wire ff0 ← din, ff1 ← ff0.

Stage count: 2. Latency: 2 destination-domain ticks to ff1 (see DoubleFlop::LATENCY_DST_TICKS in prelude).

Source

pub fn connect_double_flop( &mut self, ff0: impl Into<String>, ff1: impl Into<String>, din: impl Into<String>, span: Span, )

Wire a previously declared DoubleFlop pair: ff0 ← din, ff1 ← ff0.

Must be called inside a sequential process. ff0/ff1 should come from Self::declare_double_flop_stages.

Source

pub fn add_input(&mut self, name: impl Into<String>, ty: GroundType, span: Span)

Source

pub fn add_output( &mut self, name: impl Into<String>, ty: GroundType, span: Span, )

Source

pub fn add_inout(&mut self, name: impl Into<String>, ty: GroundType, span: Span)

Top-level InOut / Analog IO (FR27). Non-top uses are rejected at freeze.

Source

pub fn declare_wire( &mut self, name: impl Into<String>, ty: GroundType, span: Span, )

Source

pub fn declare_reg( &mut self, name: impl Into<String>, ty: GroundType, span: Span, )

Source

pub fn declare_reg_ex( &mut self, name: impl Into<String>, ty: GroundType, async_reset: bool, has_enable: bool, span: Span, )

Declare a register with optional async reset / clock enable (AD-23).

Source

pub fn declare_sync_read_mem( &mut self, name: impl Into<String>, depth: u32, width: u32, span: Span, )

Declare SyncReadMem (CHIRRTL-friendly; sync_read=true).

Source

pub fn declare_mem( &mut self, name: impl Into<String>, depth: u32, width: u32, span: Span, )

Declare Mem (async-read / reg-file style; sync_read=false).

Source

pub fn declare_mem_with_init( &mut self, name: impl Into<String>, depth: u32, width: u32, init: Vec<u64>, span: Span, )

Declare Mem with elaborate-time init words (FR73). Prefer Self::declare_mem_with_init_fn for generator closures.

Source

pub fn declare_sync_read_mem_with_init( &mut self, name: impl Into<String>, depth: u32, width: u32, init: Vec<u64>, span: Span, )

Declare SyncReadMem with elaborate-time init words (FR73).

Source

pub fn declare_mem_with_init_fn<F>( &mut self, name: impl Into<String>, depth: u32, width: u32, f: F, span: Span, )
where F: Fn(usize) -> u64,

Elaborate-time Mem init generator (FR73 / AD-18).

Runs f(addr) for each address inside the session, masks to width bits, and stores plain Vec<u64> on the HIR mem node. The closure does not enter FrozenHir (NFR36). Only non-capturing Fn is legal; capturing Wire/Reg/signal refs must be rejected via Self::assert_no_hw_capture (rhdl::E0142).

Source

pub fn declare_sync_read_mem_with_init_fn<F>( &mut self, name: impl Into<String>, depth: u32, width: u32, f: F, span: Span, )
where F: Fn(usize) -> u64,

SyncReadMem variant of Self::declare_mem_with_init_fn (FR73).

Source

pub fn check_add(&mut self, lhs: &str, rhs: &str, span: Span) -> Option<u32>

Same-width binary add. Returns Err diagnostic via session if widths differ.

Source

pub fn check_connect(&mut self, lhs: &str, rhs: &str, span: Span) -> Option<u32>

Source

pub fn pad_to( &mut self, src: &str, to_width: u32, dest: impl Into<String>, span: Span, ) -> bool

Explicit zero-extend / sign-pad to a wider width; records result as a temp wire name.

Source

pub fn trunc_to( &mut self, src: &str, to_width: u32, dest: impl Into<String>, span: Span, ) -> bool

Source

pub fn begin_combinational(&mut self, span: Span)

Source

pub fn begin_sequential(&mut self, span: Span)

Source

pub fn begin_then(&mut self, span: Span)

Start an if-branch inside a combinational process (latch analysis).

Source

pub fn begin_else(&mut self, span: Span)

Source

pub fn end_if(&mut self, span: Span)

Source

pub fn assign_add( &mut self, dst: impl Into<String>, lhs: impl Into<String>, rhs: impl Into<String>, span: Span, )

Combinational assign dst = lhs + rhs (same-width required).

Source

pub fn assign_lit(&mut self, dst: impl Into<String>, lit: u64, span: Span)

Combinational assign dst = lit.

Source

pub fn assign_eq( &mut self, dst: impl Into<String>, lhs: impl Into<String>, rhs: impl Into<String>, span: Span, )

Combinational assign dst = (lhs == rhs) (0/1).

Source

pub fn assign_mux( &mut self, dst: impl Into<String>, sel: impl Into<String>, t: impl Into<String>, f: impl Into<String>, span: Span, )

Combinational assign dst = sel ? t : f (sel != 0 is true).

Source

pub fn assign_sub( &mut self, dst: impl Into<String>, lhs: impl Into<String>, rhs: impl Into<String>, span: Span, )

Combinational dst = lhs - rhs.

Source

pub fn assign_and( &mut self, dst: impl Into<String>, lhs: impl Into<String>, rhs: impl Into<String>, span: Span, )

Combinational dst = lhs & rhs.

Source

pub fn assign_or( &mut self, dst: impl Into<String>, lhs: impl Into<String>, rhs: impl Into<String>, span: Span, )

Combinational dst = lhs | rhs.

Source

pub fn assign_xor( &mut self, dst: impl Into<String>, lhs: impl Into<String>, rhs: impl Into<String>, span: Span, )

Combinational dst = lhs ^ rhs.

Source

pub fn assign_shl( &mut self, dst: impl Into<String>, lhs: impl Into<String>, rhs: impl Into<String>, span: Span, )

Combinational dst = lhs << (rhs & 63).

Source

pub fn assign_shr( &mut self, dst: impl Into<String>, lhs: impl Into<String>, rhs: impl Into<String>, span: Span, )

Combinational dst = lhs >> (rhs & 63) (logical).

Source

pub fn assign_net( &mut self, name: impl Into<String>, from: impl Into<String>, span: Span, )

Assign a combinational net / output / wire from from.

Source

pub fn assign_reg_d_inc(&mut self, name: impl Into<String>, span: Span)

Assign Reg.d next-state as name + 1 (wrapping).

Source

pub fn assign_reg_d_from( &mut self, name: impl Into<String>, from: impl Into<String>, span: Span, )

Assign Reg.d from another signal.

Source

pub fn assign_reg_d_mux( &mut self, name: impl Into<String>, sel: impl Into<String>, t: impl Into<String>, f: impl Into<String>, span: Span, )

Assign Reg.d as a 2:1 mux (same-width t/f as the register).

Used for handwritten seq goldens alongside Self::inline_seq_fn.

Source

pub fn assign_mem_write( &mut self, mem: impl Into<String>, addr: impl Into<String>, data: impl Into<String>, span: Span, )

Sequential SyncReadMem / Mem write: mem[addr] <= data (always enabled).

Source

pub fn assign_mem_write_en( &mut self, mem: impl Into<String>, addr: impl Into<String>, data: impl Into<String>, we: impl Into<String>, span: Span, )

Sequential mem write gated by we (we != 0).

Source

pub fn assign_reg_d_mem_read( &mut self, reg: impl Into<String>, mem: impl Into<String>, addr: impl Into<String>, span: Span, )

Sequential SyncReadMem read into a register (latency 1 on tick).

Source

pub fn end_process(&mut self)

Source

pub fn end_module(&mut self)

Source

pub fn finish(self) -> Result<FrozenHir, Diagnostics>

Source

pub fn reject_unsynthesizable(&mut self, construct: &str, span: Span)

Record a synthesizable-path violation (heap, threads, f64, capturing closure, …) as a structured diagnostic (rhdl::E0141 / FR16).

Source

pub fn reject_hw_capture(&mut self, capture: &HwCaptureRef, span: Span)

Reject capturing a hardware Wire/Reg/signal ref into an elaborate-time generator or factory closure (FR73 / NFR35 / AD-18).

Stable code: rhdl::E0142. Distinct from FR16 cycle-accurate Self::reject_unsynthesizable (rhdl::E0141).

Source

pub fn assert_no_hw_capture(&mut self, captures: &[HwCaptureRef], span: Span)

Assert that no hardware Wire/Reg/signal refs were captured into a generator / factory context. Empty slice is a no-op (legal non-capturing path).

Call when a documented illegal capture is present (ATDD / macros / typed handles). Any token → rhdl::E0142 at Self::finish.

Source

pub fn reject_unsynthesizable_closure( &mut self, violation: &SynthesizableClosureViolation, span: Span, )

Reject a documented SynthesizableClosure constraint breach (FR74 / Cap-R-60).

Stable codes: rhdl::E0143 (heap), rhdl::E0144 (runtime capture state), rhdl::E0145 (impure). Does not emit closure IR into HIR (NFR36) — diagnostics only. Distinct from E0141 / E0142.

Source

pub fn check_synthesizable_closure( &mut self, violations: &[SynthesizableClosureViolation], span: Span, )

Cap-R-60 check hook: record all documented SynthesizableClosure violations.

Empty violations is a no-op (legal empty/simple closure — paves 28.2). Reachable from design crates via prelude and from future cargo bitloom check (or equivalent) wrappers.

Source

pub fn check_synthesizable_closure_marker<C: SynthesizableClosure>( &mut self, closure: &C, span: Span, )

Cap-R-60 helper: run SynthesizableClosure::synthesizable_closure_violations and record any tokens (empty = pass).

Source

pub fn inline_comb_fn<F>( &mut self, dst: impl Into<String>, args: &[&str], violations: &[SynthesizableClosureViolation], span: Span, f: F, )
where F: FnOnce(&[&str]) -> CombInline,

Inline a synthesizable combinational transform (FR75 / Cap-R-55).

Must be called inside an open Self::begin_combinational process (same rules as assign_*). Sequence:

  1. Cap-R-60 Self::check_synthesizable_closure on violations
  2. If any violation token was supplied, do not expand (finish fails)
  3. Otherwise invoke f(args) once and lower CombInline through existing Wire/assign_* paths — FrozenHir holds only ordinary AssignExpr (NFR36; no Fn objects after freeze)

Incomplete-assign / latch analysis (AD-18) still applies to dst. Sequential-block inline: Self::inline_seq_fn (Cap-R-56 / Cap-R-70).

session.begin_combinational(span);
session.inline_comb_fn("y", &["a", "b"], &[], span, |args| {
    CombInline::Add(args[0].into(), args[1].into())
});
session.end_process();
Source

pub fn inline_comb_fn_marker<C, F>( &mut self, dst: impl Into<String>, args: &[&str], marker: &C, span: Span, f: F, )

Cap-R-55 helper: run marker SynthesizableClosure check then inline.

Source

pub fn reject_seq_ownership_violation( &mut self, violation: &SeqOwnershipViolation, span: Span, )

Cap-R-70: record documented seq-ownership violations (rhdl::E0146).

Source

pub fn check_seq_ownership( &mut self, violations: &[SeqOwnershipViolation], span: Span, )

Cap-R-70 check hook: record all documented seq-ownership violations. Empty violations is a no-op.

Source

pub fn inline_seq_fn<F>( &mut self, dst_reg: impl Into<String>, args: &[&str], synth_violations: &[SynthesizableClosureViolation], ownership_violations: &[SeqOwnershipViolation], span: Span, f: F, )
where F: FnOnce(&[&str]) -> SeqInline,

Inline a synthesizable sequential transform onto Reg.d (FR75 / Cap-R-56).

Must be called inside an open Self::begin_sequential process. Sequence:

  1. Cap-R-60 Self::check_synthesizable_closure on synth_violations
  2. Cap-R-70 Self::check_seq_ownership on ownership_violations
  3. Cap-R-70 auto-detect: if dst_reg.d is already assigned in this sequential process, diagnose rhdl::E0146 and do not expand
  4. If any Cap-R-60 / Cap-R-70 token was supplied, do not expand
  5. Otherwise invoke f(args) once and lower SeqInline to ordinary sequential AssignExpr / Reg.d — FrozenHir holds no Fn (NFR36)

Cross-process multi-drive / undriven after expand still use AD-4 freeze checks (rhdl::E0140, …).

session.begin_sequential(span);
session.inline_seq_fn("count", &[], &[], &[], span, |_args| SeqInline::Inc);
session.end_process();
Source

pub fn inline_seq_fn_marker<C, F>( &mut self, dst_reg: impl Into<String>, args: &[&str], marker: &C, ownership_violations: &[SeqOwnershipViolation], span: Span, f: F, )

Cap-R-56 helper: marker Cap-R-60 check then seq inline (Cap-R-70 ownership args).

Source

pub fn add_instance( &mut self, name: impl Into<String>, module: impl Into<String>, connects: Vec<(String, String)>, params: Vec<(String, u32)>, span: Span, )

Hierarchical instance (Story 2.2); not flattened at elaborate.

Source

pub fn generate_instances<F>(&mut self, count: usize, f: F)
where F: FnMut(usize, &mut Self),

Elaborate-time module factory (FR73 / Cap-R-53).

Invokes f(i, session) for each i in 0..count. The factory should call Self::add_instance (and optional wire decls) so each iteration records a child instance plus type-safe port connects. Only ordinary Stmt::Instance / PortConnect remain after the loop — the closure does not enter FrozenHir (NFR36). Width/dir checks still run at finish (FR8 / existing instance validation). Capturing Wire/Reg into the factory is illegal — use Self::assert_no_hw_capture (rhdl::E0142).

session.generate_instances(4, |i, s| {
    s.add_instance(
        format!("u{i}"),
        "Lane",
        vec![
            ("clk".into(), "clk".into()),
            ("rst".into(), "rst".into()),
            ("x".into(), format!("x{i}")),
            ("y".into(), format!("y{i}")),
        ],
        vec![],
        Span::default(),
    );
});
Source

pub fn generate_instances_from<F>(&mut self, count: usize, f: F, span: Span)
where F: Fn(usize) -> GeneratedInstance,

Pure-return factory variant (FR73 / Cap-R-53): f(i) returns an GeneratedInstance that is immediately recorded as HIR via Self::add_instance. Prefer when the factory needs no extra session side effects (wires, dangling marks).

Source

pub fn add_dangling_input( &mut self, instance: &str, child_port: impl Into<String>, span: Span, )

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.