Merge branch 'main' of https://github.com/supleed2/AM04_CPU into main

This commit is contained in:
jc4419 2020-12-13 15:38:04 +04:00
commit da6be29109
81 changed files with 1360 additions and 336 deletions

BIN
.DS_Store vendored Normal file

Binary file not shown.

BIN
inputs/.DS_Store vendored Normal file

Binary file not shown.

1
inputs/addiu.ref.txt Normal file
View file

@ -0,0 +1 @@
30

3
inputs/addiu.txt Normal file
View file

@ -0,0 +1,3 @@
3404000a
24820014
00000008

1
inputs/addu.ref.txt Normal file
View file

@ -0,0 +1 @@
8

1
inputs/and.ref.txt Normal file
View file

@ -0,0 +1 @@
10

4
inputs/and.txt Normal file
View file

@ -0,0 +1,4 @@
3404000A
3405000F
00851024
00000008

1
inputs/andi.ref.txt Normal file
View file

@ -0,0 +1 @@
5

5
inputs/andi.txt Normal file
View file

@ -0,0 +1,5 @@
34040005
3082000f
00000008
00000000
00000000

View file

@ -1,7 +1,8 @@
50004043 34040005
50005043 34050005
20005801 10850003
00006C42 00000000
80000000 00000008
10002043 00000000
80000000 34020001
00000008

View file

@ -1,6 +1,7 @@
30004043 34040003
20001840 04810003
00006C42 00000000
80000000 00000008
10002043 00000000
80000000 34020001
00000008

View file

@ -1,7 +1,8 @@
30004043 34040003
30001940 04910004
00006C42 00000000
10002442 24420001
80000000 00000008
10002043 00000000
80000000 34020001
03E00008

View file

@ -1,6 +1,7 @@
30004043 34040003
200008C1 1C800003
00006C42 00000000
80000000 00000008
10002043 00000000
80000000 34020001
00000008

View file

@ -1,6 +1,7 @@
FFFF4043 3C05FFFF
20000881 18800003
00006C42 00000000
80000000 00000008
10002043 00000000
80000000 34020001
00000008

View file

@ -1,6 +1,7 @@
FFFF4043 3C05FFFF
20000840 04800003
00006C42 00000000
80000000 00000008
10002043 00000000
80000000 34020001
00000008

View file

@ -1,7 +1,8 @@
FFFF4043 3C05FFFF
20000940 04900004
00006C42 00000000
10002442 24420001
80000000 00000000
10002043 00000008
80000000 34020001
03E00008

View file

@ -1,7 +1,8 @@
30004043 34040003
50005043 34040005
20005841 14850003
00006C42 00000000
80000000 00000008
10002043 00000000
80000000 34020001
00000008

4
inputs/div.txt Normal file
View file

@ -0,0 +1,4 @@
34040004
34050003
0085001A
00000008

4
inputs/divu.txt Normal file
View file

@ -0,0 +1,4 @@
34040004
34050003
0085001B
00000008

1
inputs/j.ref.txt Normal file
View file

@ -0,0 +1 @@
1

6
inputs/j.txt Normal file
View file

@ -0,0 +1,6 @@
08000004
00000000
00000008
00000000
34020001
00000008

1
inputs/jal.ref.txt Normal file
View file

@ -0,0 +1 @@
2

7
inputs/jal.txt Normal file
View file

@ -0,0 +1,7 @@
0C000005
00000000
24420001
00000008
00000000
34020001
03E00008

1
inputs/jalr.ref.txt Normal file
View file

@ -0,0 +1 @@
2

9
inputs/jalr.txt Normal file
View file

@ -0,0 +1,9 @@
3405001C
3C05BCF0
00A02009
00000000
24420001
00000008
00000000
34020001
00800008

1
inputs/jr.ref.txt Normal file
View file

@ -0,0 +1 @@
1

7
inputs/jr.txt Normal file
View file

@ -0,0 +1,7 @@
34050014
3C05BCF0
00A00008
00000000
00000008
34020001
00000008

4
inputs/lb.data.txt Normal file
View file

@ -0,0 +1,4 @@
00000000
008A0000
00000000
00000000

1
inputs/lb.ref.txt Normal file
View file

@ -0,0 +1 @@
4294967178

3
inputs/lb.txt Normal file
View file

@ -0,0 +1,3 @@
34041003
80820003
00000008

4
inputs/lbu.data.txt Normal file
View file

@ -0,0 +1,4 @@
00000000
008A0000
00000000
00000000

1
inputs/lbu.ref.txt Normal file
View file

@ -0,0 +1 @@
138

3
inputs/lbu.txt Normal file
View file

@ -0,0 +1,3 @@
34041003
90820003
00000008

4
inputs/lh.data.txt Normal file
View file

@ -0,0 +1,4 @@
00000000
00008123
00000000
00000000

1
inputs/lh.ref.txt Normal file
View file

@ -0,0 +1 @@
4294934819

3
inputs/lh.txt Normal file
View file

@ -0,0 +1,3 @@
34041003
84820004
00000008

4
inputs/lhu.data.txt Normal file
View file

@ -0,0 +1,4 @@
00000000
00008123
00000000
00000000

1
inputs/lhu.ref.txt Normal file
View file

@ -0,0 +1 @@
33059

3
inputs/lhu.txt Normal file
View file

@ -0,0 +1,3 @@
34041003
94820004
00000008

1
inputs/lui.ref.txt Normal file
View file

@ -0,0 +1 @@
305419896

3
inputs/lui.txt Normal file
View file

@ -0,0 +1,3 @@
34045678
3C021234
00000008

4
inputs/lw.data.txt Normal file
View file

@ -0,0 +1,4 @@
00000000
12345678
00000000
00000000

1
inputs/lw.ref.txt Normal file
View file

