Names, not values: Tomasulo’s architecture

After this lesson you will read a reservation station and a register’s status field like a sentence — “F2 will come from RS4” — and say, for any broadcast on the common data bus, who takes the value and who ignores it.

In October 1967 IBM delivered the first System/360 Model 91 to NASA’s Goddard Space Flight Center. About fifteen were ever built, and that first one was, for a while, the most powerful computer in user operation. Its floating-point unit ran instructions out of program order with a scheme its designer, Robert Tomasulo, had just published in a nine-page paper as “a simple common data busing and register tagging scheme”. Thirty years later the Pentium II, the Alpha 21264 and the MIPS R10000 were still built on it.

Here is the puzzle. In the four-instruction fragment of this lesson, I3: FMUL F6, F10, F8 needs two registers that are ready from cycle 1. On a scoreboard (lesson 9) with the latencies of this lesson’s last widget it cannot issue until cycle 14, because an earlier FADD also writes F6 and that FADD is waiting for a divide. Tomasulo’s machine issues the multiply at cycle 4, writes its result at cycle 8 — and the program still ends with the right value in F6. It did not touch the code.

What did it change? Keep the question: the answer is what the word “F6” means inside the machine.

Three instructions, one name: why rename at all

Lesson 7 sorted the ways two instructions can collide into three kinds. Only one of them, RAW, is about a value: the second instruction needs what the first one computes. The other two are about a name. In a WAR hazard a later instruction writes a register that an earlier one still has to read; in a WAW hazard two instructions write the same register and the second write could land first. The notes call them false dependences (page 142): the instructions “appear to depend on each other because they use the same register name, but there is no true data dependency between them”. Different values are fighting over one name.

The whole lesson runs on the fragment the notes use, written in the mnemonics of the exam papers. The notes spell it DIV.D, ADD.D, S.D, MUL.D (page 142), the spelling of Hennessy and Patterson; the papers write FDIV, FADD, SD, FMUL, and so does this notebook. Older papers write $F6; the 2026 paper drops the dollar sign.

I0: FDIV F0, F2, F4
I1: FADD F6, F0, F8      ; RAW on F0 with I0
I2: SD   F6, 0(R1)       ; RAW on F6 with I1
I3: FMUL F6, F10, F8     ; WAW on F6 with I1, WAR on F6 with I2

Read the last line twice. I3 must not deliver its product into F6 before I1 has delivered its sum (WAW), and not before I2 has read that sum (WAR). Neither rule asks I3 to wait for a value: F10 and F8 are ready. Both ask it to wait for the name F6 to become free. On the scoreboard the WAW check happens at Issue, so I3 waits there — and because issue is in order, everything behind it waits too.

Static renaming: let the compiler pick another name

The oldest cure is a second name. If the compiler has a spare register S, it can send the sum there and let the store read it; the multiply keeps F6, and the two name conflicts are gone while the RAW chain is untouched:

I0: FDIV F0, F2, F4
I1: FADD S,  F0, F8      ; RAW on F0, as before
I2: SD   S,  0(R1)       ; now reads S
I3: FMUL F6, F10, F8     ; nobody else uses F6 any more

The notes name the two limits (page 142). The compiler must know every hazard in advance, which means knowing the whole execution path — hard with branches, loops and inputs that change. And every spare name costs an architectural register, a number that has to fit in the register field of the instruction; the ISA may not have one to spare. The machine of the hook is the extreme case: the System/360 had only four floating-point registers, so the compiler had nothing to rename into.

Implicit renaming: let the hardware invent names it never shows

Tomasulo’s answer is to give the result a name that exists only inside the machine. The buffer in front of a functional unit that holds a waiting instruction — the reservation station — becomes the temporary name, the tag, of the result it will produce. The notes picture it as a rewrite of the code (page 143), with the sum sent to “RS1” and the store reading “from RS1”:

I0: FDIV F0, F2, F4
I1: FADD RS1, F0, F8     ; the sum will be known as RS1
I2: SD   RS1, 0(R1)      ; the store waits for RS1, not for F6
I3: FMUL F6, F10, F8     ; its own write to F6 collides with nobody

Take the listing as a picture, not as a mechanism: no instruction text is rewritten. The renaming lives in two kinds of fields, one in the station and one in the register file, and the next section fills them in. The before/after pair shows what changes.

