Pipeline - wgrzegorz/c5xtools GitHub Wiki

Pipeline

Normative source: SPRU056D, chapter 7 (Pipeline Structure, Pipeline Operation, Pipeline Latency).

The TMS320C5x executes instructions through a four-level pipeline. At any moment up to four instructions are in flight, each occupying a different phase, so that one instruction can finish while the next three advance. The pipeline is not hardware-protected for every conflict: most interlocks are left to the programmer, who must arrange code so that two phases never fight over the same resource. This page transcribes the four phases, shows how instructions overlap cycle by cycle, walks through the conflict cases (branches, memory-mapped register loads, external-bus contention), and lists the latency a program must account for after writing certain registers.


1. Pipeline structure

The pipeline has four phases. Each instruction passes through all four in order:

Phase Letter What it does
Fetch F Reads the instruction word(s) from memory and updates the program counter (PC).
Decode D Decodes the instruction word, generates the operand address, and performs ARAU updates of the auxiliary registers.
Read R Reads operands from memory when the instruction needs them. In indirect mode it reads the location pointed at by the current AR as it stood before the update made in the previous decode phase.
Execute E Carries out the operation and, when required, writes the result of an earlier operation back to memory.

When the pipeline is fully loaded, all four phases run in parallel on four different instructions. The hardware assigns no priority among the phases, so if two phases need the same resource (a memory location or a CPU register) in the same cycle, the result is undefined. The programmer's job is to keep those collisions out of the code.

ASCII rendering of the fully loaded pipeline (after SPRU056D Figure 7-1), with instruction N entering fetch while older instructions occupy the later phases:

Each column is one CLKIN cycle. A single-word, single-cycle instruction run with no wait states overlaps perfectly: once the pipe is primed, one instruction reaches execute every cycle.


2. How instructions flow each cycle

Follow one instruction diagonally: it is fetched, then one cycle later decoded, then read, then executed - four cycles from fetch to completion. Because the four phases work on four different instructions at once, a new instruction starts and an old one finishes on every cycle of a filled pipe.

flowchart LR
    F["Fetch (F)\nread word, update PC"] --> D["Decode (D)\ndecode, address gen, ARAU update"]
    D --> R["Read (R)\nread operand (AR pre-update)"]
    R --> E["Execute (E)\noperate, write-back"]

A two-word instruction spends two cycles in fetch (one per word). The cycle that fetches the second word produces a "dummy" operation one phase downstream, because that fetched word is an operand, not a new opcode. The reference tables show this as the word "dummy" sitting in the decode, read, or execute slot.


3. Pipeline operation

The pipeline is invisible to the programmer except in a handful of situations: auxiliary-register updates, memory-mapped accesses to CPU registers, the NORM instruction, and memory-configuration changes. In those cases the lack of full protection shows through and the code must be arranged to avoid a conflict.

3.1 Normal operation (one-word and two-word)

For a stream of one-word, single-cycle instructions the pipe stays full and the F/D/R/E diagonal above holds. A worked one-word example from the source (ADD *+, SAMM TREG0, MPY *+, SQRA *+,AR2) illustrates two points that recur throughout the chapter:

  • An indirect read in the R phase uses the AR value that existed before the decode-phase update two cycles earlier, not the current value.
  • A memory-mapped store such as SAMM TREG0 writes in the E phase, so its effect is not visible to instructions already past their own decode phase.

3.2 Branch, call, and return

Because the pipe is four levels deep, a branch, a subroutine call, or a return normally takes 4 cycles to flush the partially fetched instructions that follow it in memory. A conditional branch (BCND) also costs 4 cycles when its condition is true; when the condition is false the BCND behaves like an ordinary two-word instruction and no flush occurs.

The decision happens in the branch's execute (E) phase. Only then is the PC updated - to the destination when the branch is taken, or to the next sequential instruction when it is not. The instructions fetched speculatively in the meantime are turned into dummy operations as they move down the pipe.

Transcribed flush sequence for a taken branch (SPRU056D Table 7-3, ADD/BCND LBL,NEQ/.../LBL SUB *+; F/D/R/E columns, "dummy" = flushed slot):

Cycles 4 through the re-fetch of the branch target are consumed by dummy operations - the 4-cycle flush. For a call the return address is pushed onto the top of stack (TOS) during the E phase before control transfers; for a return, the address is popped from TOS back into the PC in the E phase. The dummy sequence that surrounds them is the same.

3.3 Memory-mapped loads of auxiliary registers

