| Simulate the datapath with a small MIPS test program
| Written by Pallav Gupta (pallav.gupta@villanova.edu)

|*******************************************************************
| main:  # Assembly code       Effect                    Machine code
|        lb $2, 68($0)         # initialize $2 = 5       80020044
|        lb $7, 64($0)         # initialize $7 = 3       80070040
|        lb $3, 69($7)         # initialize $3 = 12      80e30045
|        or $4, $7, $2         # $4 <= (3 or 5 = 7)      00e22025
|        and $5, $3, $4        # $5 <= (12 and 7 = 4)    00642824
|        add $5, $5, $4        # $5 <= (4 + 7 = 11)      00a42820
|        beq $5, $7, end       # shouldn't be taken      10a70008
|        slt $6, $3, $4        # $6 <= (12 < 7 = 0)      0064302a
|        beq $6, $0, around    # should be taken         10c00001
|        lb $5, 0($0)          # shouldn't happen        80050000
| around:
|        slt $6, $7, $2        # $6 <= (3 < 5 = 1)       00e2302a
|        add $7, $6, $5        # $7 <= (1 + 11 = 12)     00c53820
|        sub $7, $7, $2        # $7 <= (12 - 5 = 7)      00e23822
|        j end                 # should be taken         0800000f
|        lb $7, 0($0)          # shouldn't happen        80070000
| end:
|        sb $7, 0($2)          # write adr 5 <= 7        a0470000
|******************************************************************* 

| Define vectors for convenience
vector memdata memdata[7] memdata[6] memdata[5] memdata[4] memdata[3] memdata[2] memdata[1] memdata[0]
vector writedata writedata[7] writedata[6] writedata[5] writedata[4] writedata[3] writedata[2] writedata[1] writedata[0]
vector adr adr[7] adr[6] adr[5] adr[4] adr[3] adr[2] adr[1] adr[0]
vector alucontrol alucontrol[2] alucontrol[1] alucontrol[0]
vector opcode instr[31] instr[30] instr[29] instr[28] instr[27] instr[26] 
vector funct instr[3] instr[2] instr[1] instr[0]
vector irwrite irwrite[3] irwrite[2] irwrite[1] irwrite[0]
vector alusrcb alusrcb[1] alusrcb[0]
vector pcsource pcsource[1] pcsource[0]

| vector src2 src2[7] src2[6] src2[5] src2[4] src2[3] src2[2] src2[1] src2[0] 
| vector src1 src1[7] src1[6] src1[5] src1[4] src1[3] src1[2] src1[1] src1[0] 

| Setup a 2-phase nonoverlapping clock with a time of 10 ns for each phase (40 ns cycle time -> 25 MHz)
clock ph1 1 0 0 0
clock ph2 0 0 1 0
stepsize 10

h pcen

| Do hard reset, sets PC <= 00000000
h reset
c
c
l reset

|------------------------------------------------------
| lb $2, 68($0)       # intialize $2 = 5      80020044
|------------------------------------------------------

| state 0

l regdst
l regwrite
l memtoreg
l iord
l alusrca
set alusrcb 01
set pcsource 00
set alucontrol 010
set memdata 10000000
set irwrite 1000
c

| state 1
assert adr 00000000

set memdata 00000010
set irwrite 0100
c

| state 2
assert adr 00000001

set memdata 00000000
set irwrite 0010
c

| state 3
assert adr 00000010

set memdata 01000100
set irwrite 0001
c

| state 4
assert adr 00000011
assert opcode 100000

l pcen
set irwrite 0000
set alusrcb 11
c

| state 5
h alusrca
set alusrcb 10
c

| state 6
h iord
set memdata 00000101
c

| state 7
assert adr 01000100

h memtoreg
h regwrite
c

|------------------------------------------------------
| lb $7, 64($0)     # initialize $7 = 3       80070040
|------------------------------------------------------

| state 0

h pcen
l regdst
l regwrite
l memtoreg
l iord
l alusrca 
set alusrcb 01
set pcsource 00
set alucontrol 010
set memdata 10000000
set irwrite 1000
c

| state 1
assert adr 00000100

set memdata 00000111
set irwrite 0100
c

| state 2
assert adr 00000101

set memdata 00000000
set irwrite 0010
c

| state 3
assert adr 00000110

set memdata 01000000
set irwrite 0001
c

| state 4
assert adr 00000111
assert opcode 100000

l pcen
set irwrite 0000
set alusrcb 11
c

| state 5
h alusrca
set alusrcb 10
c

| state 6
h iord
set memdata 00000011
c

| state 7
assert adr 01000000

h memtoreg
h regwrite
c

|------------------------------------------------------
| lb $3, 69($7)     # initialize $3 = 12      80e30045
|------------------------------------------------------

| state 0
h pcen
l regdst
l regwrite
l memtoreg
l iord
l alusrca 
set alusrcb 01
set pcsource 00
set alucontrol 010
set memdata 10000000
set irwrite 1000
c

| state 1
assert adr 00001000

set memdata 11100011
set irwrite 0100
c

| state 2
assert adr 00001001

set memdata 00000000
set irwrite 0010
c

