LinxCore Pipeline Stage Catalog¶
This published page mirrors the canonical LinxCore source in
rtl/LinxCore/docs/architecture/pipeline-stage-catalog.md.
This chapter defines the canonical LinxCore stage names, their timing coordinates, and the behavior owned at each boundary. The names follow the ARM-reference taxonomy where that taxonomy is ISA-neutral, while the behavior is rebound to LinxISA block, BID, recovery, and memory contracts.
The catalog is a target contract. Current pyCircuit, Chisel, and LinxTrace names that disagree with it are legacy implementation aliases and must not be used to redefine the stage meanings below.
Stage ownership rules¶
- Every architecturally visible stateful boundary has one named state owner. A service contributor (for example, I-cache or PRF) does not become a second owner, and one pipe module may own several separately visible E/W or R coordinates. Pure timing coordinates need a named owner family, not a one-file-per-cycle implementation.
- A lane count never determines a stage name. In particular,
I-F4does not mean “four-slot decode.” EandWare coordinate systems, not one serial stage chain.E1..Encount absolute execute cycles afterI2;W1..Wncount producer-relative actual data-bypass/result/writeback age.CMTandFLSare semantic events published coherently at R2. The physical completion/commit/flush/restart pipeline usesR0..R4.- Stage wrappers may adapt interfaces or export probes, but they must not merge multiple architectural stages into anonymous glue.
Canonical pipeline overview¶
I-SIDE: I-F0 -> I-F1 -> I-F2 -> I-F3 -> I-F4 -> Instruction Buffer -> D1 -> D2 -> D3
|
v
S1 -> S2 -> S3/IQ
|
v
[P0] -> P1 -> I1 -> I2 -> E1 -> E2 -> E3 -> ...
\---- W1/W2/W3 overlay
B-SIDE: B-F0 -> B-F1 -> B-F2 -> B-F3 -> B-F4 -> response/correction
resolve/ROB -> R0 -> R1 -> R2 -> R3 -> R4
| |
CMT/FLS typed restart -> I-F0
P0 is optional unless it is a registered, trace-visible preselect boundary.
All other named stages above are canonical.
IFU engines¶
The IFU architecture is defined normatively in ifu.md. I-SIDE and B-SIDE
are independently backpressured engines joined only by decoupled,
identity-qualified request, response, cancellation, boundary, and training
channels. I-SIDE uses I-F0..I-F4; B-SIDE uses B-F0..B-F4. The two
pipelines are not lockstep.
I-F0¶
- Owner module:
src/bcc/ifu/f0.py. - Is I-SIDE stage 0.
- Captures the selected STID/PC, aligns the cache-line address, and allocates request/epoch/checkpoint identity.
- Launches independent I-SIDE and B-SIDE requests through decoupled channels.
I-F1¶
- Target owner:
src/bcc/ifu/f1.pyafter responsibility convergence. - Is I-SIDE stage 1.
- Launches ITLB and L1I lookups in parallel for the same I-F0 request.
- Carries request ID, STID, PC, epoch, and checkpoint identity.
I-F2¶
- Target state owner:
src/bcc/ifu/f2.py;src/bcc/ifu/icache.pyis the cache service owner after stage-boundary convergence. - Is I-SIDE stage 2.
- Joins ITLB and L1I results by request identity and validates translation, permission, physical tag, integrity, and hit/miss state.
- An ITLB miss produces an identity-qualified inner flush and translation replay for that STID. It is frontend-local and does not flush architectural backend state.
- An L1I miss allocates or joins an instruction-refill transaction.
I-F3¶
- Target state owner:
src/bcc/ifu/f3.py. - Is I-SIDE stage 3.
- Captures one complete L1I cache line, aligns the byte stream from the requested PC, and retains/joins cross-line carry.
- Presents ordered bytes to I-F4 without determining instruction length or performing predecode.
I-F4¶
- Target state owner:
src/bcc/ifu/f4.pyafter responsibility convergence. - Is I-SIDE stage 4.
- Determines 2/4/6/8-byte encoded length, completes instruction assembly,
zero-extends each instruction to 64 bits, and predecodes only
BSTART/BSTOP. - Writes complete 64-bit instruction records and metadata into the Instruction Buffer.
- Does not own branch prediction, general opcode decode, operand decode, immediate extraction, split/fuse analysis, or template expansion.
- Holds its output stable under Instruction Buffer backpressure.
Instruction Buffer¶
- Owner module:
src/top/modules/ib.pyafter interface convergence. - Is a queue boundary between I-F4 and D1; it is not another name for I-F4.
- Stores a 64-bit instruction payload, PC, encoded length, STID, request ID, epoch/checkpoint, BSTART/BSTOP hints, prediction metadata, and fetch fault.
- Presents up to four consecutive same-STID records to D1 and never compacts past an invalid, cancelled, faulting, or different-STID entry.
B-F0¶
- Owns B-SIDE L0/NLP lookup and GHR/GHRQ/RAS history snapshot.
- Accepts decoupled PC/request/epoch/checkpoint identity from I-F0.
B-F1¶
- Owns uBTB and RAS lookup.
- May publish an early identity-qualified target prediction.
B-F2¶
- Owns PBTB/BTB and BIM lookup.
- Carries the B-F0 history snapshot rather than resampling live history.
B-F3¶
- Owns short/medium-history TAGE providers and IBTB lookup.
- Produces the current direction/target/confidence candidate.
B-F4¶
- Runs static prediction from matched I-F4 boundary metadata, owns long-history TAGE, final IBTB/loop predictor/loop-buffer results, and final provider arbitration.
- Provider rank is
B-F4 > B-F3 > B-F2 > B-F1 > B-F0 > sequential. - Exact RAS return and high-confidence IBTB indirect target are same-rank B-F4
target authorities. Direction override order is
loop > long-TAGE > short-TAGE > BIM > static; BTB supplies direct targets. - Backend typed restart is not a provider and has highest restart priority.
- Publishes the retained final prediction response and speculative GHR/GHRQ/ RAS recovery intent. Live speculative-state updates occur only when the same redirect returns as the canonical prune.
- Any B-F1..B-F4 result that corrects an accepted lower-ranked prediction emits an identity-qualified inner flush; canonical prune restores the immutable B-F0 GHR/RAS snapshots, appends the corrected conditional direction or applies the corrected Call/Return delta once, kills younger history rows, and restarts I-F0 at the corrected PC. B-F4 is the final such point.
- B-F4 seals the record carried by every valid D1 lane. Dispatch validates direct/call properties, while BRU E1 validates conditional direction and indirect/return targets; mismatch enters BRU flush/recover and publishes its restart to I-F0.
- Chisel
IfuBackendFeedbackBridgeimplements that type-specific comparison and atomically publishes actual-result training plus exact-keyed backend restart. Dispatch/BRU event production and full-BID ROB/BROB cleanup remain production composition owners; the wrapper does not close those paths by itself.
Decode, rename, and dispatch stages¶
D1¶
- Owner family:
src/bcc/ooo/dec1.py, Chiselfrontend/D1InstructionDecodeStage.scala, and their canonical decode helpers. - Reads up to
instructionDecodeWidthcontiguous Instruction Buffer entries from one STID; supported OOO widths are 2, 4, and 6. - Receives fixed 64-bit instruction payloads; no byte-window reconstruction or neighboring-entry concatenation is allowed.
- Each Chisel lane preserves the final B-F4 prediction sidecar and dynamic
instruction UID;
FrontendDecodeStageremains a packet/window verification fixture and is not the production D1 composition boundary. - Performs the first full opcode/operand/immediate decode, detects illegal encodings and early exceptions, identifies split/fuse forms, and forms the decode group.
- With one BROB allocation port, stops before a second new-block boundary and starts a non-leading BSTART/template in the next group.
- May compute resource demand, but does not mutate rename, ROB, BROB, or IQ state.
D2¶
- Owner family:
src/bcc/ooo/dec2.py. - Extracts architectural operands and immediates, resolves Linx boundary metadata, and calculates ROB/BROB/rename/IQ/memory-order demand.
- Produces one coherent virtual RID/group and resource-demand plan for D3.
- Marks which single boundary allocates BID and assigns that new BID to the boundary plus following rows in slot order.
- Does not claim physical tags or advance architectural ordering pointers.
D3¶
- Owner family:
src/bcc/ooo/ren.pyplus the ROB/BROB admission owners. - Provisionally reserves all required resources or reserves none.
- Allocates at most
BROB_ALLOC_PER_CYCLEBIDs and stamps boundary ownership in decode-slot order; the baseline admits adjacent BSTARTs in separate groups. - Performs scalar
Pand localT/Uphysical rename, receives grouped ROB-owned RID, BROB-ownedBID_W-bit BID, and memory-order identities, and writes the corresponding speculative side structures. - Selects the dispatch route and retains the complete reservation transaction until S1 publication.
S1¶
- Owner family:
src/bcc/ooo/s1.py. - Atomically publishes the grouped ROB members, speculative rename/MapQ state, and retained IEX speculative slots.
- Carries execution class, route, readiness seed, exact reservation identity, age, and cancellation state until IEX acceptance.
S2¶
- Owner family:
src/bcc/ooo/s2.pyandsrc/bcc/backend/dispatch.py. - Selects a free physical IQ entry and writes the packet plus initial source readiness.
S3 / IQ — resident and pick-visible boundary¶
- Owner family:
src/bcc/backend/issue.py. - Makes the S2-written row valid, resident, wakeable, and eligible for later pick.
- Owns source readiness, speculative readiness, age, and
inflightstate.
Pick and issue stages¶
P0 — optional queue-local preselect¶
- Target state owner when registered:
src/bcc/backend/issue.py. - May reduce a large IQ to a smaller candidate set.
- Is named only when implemented as a registered boundary. Combinational preselection remains part of P1.
P1¶
- Owner module:
src/bcc/backend/issue.py. - Selects the oldest ready, non-
inflightcandidate within each STID, then arbitrates fairly across eligible STIDs for each shared legal pipe. - Marks the selected resident row
inflight; it does not deallocate the row.
I1¶
- Owner modules:
src/bcc/backend/issue.pyandsrc/bcc/backend/prf.py. - Determines which operands require RF access, performs global read-port arbitration, and reads physical sources.
- A losing attempt cancels back to resident S3/IQ state.
I2¶
- Owner modules:
src/bcc/backend/issue.pyandsrc/bcc/backend/modules/exec_pipe_cluster.py. - Selects the newest legal RF/bypass value, performs final cancellation checks, and transfers the uop to its execution pipe.
- A confirmed non-speculative/non-cancellable transfer is the IQ deallocation point. A uop with live load-dependence state remains resident and inflight until all producer loads resolve hit at E5; miss/replay cancels the pipe copy and clears inflight for repick.
Execute and result coordinates¶
E-stage rules¶
E1is the first cycle after I2 issue confirmation.E2,E3, and laterElabels retain absolute position even when a result is not yet available.- Pipe behavior is named explicitly, for example
bru_e1decision,bru_e2resolve,ld_e2tag lookup, orld_e4data return.
E1¶
- Owner modules:
src/bcc/backend/modules/exec_pipe_cluster.pyandsrc/bcc/iex/iex.py. - First absolute execute cycle after I2.
E2¶
- Owner modules:
src/bcc/backend/modules/exec_pipe_cluster.pyand thesrc/bcc/iex/iex_alu.py/iex_bru.pyfamilies. - Second absolute execute cycle; baseline branch resolve is E2.
E3¶
- Owner modules:
src/bcc/backend/modules/exec_pipe_cluster.pyandsrc/bcc/backend/lsu.py. - Third absolute execute cycle for longer scalar and memory work.
E4¶
- Owner modules:
src/bcc/backend/lsu.pyandsrc/bcc/lsu/l1d.py. - Baseline load-result cycle and the first load result/writeback age.
E5 — load resolve¶
- Owner modules:
src/bcc/backend/lsu.pyand the ROB/LSU completion boundary. - Publishes stable load hit/miss/fault/replay classification and final ROB-visible load resolve after the E4 data/forwarding point.
E6 — load RF-visible retention¶
- Target owners:
src/bcc/backend/lsu.pyandsrc/bcc/backend/prf.py. - Retains a baseline hit result through the load W3/RF-visible age after E5 resolve. It does not delay the E4/W1 consumer bypass.
W-stage rules¶
- Every pipe declares
{spec_wakeup, data_bypass, rf_write, resolve}against its E and W coordinates. Speculative wakeup is a separate cancellable E-stage event that predicts a future W1. W1is the first age with actual producer data available to the bypass/ result network.W2andW3are later producer-relative ages. For the baseline integer pipe they cover RF write and RF-visible/retained-bypass timing.- Special pipes may deliver data later or write RF at W4; they must not force the baseline scalar convention onto unrelated pipelines.
- Control-only operations without a data result use E-stage resolve names and do not invent a W stage.
W1¶
- Owner module:
src/bcc/backend/modules/exec_pipe_cluster.py. - First actual data-bypass/result age for each result-producing pipe.
W2¶
- Owner modules:
src/bcc/backend/modules/exec_pipe_cluster.pyandsrc/bcc/backend/prf.py. - Second result age and baseline RF-write coordinate.
W3 — RF-visible result age¶
- Target owners:
src/bcc/backend/modules/exec_pipe_cluster.pyandsrc/bcc/backend/prf.py. - Third result age and baseline RF-visible coordinate. Current implementation and LinxTrace tokens do not yet expose this required stage.
Baseline alignment examples:
| Producer | Baseline data result | Next age | RF-visible age |
|---|---|---|---|
| 1-cycle scalar ALU | E1/W1 |
E2/W2 |
E3/W3 |
| 2-cycle scalar ALU | E2/W1 |
E3/W2 |
E4/W3 |
| 3-cycle scalar/MAC | E3/W1 |
E4/W2 |
E5/W3 |
| Baseline load hit | E4/W1 |
E5/W2 |
E6/W3 |
| Branch/control | decision at E1 |
resolve at E2 |
no W label unless it writes data |
This table defines baseline scalar data-result alignment, not universal latency. A pipe may wake speculatively at an earlier E stage, use a later RF-write age such as W4, or change latency only when its declared tuple and dependency/recovery timing are updated consistently.
ROB, commit, and recovery stages¶
ROB¶
- Owner modules:
src/bcc/ooo/rob.py,src/bcc/backend/rob.py, andsrc/bcc/backend/modules/rob_bank.py. - Owns precise row state, completion, exception/nuke metadata, and the separate commit and deallocation walks.
R0 — completion and resolve intake¶
- Target state owner:
src/bcc/backend/rob.py. - Captures execute, LSU, block, exception, and replay resolve inputs into ROB-visible state.
R1 — retire-window decision¶
- Target state owner:
src/bcc/backend/commit.py. - Reads the contiguous ROB head window, gathers completion/exception/memory/ block/cleanup eligibility, and generates the maximal legal in-order commit prefix plus any precise trap, interrupt, nuke, or boundary-flush decision.
R2 — commit and flush publication¶
- Target state owner:
src/bcc/backend/commit.py. - Publishes ordered commit rows (
CMT) and the coherentFLSflush broadcast. - Advances commit/flush state and launches rename, local-register, LSU, trace, and block-last cleanup from one R1 decision snapshot.
R3 — registered recovery processing¶
- Target state owner:
src/bcc/ooo/flush_ctrl.py. - Consumes the registered recovery/exception classification and performs owner-side recovery processing and cleanup.
- Retired rows remain resident until the deallocation contract is satisfied.
R4 — restart and restored state¶
- Target state owner:
src/bcc/ooo/flush_ctrl.py; I-F0 consumes its registered restart output. - Publishes the legal restart PC and restored architectural/frontend state to I-F0.
- Completes recovery-visible side effects that require the R2/R3 work. Later ROB deallocation is allowed and is not renamed as a W stage.
CMT¶
- Owner modules:
src/bcc/backend/commit.pyandsrc/bcc/backend/modules/commit_slot_step.py. - Semantic ordered-commit event published at R2; not a W stage.
FLS¶
- Owner modules:
src/bcc/ooo/flush_ctrl.pyandsrc/bcc/backend/modules/recovery_checks.py. - Semantic flush broadcast published coherently with CMT at R2; not a W stage. The corresponding restart PC/restored state becomes visible at R4.
Current implementation-name migration¶
| Current implementation name | Canonical interpretation |
|---|---|
src/bcc/ifu/f0.py |
Target I-F0 owner |
src/bcc/ifu/f3.py internal ibuffer |
Instruction Buffer implementation contributor |
src/bcc/ifu/f4.py, Chisel F4DecodeWindow |
Non-conforming implementation names; replace with I-F4 predecode/write and fixed-width D1 decode owners |
| incorrectly ordered frontend trace tokens | Migrate to ordered I-F4 -> IB -> D1 events |
commit-head or trace-prep W1/W2 probes |
Incorrect W ownership; move to producer result/writeback state |
missing S3, E5, E6, W3, and R0..R4 tokens |
Trace/implementation promotion gap |
Specifications and new interfaces must use only the canonical meanings above.
IB¶
- Owner module:
src/top/modules/ib.py. - Canonically IB is the queue after I-F4 and before D1.
IQ¶
- Legacy trace owner:
src/bcc/backend/issue.py. - Compatibility-only token for the current schema. Canonically the IQ entry becomes resident and pick-visible at S3; IQ is the structure, not a serial stage before S1 or S2.
LSU stage family¶
LIQ¶
- Owner module:
src/bcc/lsu/liq.py(JanusBccLsuLiq) - Design role: bring-up shell for the active load-inflight window. The
canonical C++/Chisel owners are
LDQInfo/LoadInflightQueue, which retain miss, wait-store, replay, refill, and relaunch state.
LHQ¶
- Owner module:
src/bcc/lsu/lhq.py(JanusBccLsuLhq) - Design role: bring-up shell for resolved-load state. The canonical
C++/Chisel owners are
ResolveQ/LoadResolveQueue, which retain resolved address and byte metadata for late ordering-conflict detection.
STQ¶
- Owner module:
src/bcc/lsu/stq.py(JanusBccLsuStq) - Design role: speculative store ordering, forwarding visibility, and flushable store state.
SCB¶
- Owner module:
src/bcc/lsu/scb.py(JanusBccLsuScb) - Design role: committed-store coalescing and downstream drain management.
MDB¶
- Owner module:
src/bcc/lsu/mdb.py(JanusBccLsuMdb) - Design role: memory-disambiguation/store-set prediction, recurring-conflict learning, wait-store classification, and recovery-candidate publication.
- MDB does not own precise nuke timing; the ROB/recovery owner does.
L1D¶
- Adapter owner module:
src/bcc/lsu/l1d.py(JanusBccLsuL1D). - Golden owner:
chisel/src/main/scala/linxcore/lsu/ScalarL1D.scala(ScalarL1D). The reduced pyCircuit module is an adapter, not a second architectural definition. - Design role: parameterized scalar data-cache tag/data/permission owner.
ScalarLSULoadPathsupplies the active LIQ phase lookup and retained refill;ScalarLSUconnects SCB write-side lookup and byte update to the same owner. - Port priority is refill, committed SCB update/lookup, then scalar load LRU touch. Refill blocks new array launches until duplicate installation or victim eviction is accepted. The E2 lookup result is registered and merged with SCB/STQ data in E3.
LoadMissQueueseparately owns unique-line lower requests and exact response identity.LoadRefillTransportseparately owns refill retention. The lower-memory fabric, coherence acquisition, explicit invalidation, and cache maintenance remain separate interfaces.
Block-control stages¶
BISQ¶
- Owner module:
src/bcc/bctrl/bisq.py(JanusBccBctrlBisq) - Design role: block-issue queue ownership and BID-carrying enqueue state.
BCTRL¶
- Owner module:
src/bcc/bctrl/bctrl.py(JanusBccBctrl) - Design role: block command routing, engine command launch, and response path coordination.
TMU¶
- Owner module:
src/tmu/noc/node.py(JanusTmuNocNode) - Design role: tile-network issue/response boundary used by block-control command transport.
TMA¶
- Owner module:
src/tma/tma.py(JanusTma) - Design role: reduced Tile Memory Access command/completion facade. The target architecture keeps this block-visible frontend but moves southbound memory transport to a shared CSU/L2 owner that is not yet promoted here.
CUBE¶
- Owner module:
src/cube/cube.py(JanusCube) - Design role: cube-engine command/response boundary.
VEC¶
- Owner module:
src/vec/vec.py(LinxCoreVec) - Design role: vector-engine command/response boundary.
TAU¶
- Owner module:
src/tau/tau.py(JanusTau) - Design role: typed tile-to-tile template/tile-operation command/response boundary; memory access remains tile-to-tile.
TEPL — target TAU selector¶
- Target route: BCTRL preserves the architectural selector and dispatches it to
a promoted
src/tau/tau.py(JanusTau) byTileOpcode. - Design role: preserve TEPL block identity through BCTRL/BROB while TAU owns typed tile-to-tile execution and one non-scalar completion. Current TAU is a reduced shell, so TEPL remains unsupported until this route is promoted.
BROB¶
- Owner module:
src/bcc/bctrl/brob.py(JanusBccBctrlBrob) - Design role: BID allocation, block completion, block exception capture, and oldest-block retirement gating.
XCHK¶
- Owner module:
src/top/modules/xchk.py(LinxCoreXchkStage) - Design role: strict cross-check/export correlation boundary used by commit verification and LinxTrace annotation.
Engine stages¶
TMU¶
- Owner modules:
src/tmu/noc/node.pysrc/tmu/noc/pipe.pysrc/tmu/sram/tilereg.py- Design role: tile-movement and tile-state transport ownership.
TMA¶
- Owner module:
src/tma/tma.py(JanusTma) - Design role: current Tile Memory Access frontend/completion boundary under block control. Southbound memory transport converges to the shared CSU/L2 owner rather than remaining hidden in a peer engine.
CUBE¶
- Owner module:
src/cube/cube.py(JanusCube) - Design role: cube-engine execution boundary under block control.
VEC¶
- Owner module:
src/vec/vec.py(LinxCoreVec) - Design role: programmable SIMT engine boundary under block control.
TAU¶
- Owner module:
src/tau/tau.py(JanusTau) - Design role: typed tile-to-tile template/tile-operation boundary under block control.
TEPL — TAU-selected execution¶
- Target owner module:
src/tau/tau.py(JanusTau). - Design role:
TileOpcode-selected typed tile-to-tile execution. Unsupported or not-yet-promoted selector values fail explicitly and never alias another engine.