F0 F6 F8 F10 FADD F6,F0,F8 SD F6,0(R1) FMUL F6,F10,F8 I1 I2 I3 WAW WAR one name, three users

Before: F6 is a place

F0 F6 F8 F10 RS3 Qi FADD F6,F0,F8 SD F6,0(R1) FMUL F6,F10,F8 RS1 RS2 RS3 WAW, WAR RS1 two results, two names only the newest writer owns F6

After: F6 is the newest promise

Fig. 1. Before: every reader and writer of F6 points at the same cell, and the name arcs (dotted WAW, dashed WAR) tie I3 to the two instructions ahead of it. After: the sum is called RS1 and the store waits for that tag; the register cell F6 only records who will write it last (Qi = RS3); both name arcs are crossed out, and the orange RAW arrow is the one dependence that survives.

RAW is about a value and stays; WAR and WAW are about a name and disappear the moment every result gets a name of its own.

A station holds a value or a name

Page 144 of the notes calls the reservation stations “Tomasulo’s brain”, and the reason is where they sit. The scoreboard kept one central table and asked it before every move. Tomasulo puts the control next to each functional unit: the adder has its own small buffers, the multiplier has its own, the memory unit has its own. Each buffer holds one issued instruction together with everything it needs to decide, alone, when to go. The fields of one station are few, and the exam expects you to know them by name.

The record of one reservation station (notes, page 146; the field A is Hennessy and Patterson’s, used by loads and stores).
FieldWhat it holdsSet when
Busyyes while the station holds an instructionat issue; cleared at write result
Opthe operation (FADD, FMUL, LD, SD, ADDUI, BNE)at issue
Vj, Vkthe values of the two source operands, when they are availableat issue (copied from the register file) or when the tag arrives on the CDB
Qj, Qkthe tags of the stations that will produce the operands; 0 means “nothing pending, use the value”at issue (copied from the register’s Qi); cleared when the value arrives
Aloads and stores only: the immediate at issue, the effective address once computedat issue; updated by the address unit

For each operand exactly one of the pair is meaningful at any moment: either Vj holds the value, or Qj names who will deliver it. A station whose two Q fields are 0 is ready; a station with a non-zero Q field is waiting — not for a register, but for a tag to come down the bus. The notes’ slogan on page 144 says it in one line: “We no longer wait for registers, we wait for values, and when they’re ready, we go.”

The register file gets a matching field. Each register Fi now carries its value Vi and a tag Qi (page 147): the name of the station that will produce the next value of the register. Qi = 0 means the value is valid, use it; Qi = RS4 means “F2 will come from RS4”. The tag is written at issue, by the instruction whose destination the register is, and it is overwritten by every later instruction that writes the same register. So the register remembers only its newest writer: older claims are simply forgotten. That single rule is the renaming.

The bus that shouts a name

Now the third piece, the one that ties the fields together. When a functional unit finishes, the result does not go to its destination register first. It is put on the common data bus (CDB) together with the tag of the station that produced it — the pair <tag, value> — and three things happen at once (page 145): every station whose Qj or Qk equals the tag copies the value into Vj or Vk and clears the tag; the register file writes the value into every register whose Qi equals the tag and clears that Qi; and the producing station becomes free. The notes call this “a kind of hardware-level forwarding, operands are handed off before they hit the register file” — the forwarding path of lesson 2, generalised to every unit at once.

Two consequences are the heart of the exam questions on this topic. First, the tag on the bus is the name of the producer, never of the destination register. A normal data bus says “this value goes to F2”; the CDB says “this value comes from RS1”, and every consumer decides for itself whether it was waiting for RS1. (This “come-from” reading is standard lecture material on Tomasulo’s algorithm; the notes do not use the word.) Second, the register is written only if its Qi still matches: if a later instruction has renamed the register to its own station, the register ignores the broadcast — the value still reaches every station that was waiting for it, so nobody loses anything, and the register keeps its promise to the newest writer. That is how a WAW hazard dies without a single stall.

Try it on the loop body of the 15 July 2024 paper, the first exercise of that exam. Imagine all six instructions issued and no result written yet. The loads and the store share stations RS1 and RS2 in front of the two load/store units, the two FADD share RS3 and RS4 in front of the FP unit, the integer instructions RS5 and RS6 in front of the ALU — the exam’s standard machine.

