pub struct ProcessCfg<'d> {Show 15 fields
pub blocks: Vec<BasicBlock<'d>>,
pub entry: BlockId,
pub body: Statement<'d>,
pub inlined_locals: Vec<Symbol<'d>>,
pub captures: Vec<Expression<'d>>,
pub captured: Vec<Symbol<'d>>,
pub ref_bindings: Vec<(Symbol<'d>, Symbol<'d>)>,
pub disable_names: Vec<String>,
pub fork_branch_names: Vec<String>,
pub disable_scopes: Vec<(BlockId, String, BlockId)>,
pub disable_broadcast: Vec<(String, bool)>,
pub inherited: Vec<InheritedSlot>,
pub capture_types: Vec<Option<Symbol<'d>>>,
pub recursion: Recursion,
pub share_id: Option<u64>,
}Expand description
PR-004, PR-008: the CFG built by build_cfg – one LLVM function per
process (Task S3c) will eventually switch on resume_pc with one case
per segment derived from blocks below.
Fields§
§blocks: Vec<BasicBlock<'d>>§entry: BlockId§body: Statement<'d>The process body’s original root Statement (Task S3b deviation,
not in Task S3a’s original field list): process::liveness:: compute_liveness‘s declared-local discovery needs to walk the
pre-flattening statement tree looking for Block statements’
block_symbol() scopes – blocks/stmts above only ever retain
the leaf statements CfgBuilder::walk_seq flattened into each
BasicBlock, which discards every intervening begin/end Block
statement node (and, with it, that block’s StatementBlockSymbol –
the ONLY place sv-lang=0.1.9’s pinned C API exposes a declared
local’s Symbol; there is no per-VariableDeclaration-statement
symbol accessor at all, confirmed against the real binding). Keeping
the untouched root here, alongside the flattened blocks, is the
minimal way to make both queries possible without re-walking from
the caller.
inlined_locals: Vec<Symbol<'d>>The formals and locals of every task inlined into this CFG
(ArgBinding) – declared locals of the process for frame-layout
purposes, though no Block under body declares them.
captures: Vec<Expression<'d>>The target of each intra-assignment-timed assignment’s captured
right-hand side (ArgBinding::Capture), indexed by temp: its
type sizes the temporary’s frame slot.
captured: Vec<Symbol<'d>>For a fork branch: the variables of the forking activation it uses (LRM 1800-2023 §9.3.2, §6.21) – shared with it, not copied: their frame slots, here and in the parent, hold a pointer to one cell.
ref_bindings: Vec<(Symbol<'d>, Symbol<'d>)>(formal, actual): a ref formal of an inlined task that every call
in this process binds to the same static variable or net (LRM
1800-2023 §13.5.2). The formal names the actual’s storage – it has no
frame slot and no copy-in/copy-out – so a wait on it (@(posedge clk) with ref logic clk) sees the actual change.
disable_names: Vec<String>The name(s) a disable <label>; ANYWHERE (this process, a sibling
branch, an ancestor fork, or a genuinely different process) may
single this CFG’s own live process out by (LRM 9.6.2): the
enclosing fork : NAME’s name, if this CFG is one of its branches,
and/or this CFG’s own named outermost block (peer_block(body)),
if it has one. Empty when nothing could ever name this process this
way. sv-sim-codegen::process_lower’s fork/join lowering copies this
into each branch’s own [super::super::sched::SpawnSpec:: disable_name].
fork_branch_names: Vec<String>Every name Self::disable_names of a fork branch this CFG’s own
walk resolved a disable <label>; against WITHOUT a same-process
lexical match (not an enclosing BasicBlock, not this CFG’s own
fork_name, not a procedural-assertion label): the kept disable
statement’s codegen (sv-sim-codegen::process_lower) reads this to
tell such a statement apart from the ones that resolve to the OLDER,
same-fork-only sv_rt_disable_fork_block path – see
[CfgBuilder::fork_branch_names]’s own doc comment for how it
accumulates (parent-to-branch, branch-to-branch, and forward past
the fork statement that spawned them).
disable_scopes: Vec<(BlockId, String, BlockId)>(resume, label, exit): while the process is suspended and will resume
at block resume, it is inside the named block or task activation
label, which a disable label; of another process ends by resuming
the process at block exit instead (LRM 9.6.2). Only labels some
disable of the design names ([is_disabled_somewhere]) are listed.
A segment index is a valid resume point of the compiled kernel.
disable_broadcast: Vec<(String, bool)>The labels of the disable statements this CFG keeps as statements
because they must also reach the processes other than this one that
are inside the named block or task (sv_rt_disable_named), with
whether the statement is the whole effect of the disable (an
unresolved target: no jump follows, so codegen emits the VPI
cbDisable probe itself).
inherited: Vec<InheritedSlot>For a synthetic fork branch ([CfgBuilder::walk_nba_event]): the
frame slots of the forking process copied BY VALUE into this
branch’s own at the spawn (LRM 1800-2023 §10.4.2: the right-hand
side and the repeat count are evaluated when the assignment is
reached, not when its event fires).
capture_types: Vec<Option<Symbol<'d>>>Per capture temporary (captures), the formal whose type sizes its
frame slot instead of the captured expression’s (a recursive task’s
call arguments, [CfgBuilder::inline_recursive_task]); entries past
the end are None.
recursion: RecursionWhether this CFG is a recursive task’s activation (Recursion).
Two fork branches carrying the same id were built from the same
statement in the same inherited context ([ForkBranchKey]), so
they are the same CFG and lower to the same kernel: the lowering
compiles it once per process and points every spawn at that code
(a UVM testbench otherwise cloned each branch once per path of
nested forks leading to it, tens of GB of IR). None for a branch
that is not shared.
Implementations§
Source§impl ProcessCfg<'_>
impl ProcessCfg<'_>
Sourcepub fn branch_disable_labels(&self) -> Vec<String>
pub fn branch_disable_labels(&self) -> Vec<String>
The labels of the disable scopes of every fork branch under this CFG
(nested forks included): the blocks of the branch kernels a
disable of another process can end (LRM 9.6.2).
Sourcepub fn branch_disable_broadcast(&self) -> Vec<(String, bool)>
pub fn branch_disable_broadcast(&self) -> Vec<(String, bool)>
The disable broadcast targets of every fork branch under this CFG
(nested forks included), as ProcessCfg::disable_broadcast: a
disable u1.blk; inside a branch must resolve as one in the process
itself does, or be refused (LRM 9.6.2).