The question is how do machine read the instructions?
for example:
if it is a R-type, machine first read the opcode to know the type of instruction,and base on the type, read the instruction from right to left,to know the rd and then read the funct3 and then rs1 and rs2 and last funct7.Is it right?
If you were writing a software emulator for RISC V you might have steps as follows:
Assuming byte *pc;
opcode = pc[0] & 0x7F;
if (opcode == 0x33) {
// reg/reg instruction format
rd = ((pc[0] & 0x80) >> 7) + ((pc[1] & 0x7) << 1);
func3 = (pc[1] & 0x38) >> 3;
rs1 = ...;
rs2 = ...;
s1 = reg[rs1];
s2 = reg[rs2];
switch (func3) {
case ...:
switch(func7) {
case ...:
answer = s1 + s2; break;
case ...:
answer = s1 & s2; break;
case ...:
answer = s1 | s2; break;
case ...:
answer = s1 - s2; break;
}
}
reg[rd] = answer;
}
Here you might specify that extracting the rd
field is conditional, and only done based on the opcode being reg/reg. And you might say that the rd
field is extracted first, followed by the func3
field.
However, the following would be equally valid:
opcode = pc[0] & 0x7F;
if (opcode == 0x33) {
// reg/reg instruction format
rs1 = ...;
rs2 = ...;
func3 = (pc[1] & 0x38) >> 3;
rd = ((pc[0] & 0x80) >> 7) + ((pc[1] & 0x7) << 1);
...
}
So, in software we would express an ordering of steps to decode, but the order is somewhat arbitrary. What's mostly important is to extract the fields under the condition of knowing that the instruction format is reg/reg.
However, hardware will do more like this:
parallel {
rs1 = ...;
rs2 = ...;
func3 = (pc[1] & 0x38) >> 3;
rd = ((pc[0] & 0x80) >> 7) + ((pc[1] & 0x7) << 1);
opcode = pc[0] & 0x7F;
imm = ...;
}
parallel {
s1 = reg[rs1];
s2 = reg[rs2];
}
parallel {
answer1 = s1 + s2;
answer2 = s1 - s2;
answer3 = s1 & s2;
answer4 = s1 | s2;
}
if opcode == 0x33 {
switch (func3) {
switch (func7) {
case ...:
reg[rd] = answer1; break;
case ...:
reg[rd] = answer2; break;
}
}
}
It is difficult to express a concept of ordering for the hardware — what it is going to do stepwise, first to last.
For the hardware, it is better to speak to the conditions and dependencies.
For example, as a dependency, we cannot obtain s1
without first obtaining rs1
, since s1 = reg[rs1]
.
As a condition, it should accept answer1
once it knows enough about opcode
, func3
and func7
.
However this does not stop the processor from computing other things in parallel in case the right value is answer2
. So, for the processor, it is about doing as much as it can in parallel, then excluding irrelevant information once a full determination is made regarding conditions and dependencies.
In software emulation we would not bother to extract immediate fields for reg/reg instruction format. However, the hardware would be extracting the immediate in parallel, and later disregarding the immediate field data, once it is known that the instruction format is reg/reg.