Intel announced the name Itanium on 4 October 1999, and the Usenet nickname "Itanic" appeared the same day; it stuck as the sales forecasts kept shrinking. The first systems shipped in June 2001, the last shipments ended on 29 July 2021. As textbook background: its EPIC format was meant to soften one form of binary incompatibility, a change in the number of slots — 128-bit bundles carry three 41-bit operations and a 5-bit template whose "stop" bits mark where a group of independent operations ends, so that a wider successor could issue more of them at once from the same binary.
The compiler takes the wheel: what a VLIW is
After this lesson you will read a VLIW bundle slot by slot, say who handles each hazard — the compiler, or the little hardware that is left — and weigh what static scheduling buys against what it costs.
In 1984 Josh Fisher — the researcher who coined the term instruction-level parallelism — could not find a company willing to build his very-long-instruction-word machine, so he founded one. Multiflow's TRACE 28/200 issued up to 28 operations from a single 1024-bit instruction word.
Twenty-eight operations leave in the same clock cycle, and in a VLIW no circuit compares their registers to see whether one of them needs the result of another. The notes say it plainly: "No need for runtime dependency checking anymore" (p. 267). How can such a machine compute the right answer?
And if it can, why did the idea stay out of general-purpose processors? Multiflow closed in 1990 after about 125 machines; Intel's Itanium, built on the same idea, became the "Itanic" — a nickname coined the very day its name was announced in 1999; and the processor in your laptop still checks every dependence in hardware. Keep the two questions: section 2 answers the first, section 6 the second.
One long word, one slot per unit
Your first architecture course built a pipeline that issues one instruction per cycle. Lesson 8 widened it: a superscalar issues several per cycle, and its hardware decides at run time which ones may go together. A VLIW issues several per cycle too, but the decision was taken earlier, by the compiler, and written into the program.
VLIW (Very Long Instruction Word) — a processor that executes several operations per clock cycle and relies on the compiler, not on dynamic hardware, to detect and schedule the parallelism. Independent operations are grouped into one long instruction word, the bundle, made of fixed slots, each corresponding to a functional unit (p. 266).
The notes sum the idea up in one highlighted line: "VLIW architectures represent a shift of complexity from the hardware to the compiler" (p. 267). A statically scheduled processor trusts "the compiler to 'fill the pipeline' and avoid hazards at compile time" (p. 266).
The operations inside a bundle are also called "syllables" (p. 267). A 4-issue VLIW has four slots per bundle, a 5-issue one five. The 2024 and 2026 papers use a 3-issue machine, June 2025 a 4-issue one with a second memory unit, and the sentence that describes the machine comes back almost word for word in all three.
"a 3-issue VLIW machine with fully pipelined functional units: 1 Memory Units with 3 cycles latency; 1 FP ALUs with 3 cycles latency; 1 Integer ALU with 1 cycle latency to next Int/FP/L/S & 2 cycle latency to next Branch. The branch is completed with 1 cycle delay slot (branch solved in ID stage). No branch prediction. In the Register File, it is possible to read and write at the same address at the same clock cycle."
Read it once slowly: every schedule of this lesson uses it.
Put a loop on that machine: the first loop of the 22 June 2026 paper.
LOOP1: LD F2, 0(R1) ; I0
FADD F6, F2, F2 ; I1
SD F6, 0(R1) ; I2
ADDUI R1, R1, 4 ; I3
BNE R1, R3, LOOP1 ; I4
The compiler fills a timetable with one row per clock cycle and one column per unit. The LD goes in C1. The FADD needs F2, which the memory unit delivers 3 cycles later: C4. The SD needs F6, ready 3 cycles after the FADD: C7. The ADDUI overwrites R1, which the SD still has to read; since the register file allows a read and a write of the same register in one cycle, the ADDUI may share C7 with the SD. The BNE needs the new R1, and an integer result reaches a branch 2 cycles later: C9. C10 is the delay slot.
| Memory Unit | Floating Point Unit | Integer Unit | |
|---|---|---|---|
| C1 | LD F2, 0(R1) | ||
| C2 | |||
| C3 | |||
| C4 | FADD F6, F2, F2 | ||
| C5 | |||
| C6 | |||
| C7 | SD F6, 0(R1) | ADDUI R1, R1, 4 | |
| C8 | |||
| C9 | BNE R1, R3, LOOP1 | ||
| C10 | (delay slot) |
Ten bundles of three slots: 30 slots, 5 operations, 25 empty. In the exam you leave the empty cells blank — the papers say "Please do not write in NOPs" — but in the program each one is a NOP, an operation that does nothing and still occupies its slot of the word (p. 266). The example formula sheet on the course page, prepared by a student, measures the waste in one line:
- \(IC\)
- operations scheduled in one iteration (NOPs not counted)
- \(\#\text{cycles}\)
- length of the iteration, delay slot included
- \(\#\text{issues}\)
- slots per bundle, the issue width
The papers ask three more numbers about the same table, all treated in lesson 20: the critical path, by the papers' convention the 10 cycles of the iteration with its delay slot; the CPI, cycles over instructions, 10 / 5 = 2; and the FP operations per cycle, 1 / 10 = 0.1.
Fig. 1 zooms into one row, bundle C7. Three rules keep such a word cheap for the hardware (pp. 267, 269). There is a single program counter, and each fetch brings one whole bundle. A bundle holds at most one branch, so each cycle has one next-PC decision to make. And each slot is wired to its own unit, so the decoder routes nothing.
A bundle is one row of the compiler's timetable: one slot per functional unit, an operation or a NOP in each, fetched by a single program counter.
Who handles each hazard
"The key difference compared to traditional superscalar processors lies in who decides what can run in parallel" (p. 266). A superscalar's hardware analyses dependences while the program runs; in a VLIW "this analysis is performed entirely at compile time" (p. 266). The compiler's job list on the same page has four lines: identify independent operations, solve structural hazards, solve data hazards, insert NOPs where nothing fits. Table 2 sets the two answers side by side.
| Hazard | VLIW: the compiler | Superscalar: the hardware |
|---|---|---|
| RAW | places the consumer at least one latency after the producer; fills the gap with independent operations or NOPs | holds the consumer until the operand arrives (scoreboard, reservation stations) |
| WAR, WAW | issues a WAR writer no earlier than the last reader (the same cycle is allowed) and makes a WAW writer's result land after the earlier one — or renames to another register | renames into reservation-station or ROB tags (the scoreboard of lesson 9 stalls the writer instead) |
| Structural | one operation per slot: the format itself keeps two operations off one unit | the issue logic checks for a free unit and station |
| Branch | may give a static hint; the hardware detects a misprediction and flushes (p. 271) | predicts dynamically and flushes on a misprediction |
| Data-cache miss | cannot be foreseen: the processor stalls (p. 272) | independent instructions keep executing around the miss |
The RAW row is where the compiler earns its keep. The notes' example: if C = A * B takes two cycles, "the compiler may schedule a NOP after it, before allowing an instruction that depends on C to execute" — or an independent instruction that has to run anyway (p. 270). A pipelined unit does not change the rule. The papers' FP ALU is fully pipelined: it accepts a new FADD every cycle, yet each FADD's result appears 3 cycles after it issues.
"Fully pipelined means latency 1." No. Pipelining fixes the throughput, one new operation per unit per cycle; the latency stays. In LOOP1 an independent FADD could issue in C5, right behind the first one, while the SD that needs F6 cannot go before C7.
Name dependences cost less: a WAR or a WAW shares a register name but carries no value (lesson 7). The compiler resolves them by "appropriately choosing the timing of operations" or by "using register renaming techniques" (p. 270), that is, by writing the result into another register. Structural hazards disappear "through scheduling decisions" (p. 270): with one memory slot, two memory operations simply never share a bundle.
So nothing on the chip checks the schedule. A schedule that ignores a latency does not run slower: it computes a wrong value. That is the meaning of "This static management of hazards is crucial because the hardware in VLIW processors does not dynamically detect or resolve data hazards during execution" (p. 270) — and the answer to the first question of the puzzle: the TRACE did not check its 28 operations because its compiler already had.
In a VLIW the compiler resolves RAW, WAR, WAW and structural hazards with latencies it knows in advance; the hardware only stalls on what nobody can foresee, a cache miss, and flushes a mispredicted branch.
The hardware that stays
Moving the scheduler into the compiler removes the scoreboard, the reservation stations and the dependence checks — "no complex dynamic scheduling (like Tomasulo or Scoreboarding)" (p. 275). It does not remove everything. Fig. 2 redraws the VLIW datapath of the notes (p. 268).
It is the five-stage pipeline of your first course, widened, with a stage of its own for the register read and the data-cache access inside EX: Instruction Fetch, Instruction Decode, Register Read, Execution and Write Back (p. 268). IF fetches one bundle; ID splits it into its operations; from then on "each operation within a bundle proceeds independently through the functional units connected to the pipeline" (p. 268).
The register file is what the notes call "one of the non-trivial aspects of the hardware design" (p. 268). An operation reads up to two registers and writes one, and all the operations of a bundle do it in the same cycle: a 4-issue VLIW needs a register file able to "read eight source operands and write four destination results every clock cycle" (p. 268). This is the shared, multi-ported register file.
- \(k\)
- issue width: operations per bundle, each with up to two sources and one destination (4-issue: 8 + 4; the papers' 3-issue machine: 6 + 3)
As background from the textbooks, not from the notes: every port adds its own access lines to every cell of the register file, so its area and power grow roughly with the square of the number of ports. That is the bill behind the clustered VLIWs of section 4.
Decoding stays trivial when there is one unit per slot: "each operation is directed straight to its corresponding functional unit for execution without the need for complex arbitration" (p. 269). With more units than slots, the machine needs a dispatch network — the crossbars of Fig. 2 — that forwards each operation, with its operands, to a free unit of the right kind (p. 269).
Two run-time events escape the compiler (p. 272). Whether a load misses in the data cache depends on the run: "If a cache miss occurs, the processor experiences a stall, which was not anticipated during static scheduling" — the whole timetable freezes until the data arrives. And a static branch hint can be wrong: the hardware must detect the misprediction and flush the bundles fetched behind it (pp. 271–272). Even a VLIW keeps an interlock for misses and flush logic for branches.
Gone: the hardware that finds parallelism. Kept: the pipeline, a register file with 2k read and k write ports, a dispatch network when units outnumber slots, a stall on a data-cache miss and a flush on a misprediction.
Every result needs a name: register pressure
Take the notes' example (p. 271). A bundle carries two FP operations of five cycles each; their destination registers "remain occupied for the entire duration of those five cycles". A new bundle issues every cycle, so by the time the first two results are written, five bundles have issued: 2 × 5 = 10 registers are reserved for results that do not exist yet. Put such operations in all four slots and you reach the notes' "up to twenty operations competing for register resources".
- \(N_{\text{flight}}\)
- registers held by results in flight
- \(n\)
- results started per cycle (destinations per bundle, one bundle per cycle)
- \(L\)
- latency of those operations; add a term \(n_i L_i\) for each kind of unit
It is the count of people in a queue: arrivals per minute times minutes each one stays. This pressure on the register file is what the notes call register pressure.
Predict: every cycle, a 4-issue bundle starts one load (latency 3), two FP operations (latency 5) and one integer operation (latency 1). How many registers do results in flight hold?
Check yourself
One term per kind of unit: 1 × 3 + 2 × 5 + 1 × 1 = 14. Not 4 × 5 = 20 — that is the notes' "up to twenty", the worst case in which every slot holds a 5-cycle operation.
Renaming makes it worse (p. 271). To remove a WAR or a WAW, the compiler writes the later result into a different register: it "avoids conflicts" but "increases the number of physical register needed". In a VLIW those are the architectural registers, the F0 … F31 the instruction set names; there is no hidden pool behind them. Lesson 15 did exactly this to an unrolled loop: the two registers each copy writes became eight.
Compare Tomasulo. There the code keeps naming F2 and F4, and the hardware renames every result into a reservation-station tag that no program ever sees. The values in flight still need storage — but it is silicon, bought once with the chip, not names taken from the fixed budget of the instruction set.
When the names run out, the compiler has the two ways out the widget shows (p. 271): "careful allocation strategies" — fewer operations in flight and a longer schedule — or "spilling values temporarily to memory": a store now and a reload later, both in memory slots, which pays only for a value that waits longer than the reload takes. The open challenges of the notes add a hardware remedy: clustered VLIW designs, several smaller register files, each serving a subset of the units (p. 274).
Static scheduling moves the cost of renaming from hardware tags to architectural registers: every result in flight needs a name the instruction set provides.
As fast as possible, without changing the answer
Code scheduling is "the process of rearranging program instructions to maximize parallelism during execution" (p. 275). Its goal is to reorder the instructions statically so that the execution time is minimised and semantic correctness is preserved: "we want the program to run as fast as possible without changing what it computes" (p. 275). On a VLIW nobody downstream reorders anything. If the compiler schedules badly, "the result is many NOPs and a waste of hardware resources" (p. 275).
Semantic correctness has a precise meaning (p. 275): every RAW is respected — a read comes after the write it depends on — and no WAR or WAW is violated; the scheduler analyses the dependence graph, reorders only when it is safe, and renames to remove false dependences. Try three tempting moves on LOOP1.
| Move | Rule at stake | Verdict |
|---|---|---|
FADD F6, F2, F2 up to C2, to fill a slot | RAW on F2: the FADD would read F2 before the load has written it | wrong value |
ADDUI R1, R1, 4 up to C1, "it has nothing to wait for" | WAR on R1: the SD in C7 would read the new R1 and store into the next element | wrong address — legal only as SD F6, -4(R1), an index change the papers forbid |
ADDUI R1, R1, 4 in C7, beside the SD | WAR on R1, kept: the register file reads the old R1 and writes the new one in the same cycle | allowed (Table 1) |
The second move would even pay: with the ADDUI in C1 and the SD rewritten as SD F6, -4(R1), the BNE could close the iteration in C7 and LOOP1 would take 8 cycles instead of 10. The papers rule this out in so many words — "do NOT introduce any software pipelining, loop unrolling and modifications to loop indexes" — so in the exam you reorder, you do not rewrite.
Such a scheduler works on a basic block, "a straight-line code sequence without branches except at the entry and exit points" (p. 273). Basic blocks are short — "for typical programs, only around 4 to 7 instructions are found between branches" (p. 273) — and the RAW chains inside them limit the parallelism further. LOOP1 is a five-instruction block whose chain LD → FADD → SD leaves 25 of its 30 slots empty. Filling them needs techniques that look beyond one block: unrolling, software pipelining and trace scheduling, the subject of lesson 21.
A correct schedule keeps every RAW and lets no write overtake a read (WAR) or another write (WAW) of the same register; within those rules, the shortest one wins.
What you buy, what you pay — and the answer to the puzzle
The notes list three advantages (p. 273). A VLIW exploits ILP statically, with high performance "even without the complex runtime scheduling hardware used in superscalar designs". The compiler analyses the program "with a much larger instruction window than would be feasible in hardware" — a whole loop, a whole function — especially after unrolling or software pipelining. And less hardware means "smaller die areas", "cheaper production costs and lower power consumption, making VLIWs attractive for embedded applications"; the fixed format simplifies decoding, and adding a unit means adding a slot.
Against them stand four open challenges (pp. 273–274). The machine needs strong compiler technology, inside basic blocks and across them. Code grows, with fixed bundles and NOPs, and compression "add[s] extra decoding complexity". Register management suffers from renaming, which clustered designs only partly fix. And the fourth is "a major limitation", binary incompatibility: "Even small changes in the number of slots, the types of functional units, or their latencies can render code compiled for one VLIW processor incompatible with another, even if they share the same instruction set architecture" (p. 274).
Before: compiled for, and run on, an FP latency of 3
After: the same binary on an FP latency of 4
A dynamically scheduled processor has no such problem: there "binary compatibility is preserved across generations" (p. 274). A just-in-time compiler could reschedule the binary for each new chip, but such solutions "introduce additional complexity and are rarely adopted in practice"; so VLIW processors live mainly "in embedded systems, where binaries can be compiled specifically for the target hardware" (p. 274).
Now the second question. The TRACE's compiler knew every unit and every latency and wrote its answer into the bundles, NOPs included. The price is this section's list: a compiler that must find the parallelism, code that carries its empty slots, register names spent on results in flight, stalls on misses the schedule could not foresee — and above all a binary welded to the latencies of one machine.
A laptop must run yesterday's programs on tomorrow's chip, so it keeps the scheduler in hardware and pays for it in area and power. A signal processor or an embedded controller runs one binary on one chip, so it can let the compiler drive. As textbook background, not in the notes: the Texas Instruments C6000 signal processors are VLIWs, and many GPUs and AI accelerators schedule statically in the same spirit. Multiflow's machines did not survive, but its compiler did: Intel, HP, DEC, Fujitsu and others licensed it.
VLIW trades hardware for compiler work: simpler, cheaper, lower-power chips and a large scheduling window, paid for with code size, register names, stalls on unforeseen misses and binaries tied to one implementation.
Exam-style questions
Explain the main concepts and benefits of each one of the following techniques used by VLIW processors:
- Static scheduling by the compiler
- Bundle with fixed slots
- NOP insertion
- Single program counter with at most one branch per bundle
- Shared multi-ported register file
- Fully pipelined functional units with exposed latencies
- Register renaming by the compiler
- Hardware support for dynamic events (data-cache misses, branch mispredictions)
Show model answer
1. The compiler analyses data dependences and resource constraints at compile time and decides which operations execute together and in which cycle; the hardware executes the schedule without checking it. Benefit: no dynamic scheduling hardware (no scoreboard, reservation stations or run-time dependence checks), hence less area and power; the compiler sees a much larger instruction window than any hardware. Cost: it must know all latencies and cannot see run-time events.
2. Independent operations are grouped into one very long instruction word; each slot corresponds to one functional unit (e.g. Memory, FP, Integer). Benefit: one fetch delivers k operations, decode is trivial (slot i goes to unit i, no arbitration), and scaling means adding slots.
3. When no independent operation is available for a slot, or a latency must elapse, the compiler fills the slot with a NOP. Benefit: the fixed format and the timing stay explicit, so no stall logic is needed. Cost: wasted slots and larger code; code efficiency = IC / (#cycles × #issues).
4. One PC fetches one bundle per cycle, and a bundle contains at most one branch. Benefit: a single next-PC decision per cycle keeps branch handling simple (in the exam's model the branch is solved in ID with one delay slot).
5. All the operations of a bundle read their operands in the same cycle, and every unit can write a result in every cycle: two read ports and one write port per operation, 8 + 4 for a 4-issue machine. Benefit: every unit gets its operands and writes its result without a bottleneck. Cost: area and power grow quickly with the number of ports, which leads to clustered VLIWs (several smaller register files, each serving a subset of the units).
6. Every unit accepts a new operation each cycle, and its result is available after a fixed latency (e.g. Memory 3, FP 3, Integer 1, 2 to a branch); the compiler places each consumer at least one latency after its producer and fills the gap with independent operations. Benefit: one operation per unit per cycle with no interlocks. Cost: the schedule, hence the binary, depends on the latencies of one implementation.
7. To remove WAR and WAW dependences the compiler writes results into different architectural registers. Benefit: more freedom to reorder and overlap operations, more ILP. Cost: register pressure — every result in flight needs an architectural register; when the register file saturates, values are spilled to memory.
8. The compiler cannot know whether a load will miss in the data cache or whether a static branch hint is wrong. On a miss the processor stalls; on a misprediction the hardware flushes the wrongly fetched bundles. Benefit: correct execution despite unpredictable events, while the regular flow stays free of checks. Cost: a stall freezes the whole schedule, which assumed the hit latency.
The June 2026 paper asks exactly this shape — eight techniques, five lines each, for the Tomasulo-style superscalar; this is its VLIW twin. Give each sub-point its concept in one sentence and its benefit in the next; for 3, 5, 6 and 7 add the cost too, since there the benefit only makes sense against it. Use the precise terms (bundle, slot, NOP, latency, WAR / WAW, renaming, spill), and never let the VLIW hardware "check" or "rename" anything.
Let's consider the following LOOP1 code, where Ri are integer registers and Fi are floating-point registers:
LOOP1: LD F2, 0(R1)
FADD F6, F2, F2
SD F6, 0(R1)
ADDUI R1, R1, 4
BNE R1, R3, LOOP1
Given a 3-issue VLIW machine with fully pipelined functional units: 1 Memory Unit with 3 cycles latency; 1 FP ALU with 4 cycles latency; 1 Integer ALU with 1 cycle latency to next Int/FP/L/S & 2 cycle latency to next Branch. The branch is completed with 1 cycle delay slot (branch solved in ID stage). No branch prediction. In the Register File, it is possible to read and write at the same address at the same clock cycle. Considering one iteration of the loop, complete the following table (Memory Unit | Floating Point Unit | Integer Unit, rows C1 … C15) by using the list-based scheduling (do NOT introduce any software pipelining, loop unrolling and modifications to loop indexes) on the 3-issue VLIW machine including the BRANCH DELAY SLOT. Please do not write in NOPs. (C1 is given: LD F2, 0(R1) in the Memory Unit.)
How long is the critical path for a single iteration? What CPI did you achieve? What performance did you achieve in FP ops per cycle? How much is the code efficiency?
Extra question of this lesson, not of the papers: the same loop compiled for a 3-cycle FP ALU (SD in C7) runs unchanged on this machine. Which instruction reads a wrong value?
Show model answer
| Memory Unit | Floating Point Unit | Integer Unit | |
|---|---|---|---|
| C1 | LD F2, 0(R1) | ||
| C2 | |||
| C3 | |||
| C4 | FADD F6, F2, F2 | ||
| C5 | |||
| C6 | |||
| C7 | |||
| C8 | SD F6, 0(R1) | ADDUI R1, R1, 4 | |
| C9 | |||
| C10 | BNE R1, R3, LOOP1 | ||
| C11 | (delay slot) |
FADD at C1 + 3 = C4 (F2 from the memory unit); SD at C4 + 4 = C8 (F6 from the FP ALU); ADDUI in C8 with the SD, its last reader of R1 (read and write in the same cycle); BNE at C8 + 2 = C10; delay slot C11.
Critical path = 11 cycles. CPI = 11 / 5 = 2.2. FP ops per cycle = 1 / 11 = 0.09. Code efficiency = 5 / (11 × 3) = 0.15.
Old binary: SD F6, 0(R1) in C7 reads F6 one cycle before the 4-cycle FADD (issued in C4) writes it, so it stores the F6 of the previous iteration. A VLIW has no hardware that detects the RAW hazard.
The table is the June 2026 EX2 (LOOP1) with one number changed, FP latency 4 instead of 3. Four placements decide it: the RAW distances (3 after the load, 4 after the FADD), the ADDUI in the same cycle as the SD, the 2-cycle distance to the branch and the delay slot counted in the 11. The extra question is this lesson's point: on a VLIW a latency change does not slow the old binary down, it makes it wrong.
True or False: "A 4-issue VLIW processor requires 4 Program Counters to load the necessary instructions in the 4 parallel lanes."
Show model answer
False. One PC fetches one bundle per cycle; the bundle carries up to 4 operations in its 4 slots, one per functional unit, and at most one of them is a branch.
A True/False quiz of the 11 February 2025 paper, as the notes transcribe it (p. 582). The statement mixes up the issue width (operations per bundle) with the number of instruction streams. If a motivation line is asked, name the single PC and the one-branch-per-bundle rule.
True or False: "In VLIW architectures, the compiler can detect parallelism only in basic blocks of the code."
Show model answer
False. A basic block (straight-line code with one entry and one exit) holds only about 4 to 7 instructions, and its RAW chains limit the parallelism further. VLIW compilers therefore schedule larger regions: loop unrolling and software pipelining overlap loop iterations, trace scheduling schedules the most likely path through several basic blocks.
A True/False quiz of the 11 February 2025 paper, as the notes transcribe it (p. 581). The notes answer it themselves on p. 273: substantial speedups need "techniques that go beyond individual basic blocks". The three techniques are lesson 21.
In a VLIW processor, which of the following are handled by the compiler at compile time? (MULTIPLE ANSWERS)
Show model answer
Answers 1, 2 and 3. Data hazards (RAW, WAR, WAW) and structural hazards are solved statically with known latencies and resources; cache misses and branch mispredictions are dynamic events handled by the hardware (stall, flush).
Draw the line between compile time and run time exactly: everything known in advance (latencies, units, register names) belongs to the compiler; everything that depends on the data or on the path taken belongs to the hardware.
Check yourself
Why does a VLIW allow at most one branch per bundle?
On the papers' fully pipelined FP ALU (latency 3), FADD F6 issues in C4. What is the earliest cycle for an independent FADD, and for an SD that stores F6?
A 4-issue superscalar and a 4-issue VLIW have the same functional units. Going from the first to the second, what changes? Select all that apply.
The work moves from silicon to the compiler; the register file and the misses stay where they were.
In LOOP1 the compiler wants to put ADDUI R1, R1, 4 in C1, next to the LD, because it has nothing to wait for. What happens?
When does a VLIW need a dispatch network between the decoder and the functional units?
Tomasulo renames registers without using up architectural registers. Why does the same renaming cost architectural registers on a VLIW?
In the notes' solution of the May 2025 midterm (p. 511), bundle C4 holds LD F2, 16(R2) (latency 3) and ADDUI R2, R2, 8 (latency 1). From which cycle can an integer operation read the new R2?
Per-operation latencies are the model of every VLIW table in the papers: the compiler, not a synchronised write-back, keeps the writes in order.
Key take-aways
- A VLIW fetches one long instruction word per cycle with a single program counter: fixed slots, one per functional unit, at most one branch per bundle, and a NOP in every slot the compiler cannot fill.
- The compiler resolves RAW hazards (consumer at least one latency after the producer), WAR and WAW (ordering or renaming) and structural hazards (one operation per slot); nothing checks at run time, so a wrong schedule gives wrong results, not slow ones.
- Each operation has its own exposed latency; a fully pipelined unit takes a new operation every cycle but delivers each result after L cycles. Bundles do not complete in lock step in the exam's model.
- What stays in hardware: the five-stage pipeline, a register file with 2k read and k write ports (8 + 4 for 4-issue), a dispatch network when units outnumber slots, a stall on a data-cache miss and a flush on a misprediction.
- Register pressure: results started per cycle × latency registers are held by values in flight, more with compiler renaming, because a VLIW has no hidden tags; when they run out, the compiler starts fewer operations or spills values that wait longer than a reload takes.
- Gains: simpler, cheaper, lower-power hardware, a large compile-time window and easy scaling. Costs: compiler effort, code size, register management and binaries tied to one implementation — hence VLIWs live in embedded systems.
- A correct schedule is the fastest order that keeps every RAW and violates no WAR or WAW; basic blocks of 4–7 instructions are too small to fill the slots on their own.
What to watch and read
-
Modern Microprocessors: A 90-Minute Guide!
Jason R. C. Patterson, Lighterrasection "Explicit Parallelism – VLIW"
A short, plain-English picture of the static approach next to the superscalar one, with real processor names. Come back to "The Brainiac Debate" after section 6: it is the same trade-off told as industry history.
-
Computer Architecture — Lecture 27: VLIW Architectures (Fall 2023)
Onur Mutlu, ETH Zürich
The VLIW philosophy, lock-step execution, NOP padding, binary compatibility, how Itanium/EPIC and Transmeta tried to fix it, and why the idea survived in DSPs and GPUs rather than in general-purpose CPUs — section 6 at lecture length.
-
VLIW/EPIC: Statically Scheduled ILP (L21)
MIT 6.823, Arvind, Asanović and Emer34 slides
The whole static side in one deck: VLIW, then loop unrolling, software pipelining, trace scheduling, rotating registers and IA-64. Its VLIW slides go with this lesson; the rest previews lesson 21.
-
Very Long Instruction Word Architectures and the ELI-512
Joseph A. Fisher, ISCA 198311 pages
The paper that coined the name, describing the ELI-512 — the machine no established company would build, which is why Fisher founded Multiflow. Read its argument for letting the compiler find the parallelism and hold it against the four open challenges of section 6.