diff --git a/inputs/and/and-1.txt b/inputs/and/and-1.txt index 26f7011..7a287c6 100644 --- a/inputs/and/and-1.txt +++ b/inputs/and/and-1.txt @@ -1,6 +1,6 @@ -3c05cccc -3405cccc +3c05cccc +34A5cccc 3c04aaaa -3404aaaa +3484aaaa 00851024 00000008 \ No newline at end of file diff --git a/inputs/bgez/bgez-2.ref.txt b/inputs/bgez/bgez-2.ref.txt new file mode 100644 index 0000000..7813681 --- /dev/null +++ b/inputs/bgez/bgez-2.ref.txt @@ -0,0 +1 @@ +5 \ No newline at end of file diff --git a/inputs/bgez/bgez-2.txt b/inputs/bgez/bgez-2.txt new file mode 100644 index 0000000..13d6d41 --- /dev/null +++ b/inputs/bgez/bgez-2.txt @@ -0,0 +1,7 @@ +34040003 +04810003 +00000000 +24420001 +00000000 +24420005 +00000008 \ No newline at end of file diff --git a/inputs/bltz/bltz-1.txt b/inputs/bltz/bltz-1.txt index 93100eb..758b0d3 100644 --- a/inputs/bltz/bltz-1.txt +++ b/inputs/bltz/bltz-1.txt @@ -1,4 +1,5 @@ -3C05FFFF +3C04FFFF +00000000 04800003 00000000 00000008 diff --git a/inputs/divu/divu-1.txt b/inputs/divu/divu-1.txt index 71c00bc..049449a 100644 --- a/inputs/divu/divu-1.txt +++ b/inputs/divu/divu-1.txt @@ -1,4 +1,4 @@ -34048000 +3C048000 34050002 0085001B 00002010 diff --git a/inputs/jr/jr-1.txt b/inputs/jr/jr-1.txt index 010289b..79610db 100644 --- a/inputs/jr/jr-1.txt +++ b/inputs/jr/jr-1.txt @@ -3,5 +3,5 @@ 00A00008 00000000 00000008 -34020001 +3402000A 00000008 diff --git a/inputs/lwl/lwl-1.txt b/inputs/lwl/lwl-1.txt index a62ec0b..c682e96 100644 --- a/inputs/lwl/lwl-1.txt +++ b/inputs/lwl/lwl-1.txt @@ -1,4 +1,4 @@ -34041003 +34041001 34025678 88820003 00000008 \ No newline at end of file diff --git a/inputs/mult/mult-1.txt b/inputs/mult/mult-1.txt index 86f65a6..a22f6bf 100644 --- a/inputs/mult/mult-1.txt +++ b/inputs/mult/mult-1.txt @@ -2,4 +2,5 @@ 34050003 00850018 00001012 +00000000 00000008 \ No newline at end of file diff --git a/inputs/ori/ori-1.txt b/inputs/ori/ori-1.txt index 43a087f..b41478b 100644 --- a/inputs/ori/ori-1.txt +++ b/inputs/ori/ori-1.txt @@ -1,3 +1,3 @@ 34020003 +34420005 00000008 -34020005 \ No newline at end of file diff --git a/inputs/ori/ori-2.ref.txt b/inputs/ori/ori-2.ref.txt new file mode 100644 index 0000000..35ff949 --- /dev/null +++ b/inputs/ori/ori-2.ref.txt @@ -0,0 +1 @@ +65535 \ No newline at end of file diff --git a/inputs/ori/ori-2.txt b/inputs/ori/ori-2.txt new file mode 100644 index 0000000..b13206a --- /dev/null +++ b/inputs/ori/ori-2.txt @@ -0,0 +1,4 @@ +3404FFFF +34052134 +00851025 +00000008 diff --git a/inputs/slt/slt-1.txt b/inputs/slt/slt-1.txt index 013d035..ff579ee 100644 --- a/inputs/slt/slt-1.txt +++ b/inputs/slt/slt-1.txt @@ -1,4 +1,4 @@ -3404FFFF +3404000F 3405000B 0085102A 00000008 \ No newline at end of file diff --git a/inputs/slt/slt-2.ref.txt b/inputs/slt/slt-2.ref.txt new file mode 100644 index 0000000..c227083 --- /dev/null +++ b/inputs/slt/slt-2.ref.txt @@ -0,0 +1 @@ +0 \ No newline at end of file diff --git a/inputs/slt/slt-2.txt b/inputs/slt/slt-2.txt new file mode 100644 index 0000000..013d035 --- /dev/null +++ b/inputs/slt/slt-2.txt @@ -0,0 +1,4 @@ +3404FFFF +3405000B +0085102A +00000008 \ No newline at end of file diff --git a/inputs/srav/srav-1.txt b/inputs/srav/srav-1.txt index 3b638bc..8d6dad2 100644 --- a/inputs/srav/srav-1.txt +++ b/inputs/srav/srav-1.txt @@ -1,4 +1,4 @@ -34040004 +34040002 3C05F000 00851007 00000008 diff --git a/inputs/sw/sw-1.txt b/inputs/sw/sw-1.txt index 75b14c8..181c053 100644 --- a/inputs/sw/sw-1.txt +++ b/inputs/sw/sw-1.txt @@ -1,5 +1,5 @@ 3404FFFF 34051008 -ACA40000 +ACA40004 8CA20004 00000008 \ No newline at end of file diff --git a/inputs/sw/sw-2.ref.txt b/inputs/sw/sw-2.ref.txt new file mode 100644 index 0000000..35ff949 --- /dev/null +++ b/inputs/sw/sw-2.ref.txt @@ -0,0 +1 @@ +65535 \ No newline at end of file diff --git a/inputs/sw/sw-2.txt b/inputs/sw/sw-2.txt new file mode 100644 index 0000000..087cb4c --- /dev/null +++ b/inputs/sw/sw-2.txt @@ -0,0 +1,5 @@ +3404FFFF +34051008 +ACA4FFFC +8CA2FFFC +00000008 \ No newline at end of file diff --git a/reference.txt b/reference.txt index bf33fcf..2d6129f 100644 --- a/reference.txt +++ b/reference.txt @@ -32,17 +32,17 @@ register_v0 = 8 ==AND Bitwise and== -LUI $5,0xCCCC -ORI $5,$0,0xCCCC +LUI $5,0xCCCC +ORI $5,$5,0xCCCC LUI $4,0xAAAA -ORI $4,$0,0xAAAA +ORI $4,$4,0xAAAA AND $2,$4,$5 JR $0 -3c05cccc -3405cccc +3c05cccc +34A5cccc 3c04aaaa -3404aaaa +3484aaaa 00851024 00000008 @@ -104,6 +104,22 @@ JR $0 register_v0 = 1 +ORI $4,$0,3 +BGEZ $4,3 +NOP +ADDIU $2,$2,1 +NOP +ADDIU $2,$2,5 +JR $0 + +34040003 +04810003 +00000000 +24420001 +00000000 +24420005 +00000008 + ==BGEZAL Branch on non-negative (>=0) and link== ORI $4,$0,3 @@ -176,7 +192,7 @@ NOP ORI $2,$0,1 JR $0 -3C05FFFF +3C04FFFF 04800003 00000000 00000008 @@ -252,15 +268,15 @@ register_v0 = 3 ==DIVU Divide unsigned== //May need other testcases for -ve/+ve, -ve/-ve -LUI $4,0x8000 +LUI $4,0x8000 ORI $5,$0,2 DIVU $4,$5 MFHI $4 -MFLO $5 +MFLO $5 ADDU $2,$4,$5 JR $0 -34048000 +3C048000 34050002 0085001B 00002010 @@ -343,12 +359,14 @@ NOP ORI $2,$0,1 JR $0 -3C05BFC0 -34050014 -00A00008 -00000000 -00000008 -34020001 +BFC00014 +0,4,8,c,10,14 +3C05BFC0 0 +34050014 4 +00A00008 8 +00000000 c +00000008 10 +34020001 14 00000008 register_v0 = 1 @@ -472,14 +490,14 @@ register_v0 = 0x12345678 ==LWL Load word left== -ORI $4,$0,0x1003 +ORI $4,$0,0x1001 ORI $2,$0,0x5678 LWL $2,3($4) JR $0 -Instruction Hex -34041003 +34041001 34025678 88820003 00000008 @@ -590,18 +608,26 @@ jr $0 register_v0 = 7 + ==ORI Bitwise or immediate== ori $2, $0, 3 -ori $2, $0, 5 +ori $2, $2, 5 jr $0 34020003 00000008 -34020005 +34420005 register_v0 = 7 +ori $4, $0, 0xFFFF +ori $5, $0, 0x1234 +or $2, $4, $5 +jr $0 + +register_v0 = 65535 + ==SB Store byte== lui $4, 0x1234 @@ -735,10 +761,12 @@ register_v0 = 0xFC000000 ==SRAV Shift right arithmetic variable== ori $4,$0,2 -lui $5 $0,0xF000 +lui $5, 0xF000 srav $2,$5,$4 jr $0 +F000000 -> FC000000 + 34040004 3C05F000 00851007 @@ -788,10 +816,10 @@ register_v0 = 2 ==SW Store word== -ori $4, $0, 0xFFFF -ori $5, $0, 0x1008 -sw $4, 4($5) -lw $2, 4($5) +ori $4, $0, 0xFFFF +ori $5, $0, 0x1008 +sw $4, 4($5) +lw $2, 4($5) jr $0 3404FFFF @@ -802,6 +830,20 @@ ACA40004 register_v0 = 0x0000FFFF +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 + ==XOR Bitwise exclusive or== ori $4, $0, 5 diff --git a/rtl/mips_cpu_alu.v b/rtl/mips_cpu_alu.v index 22b2967..11e564b 100644 --- a/rtl/mips_cpu_alu.v +++ b/rtl/mips_cpu_alu.v @@ -73,8 +73,8 @@ Alu Operations: // PAS = 5'd19, no need for PAS as it was based on faulty reasoning that speical registers Hi and Lo are in the reg file. SLT = 5'd20,//signed compare SLTU = 5'd21,//unsigned compare - MULU = 5'd22,//unsigned divide - DIVU = 5'd23,//unsigned multiply + MULU = 5'd22,//unsigned multiply + DIVU = 5'd23,//unsigned divide MTHI = 5'd24, MTLO = 5'd25 @@ -168,6 +168,7 @@ end end LES: begin + $display("ALU A: %h B: %h", $signed(A), $signed(B)); if ($signed(A) < $signed(B)) begin ALUCond = 1; end @@ -225,12 +226,18 @@ end if ($signed(A) < $signed(B)) begin ALURes = 1; end + else begin + ALURes = 0; + end end SLTU: begin if (A < B) begin ALURes = 1; end + else begin + ALURes = 0; + end end MULU: begin @@ -240,6 +247,7 @@ end end DIVU: begin + $display("ALU A: %h B: %h", A, B); temp_Lo = A / B; temp_Hi = A % B; end diff --git a/rtl/mips_cpu_control.v b/rtl/mips_cpu_control.v index e5fff07..a668eed 100644 --- a/rtl/mips_cpu_control.v +++ b/rtl/mips_cpu_control.v @@ -9,7 +9,7 @@ module mips_cpu_control( output logic[4:0] CtrlALUOp, output logic[4:0] Ctrlshamt, output logic CtrlMemWrite, - output logic CtrlALUSrc, + output logic[1:0] CtrlALUSrc, output logic CtrlRegWrite, output logic CtrlSpcRegWriteEn ); @@ -104,9 +104,9 @@ always @(*) begin end else if((op==J) || (op==JAL))begin CtrlPC = 2'd2; // Jumps within 256MB Region using 26-bit immediate in J type instruction $display("Jump PC Ctrl"); - end else if((op==SPECIAL)&&(funct==JR) || (funct==JALR))begin + end else if((op==SPECIAL)&&((funct==JR) || (funct==JALR)))begin 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 //CtrlMemRead and CtrlMemtoReg logic -- Interesting quirk that they have the same logic where both are concerned. Makes sense bc you'd only want to select the read data out when the memory itself is read enabled. @@ -120,12 +120,12 @@ always @(*) begin $display("Memory read disabled"); end else if ((op==JAL) || ((op==SPECIAL)&&(funct == JALR)))begin CtrlMemtoReg = 3'd2;//write data port of regfile is fed from PC + 8 - end else if ((op==SPECIAL)&&(funct == MTHI))begin + end else if ((op==SPECIAL)&&(funct == MFHI))begin CtrlMemtoReg = 3'd3;//write data port of regfile is fed from ALUHi - end else if ((op==SPECIAL)&&(funct == MTLO))begin + end else if ((op==SPECIAL)&&(funct == MFLO))begin CtrlMemtoReg = 3'd4;//write data port of regfile is fed from ALULo end else begin CtrlMemRead = 1'bx;end//Not all instructions are encompassed so, added incase for debug purposes - + $display("OP: %d, Funct: %d", op, funct); //CtrlALUOp Logic if((op==ADDIU) || ((op==SPECIAL)&&(funct==ADDU)))begin CtrlALUOp = 5'd0; //ADD from ALUOps @@ -146,6 +146,7 @@ always @(*) begin CtrlALUOp = 5'd18;//NEQ from ALUOps end else if((op==SPECIAL)&&(funct==DIV))begin CtrlALUOp = 5'd3;//DIV from ALUOps + $display("DIV CONTROL ALUOps"); end else if((op==SPECIAL)&&(funct==DIVU))begin 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==SH) || (op==SW))begin @@ -207,20 +208,24 @@ always @(*) begin end else begin CtrlMemWrite = 0;end//default is 0 to ensure no accidental overwriting. //CtrlSpcRegWriteEn logic - if((op==SPECIAL)&&((funct==MTHI) || (funct==MTLO)))begin + if((op==SPECIAL)&&((funct==MTHI) || (funct==MTLO) || (funct==MULT) || (funct==MULTU) || (funct==DIV) || (funct==DIVU)))begin CtrlSpcRegWriteEn = 1;//Special register Hi and Lo are write enabled + $display("Temp being written"); end else begin CtrlSpcRegWriteEn = 0;end//default is 0 to ensure no accidental overwriting. //CtrlALUSrc logic - if((op==ADDIU) || (op==ANDI) || (op==LUI) || (op==ORI) || (op==SLTI) || (op==SLTIU) || (op==XORI) || (op==LB) || (op==LBU) || (op==LH) || (op==LHU) || (op==LW) || (op==LWL) || (op==LWR) || (op==SB) || (op==SH) || (op==SW))begin + if((op==ADDIU) || (op==LUI) || (op==SLTI) || (op==SLTIU) || (op==LB) || (op==LBU) || (op==LH) || (op==LHU) || (op==LW) || (op==LWL) || (op==LWR) || (op==SB) || (op==SH) || (op==SW))begin CtrlALUSrc = 1;//ALU Bus B is fed from the 16-bit immediate sign extended to 32-bit value taken from Instr[15-0] end else if((op==BEQ) || (op==BGTZ) || (op==BLEZ) || (op==BNE) || ((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))) || ((op==REGIMM)&&((rt==BGEZ) || (rt==BGEZAL) || (rt==BLTZ) || (rt==BLTZAL))))begin CtrlALUSrc = 0;///ALU Bus B is fed from rt. + end else if ((op==ORI) || (op==ANDI) || (op==XORI)) begin + CtrlALUSrc = 2; end else begin CtrlALUSrc = 1'bx;end //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==XORI) || ((op==SPECIAL)&&((funct==ADDU) || (funct==AND) || (funct==MFLO) || (funct==MFHI) || (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 + $display("OPcode mflo: %h", op); end else begin CtrlRegWrite = 0;end // The Registers are Write Disabled end endmodule \ No newline at end of file diff --git a/rtl/mips_cpu_harvard.v b/rtl/mips_cpu_harvard.v index fa6ffd5..aa0e2f2 100644 --- a/rtl/mips_cpu_harvard.v +++ b/rtl/mips_cpu_harvard.v @@ -29,8 +29,8 @@ assign data_writedata = out_readdata2; logic[31:0] out_pc_out, out_ALURes, out_readdata1, out_readdata2, in_B, in_writedata, out_ALUHi, out_ALULo; logic[4:0] in_readreg1, in_readreg2, in_writereg, out_shamt, out_ALUOp; logic[5:0] in_opcode; -logic out_ALUCond, out_RegWrite, out_ALUSrc, out_MemWrite, out_MemRead, out_SpcRegWriteEn; -logic[1:0] out_RegDst, out_PC; +logic out_ALUCond, out_RegWrite, out_MemWrite, out_MemRead, out_SpcRegWriteEn; +logic[1:0] out_RegDst, out_PC, out_ALUSrc; logic[2:0] out_MemtoReg; assign in_readreg1 = instr_readdata[25:21]; @@ -72,10 +72,13 @@ always @(*) begin //Picking which output should be taken as the second operand for ALU. case(out_ALUSrc) - 1'b1:begin + 2'd2: begin + in_B = {16'd0,instr_readdata[15:0]}; + end + 2'd1:begin in_B = {{16{instr_readdata[15]}},instr_readdata[15:0]};//Output from the 16-bit immediate values sign extened to 32bits. end - 1'b0:begin + 2'd0:begin in_B = out_readdata2;//Output from 'Read data 2' port of regfile. end endcase diff --git a/rtl/mips_cpu_memory.v b/rtl/mips_cpu_memory.v index 66daf1c..a3984a9 100644 --- a/rtl/mips_cpu_memory.v +++ b/rtl/mips_cpu_memory.v @@ -56,7 +56,7 @@ module mips_cpu_memory( //Synchronous write path always_ff @(posedge clk) begin - //$display("Instruction Read: %h", instr_readdata); + //$display("Instruction: %h", instr_readdata); //$display("RAM : INFO : data_read=%h, data_address = %h, mem=%h", data_read, data_address, memory[data_address]); if (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 diff --git a/rtl/mips_cpu_regfile.v b/rtl/mips_cpu_regfile.v index 84d300b..c27fa69 100644 --- a/rtl/mips_cpu_regfile.v +++ b/rtl/mips_cpu_regfile.v @@ -77,7 +77,10 @@ always_ff @(negedge clk) begin 2'b11: memory[writereg][7:0] <= writedata[31:24]; endcase // readdata1[1:0] end - default: memory[writereg] <= writedata; //most instructions + default: begin + memory[writereg] <= writedata; //most instructions + $display("Write %d in regfile", writedata); + end endcase // opcode end end diff --git a/test/test_mips_cpu_custom.sh b/test/test_mips_cpu_custom.sh index 7ec4b34..32858e4 100755 --- a/test/test_mips_cpu_custom.sh +++ b/test/test_mips_cpu_custom.sh @@ -10,12 +10,12 @@ ./test/test_mips_cpu_harvard.sh rtl ori #Pass ./test/test_mips_cpu_harvard.sh rtl xor #Pass ./test/test_mips_cpu_harvard.sh rtl xori #Pass -#./test/test_mips_cpu_harvard.sh rtl div -#./test/test_mips_cpu_harvard.sh rtl divu -#./test/test_mips_cpu_harvard.sh rtl mthi -#./test/test_mips_cpu_harvard.sh rtl mtlo -#./test/test_mips_cpu_harvard.sh rtl mult -#./test/test_mips_cpu_harvard.sh rtl multu +./test/test_mips_cpu_harvard.sh rtl div #Pass +./test/test_mips_cpu_harvard.sh rtl divu #pass +./test/test_mips_cpu_harvard.sh rtl mthi #Pass +./test/test_mips_cpu_harvard.sh rtl mtlo #Pass +./test/test_mips_cpu_harvard.sh rtl mult #Pass +./test/test_mips_cpu_harvard.sh rtl multu #Pass # branches @@ -24,7 +24,7 @@ #./test/test_mips_cpu_harvard.sh rtl bgezal #Place return address thing how?? ./test/test_mips_cpu_harvard.sh rtl bgtz #Pass ./test/test_mips_cpu_harvard.sh rtl blez #Pass -#./test/test_mips_cpu_harvard.sh rtl bltz #Probably fails due to jump register thing? +./test/test_mips_cpu_harvard.sh rtl bltz #Probably fails due to jump register thing? ./test/test_mips_cpu_harvard.sh rtl bltzal #Pass ./test/test_mips_cpu_harvard.sh rtl bne #Pass