diff --git a/.gitignore b/.gitignore index ea6eaf9..15145de 100644 --- a/.gitignore +++ b/.gitignore @@ -3,5 +3,6 @@ exec/* *.log.txt *.out.txt mips_cpu_harvard.vcd +mips_cpu_bus.vcd .DS_Store inputs/.DS_Store diff --git a/inputs/sb/sb-1.txt b/inputs/sb/sb-1.txt index a2e8fd6..c42c078 100644 --- a/inputs/sb/sb-1.txt +++ b/inputs/sb/sb-1.txt @@ -1,7 +1,6 @@ 3C041234 34045678 -3C05BFC0 -3405001C +3405101C A0A40000 80A20000 -00000008 \ No newline at end of file +00000008 diff --git a/inputs/sh/sh-1.txt b/inputs/sh/sh-1.txt index 17b333d..2203c02 100644 --- a/inputs/sh/sh-1.txt +++ b/inputs/sh/sh-1.txt @@ -1,7 +1,6 @@ 3C041234 34045678 -3C05BFC0 -3405001C +3405101C A4A40000 -84A40000 -00000008 \ No newline at end of file +84A20000 +00000008 diff --git a/inputs/sh/sh-2.ref.txt b/inputs/sh/sh-2.ref.txt new file mode 100644 index 0000000..2bb616a --- /dev/null +++ b/inputs/sh/sh-2.ref.txt @@ -0,0 +1 @@ +22136 \ No newline at end of file diff --git a/inputs/sh/sh-2.txt b/inputs/sh/sh-2.txt new file mode 100644 index 0000000..bbbbdf7 --- /dev/null +++ b/inputs/sh/sh-2.txt @@ -0,0 +1,6 @@ +3C041234 +34045678 +3405101C +A4A40000 +8CA20000 +00000008 diff --git a/reference/reference.txt b/reference/reference.txt index 8d016c9..8d2d791 100644 --- a/reference/reference.txt +++ b/reference/reference.txt @@ -1,902 +1,914 @@ -== Instruction == -Assembly code -Hex code -Reference Output -================ - -==ADDIU Add immediate unsigned (no overflow)== - -ORI $4,$0,0xA -JR $0 -ADDIU $2,$4,20 - -3404000a -00000008 -24820014 - -register_v0 = 30 - -== ADDU Add unsigned (no overflow) == - -ORI $4,$0,3 -ORI $5,$0,5 -JR $0 -ADDU $2,$4,$5 - -34040003 -34050005 -00000008 -00851021 - -register_v0 = 8 - --Test not overflowing property - -lui $4,$0,0x1000 -lui $5,$0,0xF000 -JR $0 -ADDU $2,$4,$5 - -3C041000 -3C05F000 -00000008 -00851021 - -register_v0 = 0 - -==AND Bitwise and== - -LUI $5,0xCCCC -ORI $5,$5,0xCCCC -LUI $4,0xAAAA -ORI $4,$4,0xAAAA -JR $0 -AND $2,$4,$5 - -3c05cccc -34A5cccc -3c04aaaa -3484aaaa -00000008 -00851024 - -register_v0 = 0x88888888 / 2290649224 - -==ANDI Bitwise and immediate== - -LUI $4,0xAAAA -ORI $4,$0,0xAAAA -JR $0 -ANDI $2,$4,0xCCCC - -3c04aaaa -3404aaaa -00000008 -3082cccc - -register_v0 = 0x00008888 / 34952 - -==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 - --Testing whether it would link if branch fails - -lui $4,0xFFFF -BGEZAL $4,4 -JR $31 -ADDIU $2,$2,1 -JR $0 - -3C04FFFF -04910004 -03E00008 -24420001 -00000008 - -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 - -3C04FFFF -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 -00000008 -00000000 -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 - -3C048000 -34050002 -0085001B -00002010 -00002812 -00851021 -00000008 - -register_v0 = 0x40000000 / 1073741824 - -==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== - -LUI $5,0xBFC0 -ORI $5,$5,0x001C -JALR $4,$5 -NOP -ADDIU $2,$2,1 -JR $0 -NOP -ORI $2,$0,1 -JR $4 - -3C05BCF0 -34A5001C -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== - -LUI $5,0xBFC0 -ORI $5,$5,0x0014 -JR $5 -NOP -JR $0 -NOP -ORI $2,$0,0xA -JR $0 - -3C05BFC0 -34A50014 -00A00008 -00000000 -00000008 -3402000A -00000008 - -register_v0 = 10 - --Branch Delay slot test - -JR $0 -ORI $2,$0,5 - -00000008 -34020005 - -register_v0 = 5 - --This broke testbench once due to log.txt weirdness - -LUI $5,0xBFC0 -ORI $5,$5,0x0008 -JR $5 -JR $0 - -3C05BFC0 -34A50008 -00A00008 -00000008 - -register_v0 = 0 - -==LB Load byte== - -ORI $4,$0,0x1001 -JR $0 -LB $2,5($4) - --Instruction Hex - -34041001 -00000008 -80820005 - --Memory Hex - -00000000 -008A0000 -00000000 -00000000 - -register_v0 = 0xFFFFFF8A / 4294967178 - -==LBU Load byte unsigned== - -ORI $4,$0,0x1002 -JR $0 -LBU $2,4($4) - --Instruction Hex - -34041002 -00000008 -90820004 - --Memory Hex - -00000000 -008A0000 -00000000 -00000000 - -register_v0 = 0x0000008A / 138 - -==LH Load half-word== - -ORI $4,$0,0x1000 -JR $0 -LH $2,4($4) - --Instruction Hex - -34041003 -00000008 -84820004 - --Memory Hex - -00000000 -00008123 -00000000 -00000000 - -register_v0 = 0xFFFF8123 / 4294934819 - -==LHU Load half-word unsigned== - -ORI $4,$0,0x1000 -JR $0 -LHU $2,4($4) - --Instruction Hex - -34041000 -00000008 -94820004 - --Memory Hex - -00000000 -00008123 -00000000 -00000000 - -register_v0 = 0x00008123 / 33059 - -==LUI Load upper immediate== - -LUI $2,0x1234 -ORI $2,$2,0x5678 -JR $0 - -3C021234 -34425678 -00000008 - -register_v0 = 0x12345678 / 305419896 - -==LW Load word== - -ORI $4,$0,0x1002 -JR $0 -LW $2, 2($4) - --Instruction Hex - -34041002 -00000008 -8C820002 - --Memory Hex - -00000000 -12345678 -00000000 -00000000 - -register_v0 = 0x12345678 / 305419896 - -==LWL Load word left== - -ORI $4,$0,0x1001 -ORI $2,$0,0x5678 -JR $0 -LWL $2,3($4) - --Instruction Hex - -34041001 -34025678 -00000008 -88820003 - --Memory Hex - -00000000 -AAAA1234 -00000000 -00000000 - -register_v0 = 0x12345678 / 305419896 - -==LWR Load word right== - -LUI $2,0x1234 -ORI $4,$0,0x1002 -JR $0 -LWR $2,3($4) - --Instruction Hex - -3C021234 -34041002 -00000008 -98820003 - --Memory Hex - -00000000 -5678AAAA -00000000 -00000000 - -register_v0 = 0x12345678 / 305419896 - -==MTHI Move to HI== - -ori $4, $0, 5 -mthi $4 -mfhi $2 -jr $0 - -34040005 -00800011 -00001010 -00000008 - -register_v0 = 5 - -==MTLO Move to LO== - -ori $4, $0, 5 -mtlo $4 -mflo $2 -jr $0 - -34040005 -00800013 -00001012 -00000008 - -register_v0 = 5 - -==MULT Multiply== - -ori $4, $0, 4 -ori $5, $0, 3 -mult $4, $5 -mflo $2 -jr $0 - -34040004 -34050003 -00850018 -00001012 -00000008 - -register_v0 = 12 - -==MULTU Multiply unsigned== - -ori $4, $0, 4 -ori $5, $0, 3 -multu $4, $5 -mflo $2 -jr $0 - -34040004 -34050003 -00850019 -00001012 -00000008 - -register_v0 = 12 - -==OR Bitwise or== - -ori $4, $0, 5 -ori $5, $0, 3 -jr $0 -or $2, $4, $5 - -34040005 -34050003 -00000008 -00851025 - -register_v0 = 7 - -==ORI Bitwise or immediate== - -ori $4, $0, 0xFFFF -ori $5, $0, 0x1234 -jr $0 -or $2, $4, $5 - -3404FFFF -34051234 -00851025 -00000008 - -register_v0 = 65535 - -==SB Store byte== - -lui $4, 0x1234 -ori $4, $0, 0x5678 -lui $5, 0xBFC0 -ori $5, $0, 0x001C -sb $4, 0($5) -lb $2, 0($5) -jr $0 - -3C041234 -34045678 -3C05BFC0 -3405001C -A0A40000 -80A20000 -00000008 - -register_v0 = 0x00000078 - -==SH Store half-word== - -lui $4, 0x1234 -ori $4, $0, 0x5678 -lui $5, 0xBFC0 -ori $5, $0, 0x001C -sh $4, 0($5) -lh $2, 0($5) -jr $0 - -3C041234 -34045678 -3C05BFC0 -3405001C -A4A40000 -84A40000 -00000008 - -register_v0 = 0x00005678 - -==SLL Shift left logical== - -ori $4,$0,3 -jr $0 -sll $2,$4,2 - - -34040003 -00000008 -00041080 - -register_v0 = 12 - -==SLLV Shift left logical variable== - -ori $4,$0,2 -ori $5,$0,3 -jr $0 -sllv $2,$5,$4 - -34040002 -34050003 -00000008 -00851004 - -register_v0 = 12 - -==SLT Set on less than (signed)== - -ORI $4 $zero 0xFFFF -ORI $5 $zero 0x000B -jr $0 -SLT $2 $4 $5 - -3404FFFF -3405000B -00000008 -0085102A - -register_v0 = 0 - -==SLTI Set on less than immediate (signed)== - -ori $4, $0, 10 -jr $0 -slti $2, $4, 9 - -3404000a -00000008 -28820009 - -register_v0 = 0 - -==SLTIU Set on less than immediate unsigned== - -ori $4, $0, 10 -jr $0 -sltiu $2, $4, 9 - -3404000a -00000008 -2c820009 - -register_v0 = 0 - -==SLTU Set on less than unsigned== - -ori $4, $0, 10 -ori $5, $0, 9 -jr $0 -sltu $2, $4, $5 - -3404000a -34050009 -00000008 -0085102b - -register_v0 = 0 - -==SRA Shift right arithmetic== - -lui $5 $0,0xF000 -jr $0 -srav $2,$5,2 - -3C05F000 -00000008 -00051083 - -register_v0 = 0xFC000000 / 4227858432 - -==SRAV Shift right arithmetic variable== - -ori $4,$0,2 -lui $5, 0xF000 -jr $0 -srav $2,$5,$4 - -34040002 -3C05F000 -00000008 -00851007 - -register_v0 = 0xFC000000 / 4227858432 - -==SRL Shift right logical== - -ori $4,$0,16 -jr $0 -srl $2,$4,2 - -34040010 -00000008 -00041082 - -register_v0 = 4 - -==SRLV Shift right logical variable== - -ori $4,$0,2 -ori $5,$0,16 -jr $0 -srlv $2,$5,$4 - -34040002 -34050010 -00000008 -00851006 - -register_v0 = 4 - -==SUBU Subtract unsigned== - -ori $4,$0,5 -ori $5,$0,3 -jr $0 -subu $2,$4,$5 - -34040005 -34050003 -00000008 -00851023 - -register_v0 = 2 - -==SW Store word== - -ori $4, $0, 0xFFFF -ori $5, $0, 0x1008 -sw $4, 4($5) -lw $2, 4($5) -jr $0 - -3404FFFF -34051008 -ACA40004 -8CA20004 -00000008 - -register_v0 = 0x0000FFFF / 65535 - --Negative Offset - -ori $4, $0, 0xFFFF -ori $5, $0, 0x1008 -sw $4, -4($5) -lw $2, -4($5) -jr $0 - -3404FFFF -34051008 -ACA4FFFC -8CA2FFFC -00000008 - -register_v0 = 0x0000FFFF / 65535 - -==XOR Bitwise exclusive or== - -ori $4, $0, 5 -ori $5, $0, 2 -jr $0 -xor $2, $4, $5 - -34040005 -34050002 -00000008 -00851026 - -register_v0 = 7 - -==XORI Bitwise exclusive or immediate== - -ori $4,$0,5 -jr $0 -xori $2,$4,0x000F - -34040005 -00000008 -3882000F - -register_v0 = 10 +== Instruction == +Assembly code +Hex code +Reference Output +================ + +==ADDIU Add immediate unsigned (no overflow)== + +ORI $4,$0,0xA +JR $0 +ADDIU $2,$4,20 + +3404000a +00000008 +24820014 + +register_v0 = 30 + +== ADDU Add unsigned (no overflow) == + +ORI $4,$0,3 +ORI $5,$0,5 +JR $0 +ADDU $2,$4,$5 + +34040003 +34050005 +00000008 +00851021 + +register_v0 = 8 + +-Test not overflowing property + +lui $4,$0,0x1000 +lui $5,$0,0xF000 +JR $0 +ADDU $2,$4,$5 + +3C041000 +3C05F000 +00000008 +00851021 + +register_v0 = 0 + +==AND Bitwise and== + +LUI $5,0xCCCC +ORI $5,$5,0xCCCC +LUI $4,0xAAAA +ORI $4,$4,0xAAAA +JR $0 +AND $2,$4,$5 + +3c05cccc +34A5cccc +3c04aaaa +3484aaaa +00000008 +00851024 + +register_v0 = 0x88888888 / 2290649224 + +==ANDI Bitwise and immediate== + +LUI $4,0xAAAA +ORI $4,$0,0xAAAA +JR $0 +ANDI $2,$4,0xCCCC + +3c04aaaa +3404aaaa +00000008 +3082cccc + +register_v0 = 0x00008888 / 34952 + +==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 + +-Testing whether it would link if branch fails + +lui $4,0xFFFF +BGEZAL $4,4 +JR $31 +ADDIU $2,$2,1 +JR $0 + +3C04FFFF +04910004 +03E00008 +24420001 +00000008 + +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 + +3C04FFFF +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 +00000008 +00000000 +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 + +3C048000 +34050002 +0085001B +00002010 +00002812 +00851021 +00000008 + +register_v0 = 0x40000000 / 1073741824 + +==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== + +LUI $5,0xBFC0 +ORI $5,$5,0x001C +JALR $4,$5 +NOP +ADDIU $2,$2,1 +JR $0 +NOP +ORI $2,$0,1 +JR $4 + +3C05BCF0 +34A5001C +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== + +LUI $5,0xBFC0 +ORI $5,$5,0x0014 +JR $5 +NOP +JR $0 +NOP +ORI $2,$0,0xA +JR $0 + +3C05BFC0 +34A50014 +00A00008 +00000000 +00000008 +3402000A +00000008 + +register_v0 = 10 + +-Branch Delay slot test + +JR $0 +ORI $2,$0,5 + +00000008 +34020005 + +register_v0 = 5 + +-This broke testbench once due to log.txt weirdness + +LUI $5,0xBFC0 +ORI $5,$5,0x0008 +JR $5 +JR $0 + +3C05BFC0 +34A50008 +00A00008 +00000008 + +register_v0 = 0 + +==LB Load byte== + +ORI $4,$0,0x1001 +JR $0 +LB $2,5($4) + +-Instruction Hex + +34041001 +00000008 +80820005 + +-Memory Hex + +00000000 +008A0000 +00000000 +00000000 + +register_v0 = 0xFFFFFF8A / 4294967178 + +==LBU Load byte unsigned== + +ORI $4,$0,0x1002 +JR $0 +LBU $2,4($4) + +-Instruction Hex + +34041002 +00000008 +90820004 + +-Memory Hex + +00000000 +008A0000 +00000000 +00000000 + +register_v0 = 0x0000008A / 138 + +==LH Load half-word== + +ORI $4,$0,0x1000 +JR $0 +LH $2,4($4) + +-Instruction Hex + +34041003 +00000008 +84820004 + +-Memory Hex + +00000000 +00008123 +00000000 +00000000 + +register_v0 = 0xFFFF8123 / 4294934819 + +==LHU Load half-word unsigned== + +ORI $4,$0,0x1000 +JR $0 +LHU $2,4($4) + +-Instruction Hex + +34041000 +00000008 +94820004 + +-Memory Hex + +00000000 +00008123 +00000000 +00000000 + +register_v0 = 0x00008123 / 33059 + +==LUI Load upper immediate== + +LUI $2,0x1234 +ORI $2,$2,0x5678 +JR $0 + +3C021234 +34425678 +00000008 + +register_v0 = 0x12345678 / 305419896 + +==LW Load word== + +ORI $4,$0,0x1002 +JR $0 +LW $2, 2($4) + +-Instruction Hex + +34041002 +00000008 +8C820002 + +-Memory Hex + +00000000 +12345678 +00000000 +00000000 + +register_v0 = 0x12345678 / 305419896 + +==LWL Load word left== + +ORI $4,$0,0x1001 +ORI $2,$0,0x5678 +JR $0 +LWL $2,3($4) + +-Instruction Hex + +34041001 +34025678 +00000008 +88820003 + +-Memory Hex + +00000000 +AAAA1234 +00000000 +00000000 + +register_v0 = 0x12345678 / 305419896 + +==LWR Load word right== + +LUI $2,0x1234 +ORI $4,$0,0x1002 +JR $0 +LWR $2,3($4) + +-Instruction Hex + +3C021234 +34041002 +00000008 +98820003 + +-Memory Hex + +00000000 +5678AAAA +00000000 +00000000 + +register_v0 = 0x12345678 / 305419896 + +==MTHI Move to HI== + +ori $4, $0, 5 +mthi $4 +mfhi $2 +jr $0 + +34040005 +00800011 +00001010 +00000008 + +register_v0 = 5 + +==MTLO Move to LO== + +ori $4, $0, 5 +mtlo $4 +mflo $2 +jr $0 + +34040005 +00800013 +00001012 +00000008 + +register_v0 = 5 + +==MULT Multiply== + +ori $4, $0, 4 +ori $5, $0, 3 +mult $4, $5 +mflo $2 +jr $0 + +34040004 +34050003 +00850018 +00001012 +00000008 + +register_v0 = 12 + +==MULTU Multiply unsigned== + +ori $4, $0, 4 +ori $5, $0, 3 +multu $4, $5 +mflo $2 +jr $0 + +34040004 +34050003 +00850019 +00001012 +00000008 + +register_v0 = 12 + +==OR Bitwise or== + +ori $4, $0, 5 +ori $5, $0, 3 +jr $0 +or $2, $4, $5 + +34040005 +34050003 +00000008 +00851025 + +register_v0 = 7 + +==ORI Bitwise or immediate== + +ori $4, $0, 0xFFFF +ori $5, $0, 0x1234 +jr $0 +or $2, $4, $5 + +3404FFFF +34051234 +00851025 +00000008 + +register_v0 = 65535 + +==SB Store byte== + +lui $4, 0x1234 +ori $4, $0, 0x5678 +ori $5, $0, 0x101C +sb $4, 0($5) +lb $2, 0($5) +jr $0 + +3C041234 +34045678 +3405101C +A0A40000 +80A20000 +00000008 + +register_v0 = 0x00000078 + +==SH Store half-word== + +lui $4, 0x1234 +ori $4, $0, 0x5678 +ori $5, $0, 0x101C +sh $4, 0($5) +lh $2, 0($5) +jr $0 + +3C041234 +34045678 +3405101C +A4A40000 +84A20000 +00000008 + +-Load Entire Word Version + +lui $4, 0x1234 +ori $4, $0, 0x5678 +ori $5, $0, 0x101C +sh $4, 0($5) +lw $2, 0($5) +jr $0 + +3C041234 +34045678 +3405101C +A4A40000 +8CA20000 +00000008 + +register_v0 = 0x00005678 + +==SLL Shift left logical== + +ori $4,$0,3 +jr $0 +sll $2,$4,2 + + +34040003 +00000008 +00041080 + +register_v0 = 12 + +==SLLV Shift left logical variable== + +ori $4,$0,2 +ori $5,$0,3 +jr $0 +sllv $2,$5,$4 + +34040002 +34050003 +00000008 +00851004 + +register_v0 = 12 + +==SLT Set on less than (signed)== + +ORI $4 $zero 0xFFFF +ORI $5 $zero 0x000B +jr $0 +SLT $2 $4 $5 + +3404FFFF +3405000B +00000008 +0085102A + +register_v0 = 0 + +==SLTI Set on less than immediate (signed)== + +ori $4, $0, 10 +jr $0 +slti $2, $4, 9 + +3404000a +00000008 +28820009 + +register_v0 = 0 + +==SLTIU Set on less than immediate unsigned== + +ori $4, $0, 10 +jr $0 +sltiu $2, $4, 9 + +3404000a +00000008 +2c820009 + +register_v0 = 0 + +==SLTU Set on less than unsigned== + +ori $4, $0, 10 +ori $5, $0, 9 +jr $0 +sltu $2, $4, $5 + +3404000a +34050009 +00000008 +0085102b + +register_v0 = 0 + +==SRA Shift right arithmetic== + +lui $5 $0,0xF000 +jr $0 +srav $2,$5,2 + +3C05F000 +00000008 +00051083 + +register_v0 = 0xFC000000 / 4227858432 + +==SRAV Shift right arithmetic variable== + +ori $4,$0,2 +lui $5, 0xF000 +jr $0 +srav $2,$5,$4 + +34040002 +3C05F000 +00000008 +00851007 + +register_v0 = 0xFC000000 / 4227858432 + +==SRL Shift right logical== + +ori $4,$0,16 +jr $0 +srl $2,$4,2 + +34040010 +00000008 +00041082 + +register_v0 = 4 + +==SRLV Shift right logical variable== + +ori $4,$0,2 +ori $5,$0,16 +jr $0 +srlv $2,$5,$4 + +34040002 +34050010 +00000008 +00851006 + +register_v0 = 4 + +==SUBU Subtract unsigned== + +ori $4,$0,5 +ori $5,$0,3 +jr $0 +subu $2,$4,$5 + +34040005 +34050003 +00000008 +00851023 + +register_v0 = 2 + +==SW Store word== + +ori $4, $0, 0xFFFF +ori $5, $0, 0x1008 +sw $4, 4($5) +lw $2, 4($5) +jr $0 + +3404FFFF +34051008 +ACA40004 +8CA20004 +00000008 + +register_v0 = 0x0000FFFF / 65535 + +-Negative Offset + +ori $4, $0, 0xFFFF +ori $5, $0, 0x1008 +sw $4, -4($5) +lw $2, -4($5) +jr $0 + +3404FFFF +34051008 +ACA4FFFC +8CA2FFFC +00000008 + +register_v0 = 0x0000FFFF / 65535 + +==XOR Bitwise exclusive or== + +ori $4, $0, 5 +ori $5, $0, 2 +jr $0 +xor $2, $4, $5 + +34040005 +34050002 +00000008 +00851026 + +register_v0 = 7 + +==XORI Bitwise exclusive or immediate== + +ori $4,$0,5 +jr $0 +xori $2,$4,0x000F + +34040005 +00000008 +3882000F + +register_v0 = 10 diff --git a/rtl/mips_cpu_bus.v b/rtl/mips_cpu_bus.v new file mode 100644 index 0000000..478766c --- /dev/null +++ b/rtl/mips_cpu_bus.v @@ -0,0 +1,231 @@ +module mips_cpu_bus( + /* Standard signals */ + input logic clk, + input logic reset, + output logic active, + output logic[31:0] register_v0, + + /* Avalon memory mapped bus controller (master) */ + output logic[31:0] address, + output logic write, + output logic read, + input logic waitrequest, + output logic[31:0] writedata, + output logic[3:0] byteenable, + input logic[31:0] readdata +); + +logic[1:0] state; // current state of cpu within cycle +logic[1:0] n_state; // state to be set at next clk edge +logic[31:0] instr_reg; // instruction register / single-word cache for current instruction +logic clk_internal; // modulated clock to be passed to harvard cpu +logic[31:0] harvard_instr_address; // instr addr from pc +logic harvard_read; // harvard cpu read flag +logic harvard_write; // harvard cpu write flag +logic[31:0] harvard_data_address; // data addr from ALU +logic[31:0] harvard_readdata; // <= data read from Avalon MM Device +logic[31:0] harvard_writedata; // data to be written to Avalon MM Device +logic[3:0] write_byteenable; // byteenable calculator for partial write +logic clk_state; // make sure posedge and negedge of clk do not occur repeatedly +logic partial_write; // flag to control datapath when doing a partial write +logic[31:0] partial_writedata; // modified data for partial writes (StoreHalfword or StoreByte) +logic[31:0] write_data_address; // modified data address for partial writes +logic clk_enable; // unused floating wire + +initial begin + clk_internal = 1'b0; + n_state = 2'b00; + state = 2'b00; + instr_reg = 32'h00000000; + address = 32'h00000000; + write = 1'b0; + read = 1'b0; + writedata = 32'h00000000; + byteenable = 4'b0000; + clk_state = 0; +end + +always_ff @(negedge reset) begin // kickstart clock after reset + clk_internal <= 1'b1; + state <= 2'b00; +end + +always_ff @(posedge clk) begin // CLK Rising Edge + if (!waitrequest && !clk_state) begin + case (n_state) + 2'b00: begin // fetch + clk_internal <= 1'b1; + state <= 2'b00; + end + 2'b01: begin // execute + state <= 2'b01; + instr_reg <= readdata; + end + 2'b10: begin // read + state <= 2'b10; + end + 2'b11: begin // write + state <= 2'b11; + end + endcase // state + end + clk_state <= 1'b1; +end + +always_ff @(negedge clk) begin // CLK Falling Edge + if (!waitrequest && clk_state) begin + case (state) + 2'b00: begin // nothing happens on fetch negedge + end + 2'b01: begin // execute negedge + if (!harvard_read && !harvard_write) begin // instruction complete, trigger writeback + clk_internal <= 1'b0; + end // otherwise do nothing + end + 2'b10: begin + clk_internal <= 1'b0; + end + 2'b11: begin + clk_internal <= 1'b0; + end + endcase + end + clk_state <= 1'b0; +end + +always @(*) begin + case (instr_reg[31:26]) + 6'b101000: begin // Store Byte + partial_write = 1'b1; + case (harvard_data_address[1:0]) + 2'b00: begin + partial_writedata = {{24{1'b0}}, harvard_writedata[7:0]}; + write_byteenable = 4'b0001; + write_data_address = {harvard_data_address[31:2], 2'b00}; + end + 2'b01: begin + partial_writedata = {{16{1'b0}}, harvard_writedata[7:0], {8{1'b0}}}; + write_byteenable = 4'b0010; + write_data_address = {harvard_data_address[31:2], 2'b00}; + end + 2'b10: begin + partial_writedata = {{8{1'b0}}, harvard_writedata[7:0], {16{1'b0}}}; + write_byteenable = 4'b0100; + write_data_address = {harvard_data_address[31:2], 2'b00}; + end + 2'b11: begin + partial_writedata = {harvard_writedata[7:0], {24{1'b0}}}; + write_byteenable = 4'b1000; + write_data_address = {harvard_data_address[31:2], 2'b00}; + end + endcase + end + 6'b101001: begin // Store Halfword + partial_write = 1'b1; + case (harvard_data_address[1:0]) + 2'b00: begin + partial_writedata = {{16{1'b0}}, harvard_writedata[15:0]}; + write_byteenable = 4'b0011; + write_data_address = {harvard_data_address[31:2], 2'b00}; + end + 2'b01: begin // halfword address must be matrually aligned, last bit must be 0 + partial_writedata = 32'hxxxxxxxx; + write_byteenable = 4'bxxxx; + write_data_address = 32'hxxxxxxxx; + end + 2'b10: begin + partial_writedata = {harvard_writedata[15:0], {16{1'b0}}}; + write_byteenable = 4'b1100; + write_data_address = {harvard_data_address[31:2], 2'b00}; + end + 2'b11: begin // halfword address must be matrually aligned, last bit must be 0 + partial_writedata = 32'hxxxxxxxx; + write_byteenable = 4'bxxxx; + write_data_address = 32'hxxxxxxxx; + end + endcase + end + default: begin // Store Word OR All other instructions (These flags are ignored outside the write state) + partial_write = 1'b0; + partial_writedata = 32'h00000000; + write_byteenable = 4'b1111; + write_data_address = harvard_data_address; + end + endcase +end + +always_comb begin + if (reset) begin + clk_internal = 1'b0; + n_state = 2'b00; + state = 2'b00; + instr_reg = 32'h00000000; + address = 32'h00000000; + write = 1'b0; + read = 1'b0; + writedata = 32'h00000000; + byteenable = 4'b0000; + end else begin + case (state) + 2'b00: begin // connecting wires when in fetch state + address = harvard_instr_address; + read = 1'b1; + write = 1'b0; + byteenable = 4'b1111; + harvard_readdata = 32'h00000000; + writedata = 32'h00000000; + n_state = 2'b01; + end + 2'b01: begin // connecting wires when in execute state + address = 32'h00000000; + read = 1'b0; + write = 1'b0; + byteenable = 4'b0000; + harvard_readdata = 32'h00000000; + writedata = 32'h00000000; + if (harvard_read) begin + n_state = 2'b10; // next state is read + end else if (harvard_write) begin + n_state = 2'b11; // next state is write + end else begin + n_state = 2'b00; // next state is fetch + end + end + 2'b10: begin // connecting wires when in read state + address = harvard_data_address; + read = clk_internal ? 1'b1 : 1'b0; + write = 1'b0; + byteenable = 4'b1111; + harvard_readdata = readdata; + writedata = 32'h00000000; + n_state = 2'b00; + end + 2'b11: begin // connecting wires when in write state + address = write_data_address; + read = 1'b0; + write = 1'b1; + byteenable = write_byteenable; + harvard_readdata = 32'h00000000; + writedata = partial_write ? partial_writedata : harvard_writedata; + n_state = 2'b00; + end + endcase // state + end +end + +mips_cpu_harvard mips_cpu_harvard( // Harvard CPU within wrapper +.clk(clk_internal), // modulated clock input to allow waiting for valid data from memory, input +.reset(reset), // CPU reset, input +.active(active), // Is CPU active, output +.register_v0(register_v0), // $2 / $v0 debug bus, output +.clk_enable(clk_enable), // unused clock enable, input +.instr_address(harvard_instr_address), // instr addr from pc, output +.instr_readdata(instr_reg), // cached instruction passed into harvard cpu, input +.data_address(harvard_data_address), // harvard data memory address, output +.data_write(harvard_write), // harvard write flag, output +.data_read(harvard_read), // harvard read flag, output +.data_writedata(harvard_writedata), // data output from regfile readport2, output +.data_readdata(harvard_readdata) // data in from read instruction, input +); + +endmodule diff --git a/rtl/mips_cpu_control.v b/rtl/mips_cpu_control.v index 83f28c7..af5d76f 100644 --- a/rtl/mips_cpu_control.v +++ b/rtl/mips_cpu_control.v @@ -117,6 +117,8 @@ always @(*) begin CtrlMemtoReg = 3'd3;//write data port of regfile is fed from ALUHi end else if ((op==SPECIAL)&&(funct == MFLO))begin CtrlMemtoReg = 3'd4;//write data port of regfile is fed from ALULo + end else if (((op==SPECIAL)&&(funct == JR)) || (op == BEQ) || (op==SW) ||((op==REGIMM)&&(rt==BGEZ)) || (op==BGTZ) || ((op==REGIMM)&&(rt==BLTZ)) || (op==BLEZ) || (op==BNE) || (op==J) || ((op==SPECIAL)&&(funct==MTHI)) || ((op==SPECIAL)&&(funct==MTLO)) || ((op==SPECIAL)&&(funct==MULT)) || ((op==SPECIAL)&&(funct==MULTU)) || ((op==SPECIAL)&&(funct==DIV)) || ((op==SPECIAL)&&(funct==DIVU)) || (op==SB) || (op==SH))begin + CtrlMemRead = 0;//Read disabled during jump end else begin CtrlMemRead = 1'bx;end//Not all instructions are encompassed so, added incase for debug purposes //CtrlALUOp Logic diff --git a/rtl/mips_cpu_npc.v b/rtl/mips_cpu_npc.v index 53cc2ae..1971762 100644 --- a/rtl/mips_cpu_npc.v +++ b/rtl/mips_cpu_npc.v @@ -9,6 +9,7 @@ reg[31:0] npc_curr; initial begin npc_curr = (32'hBFC00000 + 32'd4); + npc_out = 32'hBFC00000; end // initial always_comb begin diff --git a/test/test_mips_cpu_bus.sh b/test/test_mips_cpu_bus.sh index bee7f43..17c1dde 100755 --- a/test/test_mips_cpu_bus.sh +++ b/test/test_mips_cpu_bus.sh @@ -1,4 +1,60 @@ #!/bin/bash -# should not create any files in the rtl dir -# but auxiliary files / dirs can be utilised \ No newline at end of file +SRC_DIR=${1?Error: no source directory given in argument}; +SRC=$(find ./${SRC_DIR}/*); +SRC_TEMP=""; +for src in ${SRC} +do + SRC_TEMP+=${src}" "; +done +SRC=${SRC_TEMP}; + + +INSTR=${2:-"No instruction specified: running all testcases"}; + +if [[ ${INSTR} == "No instruction specified: running all testcases" ]]; +then + for DIR in inputs/*/ + do + DIR=$(basename ${DIR}); + LOOP=$(find inputs/${DIR}/* ! -name '*ref*' ! -name '*log*' ! -name '*data*' ! -name '*out*'); + for TESTCASE in ${LOOP} + do + TESTCASE=$([[ ${TESTCASE} =~ /([^./]+)\. ]] && echo "${BASH_REMATCH[1]}"); + iverilog -Wall -g2012 \ + -s mips_cpu_bus_tb \ + -P mips_cpu_bus_tb.INSTR_INIT_FILE=\"inputs/${DIR}/${TESTCASE}.txt\" \ + -P mips_cpu_bus_tb.DATA_INIT_FILE=\"inputs/${DIR}/${TESTCASE}.data.txt\" \ + -o exec/mips_cpu_bus_tb_${TESTCASE} testbench/mips_cpu_bus_tb.v testbench/mips_cpu_bus_memory.v \ + ${SRC} 2> /dev/null + ./exec/mips_cpu_bus_tb_${TESTCASE} &> ./inputs/${DIR}/${TESTCASE}.log.txt; # log file for debugging (contains $display) + echo "$(tail -1 ./inputs/${DIR}/${TESTCASE}.log.txt)" > ./inputs/${DIR}/${TESTCASE}.out.txt; # register v0 output to compare with reference + if diff -w ./inputs/${DIR}/${TESTCASE}.out.txt ./inputs/${DIR}/${TESTCASE}.ref.txt &> /dev/null # compare + then + echo ${TESTCASE} ${DIR} "Pass"; + else + printf '%s %s %s%d %s%d%s\n' "${TESTCASE}" "${DIR}" "Fail Output=" "$(tail -1 ./inputs/${DIR}/${TESTCASE}.out.txt)" "Ref=" "$(tail -1 ./inputs/${DIR}/${TESTCASE}.ref.txt)" 2> /dev/null; + fi + done + done +else + LOOP=$(find inputs/${INSTR}/* ! -name '*ref*' ! -name '*log*' ! -name '*data*' ! -name '*out*'); + for TESTCASE in ${LOOP} + do + TESTCASE=$([[ ${TESTCASE} =~ /([^./]+)\. ]] && echo "${BASH_REMATCH[1]}"); + iverilog -Wall -g2012 \ + -s mips_cpu_bus_tb \ + -P mips_cpu_bus_tb.INSTR_INIT_FILE=\"inputs/${INSTR}/${TESTCASE}.txt\" \ + -P mips_cpu_bus_tb.DATA_INIT_FILE=\"inputs/${INSTR}/${TESTCASE}.data.txt\" \ + -o exec/mips_cpu_bus_tb_${TESTCASE} testbench/mips_cpu_bus_tb.v testbench/mips_cpu_bus_memory.v \ + ${SRC} 2> /dev/null + ./exec/mips_cpu_bus_tb_${TESTCASE} &> ./inputs/${INSTR}/${TESTCASE}.log.txt; # log file for debugging (contains $display) + echo "$(tail -1 ./inputs/${INSTR}/${TESTCASE}.log.txt)" > ./inputs/${INSTR}/${TESTCASE}.out.txt; # register v0 output to compare with reference + if diff -w ./inputs/${INSTR}/${TESTCASE}.out.txt ./inputs/${INSTR}/${TESTCASE}.ref.txt &> /dev/null # compare + then + echo ${TESTCASE} ${INSTR} "Pass"; + else + printf '%s %s %s%d %s%d%s\n' "${TESTCASE}" "${INSTR}" "Fail Output=" "$(tail -1 ./inputs/${INSTR}/${TESTCASE}.out.txt)" "Ref=" "$(tail -1 ./inputs/${INSTR}/${TESTCASE}.ref.txt)" 2> /dev/null; + fi + done +fi \ No newline at end of file diff --git a/test/test_mips_cpu_harvard.sh b/test/test_mips_cpu_harvard.sh index 3adf52f..e5cd348 100755 --- a/test/test_mips_cpu_harvard.sh +++ b/test/test_mips_cpu_harvard.sh @@ -47,7 +47,7 @@ else -P mips_cpu_harvard_tb.INSTR_INIT_FILE=\"inputs/${INSTR}/${TESTCASE}.txt\" \ -P mips_cpu_harvard_tb.DATA_INIT_FILE=\"inputs/${INSTR}/${TESTCASE}.data.txt\" \ -o exec/mips_cpu_harvard_tb_${TESTCASE} testbench/mips_cpu_harvard_tb.v testbench/mips_cpu_memory.v\ - ${SRC} #2> /dev/null + ${SRC} 2> /dev/null ./exec/mips_cpu_harvard_tb_${TESTCASE} &> ./inputs/${INSTR}/${TESTCASE}.log.txt; # log file for debugging (contains $display) echo "$(tail -1 ./inputs/${INSTR}/${TESTCASE}.log.txt)" > ./inputs/${INSTR}/${TESTCASE}.out.txt; # register v0 output to compare with reference if diff -w ./inputs/${INSTR}/${TESTCASE}.out.txt ./inputs/${INSTR}/${TESTCASE}.ref.txt &> /dev/null # compare diff --git a/testbench/mips_cpu_bus_memory.v b/testbench/mips_cpu_bus_memory.v new file mode 100644 index 0000000..822c423 --- /dev/null +++ b/testbench/mips_cpu_bus_memory.v @@ -0,0 +1,100 @@ +module mips_cpu_bus_memory( //Avalon memory mapped bus controller (slave) + input logic clk, + input logic reset, + input logic[31:0] address, + input logic write, + input logic read, + output logic waitrequest, + input logic[31:0] writedata, + input logic[3:0] byteenable, + output logic[31:0] readdata +); + +parameter INSTR_INIT_FILE = ""; +parameter DATA_INIT_FILE = ""; + +logic [31:0] data_memory [0:63]; // location 0x00001000 onwards +logic [31:0] instr_memory [0:63]; // location 0xBFC00000 onwards + +initial begin + for (integer i=0; i<$size(data_memory); i++) begin //Initialise data to zero by default + data_memory[i] = 0; + end + + for (integer i=0; i<$size(instr_memory); i++) begin //Initialise instr to zero by default + instr_memory[i] = 0; + end + + if (INSTR_INIT_FILE != "") begin //Load instr contents from file if specified + $display("RAM: Loading RAM contents from %s", INSTR_INIT_FILE); + $readmemh(INSTR_INIT_FILE, instr_memory); + end + + for (integer i = 0; i<$size(instr_memory); i++) begin //Read out instr contents to log + $display("byte +%h: %h", 32'hBFC00000+i*4, instr_memory[i]); + end + + if (DATA_INIT_FILE != "") begin //Load data contents from file if specified + $display("MEM: Loading MEM contents from %s", DATA_INIT_FILE); + $readmemh(DATA_INIT_FILE, data_memory); + end else begin + $display("MEM FILE NOT GIVEN"); + end + + for (integer i = 0; i<$size(data_memory); i++) begin //Read out data contents to log + $display("byte +%h: %h", 32'h00001000+i*4, data_memory[i]); + end + + waitrequest = 1'b0; // set waitrequest low to begin + readdata = 32'h00000000; // set readdata low to begin + +end + +always_comb begin + if (reset) begin + waitrequest = 1'b0; + end +end + +always_ff @(posedge read or posedge write) begin + waitrequest <= 1'b1; +end + +always_ff @(posedge clk) begin + if (waitrequest) begin + if (read) begin + if (address >= 32'hBFC00000) begin // instruction read + readdata <= instr_memory[{address-32'hBFC00000}>>2]; + end else if (address >= 32'h00001000) begin // data read + readdata <= data_memory[{address-32'h00001000}>>2]; + end + waitrequest <= 1'b0; // end with setting waitrequest low + end else if (write) begin + if (address >= 32'hBFC00000) begin // writing to instr mem area is invalid + $display("Error, write attempted in instr area at address: %h", address); + end else if (address >= 32'h00001000) begin // write to data mem + if (byteenable[3]) begin // if first byte enabled, write + data_memory[{address-32'h00001000}>>2][31:24] <= writedata[31:24]; + end + if (byteenable[2]) begin // if second byte enabled, write + data_memory[{address-32'h00001000}>>2][23:16] <= writedata[23:16]; + end + if (byteenable[1]) begin // if third byte enabled, write + data_memory[{address-32'h00001000}>>2][15:8] <= writedata[15:8]; + end + if (byteenable[0]) begin // if fourth byte enabled, write + data_memory[{address-32'h00001000}>>2][7:0] <= writedata[7:0]; + end + waitrequest <= 1'b0; // end with setting waitrequest low + end + end else begin + waitrequest <= 1'bx; + readdata <= 32'hxxxxxxxx; + end + end else begin + waitrequest <= 1'b0; + readdata <= 32'h00000000; + end +end + +endmodule \ No newline at end of file diff --git a/testbench/mips_cpu_bus_tb.v b/testbench/mips_cpu_bus_tb.v index 6e77504..4bd0d89 100644 --- a/testbench/mips_cpu_bus_tb.v +++ b/testbench/mips_cpu_bus_tb.v @@ -1,61 +1,80 @@ module mips_cpu_bus_tb; - timeunit 1ns / 10ps; - parameter RAM_INIT_FILE = "test/01-binary/countdown.hex.txt"; - parameter TIMEOUT_CYCLES = 10000; +parameter INSTR_INIT_FILE = ""; +parameter DATA_INIT_FILE = ""; +parameter TIMEOUT_CYCLES = 100; // Timeout cycles are higher to account for memory stall delays - logic clk; - logic rst; +logic clk, reset, active, write, read, waitrequest; +logic[31:0] address, register_v0, writedata, readdata; +logic[3:0] byteenable; - logic running; +mips_cpu_bus_memory #(INSTR_INIT_FILE, DATA_INIT_FILE) memInst( //Avalon memory mapped bus controller (slave) + .clk(clk), // clk input to mem + .reset(reset), // reset input to stall mem during cpu reset + .address(address), // addr input to mem + .write(write), // write flag input + .read(read), // read flag input + .waitrequest(waitrequest), // mem stall output + .writedata(writedata), // data to be written + .byteenable(byteenable), // byteenable bus for writes + .readdata(readdata) // read output port +); - logic[11:0] address; - logic write; - logic read; - logic[15:0] writedata; - logic[15:0] readdata; +mips_cpu_bus cpuInst( + .clk(clk), // clk input to cpu wrapper + .reset(reset), // reset input + .active(active), // active output flag + .register_v0(register_v0), // debug $2 or $v0 output bus + .address(address), // mem addr output + .write(write), // mem write output flag + .read(read), // mem read output flag + .waitrequest(waitrequest), // mem stall input flag + .writedata(writedata), // data to write to mem output + .byteenable(byteenable), // bytes to write output + .readdata(readdata) // data from mem input +); - RAM_16x4096_delay1 #(RAM_INIT_FILE) ramInst(clk, address, write, read, writedata, readdata); - - CPU_MU0_delay1 cpuInst(clk, rst, running, address, write, read, writedata, readdata); +// Setup and clock +initial begin + $dumpfile("mips_cpu_bus.vcd"); + $dumpvars(0,mips_cpu_bus_tb); + clk=0; - // Generate clock - initial begin - clk=0; - - repeat (TIMEOUT_CYCLES) begin - #10; - clk = !clk; - #10; - clk = !clk; - end - - $fatal(2, "Simulation did not finish within %d cycles.", TIMEOUT_CYCLES); + repeat (TIMEOUT_CYCLES) begin + #10; + clk = !clk; + #10; + clk = !clk; end - initial begin - rst <= 0; + $fatal(2, "Simulation did not finish within %d cycles.", TIMEOUT_CYCLES); +end +initial begin + reset <= 1; + @(posedge clk); + reset <= 0; + + @(posedge clk); + assert(active==1) + else $display("TB : CPU did not set active=1 after reset."); + + while (active) begin + //$display("Clk: %d", clk); @(posedge clk); - rst <= 1; - - @(posedge clk); - rst <= 0; - - @(posedge clk); - assert(running==1) - else $display("TB : CPU did not set running=1 after reset."); - - while (running) begin - @(posedge clk); - end - - $display("TB : finished; running=0"); - - $finish; - + //$display("Register v0: %d", register_v0); + //$display("Reg File Write data: %d", cpuInst.in_writedata); + $display("Reg File Out Read data: %h", cpuInst.mips_cpu_harvard.out_readdata1); + $display("Reg File opcode: %b", cpuInst.mips_cpu_harvard.regfile.opcode); + //$display("ALU output: %h", cpuInst.out_ALURes); + //$display("ALU input B: %h", cpuInst.alu.B); end - + @(posedge clk); + $display("TB: CPU Halt; active=0"); + $display("Output:"); + $display("%d",register_v0); + $finish; +end endmodule \ No newline at end of file