I0: LD    F2, A(R1)
I1: FADD  F2, F2, F2      ; RAW on F2 with I0, WAW with I0
I2: FADD  F2, F2, F4      ; RAW on F2 with I1, WAR and WAW with I1
I3: SD    F2, A(R1)       ; RAW on F2 with I2
I4: ADDUI R1, R1, 8       ; WAR on R1 with I0 and I3
I5: BNE   R1, R2, FOR     ; RAW on R1 with I4
The frozen state: every instruction issued, nothing written. Register values before the loop: F2 = 0.0, F4 = 0.5, R1 = 100, R2 = 200; the offset A is taken as 0, so the load and the store both address 100, where memory holds 1.5.
RSBusyOpVjQjVkQkAUnit
RS1yesLD1000——100LDU1
RS2yesSD1000—RS4100LDU2
RS3yesFADD—RS1—RS1—FPU1
RS4yesFADD—RS30.50—FPU1
RS5yesADDUI100080—ALU1
RS6yesBNE—RS52000—ALU1
Register statusF2F4R1R2
Vi0.00.5100200
QiRS40RS50

Read the tables as sentences before you touch the widget. RS3 says: “I add two copies of whatever RS1 delivers.” RS2 says: “I store at address 100 whatever RS4 delivers” — and notice that it already holds R1 = 100, copied at issue, so the ADDUI in RS5 can change R1 whenever it likes. The register status says: “F2 will come from RS4, R1 from RS5.” F2 has been promised three times, by I0, I1 and I2; only the newest promise is kept.

Who listens? One broadcast on the common data bus

The six stations and the register file of the frozen state above. Pick the station that finishes next and press Broadcast: its <tag, value> goes on the bus, and every field that carries that tag fills at once. A station that still has a tag in Qj or Qk cannot finish — the widget tells you why. The one thing to see: a tag is the producer’s name, one broadcast serves every consumer of it, and the register file takes the value only if its Qi still says that name.

  1. Before pressing anything: RS1 (the load of F2) finishes first. How many fields will its broadcast fill, and will the register F2 be written? Then select RS1 and press Broadcast.
    What you should see

    Two fields fill from one broadcast, and both are in the same station: RS3.Vj and RS3.Vk become 1.5, because FADD F2, F2, F2 takes both operands from RS1. F2 is not written: its Qi says RS4 — I1 and I2 renamed it after I0 — so the register ignores the value that was once meant for it. Nothing is lost: the only consumer of I0’s load, RS3, got it.

  2. Now finish RS5, the ADDUI. Who listens? Does the store in RS2, whose address was computed from R1, change?
    What you should see

    RS6.Vj fills with 108 (the branch was waiting for RS5), and R1 becomes 108 with Qi cleared, because R1 still named RS5. The store does not change: it copied R1 = 100 at issue. That copy is why the WAR hazard between the store and the ADDUI cannot hurt — the reader never goes back to the register.

  3. Try to finish RS4 before RS3. What does the widget answer, and which rule is it quoting?
    What you should see

    RS4 is refused: it still holds Qj = RS3, so it has never started executing. The execute condition is Qj = Qk = 0 — both operands as values — and a station cannot broadcast what it has not computed. Finish RS3 first; then RS4 becomes ready.

  4. Finish RS3, then RS4, then the store in RS2. When RS4 broadcasts, who takes the value? And when the store finishes, what appears on the bus?
    What you should see

    RS4’s <RS4, 3.5> fills RS2.Vk (the store’s data) and is written into F2, because this time F2.Qi = RS4 matches — the newest writer delivers. The store then puts nothing on the bus: it writes 3.5 into memory at address 100 and nobody listens for RS2, because no instruction can read a store’s result through a register. A store listens on the CDB but never speaks on it.

A tag is the name of a producer: one broadcast fills every field that carries it, and a register takes it only if its Qi still says so.

The whole machine: Figure 26 end to end

The notes’ Figure 26 (page 149) is Hennessy and Patterson’s drawing of the floating-point unit of a RISC-V processor built this way — in the 5th edition the same figure is drawn for MIPS. Figure 2 redraws it. Follow one floating-point instruction and one load through it; every block has a job you now know.