@ -0,0 +1 @@
305419896

3
inputs/lw.txt Normal file
View file

@ -0,0 +1,3 @@
34041002
8C820002
00000008

4
inputs/lwl.data.txt Normal file
View file

@ -0,0 +1,4 @@
00000000
AAAA1234
00000000
00000000

1
inputs/lwl.ref.txt Normal file
View file

@ -0,0 +1 @@
305419896

4
inputs/lwl.txt Normal file
View file

@ -0,0 +1,4 @@
34041003
34025678
88820003
00000008

4
inputs/lwr.data.txt Normal file
View file

@ -0,0 +1,4 @@
00000000
5678AAAA
00000000
00000000

1
inputs/lwr.ref.txt Normal file
View file

@ -0,0 +1 @@
305419896

4
inputs/lwr.txt Normal file
View file

@ -0,0 +1,4 @@
34041003
3C021234
98820002
00000008

4
inputs/mfhi.txt Normal file
View file

@ -0,0 +1,4 @@
34040003
00800011
00001010
00000008

5
inputs/mflo.txt Normal file
View file

@ -0,0 +1,5 @@
34040004
34050003
00850019
00001012
00000008

3
inputs/mthi.txt Normal file
View file

@ -0,0 +1,3 @@
34040005
00800011
00000008

3
inputs/mtlo.txt Normal file
View file

@ -0,0 +1,3 @@
34040005
00800013
00000008

5
inputs/mult.txt Normal file
View file

@ -0,0 +1,5 @@
34040004
34050003
00850018
00001012
00000008

4
inputs/multcurrent.txt Normal file
View file

@ -0,0 +1,4 @@
34040004
34050003
00850018
00000008

5
inputs/multu.txt Normal file
View file

@ -0,0 +1,5 @@
34040004
34050003
00850019
00001012
00000008

4
inputs/multucurrent.txt Normal file
View file

@ -0,0 +1,4 @@
34040004
34050003
00850019
00000008

4
inputs/or.txt Normal file
View file

@ -0,0 +1,4 @@
34040005
34050003
00851025
00000008

View file

@ -1,8 +1,2 @@
34040003 34040003
00000008 00000008
00000000
00000000
00000000
00000000
00000000
00000000

View file

@ -1,224 +0,0 @@
== Instruction ==
C code
Assembly code
Hex code
Reference Output
================
== ADDIU Add immediate unsigned (no overflow) ==
== ADDU Add unsigned (no overflow) ==
int main(void) {
int a = 3 + 5;
}
ORI $4,$0,3
ORI $5,$0,5
ADDU $2,$4,$5
JR $0
34040003
34050005
00851021
00000008
register_v0 = 8
== AND Bitwise and ==
ANDI Bitwise and immediate
==BEQ Branch on equal==
ORI $4,$0,5
ORI $5,$0,5
BEQ $4,$5,2
ADDIU $6,$6,0
JR $0
ORI $2,$0,1
JR $0
50004043
50005043
20005801
00006C42
80000000
10002043
80000000
register_v0 = 1
==BGEZ Branch on greater than or equal to zero==
ORI $4,$0,3
BGEZ $4,2
ADDIU $6,$6,0
JR $0
ORI $2,$0,1
JR $0
30004043
20001840
00006C42
80000000
10002043
80000000
register_v0 = 1
==BGEZAL Branch on non-negative (>=0) and link==
ORI $4,$0,3
BGEZAL $4,3
ADDIU $6,$6,0
ADDIU $2,$2,1
JR $0
ORI $2,$0,1
JR $31
30004043
30001940
00006C42
10002442
80000000
10002043
80000000
register_v0 = 2
==BGTZ Branch on greater than zero==
ORI $4,$0,3
BGTZ $4,2
ADDIU $6,$6,0
JR $0
ORI $2,$0,1
JR $0
30004043
200008C1
00006C42
80000000
10002043
80000000
register_v0 = 1
==BLEZ Branch on less than or equal to zero==
ORI $4,$0,-1
BLEZ $4,2
ADDIU $6,$6,0
JR $0
ORI $2,$0,1
JR $0
FFFF4043
20000881
00006C42
80000000
10002043
80000000
register_v0 = 1
==BLTZ Branch on less than zero==
ORI $4,$0,-1
BLTZ $4,2
ADDIU $6,$6,0
JR $0
ORI $2,$0,1
JR $0
FFFF4043
20000840
00006C42
80000000
10002043
80000000
register_v0 = 1
==BLTZAL Branch on less than zero and link==
ORI $4,$0,-1
BLTZAL $4,3
ADDIU $6,$6,0
ADDIU $2,$2,1
JR $0
ORI $2,$0,1
JR $31
FFFF4043
20000940
00006C42
10002442
80000000
10002043
80000000
register_v0 = 2
==BNE Branch on not equal==
ORI $4,$0,3
ORI $5,$0,5
BNE $4,$5,2
ADDIU $6, $6, 0
JR $0
ORI $2,$0,1
JR $
30004043
50005043
20005841
00006C42
80000000
10002043
80000000
register_v0 = 1
DIV Divide
DIVU Divide unsigned
J Jump
JALR Jump and link register
JAL Jump and link
JR Jump register
LB Load byte
LBU Load byte unsigned
LH Load half-word
LHU Load half-word unsigned
LUI Load upper immediate
LW Load word
LWL Load word left
LWR Load word right
MTHI Move to HI
MTLO Move to LO
MULT Multiply
MULTU Multiply unsigned
OR Bitwise or
ORI Bitwise or immediate
SB Store byte
SH Store half-word
SLL Shift left logical
SLLV Shift left logical variable
SLT Set on less than (signed)
SLTI Set on less than immediate (signed)
SLTIU Set on less than immediate unsigned
SLTU Set on less than unsigned
SRA Shift right arithmetic
SRAV Shift right arithmetic
SRL Shift right logical
SRLV Shift right logical variable
SUBU Subtract unsigned
SW Store word
XOR Bitwise exclusive or
XORI Bitwise exclusive or immediate

