I have understood that you get the value as address + 4 + (imm<<2) However we do not have a imm value here. Is the D signal then just address + 4 ( 0x40000124)?
No, the hardware computes exactly the formula you stated (well using signextend16to32(imm)<<2
not 2<<imm
) — as if this instruction did indeed have an immediate. To find the value for D
, you need to decode the subtraction instruction as if using the I-Type format, which is to say the lower 16 bits of that subtraction instruction.
Of course, because this is not an I-Type instruction, the control signal for Branch
will tell the pc to accept PC+4 not the other formula calculated for the D
datapath.
In effect, there's enough hardware there to execute any instruction, put another way, the hardware has the union of all components needed to execute every possible instruction. It is common then, for some calculations to happen that are later ignored, since that hardware and calculation made simply they don't apply to every instruction.
It is easier to tell the hardware to ignore some inappropriate calculation, than to simply not do the calculation. (It is also faster, in that many calculations happen before we know whether or not they're needed. That hardware is there, it runs and costs some power even though its result is only used on taken branch instructions.)
This is the purpose of mux
es and control signals that tell the mux
what data is relevant to this particular instruction (and hence also what to ignore).
A mux
is equivalent to the ?:
operator in C or an if-then-else such as
datapath = x ? PC+4 : PC+4+(imm<<2)
or
datapath = if x then PC+4 else PC+4+(imm<<2)
or
if x then
datapath = PC+4
else
datapath = PC+4+(imm<<2)
The primary difference being that in C, say, only one side of the ?: or the then/else will execute, whereas in hardware, both sides execute, even though only one is chosen/useful.
For more info on operator execution in various languages, see Eager vs. Short-Circuit