| state 3
assert adr 00001010

set memdata 01000101
set irwrite 0001
c

| state 4
assert adr 00001011
assert opcode 100000

l pcen
set irwrite 0000
set alusrcb 11
c

| state 5
h alusrca
set alusrcb 10
c

| state 6
h iord
set memdata 00001100
c

| state 7
assert adr 01001000

h memtoreg
h regwrite
c

|------------------------------------------------------
| or $4, $7, $2     # $4 <= (3 or 5 = 7)      00e22025
|------------------------------------------------------

| state 0
h pcen
l regdst
l regwrite
l memtoreg
l iord
l alusrca 
set alusrcb 01
set pcsource 00
set alucontrol 010
set memdata 00000000
set irwrite 1000
c

| state 1
assert adr 00001100

set memdata 11100010
set irwrite 0100
c

| state 2
assert adr 00001101

set memdata 00100000
set irwrite 0010
c

| state 3
assert adr 00001110

set memdata 00100101
set irwrite 0001
c

| state 4
assert adr 00001111
assert opcode 000000

l pcen
set irwrite 0000
set alusrcb 11
c

| state 9
assert funct 0101

h alusrca
set alusrcb 00
set alucontrol 001
c

| state 10
| assert src1 00000011
| assert src2 00000101

h regdst
h regwrite
c

|------------------------------------------------------
| and $5, $3, $4   # $5 <= (12 and 7 = 4)    00642824
|------------------------------------------------------

| state 0
h pcen
l regdst
l regwrite
l memtoreg
l iord
l alusrca 
set alusrcb 01
set pcsource 00
set alucontrol 010
set memdata 00000000
set irwrite 1000
c

| state 1
assert adr 00010000

set memdata 01100100
set irwrite 0100
c

| state 2
assert adr 00010001

set memdata 00101000
set irwrite 0010
c

| state 3 
assert adr 00010010

set memdata 00100100
set irwrite 0001
c

| state 4
assert adr 00010011
assert opcode 000000


l pcen
set irwrite 0000
set alusrcb 11
c

| state 9
assert funct 0100

h alusrca
set alusrcb 00
set alucontrol 000
c

| state 10
| assert src1 00001100
| assert src2 00000111

h regdst
h regwrite
c

|------------------------------------------------------
| add $5, $5, $4   # $5 <= (4 + 7 = 11)      00a42820
|------------------------------------------------------

| state 0

h pcen
l regdst
l regwrite
l memtoreg
l iord
l alusrca
set alusrcb 01
set pcsource 00
set alucontrol 010
set memdata 00000000
set irwrite 1000
c

| state 1
assert adr 00010100

set memdata 10100100
set irwrite 0100
c

| state 2
assert adr 00010101

set memdata 00101000
set irwrite 0010
c

| state 3
assert adr 00010110

set memdata 00100000
set irwrite 0001
c

| state 4
assert adr 00010111
assert opcode 000000

l pcen
set irwrite 0000
set alusrcb 11
c

| state 9
assert funct 0000

h alusrca
set alusrcb 00
set alucontrol 010
c

| state 10
| assert src1 00000100
| assert src2 00000111

h regdst
h regwrite
c

|------------------------------------------------------
| beq $5, $7, end   # shouldn't be taken      10a70008
|------------------------------------------------------

| state 0

h pcen
l regdst
l regwrite
l memtoreg
l iord
l alusrca
set alusrcb 01
set pcsource 00
set alucontrol 010
set memdata 00010000
set irwrite 1000
c

| state 1
assert adr 00011000

set memdata 10100111
set irwrite 0100
c

| state 2
assert adr 00011001

set memdata 00000000
set irwrite 0010
c

| state 3
assert adr 00011010

set memdata 00001000
set irwrite 0001
c

| state 4
assert adr 00011011
assert opcode 000100

l pcen
set irwrite 0000
set alusrcb 11
c

| state 11
| pcen = pcwrite | (pcwritecond & zero), don't set pcen to simulate this scenario
h alusrca
set alusrcb 00
set alucontrol 110
set pcsource 01
c

|------------------------------------------------------
| slt $6, $3, $4    # $6 <= (12 < 7 = 0)       0064302a
|------------------------------------------------------

| state 0

h pcen
l regdst
l regwrite
l memtoreg
l iord
l alusrca
set alusrcb 01
set pcsource 00
set alucontrol 010
set memdata 00000000
set irwrite 1000
c

| state 1
assert adr 00011100

set memdata 01100100
set irwrite 0100
c

| state 2
assert adr 00011101

set memdata 00110000
set irwrite 0010
c

| state 3
assert adr 00011110

set memdata 00101010
set irwrite 0001
c

| state 4
assert adr 00011111
assert opcode 000000

l pcen
set irwrite 0000
set alusrcb 11
c

| state 9
assert funct 1010

h alusrca
set alusrcb 00
set alucontrol 111
c

| state 10
| assert src1 00001100
| assert src2 00000111

h regdst
h regwrite
c

|------------------------------------------------------
| beq $6, $0, around  # should be taken       10c00001
|------------------------------------------------------

| state 0