from the instruction unit instruction queue FP registers F0 F2 F4 … Qi loads and stores Address unit store buffers load buffers data address Memory unit FP operations operation bus operand buses reservation stations FP adders FP multipliers common data bus (CDB) tag and value, to everyone
Fig. 2. The notes’ Figure 26 (page 149), redrawn. Loads and stores leave the instruction queue for the address unit and the store and load buffers in front of the memory unit; floating-point operations travel on the operation bus to the reservation stations (three for the adders, two for the multipliers); the FP registers, each with its Qi field, feed the operand buses. Every result — from the memory unit, the adders or the multipliers — goes onto the common data bus, which runs back up to the reservation stations, the store buffers and the FP registers.

An FADD leaves the queue in program order, travels on the operation bus to a free adder station, and fills it: values from the FP registers over the operand buses where Qi = 0, tags where it is not. Its destination register gets the station’s name as Qi. The station then watches the CDB until both Q fields are 0, sends the operation into an adder when one is free, and finally puts <tag, value> on the bus. A load takes the other path: the address unit adds the base register and the offset, the load buffer waits for the memory unit, and the loaded value goes on the same bus with the load buffer’s tag — a load is a producer like any other.

Loads and stores: the buffer that listens but never speaks

Memory operations need two steps instead of one, and the notes separate them (page 147). A load buffer first computes the effective address, base register plus offset, then waits for the memory unit and reads. A store buffer needs two things before it can act — the address and the data — and either may be a tag, so store buffers monitor the CDB like any reservation station. When both are present it writes memory. What it never does is put anything on the bus: a store has no destination register, so no station and no Qi can be waiting for its tag. That missing arrow is the whole difference between the two panels of Figure 3, and the exam quizzes it directly.

Busy A Vj Qj yes 0 100 0 RS1: LD Address unit A ← Vj + A Memory unit read [100] <RS1, 1.5> CDB speaks on the bus

Load: address, then memory, then the bus

Busy A Vj Qj Vk Qk yes 100 100 0 — RS4 <RS4, 3.5> Address unit Memory unit write [100] CDB nothing goes up here

Store: listens for its data, writes memory, says nothing

Fig. 3. Both buffers compute their address and use the memory unit. The load ends on the common data bus with its tag; the store takes its data from the bus (here <RS4, 3.5> into Vk) and ends in memory. No instruction waits for a store, so a store never broadcasts.

One bus, one result per cycle

Look at Figure 2 once more and count how many things hang on the CDB: every reservation station, every store buffer, every register. That is why one broadcast can wake everybody at once — and it is also the price. A bus can carry one <tag, value> per cycle, so one CDB means one result per cycle, however many units finish together; the exam’s “single Common Data Bus” is exactly this rule, and the older instruction gets the bus first (lesson 12). Behind the rule sits hardware the notes do not mention: every station and every register compares its tag with the bus every cycle — associative compares at full speed — and the bus fans out to every unit, so it is long, loaded and slow to drive. More buses mean more comparators everywhere. (Standard lecture material on Tomasulo’s drawbacks; the notes list only the benefits.)

Page 148 sums up why the design works, and the four reasons are the four blocks you have just seen: issue is decoupled from operand readiness, so out-of-order execution is natural; several stations per unit let several instructions of one type be in flight; the register file need not remember everything, because the stations hold the values and the dependences; and the broadcast hands every waiting unit what it needs without any central control. The notes’ word for the result is dataflow-like (page 145): an instruction runs when its operands are ready, not when a global scheduler says so.

Issue, execute, write result: the flow in three steps