ARAU updates of the ARs happen in the decode (D) phase, early enough to feed the following read (R) phase. But a memory-mapped write to an AR (for example SAMM, LMMR, SACL, or SPLK targeting the AR) happens in the execute (E) phase, which is later. Consequently:

  • The next two instructions after a memory-mapped load of an AR must not use that AR.
  • Updates to the index register (INDX) and to the auxiliary-register compare register (ARCR) also occur in the E phase, so any AR update that relies on INDX or ARCR must come at least two cycles after the load of those registers.

Inserting one or two NOPs between the memory-mapped load and the dependent use (as the source's Example 7-7 and Example 7-8 show) resolves the hazard.

3.4 External-memory bus conflict

The C5x has a single external address/data bus pair. If both program and data memory are external, the instruction fetch (F), operand read (R), and execute (E) write phases can all demand the external bus at once. The hardware inserts a dummy operation to break the tie, delaying the losing access by a cycle. An external write takes 3 cycles, so while a store (e.g. SACL) occupies the E phase writing externally, any instruction fetch or operand read that needs the external bus is delayed for 3 cycles.


4. Pipeline latency

Memory-mapped registers are reached in the decode (D) and fetch (F) phases, but they are written in the E phase. A write therefore does not take effect until a few instruction words later; instructions in between see the old value. Table 7-10 of the source lists, for each register, how many words of latency to allow.

Direct accesses that do not use memory-mapped addressing - all the C2x-compatible instructions such as LAR and LT - are pipeline-protected (stalled) in hardware, so they introduce no programmer-visible latency. The latency below applies only to the memory-mapped write path.

Register Description Words A later instruction is affected by
ARx Auxiliary registers 0-7 2 Next word uses the previous value; a second-word update is overwritten
ARCR Auxiliary register compare register 2 Next 2 words use the previous value
BMAR Block move address register 1 Next 1 word uses the previous value
CBCR Circular buffer control register 2 Next 2 words cannot be the end of a buffer
CBER Circular buffer end registers 1 and 2 2 Next 2 words cannot be the end of a buffer
CBSR Circular buffer start registers 1 and 2 2 Next 2 words use the previous value
CWSR Wait-state control register 1 Next 1 word uses the previous modes
GREG Global memory allocation register 1 Next 1 word uses the previous map
INDX Index register 2 Next 2 words use the previous value
IOWSR I/O port wait-state register 1 Next 1 word uses the previous count
PDWSR Program/data wait-state register 1 Next 1 word uses the previous count
PMST Processor mode status register 2 Next 2 words use the previous map
ST1 Configuration control (CNF) bit in ST1 2 Next 2 words use the previous map
TREG1 Dynamic shift count 1 Next 1 word uses the old shift count
TREG2 Dynamic bit address 1 Next 1 word uses the old bit address

4.1 NORM and the -p assembler option

The NORM instruction changes the current AR in its execute (E) phase. The same pipeline management applies: an AR update or an SAR store placed directly after a NORM would use the stale AR. The assembler's -p option detects an AR update or store immediately after NORM and inserts NOP instructions automatically, so the code stays source-compatible with the C2x.

4.2 Memory-reconfiguration latency

The C5x reconfigures memory segments (internal versus external) during the E phase. Before an instruction can rely on the new configuration, at least two instruction words must follow the reconfiguring instruction. A long-immediate instruction counts as two words and can fill the requirement by itself:

    CLRC    CNF             ; map RAM block B0 into data space
    LACC    #01234h         ; 2-word instruction fills the 2-word gap; ACC = 00001234h
    ADD     *               ; ACC = 00001235h

The same two-word rule applies to configurations controlled by the PMST. A related caveat concerns CNF and interrupts: if the main code runs in block B0 (CNF = 1) and an interrupt service routine that is not in B0 clears CNF to 0, a RETE will not restore CNF in time to fetch the next instruction from B0. The service routine must therefore set the CNF bit at least two words before the RETE.


5. Relation to the Instruction Timing page

Everything above describes the mechanism; the Instruction Timing page gives the resulting cycle counts. A one-word, single-cycle instruction in a full pipe retires every cycle - the non-delayed, fully overlapped case. Operations that break the overlap cost extra cycles that Instruction Timing accounts for: a branch, call, or return flushes the pipe for 4 cycles, external-bus contention inserts dummy cycles (and up to 3 cycles for an external write), and the memory-mapped register latencies above force spacing (one or two words) between a write and its first dependent use. Read the two pages together: this page says why a given instruction class is not single-cycle, and Instruction Timing says how many cycles it is.


License

MIT - (c) 2026 Grzegorz Worona [email protected]. See LICENSE.