m8pple/arch2-2016-cw

Overwriting registers

ZoeSlattery opened this issue · 8 comments

When creating functions that require a destination register for the result, how do you choose which to use to avoid overwriting values already in them?

Do you mean from the tester's side? So if you want to test an add instruction,
how do you find a "free" register? Or do you mean if you want to use a destination
register that is also a source register?

Can you give an example of when/where this occurs?

Yes, from the tester's side, and yes to the second question. How do you tell which is destination and which is source, I thought we decided that? This occurs when attempting to use an add instruction, I'm unclear about where the answer ends up, or if we have to put it somewhere specifically?

So if you're on the tester side, you want to do the following steps (I'm not looking at the
API right now, so function names are from memory):

  • Choose/create an add instruction, along with two source registers and a destination register
  • Put that add instruction in a known memory location (mips_mem_write)
  • Place two known values in the source registers (mips_cpu_set_reg)
  • Place the programme counter on the instruction (mips_cpu_set_pc)
  • Step the cpu (mips_cpu_step)
  • Read the value back from the destination register (mips_cpu_get_reg)
  • Check that the value in the destination register was the sum of the two known values

On the CPU side you'll have to implement those functions being called, but
the main action happens inside the call to mips_cpu_step:

  • Turn the programme counter into the instruction (mips_mem_read)
  • (At this point it is convenient to do pc=pcNext, pcNext=pcNext+4)
  • Decode the instruction, and find out it is an R-type
  • Extract the two source register indexes, the destination and the function code
  • Turn the source register index into the two values
  • Use the function code to determine that the values should be added together
  • Add them together
  • Write the sum into the destination register
  • Return success

Thank you! Another thing, we've been having trouble in that we can't write to any register which isn't 0?
And are also confused about the difference between mem_write and set_reg

You can write to any register, including zero. The only difference is that 0 is guaranteed to remain
0, even if you write something non-zero.

That applies on either side: the tester is free to modify any register, as it is "between" clock
cycles, so the CPU can't observe any changes.

The CPU can change any register values it needs to (as determined by the instruction),
but only does that within a few constrained functions where it is allowed to modify
the state of the registers. For example, mips_cpu_get_reg should never change a
register value, but mips_cpu_set_reg and mips_cpu_step can.

Regarding the difference between mips_mem_write and mips_cpu_set_reg: the
registers are entirely inside the CPU, and are indexed using 5-bit register indices.
The ram/memory is entirely outside the CPU, and is indexed by a full 32-bit
address. Both serve the function of mapping addresses to storage locations, but
registers are very fast and on the inside, and RAM is slower and on the outside.

The register indices and addresses also mean different things: register index 4
is talking about the fourth register, while address 4 is talking about memory
starting at the 4th byte.

As a thought experiment - your tester wants to get instructions over to
the CPU to test it. However, writing an instruction using mips_cpu_set_reg
only places bits of the instruction in a register. There is no actual path
to allow that value to be decoded (you can refer to the control+data path
from the last lecture). The only way of getting instructions to the decoder
is via the "PC -> memory -> decode" route, which means
your tester must use mips_mem_write in order to place it in the memory.

We have an issue with the concept of retrieve and writing to memory amongst others. Could we come and see you tomorrow? Because we seem to be implementing something wrong as the only register we can change is 0. Would either 9am - 12pm or after 4pm work for you? Mwana and Zoe

In mips_cpu_step the specification says the instruction mist be fetched from memory. The only parameter passed in is mips_cpu_h state. How do we know where to fetch the instruction from?

I can't really do any time but 1300 tomorrow. See #28

Re where to get the memory from - remember that you were passed a mips_mem_h when you created the cpu. As long as you keep a copy of the memory handle in your cpu state, you can read or write to memory whenever you want.

(On my phone, so afraid a bit brief)