Page 150 ends with the execution flow, and it is shorter than the scoreboard’s: three steps, not four. There is no Read Operands stage, because reading happens at issue (the values that exist) or on the bus (the ones that do not). Each step has one condition that lets an instruction through; the stepper states it and says why it is the right one. The exact rules for the exam table — what “the cycle after” means, ties on the bus, when a station is reusable — are lesson 12; the full cycle-by-cycle run of the notes’ six-instruction example is lesson 13.

  1. Issue (instruction queue → station), in program order. Condition: a station of the right type is free. Copy the instruction in; for each source register copy the value into Vj/Vk if Qi = 0, otherwise copy the register’s Qi into Qj/Qk; then set the destination register’s Qi to this station’s tag. Why in order: the renaming must see the instructions in program order, so that Qi always names the latest writer and every later reader captures the right producer. If no station is free the instruction waits — a structural hazard — and so does everything behind it.

  2. Execute (station → functional unit), out of order. Condition: Qj = Qk = 0 and the unit is free. The station sends the operation into the unit, which computes for its latency. Why operands and not order: a RAW dependence is the only thing the hardware still has to honour, and “both tags cleared” is exactly “both producers have broadcast”. The station stays Busy while the unit works — it still has to deliver the result.

  3. Write result (unit → CDB), out of order. Condition: the CDB is free. Put <tag, value> on the bus; every station with a matching Qj/Qk fills the field and clears the tag; every register with a matching Qi is written and its Qi cleared; the station becomes free. Why the register is written at all when the consumers already have the value: instructions issued later will read the register file, and Qi = 0 tells them the value there is good.

“The station is released when the instruction enters the functional unit.” No — at write result. From issue through write result the station holds the instruction, and in the exam’s tables it can be reused only from the cycle after WRITE RESULT: on page 559 the notes’ reproduction of a professor’s solution has LD $F0 write at 8 and the next load/store instruction take the same RS1 at 9. Count the station as free at execute and every later ISSUE cycle shifts.

Issue needs a free station; execute needs both tags at 0 and a free unit; write result needs the bus.

Scoreboard versus Tomasulo, and the answer to the puzzle

The notes compare the two machines twice, in Table 16 (page 141) and Table 17 (page 145). Merged, with the vocabulary of lesson 9 on the left:

Tables 16 and 17 of the notes merged (pages 141 and 145). Scoreboard = CDC 6600, Tomasulo = IBM 360/91.
FeatureScoreboardTomasulo
Register renamingnoneimplicit, through the reservation stations
WAR / WAW hazardsstall (WAW at Issue, WAR at Write Result)avoided by renaming
Operand waitingfor a register to be writtenfor a value — held in the station, or named by the tag that will bring it
Operand trackingcentralised, in the scoreboard’s tablesdistributed, in every station
Data communicationthrough the register file, no forwardingbroadcast with a tag on the CDB
Controlone central scoreboarddistributed: each unit has its own stations
Execution starts whenthe operand registers are ready and have been read (Read Operands)both operand values are in the station (Qj = Qk = 0) and the unit is free

Every row of the table is one consequence of renaming, and the widget below shows the first two on the fragment of the hook. The two timelines run on the same machine — one station per unit, FDIV 7 cycles, FADD and FMUL 3, the store 4, operands usable the cycle after their producer writes, one CDB — and the switch changes one thing only: whether a second writer of a register must wait for the name (the scoreboard’s two rules: WAW at issue, WAR at write result) or gets a tag of its own.

Renaming on, renaming off: which waits disappear

Top: the four instructions with their dependence arcs — orange RAW arrows on the left, the dotted WAW and dashed WAR arcs on the right. Bottom: the timeline, one row per instruction (I = issue, blue = executing, dashed orange = waiting for the hazard written inside, blue tick = write result). Fragment A is the notes’ example; fragment B changes the multiply so that the only name conflict is a WAR. The one thing to see: renaming erases exactly the name dependences, their arcs and their waits — and nothing else, the RAW chain included.

  1. Renaming off, fragment A. Predict the issue cycle of I3 (the FMUL), whose operands are ready from cycle 1. Then read the timeline.
    What you should see

    Cycle 14: the dashed bar “WAW F6” runs from 4 to 13. I3 may not enter the machine while I1 still has to write F6, and I1 is waiting for the divide; so the multiply, which needs nothing from anybody, inherits the divide’s latency plus the add’s. It executes 15–17 and writes at 18.

  2. Switch renaming on. Which bars vanish, which stay, and does the last write-result cycle move?
    What you should see

    Only the WAW bar vanishes: I3 issues at 4, executes 5–7, writes at 8. The RAW bars stay exactly where they were — I1 still waits for F0 until 9, the store still waits for the sum until 13 — and the last write result is 18 in both runs. The critical path is the RAW chain FDIV → FADD → SD, and renaming does not touch it.

  3. Pick fragment B with renaming off. Where is I3’s wait now, and what is it waiting for?
    What you should see

    At the end of its row: I3 issues at 4 and finishes computing at 7, but may not write F8 until I1 has read the old F8 — and I1 reads only when it starts, at 10. A WAR wait from 8 to 10; write result at 11. With renaming on it writes at 8: I1 copied F8 at issue and never looks at the register again.

  4. Renaming on, fragment A: I3 writes F6 at cycle 8 and I1 broadcasts its sum at 13. Which value is in F6 at the end, and how did the machine get it right?
    What you should see

    The product — program order’s last writer. At issue I3 set F6.Qi to its own station; when I1 broadcasts at 13, the register sees a different tag and ignores the sum, while the store takes it from the bus through its Qk. Two writers, two names, no collision — the rule of the first widget.