h pcen
l regdst
l regwrite
l memtoreg
l iord
l alusrca
set alusrcb 01
set pcsource 00
set alucontrol 010
set memdata 00010000
set irwrite 1000
c

| state 1
assert adr 00100000

set memdata 11000000
set irwrite 0100
c

| staet 2
assert adr 00100001

set memdata 00000000
set irwrite 0010
c

| state 3
assert adr 00100010

set memdata 00000001
set irwrite 0001
c

| state 4
assert adr 00100011
assert opcode 000100

l pcen
set irwrite 0000
set alusrcb 11
c

| state 11
| pcen = pcwrite | (pcwritecond & zero), set pcen to take branch
h pcen
h alusrca
set alusrcb 00
set alucontrol 110
set pcsource 01
c

|------------------------------------------------------
| slt $6, $7, $2   # $6 <= (3 < 5 = 1)       00e2302a
|------------------------------------------------------

| state 0

l regdst
l regwrite
l memtoreg
l iord
l alusrca
set alusrcb 01
set pcsource 00
set alucontrol 010
set memdata 00000000
set irwrite 1000
c

| state 1
assert adr 00101000

set memdata 11100010
set irwrite 0100
c

| state 2
assert adr 00101001

set memdata 00110000
set irwrite 0010
c

| state 3
assert adr 00101010

set memdata 00101010
set irwrite 0001
c

| state 4
assert adr 00101011
assert opcode 000000

l pcen
set irwrite 0000
set alusrcb 11
c

| state 9
assert funct 1010

h alusrca
set alusrcb 00
set alucontrol 111
c

| state 10
| assert src1 00000011
| assert src2 00000101

h regdst
h regwrite
c

|------------------------------------------------------
| add $7, $6, $5    # $7 <= (1 + 11 = 12)     00c53820
|------------------------------------------------------

| state 0

h pcen
l regdst
l regwrite
l memtoreg
l iord
l alusrca
set alusrcb 01
set pcsource 00
set alucontrol 010
set memdata 00000000
set irwrite 1000
c

| state 1
assert adr 00101100

set memdata 11000101
set irwrite 0100
c

| state 2
assert adr 00101101

set memdata 00111000
set irwrite 0010
c

| state 3
assert adr 00101110

set memdata 00100000
set irwrite 0001
c

| state 4
assert adr 00101111
assert opcode 000000

l pcen
set irwrite 0000
set alusrcb 11
c

| state 9
assert funct 0000

h alusrca
set alusrcb 00
set alucontrol 010
c

| state 10
| assert src1 00000001
| assert src2 00001011

h regdst
h regwrite
c

|------------------------------------------------------
| sub $7, $7, $2   # $7 <= (12 - 5 = 7)      00e23822
|------------------------------------------------------

| state 0
h pcen
l regdst
l regwrite
l memtoreg
l iord
l alusrca
set alusrcb 01
set pcsource 00
set alucontrol 010
set memdata 00000000
set irwrite 1000
c

| state 1
assert adr 00110000

set memdata 11100010
set irwrite 0100
c

| state 2
assert adr 00110001

set memdata 00111000
set irwrite 0010
c

| state 3
assert adr 00110010

set memdata 00100010
set irwrite 0001
c

| state 4
assert adr 00110011
assert opcode 000000

l pcen
set irwrite 0000
set alusrcb 11
c

| state 9
assert funct 0010

h alusrca
set alusrcb 00
set alucontrol 110
c

| state 10
| assert src1 00001100
| assert src2 00000101

h regdst
h regwrite
c

|------------------------------------------------------
| j end            # should be taken         0800000f
|------------------------------------------------------

| state 0

h pcen
l regdst
l regwrite
l memtoreg
l iord
l alusrca
set alusrcb 01
set pcsource 00
set alucontrol 010
set memdata 00001000
set irwrite 1000
c

| state 1
assert adr 00110100

set memdata 00000000
set irwrite 0100
c

| state 2
assert adr 00110101

set memdata 00000000
set irwrite 0010
c

| state 3
assert adr 00110110

set memdata 00001111
set irwrite 0001
c

| state 4
assert adr 00110111
assert opcode 000010

l pcen
set irwrite 0000
set alusrcb 11
c

| state 12
h pcen
set pcsource 10
c

|------------------------------------------------------
| sb $7, 0($2)     # write adr 5 <= 7        a0470000
|------------------------------------------------------

| state 0

h pcen
l regdst
l regwrite
l memtoreg
l iord
l alusrca
set alusrcb 01
set pcsource 00
set alucontrol 010
set memdata 10100000
set irwrite 1000
c

| state 1
assert adr 00111100

set memdata 01000111
set irwrite 0100
c

| state 2
assert adr 00111101

set memdata 00000000
set irwrite 0010
c

| state 3
assert adr 00111110

set memdata 00000000
set irwrite 0001
c

| state 4
assert adr 00111111
assert opcode 101000

l pcen
set irwrite 0000
set alusrcb 11
c

| state 5
h alusrca
set alusrcb 10
c

| state 8
h iord
c

assert writedata 00000111
assert adr 00000101

| Hooray, everything passes!