Skip to main content...
S2 · Verilog RTL Design
30 min

Day 88: The forwarding unit in RTL

The forwarding unit is a dozen lines of comparison logic that eliminates most pipeline stalls — theory from Stage 1, now RTL.

The forwarding unit in RTL

Implement forwarding (Stage 1, Day 44): compare the destination register of the instruction in EX/MEM and MEM/WB against the source registers of the instruction in EX, and drive the ALU-input forwarding muxes when they match (and the destination isn't x0 and reg_write is set). EX/MEM takes priority over MEM/WB when both match. This small block eliminates the stall for most back-to-back dependencies.

The forwarding unit
// forwardA/forwardB select the EX-stage ALU operands
always @(*) begin
    forwardA = 2'b00;   // 00 = register, 10 = EX/MEM, 01 = MEM/WB
    forwardB = 2'b00;
    // EX/MEM has priority (most recent)
    if (exmem.reg_write && exmem.rd != 0 && exmem.rd == idex.rs1) forwardA = 2'b10;
    else if (memwb.reg_write && memwb.rd != 0 && memwb.rd == idex.rs1) forwardA = 2'b01;
    if (exmem.reg_write && exmem.rd != 0 && exmem.rd == idex.rs2) forwardB = 2'b10;
    else if (memwb.reg_write && memwb.rd != 0 && memwb.rd == idex.rs2) forwardB = 2'b01;
end

Priority and the x0 guard

Two correctness details: EX/MEM wins over MEM/WB (the newer result is the right one), and you must exclude `x0` (forwarding a write to x0 would inject a stale zero). Miss either and you'll see subtle, data-dependent failures — exactly the kind the ISS comparison (Day 86) catches instantly.

Progress for Day 88

When both EX/MEM and MEM/WB could forward the same source register, which should the forwarding unit choose?

We use cookies

We use cookies to enhance your browsing experience, serve personalized content, and analyze our traffic. By clicking "Accept All", you consent to our use of cookies. Learn more

    Day 88: The forwarding unit in RTL | RBTechIconX