Computer Organization

Lab: Single-Cycle Datapath and Control

Purpose
Learn how to implement instructions for a CPU.
Method
Implement the datapath and control for a subset of the MIPS instruction set architecture described in the textbook.
Preparation
Read sections 5.1 through 5.4 in the textbook.
Files to Use
datapath.circ, control.circ, cpu32.circ, misc32.circ, and loop.mem.
What to Hand In
Datapath: Completed datapath.circ, loop.mem, and first table of control settings.
Control: Completed control.circ, loop.s loop.mem, slti.s, slti.mem and completed table of control settings.

The file datapath.circ contains an incomplete implementation of the MIPS instruction set architecture (ISA). This circuit is similar to Figure 5.17 on page 307 in the textbook. This datapath can execute the following instructions: add, sub, and, or, nor, slt, addi, lw, sw, and beq.

  1. Complete the circuit for the datapath by adding appropriate multiplexors and logic gates and wiring them to the components that are already in place. Note that some of the wiring, such as the wiring for the instrucution memory and data memory, is already done.
  2. Connect the control lines from the Control and ALUcontrol subcircuits to the datapath as appropriate.
  3. Translate the following assembly language program into hexadecimal machine language. (You may want to use the MARS simulator to assist you with this task, but be careful.) Put the resulting machine language program (in hexadecimal) in the file loop.mem.
    loop:	addi	$t0, $zero, 17
    	sw	$t0, 0($zero)
    	beq	$zero, $zero, loop
    
  4. Complete the table (doc, pdf) showing how the control signals should be set for each instruction of the program above. Remember that ALUop is 2 bits and Operation is the 4-bit control for the ALU.
  5. Test your datapath by executing a short program. You will have to manually set the control signals for the Control and ALUcontrol circuits.
    1. Connect a 9-bit input to the top of the Control circuit.
    2. Connect a 4-bit input to the top of the ALUcontrol circuit.
    3. Reset the program counter to zero.
    4. Load your edited file loop.mem into the instruction memory.
    5. Set the control signals for the Control and ALUcontrol circuits to correspond to the first instruction of the program. In order to have the correct data stored in the registes or memory you must cause a rising edge on the appropriate control line after the other control lines have been set.
    6. Put the clock through one cycle to update the program counter.
    7. Go back to step 3 and repeat this procedure for the remaining instructions of the program.

Next complete the control to implement our subset of instructions.

  1. Complete the truth tables (doc, pdf) for the Control and ALUconrol circuits. Use X for "don't care" where appropriate. Note that the slti instruction is not discussed in the textbook, but can be executed on this datapath with appropriate control settings.
  2. Build the Control_0, Control_1, and ALUcontrol_0 subcircuits in control.circ. Do not make any changes to the circuits in datapath.circ.
  3. Test your CPU using each of the following test programs. Translate each of the assembly language programs into machine language. (You may want to use the SPIM simulator to assist you with this task, but be careful.) Enter the machine language into the program memory using hexadecimal notation. Run each program to test your CPU.
    1. nop is a pseudo-instruction that does nothing. It is encoded as 0x00000000 and is equivalent to an R-type instruction with register $zero as its operands and its destination. Because the contents of register $zero cannot be altered, this instruction has no effect. Fill program memory with several nop instructions. The program counter should increase by 4 as each nop instruction is executed.
      	nop			# sll	$zero, $zero, 0
      
    2. halt is a pseudo-instruction that halts the CPU. It is equivalent to a branch with an address offset of -1. Replace one of the nop instructions with a halt instruction. The program counter should increase by 4 as each nop instruction is executed. The program counter should stop changing when the halt instruction is reached.
      	halt			# beq	$zero, $zero, -1
      
    3. This program loads a value from the first location in data memory and copies it to the next location in data memory. (Depending on the phase of the clock at the time the CPU is reset, the first instruction may not be executed correctly. The initial nop instruction ensures that the first important instruction of the program will always be executed.) Enter a hexadecimal value into the first data memory location before executing this program.
      	nop
      	lw	$t0, 0($zero)	# n = mem[0]
      	sw	$t0, 4($zero)	# mem[4] = n
      	halt
      
    4. This program loads a value from the first location in data memory, adds 1, then stores the result in the next location in data memory. Enter a hexadecimal value into the first data memory location before executing this program.
      	nop
      	lw	$t0, 0($zero)	# n = mem[0]
      	addi	$t0, $t0, 1	# n++
      	sw	$t0, 4($zero)	# mem[4] = n
      	halt
          
    5. This program loads a value n from the first location in data memory and then fills the first n memory locations with the values from 0 to n-1. Enter a hexadecimal value into the first data memory location before executing this program.

      Translate the program to an equivalent assembly language program that uses only instructions supported directly by the hardware. Save the resulting assembly language program in a file named loop.s and save the corresponding machine language program (in hexadecimal) in a file named loop.mem. You may want to use the file loop.mem from the previous lab as a template.

      	nop
      	li	$t0, 0		# n = 0
      	lw	$t2, 0($t0)	# limit = mem[0]
      	j	test		# test at end of loop
      loop:	add	$t1, $t0, $t0	# t1 = 2n
      	add	$t1, $t1, $t1	# t1 = 4n
      	sw	$t0, 0($t1)	# mem[4n] = n
      	addi	$t0, $t0, 1	# n++
      test:	blt	$t0, $t2, loop	# while(n < limit)
      	halt
      
    6. Create a program of your own that demonstrates the use of the slti instruction. Save your assembly language program in a file named slti.s and the corresponding machine language program (in hexadecimal) in a file named slti.mem.