The answer to the puzzle

What Tomasulo’s machine changed is the meaning of “F6”. On the scoreboard F6 is a place: one cell, and whoever wants to write it must wait until the previous writer has written and the previous reader has read. In Tomasulo’s machine F6 is a promise: the cell records the name of the station that will write it last, and nothing else. The sum of I1 is called RS-whatever-the-adder’s-station-is from the moment it is issued; the store asks for that name, not for F6; the multiply, issued two cycles later, writes its own name into F6.Qi and runs. When the sum finally arrives on the bus it goes to the store, which was waiting for it, and is ignored by F6, which has promised itself to the multiply. No stall, no wrong value — and no change to the code, because the compiler never sees a station name.

State the cost next to the benefit, as the open question of the exam expects. The benefit: WAR and WAW can never stall or corrupt, only true dependences remain, and the machine runs code compiled for other implementations because the renaming is invisible to the ISA — the ISA’s register count no longer limits what can be in flight. The cost: every station and every register is an associative comparator on the bus, the bus itself is the throughput limit, and results are still written out of order, so an exception leaves the registers in a state no sequential program would have produced — the problem that the reorder buffer of lesson 17 fixes.

Robert Tomasulo published the scheme in January 1967, three years after the CDC 6600 and its scoreboard, in a paper whose abstract promises “a simple common data busing and register tagging scheme which permits simultaneous execution of independent instructions while preserving the essential precedences” — with hardware that looked ahead about eight instructions. The Model 91 it was built for had imprecise exceptions and out-of-order stores, the two problems the reorder buffer later solved. Tomasulo received the Eckert–Mauchly Award in 1997 “for the ingenious Tomasulo algorithm, which enabled out-of-order execution processors to be implemented”.

Exam-style questions

Explain the main concepts and benefits of each one of the following techniques used by modern superscalar processors (Tomasulo-style): 4. Reservation stations; 5. Dynamic register renaming; 6. Out-of-order execution. (Three of the eight items of Question 1, 22 June 2026 — five lines each.)

Show model answer

Reservation stations. Buffers in front of each functional unit. An issued instruction waits there with its operation, its operand values (Vj, Vk) or the tags of the producers it waits for (Qj, Qk), and a busy bit. They decouple issue from execution: an instruction waits locally for its operands instead of blocking the pipeline, the station’s name is the temporary name of its result (renaming), and the control is distributed — each unit schedules itself. Benefit: no central scoreboard, no stall of the instructions behind a waiting one, more instructions in flight than there are registers.

Dynamic register renaming. At issue the destination register’s status field Qi is set to the station’s tag, and every later consumer records that tag instead of the register name. Results are broadcast with the tag; a register is written only if its Qi still holds that tag (the newest writer owns the register). Benefit: WAR and WAW hazards — name dependences — can never stall or corrupt; only true RAW dependences remain; the renaming is done by hardware, invisible to the ISA, so the register count of the ISA no longer limits scheduling.

Out-of-order execution. An instruction leaves its station for the functional unit as soon as Qj = Qk = 0 and the unit is free, independently of program order; results return out of order over the common data bus. Benefit: independent instructions proceed while a long-latency one (a load, a divide) waits, so stalls are filled and the CPI falls. Cost: completion out of order gives imprecise exceptions unless a reorder buffer restores in-order commit.

The form of the real question is a table with five lines per item: write labelled statements, not an essay. Full marks need the concept (what the structure holds or does), the mechanism (tags, Qi, the CDB) and a benefit stated as a benefit; for item 6, naming the cost (imprecise exceptions) shows you know what the next item, the reorder buffer, is for.

