Reputation: 1302
The code for this is too long to post so Ill just describe it. I've created a 5 stage mips pipe that almost works. The catch is that EVERY lw instruction that reaches the instruction decode stage overwrites the control signal values in the execution stage. Not only that it causes the PC to skip can instruction, i.e from 300 -> 308. I just need some idea on where to look for bugs since this is a class assignment. If we take out all the LW instructions the CPU works fine.
Example: The adder in the EX stage is going to sub $4 $1 $2 which should be 1 Once LW enters the ID stage ALUsrc is asserted AND ALUop is changed from subtract to add This forces the adder in the EX stage to add $4 $1 $2 resulting in 5 being stored in $4
Upvotes: 0
Views: 4046
Reputation:
http://en.wikipedia.org/wiki/File:MIPS_Architecture_%28Pipelined%29.svg
The MIPS 5 Stage Pipeline (annotated to show Write Reg Select and enable)
The bottom line through the pipeline stages represents the register file write (back) port address and write enable and WB is the data from memory.
http://www.mrc.uidaho.edu/mrc/people/jff/digital/MIPSir.html
Load Word Instruction Description: A word is loaded into a register from the specified address.
Operation: $t = MEM[$s + offset]; advance_pc (4);
Syntax: lw $t, offset($s)
Encoding: 1000 11ss ssst tttt iiii iiii iiii iiii
Where the write register address ($t) input is read from data memory address comprised of register file register $s offset with the immediate value i which gets sign extended. Your $4 is $t above, $1 or $2 is $s while the remaining register file output lane sounds to be suborned for the sign extended immediate.
From your description it sounds like you aren't using a three port register file with one port a write only port.
With a three port register file the only time you run into conflicts is when you attempt to use the new register file value from memory before it is read from memory and written to the register file. That can be managed by a compiler scheduling NOOPs until the outstanding register file write is retired when a following instruction is trying to use it, or stalling the IF/ID in hardware when it's output contains a reference to an outstanding register file write.
There are three instructions that can be in flight to the right of IF/ID, each with a write to register file address and a write enable. You'd need to compare both instruction decode register file addresses to all three of those and stall IF/ID until those clear out. The write enable stored in each of those three pipeline stages are used to determine whether the write register address in those pipeilne stages should be compared.
Because the ID/EX, EX/MEM and MEM/WB write register file addresses are not used anywhere else the circuitry for doing the comparison can be collocated with IF/ID and the Register File, preventing unnecessary layout delays affecting the minimum clock cycle.
Using a two port register file is much simpler and infers IF/ID stalling until the write enable comes back from MEM/WB, effectively turning any memory reading instructions into 3 cycle instructions (or more, data memory can stall if it's a cache or slow). It makes a three port register file more or less necessary for performance reasons. There's an implied multiplexer to source for at least one of the two register file port controls (write enable, write address) from the MEM/WB stage when IF/ID is stalled (for memory->regfile).
Data memory access can stall MEM/WB, just like instruction memory access can also stall IF/ID. A stalled IF/ID doesn't issue a write enable for the register file to ID/EX nor does a stalled MEM/WB.
Upvotes: 1