======== START LECTURE #16
========
Don't forget the mirror site. My main website will be
going down for an OS upgrade. Start at http://cs.nyu.edu/
load and store
lw $r,disp($s)
sw $r,disp($s)
- lw $r,disp($s):
- Computes the effective address formed by adding the 16-bit
immediate constant ``disp'' to the contents of register $s.
- Fetches the value from this address.
- Inserts this value into register $r
- sw $r,disp($s):
- Computes the same effective address as lw $r,disp($s)
- Stores the contents of register $r into this address
- We have a 32-bit adder so need to extend the 16-bit immediate
constant to 32 bits. Produce an additional 16 HOBs all equal to the
sign bit of the 16-bit immediate constant. This is called sign
extending the constant.
- I previously said that the address was a word address and that the
hardware shifted the address 2 bits. This is wrong and has
been corrected.
There is a cheat here.
- For lw we read register r (and read s)
- For sw we write register r (and read s)
- But we indicate that the same bits in the register always go to
the same ports in the register file.
- We are ``mux deficient''.
- We will put in the mux later
Branch on equal (beq)
Compare two registers and branch if equal
- To check for equal we subtract and test for zero (our ALU does
this)
- If $r=$s, the target of the branch beq $r,$s,disp is the sum of
- The program counter PC after it has been incremented,
that is the address of the next sequential instruction
- The 16-bit immediate constant ``disp'' (treated as a signed
number) left shifted 2 bits.
- The value of PC after the increment is available. We computed it
in the basic instruction fetch datapath.
- Since the immediate constant is signed it must be sign extended.
- The top ``alu symbol'' labeled ``add'' is just an adder so does
not need any control
- The shift left 2 is not a shifter. It simply moves wires and
includes two zero wires. We need a 32-bit version. Below is a 5 bit
version.
5.3: A simple implementation scheme
We will just put the pieces together and then figure out the control
lines that are needed and how to set them. We are not now worried
about speed.
We are assuming that the instruction memory and data memory are
separate. So we are not permitting self modifying code. We are not
showing how either memory is connected to the outside world (i.e. we
are ignoring I/O).
We have to use the same register file with all the pieces since when a
load changes a register a subsequent R-type instruction must see the
change, when an R-type instruction makes a change the lw/sw must see
it (for loading or calculating the effective address, etc.
We could use separate ALUs for each type but it is easy not to so we
will use the same ALU for all. We do have a separate adder for
incrementing the PC.
Combining R-type and lw/sw
The problem is that some inputs can come from different sources.
- For R-type, both ALU operands are registers. For I-type (lw/sw)
the second operand is the (sign extended) immediate field.
- For R-type, the write data comes from the ALU. For lw it comes
from the memory.
- For R-type, the write register comes from field rd, which is bits
15-11. For sw, the write register comes from field rt, which is bits
20-16.
We will deal with the first two now by using a mux for each. We
will deal with the third shortly by (surprise) using a mux.
Combining R-type and lw/sw
Including instruction fetch
This is quite easy
Finally, beq
We need to have an ``if stmt'' for PC (i.e., a mux)
Homework:
- 5.5 and 5.8 (just datapaths not control)
- 5.9