Why does the scoreboard stall on a WAR hazard while Tomasulo’s algorithm does not? Where in Tomasulo’s three stages is the WAR hazard resolved?

Show model answer

In the scoreboard an instruction reads its operands from the register file in the Read Operands stage. A later instruction that writes one of those registers must therefore wait at Write Result until the read has happened, otherwise the reader would get the new value: the WAR hazard costs a stall of the writer. In Tomasulo’s algorithm the reader takes a copy of the operand at Issue (into Vj/Vk) if it is available, or records the producer’s tag (Qj/Qk) and receives the value from the CDB; it never reads the register file later. The later writer cannot overwrite anything the reader still needs; it only sets the register’s Qi to its own station. The WAR hazard is dissolved at Issue — copy or tag — and no stage ever stalls for it.

Two sentences carry the marks: “the reader copies or tags at issue and never returns to the register” and “the writer renames the register to its own station”. The stage asked for is Issue.

Let’s consider the following assembly code containing multiple types of intra-loop dependences. Complete the following table by inserting all types of true-data-dependences, anti-dependences and output dependences for each instruction (I0 and I2: None). (Part 1 of Exercise 1, 22 June 2026.)

I0  FOR: LD    F2, AA(R1)
I1       FADD  F2, F2, F2
I2       LD    F4, BB(R1)
I3       FADD  F2, F2, F4
I4       SD    F2, A(R1)
I5       ADDUI R1, R1, 8
I6       BNE   R1, R2, FOR
Show model answer
I#Dependences
I0None
I1True data dependence with I0 for F2; output dependence with I0 for F2
I2None
I3True data dependence with I1 for F2 and with I2 for F4; anti-dependence with I1 for F2 (I1 reads F2, I3 writes it); output dependence with I1 and with I0 for F2
I4True data dependence with I3 for F2
I5Anti-dependence with I0, I2 and I4 for R1 (they read R1, I5 writes it)
I6True data dependence with I5 for R1

The paper wants every pair named “with I# for Fx”. The ones students miss: the anti-dependences of the ADDUI on every earlier reader of R1 (two loads and the store), and the output dependence of I3 on I0 as well as on I1. In the Tomasulo table of part 2 (lesson 12) all the WAR and WAW entries are “solved by renaming” — but part 1 asks you to find them.

In Tomasulo’s algorithm, a reservation station is released: (single answer)

  • when the instruction is issued into it At issue the station is filled, not freed: it must hold the operands or tags until the instruction can execute.
  • when the instruction starts execution in the functional unit The station stays busy while the unit works; it still has to deliver the result with its tag.
  • when the instruction writes its result on the CDB Write result: broadcast the pair, fill every waiting field, write the register if Qi matches, free the station.
  • when the next instruction of the same type is issued A later instruction can take the station only because it is already free — from the cycle after the write result.
Show model answer

Answer 3: the station is busy from Issue through Write Result and reusable from the next cycle.

The notes themselves say “the RS is now free” during execution on page 155; that is the wrong answer here and the wrong ISSUE column in the exercise.

Which of the following can stall the ISSUE stage of Tomasulo’s algorithm? (multiple answers)

  • a RAW hazard on a source register No: the instruction is issued with the producer’s tag in Qj or Qk and waits inside its station.
  • no free reservation station of the required type The structural hazard — the most common “STRUCTURAL” entry in the exam tables.
  • a WAW hazard on the destination register No: the destination is renamed to the new station; the older writer’s claim is simply forgotten.
  • a full load/store buffer A load or store needs a free buffer of its own kind, exactly as an FP operation needs a free station.
  • an unresolved branch in a machine without speculation Without speculation the instructions after the branch cannot be issued until it resolves — dynamic scheduling stays inside the basic block.
Show model answer

Answers 2, 4 and 5. Data hazards never stall issue in Tomasulo’s algorithm: RAW waits in the station, WAR and WAW are dissolved by the tags.

The question tests the one thing the scoreboard and Tomasulo disagree about at Issue: WAW stalls the scoreboard there and never stalls Tomasulo.

True or false: in Tomasulo’s algorithm a store instruction writes its result on the common data bus.

  • True A store has no destination register; nothing can wait for its tag, so there is nothing to broadcast.
  • False A store waits for its address and its data (the data may arrive from the CDB), then writes memory. It listens on the bus and never speaks on it.
