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.
Example code, for later: https://github.com/cvut/QtMips-Playground
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];
.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);