Pipeline registers.

Picture the CPU pipeline like a relay race. Each stage of the CPU is like a runner who does part of the job, then hands a baton to the next runner. That baton is a pipeline register, and it carries all the info the next stage needs. This setup lets different stages work at the same time instead of waiting for one to finish completely.


We start at the Fetch stage. Here the CPU grabs an instruction from instruction memory (instr_mem) and also keeps track of where that instruction came from using the program counter (PC). Both the instruction and the PC are passed forward and stored in the IF/ID register.

Next comes Decode. The instruction is broken into parts: register numbers, register values, and immediates. The control unit also figures out what type of instruction it is. All of these pieces are collected into the ID/EX register, ready for Execute. Importantly, the destination register number (rd) and all the control flags are also stored here so they can move forward with the instruction.

Execute is where the ALU does its work: math, logic, or deciding if a branch should be taken. The results include the ALU output, the destination register (rd), and any store data. These are placed into the EX/MEM register. The control flags from ID/EX are passed along directly, so the Memory stage knows whether it should read, write, or prepare for write-back.

In the Memory stage, the CPU may read data from memory (for loads) or just keep the ALU result. Along with the register number and a write-enable signal, this information is stored in the MEM/WB register so the Write-back stage can update the register file.

Notice that the full instruction itself does not travel all the way to the end. After Decode, the CPU no longer needs the raw instruction bits. Instead, the control signals and relevant fields (like rd, rs1, rs2, and immediates) are what get passed along. By the time we reach Write-back, only the result, the destination register, and the write-enable matter.


Summary: signals per register

IF/ID: instr, pc_plus4, pc
ID/EX: rs1_data, rs2_data, rs1, rs2, rd, imm, pc, pc_plus4, alu_op, alu_src, mem_read, mem_write, reg_write, wb_sel, branch, jump
EX/MEM: alu_result, store_data, rd, mem_read, mem_write, reg_write, wb_sel, branch_taken, next_pc
MEM/WB: mem_rdata, alu_result, rd, reg_write, wb_sel