Show model answer

False: the store buffer monitors the CDB for its data and writes memory; it broadcasts nothing. In the exam table its WRITE RESULT entry is the cycle the memory write completes.

“Motivate your answer” is worth the extra point: say what the store waits for and where its result goes.

Check yourself

Which of these are name dependences — the ones renaming removes?

  • WAR, a later instruction writing a register an earlier one still has to read No value flows between the two; they only share a name.
  • WAW, two instructions writing the same register Give the two results two names and the conflict is gone.
  • RAW, a later instruction reading what an earlier one computes A value really flows: this is the dependence renaming keeps, and the one that still costs cycles.
  • a structural hazard, two instructions wanting the same unit A resource conflict, not a register-name conflict; renaming does nothing about it.

RS3 broadcasts <RS3, 2.0>. The register file holds F6.Qi = RS5 and F8.Qi = RS3. What happens in the register file?

  • Both F6 and F8 are written with 2.0 F6 is waiting for RS5, a newer writer; writing it now would put a stale value under a newer promise.
  • Only F8 is written; F6 ignores the broadcast The register takes the value only if its Qi equals the tag: F8 matches, F6 does not.
  • Only F6 is written, because it was renamed last Being renamed last means F6 belongs to RS5, not to RS3.
  • Neither: registers are written only when the instruction commits That is the reorder-buffer version (lesson 17); basic Tomasulo writes the register at Write Result.

Why can a reader in Tomasulo’s machine never be hurt by a later writer of its source register (a WAR hazard)?

  • Because it reads the register file at Write Result, after the writer Reading after the writer would give the new value — the very error a WAR rule prevents.
  • Because it copies the operand at issue, or takes it from the CDB by tag, and never reads the register later The station is the reader’s private copy; the register can change freely afterwards.
  • Because the later writer is stalled at issue until the reader has read That is the scoreboard’s cure (a stall); Tomasulo needs none.
  • Because the register file keeps two copies of every register It keeps one value and one tag; the copies live in the stations.

Compared with static (compiler) renaming, hardware renaming needs more of what?

  • architectural registers encoded in the ISA That is exactly the limit of static renaming; the hardware’s names are invisible to the ISA.
  • reservation stations — temporary names that exist only inside the machine Each station is one name; more stations, more results in flight.
  • compile-time knowledge of the whole execution path The other limit of static renaming; the hardware renames at run time, whatever the path.
  • bits in the instruction format The instruction still names F6; the tag never appears in the code.

A store buffer holding SD F2, A(R1) can write memory only when it has … (select all that apply)

  • the base register R1 as a value, to compute the address Vj/Qj: if the ADDUI that writes R1 is still pending, the buffer holds its tag.
  • the data F2 as a value Vk/Qk: the data may arrive from the CDB, which is why store buffers monitor the bus.
  • a free slot on the CDB to broadcast the stored value A store broadcasts nothing; it writes memory.
  • its destination register’s Qi equal to its own tag A store has no destination register and no Qi to match.

Address and data, both possibly tags; then memory, never the bus.

A machine has three functional units that all finish in the same cycle and a single CDB. How many results are written in that cycle, and why?

  • Three — each unit writes its own register Results do not go to registers directly; they go on the bus, and the bus carries one pair per cycle.
  • One — the bus carries one <tag, value> per cycle; the others wait their turn One CDB, one result per cycle; in the exam the older instruction goes first.
  • One per reservation station that is waiting Listeners do not limit the bus; the bus limits the producers.
  • Two — one for the register file and one for the stations There is one bus and everyone listens to it.

Where do the fields Qi and Qj/Qk live, and what does each one say?

  • All three live in the reservation station Qj and Qk do; Qi is a field of each register in the register file.
  • All three live in the register file Qi does; Qj and Qk are the station’s own fields for its two operands.
  • Qi in the register file (“who will write this register”), Qj and Qk in the station (“who delivers my operands”) — all three hold station tags At issue the station copies the register’s Qi into its Qj or Qk: the same name, seen from the other side.
  • Qi in the instruction queue, Qj and Qk in the functional unit Neither the queue nor the unit keeps tags; the station and the register file do.

Key take-aways

What to watch and read