View file

@ -0,0 +1,481 @@
===== ADDIU ==========
int main(void) {
int a = -2147483648 + -32768 ;
}
ORI $4,$0,-2147483648
ADDIU $2,$4,-32768
JR $0
//used to check for overflow 32768 is 2^15 which should
be sign extended. 21... is 2^31
register_v0 =
==========XORI Bitwise exclusive or immediate=============
int main(void) {
int a = 5 ^ 2;
}
ori $4,$0,5
xori $2,$4,2
jr $0
register 0 = 7
34040005
38820002
00000008
convert to little endian
////////
====XOR Bitwise exclusive or==========
int main(void) {
int a = 5 ^ 2;
}
ori $4, $0, 5
ori $5, $0, 2
xor $2, $4, $5
jr $0
register 0 = 7
34040005
34050002
00851026
00000008
convert to little endian
////////
========SW Store word==============
int main(void) {
ori $4, $0, 5
ori $5, $0, 1
sw $4, 1($5)
jr $0
register 0 = 5
34040005
34050001
aca40001
00000008
=========== SUBU Subtract unsigned ===========
int main(void) {
int a = 5-3;
}
ori $4,$0,5
ori $5,$0,3
subu $2,$4,$5
jr $0
register_v0 = 2
34040005
34050003
00851023
00000008
========= SRLV Shift right logical variable ======
int main(void) {
int a = 2;
int b = 16>>a;
}
ori $4,$0,2
ori $5,$0,16
srlv $2,$5,$4
jr $0
register 0 = 3
34040002
34050010
//////
//////
=============== SRL Shift right logical ==============
int main(void) {
int a = -2147483647>>2; #logical shift - should feed in 0s
}
ori $4,$0,-2147483647
srl $2,$4,$2
jr $0
register 0 = 536870912 (2^29)
34040001
00041002
00000008
========== SRAV Shift right arithmetic variable =======
int main(void) {
int a = 2;
int b = -2147483647>>2; #arithemtic shift not logical - feed in 1s (sign extension)
}
ori $4, $0, 2
ori $5,$0,-2147483647
srav $2,$5,$4
jr $0
register 0 = -536870912 (first 3 bits high - rest low)
34040002
34050001
////////
///////
====== SRA Shift right arithmetic ==========
int main(void) {
int a = -2147483647>>2; #arithemtic shift not logical - feed in 1s (sign extension)
}
ori $4,$0,-2147483647
sra $2,$4,$2
jr $0
register 0 = -536870912 (first 3 bits high - rest low)
34040001
00041003
00000008
======= SLTU Set on less than unsigned =====
int main() {
int a = 10;
int b = 9;
max = a < b ? 1 : 0;
return max;
}
ori $4, $0, 10
ori $5, $0, 9
sltu $2, $4, $5
jr $0
register 0 = 0
3404000a
34050009
0085102b
00000008
=========== SLTIU Set on less than immediate unsigned ==================
int main() {
int a = 10;
max = a < 9 ? 1 : 0;
return max;
}
ori $4, $0, 10
sltiu $2, $4, 9
jr $0
register 0 = 0
3404000a
2c820009
00000008
======= SLTI Set on less than immediate (signed) ========
int main() {
int a = 10;
max = a < 9 ? 1 : 0;
return max;
}
ori $4, $0, 10
slti $2, $4, 9
jr $0
register 0 = 0
3404000a
28820009
00000008
======= SLLV Shift left logical variable ======
int main(void) {
int a = 2;
int b = 3<<a;
}
ori $4,$0,2
ori $5,$0,3
sllv $2,$5,$4
jr $0
register 0 = 16
34040002
34050003
//////
//////
======= SLL Shift left logical ======
int main(void) {
int a = 3<<2;
}
ori $4,$0,3
sll $2,$4,2
jr $0
register 0 = 16
34040003
00041080
00000008
======== SB Store byte =======
ori $4, $0, 1029
ori $5, $0, 1
sb $4, 1($5)
jr $0
register 0 = 5
34040405
34050001
a0a40001
00000008
======== ORI Bitwise or immediate ===
ori $4,$0,3
jr $0
register a0 = 3
34040003
00000008
======== OR Bitwise or ===
int main(){
int a =5;
int b= 3;
int c = 5 | 3;
return 0;
}
ori $4, $0, 5
ori $5, $0, 3
or $2, $4, $5
jr $0
34040005
34050003
00851025
00000008
register 0 = 7
======= MULT Multiply =====
ori $4, $0, 4
ori $5, $0, 3
mult $4, $5
jr $0
$LO = 12
34040004
34050003
00850018
00000008
======= MULT Multiply =====
ori $4, $0, 4
ori $5, $0, 3
mult $4, $5
mflo $2
jr $0
register v0 = 12
34040004
34050003
00850018
00001012
00000008
======= MULTU Multiply unsigned =====
ori $4, $0, 4
ori $5, $0, 3
multu $4, $5
jr $0
$LO = 12
34040004
34050003
00850019
00000008
======= MULTU Multiply unsigned =====
ori $4, $0, 4
ori $5, $0, 3
multu $4, $5
mflo $2
jr $0
$2 = 12
34040004
34050003
00850019
00001012
00000008
======= MFLO Move from lo ======
ori $4, $0, 4
ori $5, $0, 3
multu $4, $5
mflo $2
jr $0
$2 = 12
34040004
34050003
00850019
00001012
00000008
=========== MFHI Move from Hi ==========
ori $4, $0, 3
mthi $4
mfhi $2
jr $0
register v0 = 3
34040003
00800011
00001010
00000008
======== MTHI Move to HI ====
ori $4, $0, 5
mthi $4
jr $0
$HI = 5
34040005
00800011
00000008
======= MTLO Move to LO ===
ori $4, $0, 5
mtlo $4
jr $0
$HI = 5
34040005
00800013
00000008
==================== SH Store half-word =======
/////////
======== DIV Divide ======
ori $4, $0, 4
ori $5, $0, 3
div $4, $5
jr $0
$LO = 1
$HI = 1
34040004
34050003
0085001A
00000008
========= DIVU Divide unsigned =====
ori $4, $0, 4
ori $5, $0, 3
divu $4, $5
jr $0
$LO = 1
$HI = 1
34040004
34050003
0085001B
00000008

View file

@ -0,0 +1,564 @@
== Instruction ==
C code
Assembly code
Hex code
Reference Output
================
ADDIU Add immediate unsigned (no overflow)
== ADDU Add unsigned (no overflow) ==
int main(void) {
int a = 3 + 5;
}
ORI $4,$0,3
ORI $5,$0,5
ADDU $2,$4,$5
JR $0
34040003
34050005
00851021
00000008
register_v0 = 8
==AND Bitwise and==
ORI $5,$0,0xCCCC
LUI $5,0xCCCC
ORI $4,$0,0xAAAA
LUI $4,0xAAAA
AND $2,$4,$5
JR $0
3405cccc
3c05cccc
3404aaaa
3c04aaaa
00851024
00000008
register_v0 = 0x88888888
==ANDI Bitwise and immediate==
ORI $4,$0,0xAAAA
LUI $4,0xAAAA
ANDI $2,$4,0xCCCC
JR $0
3404aaaa
3c04aaaa
3082cccc
00000008
register_v0 = 0x00008888
==BEQ Branch on equal==
ORI $4,$0,5
ORI $5,$0,5
BEQ $4,$5,3
NOP
JR $0
NOP
ORI $2,$0,1
JR $0
34040005
34050005
10850003
00000000
00000008
00000000
34020001
00000008
register_v0 = 1
==BGEZ Branch on greater than or equal to zero==
ORI $4,$0,3
BGEZ $4,3
NOP
JR $0
NOP
ORI $2,$0,1
JR $0
34040003
04810003
00000000
00000008
00000000
34020001
00000008
register_v0 = 1
==BGEZAL Branch on non-negative (>=0) and link==
ORI $4,$0,3
BGEZAL $4,4
NOP
ADDIU $2,$2,1
JR $0
NOP
ORI $2,$0,1
JR $31
34040003
04910004
00000000
24420001
00000008
00000000
34020001
03E00008
register_v0 = 2
==BGTZ Branch on greater than zero==
ORI $4,$0,3
BGTZ $4,3
NOP
JR $0
NOP
ORI $2,$0,1
JR $0
34040003
1C800003
00000000
00000008
00000000
34020001
00000008
register_v0 = 1
==BLEZ Branch on less than or equal to zero==
LUI $4,0xFFFF
BLEZ $4,3
NOP
JR $0
NOP
ORI $2,$0,1
JR $0
3C05FFFF
18800003
00000000
00000008
00000000
34020001
00000008
register_v0 = 1
==BLTZ Branch on less than zero==
LUI $4,0xFFFF
BLTZ $4,3
NOP
JR $0
NOP
ORI $2,$0,1
JR $0
3C05FFFF
04800003
00000000
00000008
00000000
34020001
00000008
register_v0 = 1
==BLTZAL Branch on less than zero and link==
LUI $4,0xFFFF
BLTZAL $4,4
NOP
ADDIU $2,$2,1
JR $0
NOP
ORI $2,$0,1
JR $31
3C05FFFF
04900004
00000000
24420001
00000000
00000008
34020001
03E00008
register_v0 = 2
==BNE Branch on not equal==
ORI $4,$0,3
ORI $5,$0,5
BNE $4,$5,3
NOP
JR $0
NOP
ORI $2,$0,1
JR $0
34040003
34040005
14850003
00000000
00000008
00000000
34020001
00000008
register_v0 = 1
==DIV Divide== //May need other testcases for -ve/+ve, -ve/-ve
ORI $4,$0,3
ORI $5,$0,9
DIV $5,$4
MFHI $4
MFLO $5
ADDU $2,$4,$5
JR $0
34040003
34050009
00A4001A
00002010
00002812
00851021
00000008
register_v0 = 3
==DIVU Divide unsigned== //May need other testcases for -ve/+ve, -ve/-ve
LUI $4,0x8000
ORI $5,$0,2
DIVU $4,$5
MFHI $4
MFLO $5
ADDU $2,$4,$5
JR $0
34048000
34050002
0085001B
00002010
00002812
00851021
00000008
register_v0 = 0x40000000
==J Jump==
J 4
NOP
JR $0
NOP
ORI $2,$0,1
JR $0
08000004
00000000
00000008
00000000
34020001
00000008
register_v0 = 1
==JALR Jump and link register==
ORI $5,$0,0x001C
LUI $5,0xBFC0
JALR $4,$5
NOP
ADDIU $2,$2,1
JR $0
NOP
ORI $2,$0,1
JR $4
3405001C
3C05BCF0
00A02009
00000000
24420001
00000008
00000000
34020001
00800008
register_v0 = 2
==JAL Jump and link==
JAL 5
NOP
ADDIU $2,$2,1
JR $0
NOP
ORI $2,$0,1
JR $31
0C000005
00000000
24420001
00000008
00000000
34020001
03E00008
register_v0 = 2
==JR Jump register==
ORI $5,$0,0x0014
LUI $5,0xBFC0
JR $5
NOP
JR $0
NOP
ORI $2,$0,1
JR $0
34050014
3C05BCF0
00A00008
00000000
00000008
34020001
00000008
register_v0 = 1
==LB Load byte==
ORI $4,$0,0x1003
LB $2,3($4)
JR $0
-Instruction Hex
34041003
80820003
00000008
-Memory Hex
00000000
008A0000
00000000
00000000
register_v0 = 0xFFFFFF8A
==LBU Load byte unsigned==
ORI $4,$0,0x1003
LBU $2,3($4)
JR $0
-Instruction Hex
34041003
90820003
00000008
-Memory Hex
00000000
008A0000
00000000
00000000
register_v0 = 0x0000008A
==LH Load half-word==
ORI $4,$0,0x1003
LH $2,4($4)
JR $0
-Instruction Hex
34041003
84820004
00000008
-Memory Hex
00000000
00008123
00000000
00000000
register_v0 = 0xFFFF8123
==LHU Load half-word unsigned==
ORI $4,$0,0x1003
LHU $2,4($4)
JR $0
-Instruction Hex
34041003
94820004
00000008
-Memory Hex
00000000
00008123
00000000
00000000
register_v0 = 0x00008123
==LUI Load upper immediate==
ORI $2,$0,0x5678
LUI $2,0x1234
JR $0
34045678
3C021234
00000008
register_v0 = 0x12345678
==LW Load word==
ORI $4,$0,0x1002
LW $2, 2($4)
JR $0
-Instruction Hex
34041002
8C820002
00000008
-Memory Hex
00000000
12345678
00000000
00000000
register_v0 = 0x12345678
==LWL Load word left==
ORI $4,$0,0x1003
ORI $2,$0,0x5678
LWL $2,3($4)
JR $0
-Instruction Hex
34041003
34025678
88820003
00000008
-Memory Hex
00000000
AAAA1234
00000000
00000000
register_v0 = 0x12345678
==LWR Load word right==
ORI $4,$0,0x1003
LUI $2,0x1234
LWR $2,2($4)
JR $0
-Instruction Hex
34041003
3C021234
98820002
00000008
-Memory Hex
00000000
5678AAAA
00000000
00000000
register_v0 = 0x12345678
// DIVU Divide unsigned
// DIV Divide
//MFHI Move from Hi
//MFLO Move from lo
//MTHI Move to HI
//MTLO Move to LO
//MULT Multiply**
//MULTU Multiply unsigned**
//OR Bitwise or
//ORI Bitwise or immediate
//SB Store byte
//SH Store half-word**
//SLL Shift left logical
//SLLV Shift left logical variable **
//SLT Set on less than (signed)
//SLTI Set on less than immediate (signed)
//SLTIU Set on less than immediate unsigned
//SLTU Set on less than unsigned
//SRA Shift right arithmetic
//SRAV Shift right arithmetic**
//SRL Shift right logical
//SRLV Shift right logical variable**
//SUBU Subtract unsigned
//SW Store word
//XOR Bitwise exclusive or
//XORI Bitwise exclusive or immediate

4
inputs/sb.txt Normal file
View file

@ -0,0 +1,4 @@
34040405
34050001
a0a40001
00000008

0
inputs/sh.txt Normal file
View file

3
inputs/sll.txt Normal file
View file

@ -0,0 +1,3 @@
34040003
00041080
00000008

4
inputs/sllv.txt Normal file
View file

@ -0,0 +1,4 @@
34040002
34050003
//////
//////

3
inputs/slti.txt Normal file
View file

@ -0,0 +1,3 @@
3404000a
28820009
00000008

3
inputs/sltiu.txt Normal file
View file

@ -0,0 +1,3 @@
3404000a
2c820009
00000008

4
inputs/sltu.txt Normal file
View file

@ -0,0 +1,4 @@
3404000a
34050009
0085102b
00000008

3
inputs/sra.txt Normal file
View file

@ -0,0 +1,3 @@
34040001
00041003
00000008

4
inputs/srav.txt Normal file
View file

@ -0,0 +1,4 @@
34040002
34050001
////////
///////

3
inputs/srl.txt Normal file
View file

@ -0,0 +1,3 @@
34040010
00041002
00000008

4
inputs/srlv.txt Normal file
View file

@ -0,0 +1,4 @@
34040002
34050010
//////
//////

4
inputs/subu.txt Normal file
View file

@ -0,0 +1,4 @@
34040005
34050003
00851023
00000008

4
inputs/sw.txt Normal file
View file

@ -0,0 +1,4 @@
34040005
34050001
aca40001
00000008

4
inputs/xor.txt Normal file
View file

@ -0,0 +1,4 @@
34040005
34050002
00851026
00000008

3
inputs/xori.txt Normal file
View file

@ -0,0 +1,3 @@
34040005
38820002
00000008

View file

@ -83,9 +83,9 @@ assign rt = Instr[20:16];
always @(*) begin always @(*) begin
//CtrlRegDst logic //CtrlRegDst logic
if((op==ADDIU) || (op==ANDI) || (op==LB) || (op==LBU) || (op==LH) || (op==LHU) || (op==LUI) || (op==LW) || (op==LWL) || (op==LWR) || (op==ORI) || (op==SLTI) || (op==SLTIU) || (op==XORI))begin // if((op==ADDIU) || (op==ANDI) || (op==LB) || (op==LBU) || (op==LH) || (op==LHU) || (op==LUI) || (op==LW) || (op==LWL) || (op==LWR) || (op==ORI) || (op==SLTI) || (op==SLTIU) || (op==XORI))begin
CtrlRegDst = 2'd0; //Write address comes from rt CtrlRegDst = 2'd0; //Write address comes from rt
end else if ((op==SPECIAL)&&((funct==ADDU) || (funct==AND) || (funct==JALR) || (funct==OR) || (funct==SLL) || (funct==SLLV) || (funct==SLT) || (funct==SLTU) || (funct==SRA) || (funct==SRAV) || (funct==SRL) || (funct==SRLV) || (funct==SUBU) || (funct==XOR)))begin// end else if ((op==SPECIAL)&&((funct==ADDU) || (funct==AND) || (funct==JALR) || (funct==OR) || (funct==SLL) || (funct==SLLV) || (funct==SLT) || (funct==SLTU) || (funct==SRA) || (funct==SRAV) || (funct==SRL) || (funct==SRLV) || (funct==SUBU) || (funct==XOR)))begin
CtrlRegDst = 2'd1; //Write address comes from rd CtrlRegDst = 2'd1; //Write address comes from rd
end else if (op == JAL)begin end else if (op == JAL)begin
CtrlRegDst = 2'd2; //const reg 31, for writing to the link register CtrlRegDst = 2'd2; //const reg 31, for writing to the link register
@ -96,10 +96,10 @@ always @(*) begin
CtrlPC = 2'd1; // Branches - Jumps relative to PC CtrlPC = 2'd1; // Branches - Jumps relative to PC
end else if((op==J) || (op==JAL))begin end else if((op==J) || (op==JAL))begin
CtrlPC = 2'd2; // Jumps within 256MB Region using 26-bit immediate in J type instruction CtrlPC = 2'd2; // Jumps within 256MB Region using 26-bit immediate in J type instruction
end else if((op==JR) || (op==JALR))begin end else if((funct==JR) || (funct==JALR))begin
CtrlPC = 2'd3; // Jumps using Register. CtrlPC = 2'd3; // Jumps using Register.
$display("Ctrl PC Jump Register"); //$display("Ctrl PC Jump Register");
end else begin CtrlPC = 2'd0; $display("Ctrl PC No Jump/Branch");end // No jumps or branches, just increment to next word end else begin CtrlPC = 2'd0; /*/$display("Ctrl PC No Jump/Branch");*/end // No jumps or branches, just increment to next word
//CtrlMemRead and CtrlMemtoReg logic -- Interesting quirk that they have the same logic. Makes sense bc you'd only want to select the read data out when the memory itself is read enabled. //CtrlMemRead and CtrlMemtoReg logic -- Interesting quirk that they have the same logic. Makes sense bc you'd only want to select the read data out when the memory itself is read enabled.
if((op==LB) || (op==LBU) || (op==LH) || (op==LHU) || (op==LW) || (op==LWL) || (op==LWR))begin if((op==LB) || (op==LBU) || (op==LH) || (op==LHU) || (op==LW) || (op==LWL) || (op==LWR))begin
@ -115,7 +115,7 @@ always @(*) begin
//CtrlALUOp Logic //CtrlALUOp Logic
if((op==ADDIU) || ((op==SPECIAL)&&(funct==ADDU)))begin if((op==ADDIU) || ((op==SPECIAL)&&(funct==ADDU)))begin
CtrlALUOp = 5'd0; //ADD from ALUOps CtrlALUOp = 5'd0; //ADD from ALUOps
end else if((op==ANDI) || ((op==SPECIAL)&&(funct==AND)))begin((op==ANDI) || ((op==SPECIAL)&&(funct==AND))) end else if((op==ANDI) || ((op==SPECIAL)&&(funct==AND)))begin
CtrlALUOp = 5'd4;//AND from ALUOps CtrlALUOp = 5'd4;//AND from ALUOps
end else if(op==BEQ) begin end else if(op==BEQ) begin
CtrlALUOp = 5'd13;//EQ from ALUOps CtrlALUOp = 5'd13;//EQ from ALUOps
@ -133,7 +133,7 @@ always @(*) begin
CtrlALUOp = 5'd3;//DIV from ALUOps CtrlALUOp = 5'd3;//DIV from ALUOps
end else if((op==SPECIAL)&&(funct==DIVU))begin end else if((op==SPECIAL)&&(funct==DIVU))begin
CtrlALUOp = 5'd23;//DIVU from ALUOps CtrlALUOp = 5'd23;//DIVU from ALUOps
end else if((op==LB) || (op==LBU) || (op==LH) || (op==LHU) || (op==LW) || (op==LWL) || (op==LWR) || (op==SB) || (op==SBH) || (op==SW))begin end else if((op==LB) || (op==LBU) || (op==LH) || (op==LHU) || (op==LW) || (op==LWL) || (op==LWR) || (op==SB) || (op==SH) || (op==SW))begin
CtrlALUOp = 5'd0;//ADD from ALUOps CtrlALUOp = 5'd0;//ADD from ALUOps
end else if(op==LUI)begin end else if(op==LUI)begin
CtrlALUOp = 5'd7;//SLL from ALUOps CtrlALUOp = 5'd7;//SLL from ALUOps
@ -189,9 +189,8 @@ always @(*) begin
end else begin CtrlALUSrc = 1'bx;end end else begin CtrlALUSrc = 1'bx;end
//CtrlRegWrite logic //CtrlRegWrite logic
if((op == ADDIU | op == ANDI | op == LB | op == LBU | op == LH | op == LHU | op == LUI | op == LW | op == LWL | op == LWR | op == ORI | op == SLTI | op == SLTIU | op == XORI | (op == SPECIAL & ((funct == ADDU | funct == AND | funct == DIV | funct == DIVU | funct == MULT | funct == MULTU | funct == JALR | funct == OR | funct == SLL | funct == SLLV | funct == SLT | funct == SLTU | funct == SRA | funct == SRAV | funct == SRL | funct == SRLV | funct == SUBU | funct == XOR)))))begin if ((op==ADDIU) || (op==ANDI) || (op==LB) || (op==LBU) || (op==LH) || (op==LHU) || (op==LUI) || (op==LW) || (op==LWL) || (op==LWR) || (op==ORI) || (op==SLTI) || (op==XORI) || ((op==SPECIAL)&&((funct==ADDU) || (funct==AND) || (funct==DIV) || (funct==DIVU) || (funct==MULT) || (funct==MULTU) || (funct==OR) || (funct==SLL) || (funct==SLLV) || (funct==SLT) || (funct==SLTU) || (funct==SRA) || (funct==SRAV) || (funct==SRL) || (funct==SRLV) || (funct==SUBU) || (funct==XOR)))) begin
CtrlRegWrite = 1;//The Registers are Write Enabled CtrlRegWrite = 1;//The Registers are Write Enabled
end else begin CtrlRegWrite = 0;end // The Registers are Write Disabled end else begin CtrlRegWrite = 0;end // The Registers are Write Disabled
((op==ADDIU) || (op==ANDI) || (op==LB) || (op==LBU) || (op==LH) || (op==LHU) || (op==LUI) || (op==LW) || (op==LWL) || (op==LWR) || (op==ORI) || (op==SLTI) || (op==XORI) || ((op==SPECIAL)&&((funct==ADDU) || (funct==AND) || (funct==DIV) || (funct==DIVU) || (funct==MULT) || (funct==MULTU) || (funct==OR) || (funct==SLL) || (funct==SLLV) || (funct==SLT) || (funct==SLTU) || (funct==SRA) || (funct==SRAV) || (funct==SRL) || (funct==SRLV) || (funct==SUBU) || (funct==XOR))))
end end
endmodule endmodule

View file

@ -1,19 +1,3 @@
/*
Memory for Harvard Interface
- RAM Size: 32 x 2^32 = 32 x 4294967296
- Instructions in binaries or hex -> RAM_INIT_FILE
- combinatorial read/fetch of instruction via instr_ port
- combinatorial read and single cycle write of data via data_ port
Instantiation of Memory Module
- mips_cpu_memory #(RAM_INIT_FILE) ramInst(clk, data_address, data_write, data_read, data_writedata, data_readdata, instr_address, instr_readdata);
Special Memory Locations
- Whether a particular address maps to RAM, ROM, or something else is entirely down to the top-level circuit outside your CPU.
- special memory locations: 0x00000000 (CPU halt), 0xBFC00000 (start execution after reset)
- PC should be 0xBFC00000 at the start and 0x00000000 at the end
*/
module mips_cpu_memory( module mips_cpu_memory(
input logic clk, input logic clk,
@ -31,41 +15,42 @@ module mips_cpu_memory(
); );
parameter RAM_INIT_FILE = ""; parameter RAM_INIT_FILE = "";
reg [31:0] memory [0:7]; // 2^30 set as 8 for now for small testcases reg [31:0] data_memory [0:63];
reg [31:0] instr_memory [0:63];
initial begin initial begin
integer i; integer i;
//Initialise to zero by default //Initialise to zero by default
for (i=0; i<8; i++) begin for (i=0; i<$size(data_memory); i++) begin
memory[i]=0; data_memory[i] = 0;
end
for (i=0; i<$size(instr_memory); i++) begin
instr_memory[i] = 0;
end end
//Load contents from file if specified //Load contents from file if specified
if (RAM_INIT_FILE != "") begin if (RAM_INIT_FILE != "") begin
$display("RAM: Loading RAM contents from %s", RAM_INIT_FILE); $display("RAM: Loading RAM contents from %s", RAM_INIT_FILE);
$readmemh(RAM_INIT_FILE, memory, 32'h4); //32'hBFC00000 equivalent for small memory as byte 16 $readmemh(RAM_INIT_FILE, instr_memory);
end end
//Display what's in memory for debugging for (integer j = 0; j<$size(instr_memory); j++) begin
for (integer j = 0; j<$size(memory); j++) begin $display("byte +%h: %h", 32'hBFC00000+j*4, instr_memory[j]);
$display("Byte %d, %h", j*4, memory[j]);
end end
end end
//Combinatorial read path for data and instruction. //Combinatorial read path for data and instruction.
assign data_readdata = data_read ? {memory[data_address],memory[data_address+1],memory[data_address+2],memory[data_address+3]} : 16'hxxxx; assign data_readdata = data_read ? data_memory[data_address>>2] : 32'hxxxxxxxx;
assign instr_readdata = memory[instr_address/4]; assign instr_readdata = (instr_address >= 32'hBFC00000 && instr_address < 32'hBFC00000+$size(instr_memory)) ? instr_memory[(instr_address-32'hBFC00000)>>2] : 32'hxxxxxxxx;
//Synchronous write path //Synchronous write path
always_ff @(posedge clk) begin always_ff @(posedge clk) begin
$display("Instruction Read: %h", instr_readdata); //$display("Instruction Read: %h", instr_readdata);
//$display("RAM : INFO : data_read=%h, data_address = %h, mem=%h", data_read, data_address, memory[data_address]); //$display("RAM : INFO : data_read=%h, data_address = %h, mem=%h", data_read, data_address, memory[data_address]);
if (!data_read & data_write) begin //cannot read and write to memory in the same cycle if (!data_read & data_write) begin //cannot read and write to memory in the same cycle
if (instr_address != data_address) begin //cannot modify the instruction being read if (instr_address != data_address) begin //cannot modify the instruction being read
memory[data_address] <= data_writedata; data_memory[data_address>>2] <= data_writedata;
end end
end end
end end
endmodule endmodule

View file

@ -1,11 +1,10 @@
#!/bin/bash #!/bin/bash
# should not create any files in the rtl dir #**Delete command for windows before submission**
# but auxiliary files / dirs can be utilised #rm inputs/*.log.txt inputs/*.ref.txt
# Source File & Source Directory Parsing # Source File & Source Directory Parsing
SRC_DIR=${1?Error: no source directory given in argument}; # e.g. ./rtl SRC_DIR=${1?Error: no source directory given in argument}; # e.g. rtl
SRC=$(ls ${SRC_DIR} | grep -E "harvard|memory|alu|regfile|pc|control"); SRC=$(ls ${SRC_DIR} | grep -E "harvard|memory|alu|regfile|pc|control");
SRC_TEMP=""; SRC_TEMP="";
for src in ${SRC} for src in ${SRC}
@ -13,40 +12,52 @@ do
SRC_TEMP+=${SRC_DIR}/${src}" "; SRC_TEMP+=${SRC_DIR}/${src}" ";
done done
SRC=${SRC_TEMP} SRC=${SRC_TEMP}
echo ${SRC}
# Instruction Argument # Instruction Argument
INSTR=${2:-"No instruction specified: running all testcases"}; # e.g. addiu INSTR=${2:-"No instruction specified: running all testcases"}; # e.g. addiu
echo ${INSTR};
# Start Testing # Start Testing
if [[ ${INSTR} == "No instruction specified: running all testcases" ]]; if [[ ${INSTR} == "No instruction specified: running all testcases" ]];
then then
# All Testcase Files # All Testcase Files
TESTCASES=$(ls ./inputs | grep ".txt"); TESTCASES=$(find ./inputs ! -name '*ref*' ! -name '*log*' ! -name '*out*' ! -name 'inputs' | sed 's#.*/##');
echo ${TESTCASES} #echo ${TESTCASES}
for TESTCASE in ${TESTCASES} for TESTCASE in ${TESTCASES}
do do
# Run Each Testcase File # Run Each Testcase File
echo ${TESTCASE} TESTCASE="${TESTCASE%%.*}";
/mnt/c/Windows/System32/cmd.exe /C \ #echo ${TESTCASE};
#/mnt/c/Windows/System32/cmd.exe /C \
iverilog -Wall -g2012 \ iverilog -Wall -g2012 \
-s mips_cpu_harvard_tb \ -s mips_cpu_harvard_tb \
-P mips_cpu_harvard_tb.RAM_INIT_FILE=\"inputs/${TESTCASE}.txt\" \ -P mips_cpu_harvard_tb.RAM_INIT_FILE=\"inputs/${TESTCASE}.txt\" \
-o exec/mips_cpu_harvard_tb_${TESTCASE} testbench/mips_cpu_harvard_tb.v \ -o exec/mips_cpu_harvard_tb_${TESTCASE} testbench/mips_cpu_harvard_tb.v \
${SRC} ${SRC} 2> /dev/null
/mnt/c/Windows/System32/cmd.exe /C vvp ./exec/mips_cpu_harvard_tb_${TESTCASE}; /mnt/c/Windows/System32/cmd.exe /C vvp ./exec/mips_cpu_harvard_tb_${TESTCASE} &> ./inputs/${TESTCASE}.log.txt; # log file for debugging (contains $display)
echo "$(tail -1 ./inputs/${TESTCASE}.log.txt)" > ./inputs/${TESTCASE}.out.txt; # register v0 output to compare with reference
if diff -w ./inputs/${TESTCASE}.out.txt ./inputs/${TESTCASE}.ref.txt &> /dev/null # compare
then
echo ${TESTCASE} ${TESTCASE} "Pass";
else
printf '%s %s %s%d %s%d%s\n' "${TESTCASE}" "${TESTCASE}" "Fail Output=" "$(tail -1 ./inputs/${TESTCASE}.out.txt)" "Ref=" "$(tail -1 ./inputs/${TESTCASE}.ref.txt)" 2> /dev/null;
fi
done done
else else
# Run Testcase File Of Specified Instruction # Run Testcase File Of Specified Instruction
echo ${INSTR};
/mnt/c/Windows/System32/cmd.exe /C \ /mnt/c/Windows/System32/cmd.exe /C \
iverilog -Wall -g2012 \ iverilog -Wall -g2012 \
-s mips_cpu_harvard_tb \ -s mips_cpu_harvard_tb \
-P mips_cpu_harvard_tb.RAM_INIT_FILE=\"inputs/${INSTR}.txt\" \ -P mips_cpu_harvard_tb.RAM_INIT_FILE=\"inputs/${INSTR}.txt\" \
-o exec/mips_cpu_harvard_tb_${INSTR} testbench/mips_cpu_harvard_tb.v \ -o exec/mips_cpu_harvard_tb_${INSTR} testbench/mips_cpu_harvard_tb.v \
${SRC} ${SRC} 2> /dev/null
/mnt/c/Windows/System32/cmd.exe /C vvp ./exec/mips_cpu_harvard_tb_${INSTR}; /mnt/c/Windows/System32/cmd.exe /C vvp ./exec/mips_cpu_harvard_tb_${INSTR} &> ./inputs/${INSTR}.log.txt; # log file for debugging (contains $display)
echo "$(tail -1 ./inputs/${INSTR}.log.txt)" > ./inputs/${INSTR}.out.txt; # register v0 output to compare with reference
if diff -w ./inputs/${INSTR}.out.txt ./inputs/${INSTR}.ref.txt &> /dev/null # compare
then
echo ${INSTR} ${INSTR} "Pass";
else
printf '%s %s %s%d %s%d%s\n' "${INSTR}" "${INSTR}" "Fail Output=" "$(tail -1 ./inputs/${INSTR}.out.txt)" "Ref=" "$(tail -1 ./inputs/${INSTR}.ref.txt)" 2> /dev/null;
fi fi
fi