You ask good questions. So +1.
In contrast to the way you put your question, suppose the instruction sitting in the IF/ID latch is BEQ. And suppose that the two source resisters just happen to be the same register. Say BEQ $1, $1, addr
? (Or, in some instruction sets, JMP.)
This is the same thing as an unconditional jump instruction. In fact, a separate unconditional jump instruction isn't needed, so doing it this way saves on instruction space.
(It is also conceivable to include a comparator directly inside the ID stage that looks at the two REG file read-data outputs and gives a yes/no on that compare, which can be used to anticipate the result of a BEQ or BNE before it gets to the EX stage. That could reduce one of the two bubbles otherwise needed if the ALU in the EX stage is first required.)
An unconditional jump means that the instruction following it is not needed.
Detecting an unconditional jump in the control unit reduces further delays by doing this branch test early, in the control unit, and avoids a stall (which is what the hazard detection unit does.)
The purpose of the IF.Flush is to insert a bubble into the IF/ID latch when an unconditional jump is detected, without requiring a stall. This specific detection is done by the control unit, not the hazard detection unit.
In this case, the IF/ID latch will have already latched the PC address of the BEQ and also the immediate constant present in a field of the BEQ. These two values are already being presented to an adder, so that the new PC address is also already at the adder output and ready to be presented to the instruction address register.
So the control unit will signal an IF.Flush but it will also signal a mux to pick off the appropriate adder output that currently has the branch-to address already calculated and send that along towards the instruction address register input (via other muxes.) This bypasses the usual PC counter adder, which will have already computed a different address -- but one that isn't needed.
However, the instruction address register hasn't yet latched that value. It's sitting at its input already. But it needs a clock to latch it and present it to the instruction memory.
So an IF.Flush bubble is inserted into the IF/ID for one clock. That extra clock allows the instruction memory to find and present the next instruction located at the BEQ target address and present it to the input of the IF/ID. And one more clock (the one just following the bubble) latches this target instruction into the IF/IF.
Meanwhile, the rest of the pipeline can continue for a clock, with all necessary forwarding activities still taking place.