1. MIPS simulator

QtMips simulator

Download, unzip, and run the desktop version. Or, you can use the web version, but be aware that the graphics may be glitchy.

2. You are the assembler

Load the QtMips simulator, then load this code:

// Directives to make interresting windows visible
#pragma qtmips show registers
#pragma qtmips show memory

.globl _start
.set noat
.set noreorder

.text

_start:
main:
loop:
	la     $5, vect_a
	la     $6, vect_b
	la     $7, vect_c
	addi   $8, $0, 16
vect_next:
	lw     $2, 0($5)
	lw     $3, 0($6)
	add    $4, $2, $3
	sw     $4, 0($7)

	addi   $5, $5, 4
	addi   $6, $6, 4
	addi   $7, $7, 4
	addi   $8, $8, -1
	bne    $8, $0, vect_next
	nop

	// stop execution wait for debugger/user
	break
	// ensure that continuation does not
	// interpret random data
	beq    $0, $0, loop
	nop

.org 0x1000

.data

vect_a:	// int vect_a[16] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0};
	.word  0x01
	.word  0x02
	.word  0x03
	.word  0x04
	.word  0x05
	.word  0x06
	.word  0x07
	.word  0x08
	.word  0x09
	.word  0x0a
	.word  0x0b
	.word  0x0c
	.word  0x0d
	.word  0x0e
	.word  0x0f
	.word  0x00

vect_b:	// int vect_b[16] = {16, 32, 48, 64, ...};
	.word  0x10
	.word  0x20
	.word  0x30
	.word  0x40
	.word  0x50
	.word  0x60
	.word  0x70
	.word  0x80
	.word  0x90
	.word  0xa0
	.word  0xb0
	.word  0xc0
	.word  0xd0
	.word  0xe0
	.word  0xf0
	.word  0x00

vect_c:	// int vect_c[16];![](data/vect-add.c)
	.skip  64

// Specify location to show in memory window
#pragma qtmips focus memory vect_a
  • What does it do?

  • Rewrite into an equivalent block of C code.


There are data hazards present in this particular code for a pipelined datapath.

  • Where are all of the data hazards? (you should find 4)

We know that adding a forwarding unit helps speed up some hazards.

  • Rewrite the assembly so that it has zero stalls.

3. Followup

Video of my solution: Translate MIPS assembly to C

/*
 * ECE 424 Computer Architecture
 *
 * Translate MIPS assembly to C
 */


int vect_a[16] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0};
int vect_b[16] = {
    0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80,
    0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0, 0x00
};

// result
int vect_c[16];



/*loop:*/
do {
    /*la     $5, vect_a*/
    /*la     $6, vect_b*/
    /*la     $7, vect_c*/
    int *pa5 = &vect_a[0];
    int *pb6 = &vect_b[0];
    int *pc7 = &vect_c[0];

    /*addi   $8, $0, 16*/
    // loop counter
    int count8 = 16;

    /*vect_next:*/
    do {
        /*lw     $2, 0($5)*/
        /*lw     $3, 0($6)*/
        int tmpa2 = *pa5;
        int tmpb3 = *pb6;

        int tmpc4;

        /*add    $4, $2, $3*/
        tmpc4 = tmpa2 + tmpb3;

        /*sw     $4, 0($7)*/
        *pc7 = tmpc4;

        /*addi   $5, $5, 4*/
        /*addi   $6, $6, 4*/
        /*addi   $7, $7, 4*/
        pa5++;
        pb6++;
        pc7++;

        /*addi   $8, $8, -1*/
        count--;  // or count = count - 1;

        /*bne    $8, $0, vect_next*/
        /*nop*/
    } while (count8 != 0);

    /*beq    $0, $0, loop*/
    /*nop*/
} while (0 == 0);