diff --git a/cMIPS/tests/doTests.sh b/cMIPS/tests/doTests.sh index c4a4dd46555af4a39f9f94b8b240b782d1589a7e..5173ef8bf640bd83ea99f3dce9270b66378bbcf8 100755 --- a/cMIPS/tests/doTests.sh +++ b/cMIPS/tests/doTests.sh @@ -67,7 +67,7 @@ a_FWD="fwdAddAddAddSw fwd_SW lwFWDsw lwFWDsw2 slt32 slt_u_32 slt_s_32 reg0" a_CAC="dCacheTst lhUshUCache lbUsbUCache lbsbCache dCacheTstH dCacheTstB" a_BEQ="lw-bne bXtz sltbeq beq_dlySlot jr_dlySlot" a_FUN="jaljr jr_2 jal_fun_jr jalr_jr bltzal_fun_jr" -a_OTH="mult div sll slr movz wsbh_seb extract insert" +a_OTH="mult div mul sll slr movz wsbh_seb extract insert" a_BHW="lbsb lhsh lwsw lwswIncr swlw lwl_lwr" a_MEM="lwSweepRAM" a_CTR="teq_tne teq_jal teq_lw tlt_tlti tltu_tgeu eiDI ll_sc overflow counter" @@ -75,8 +75,6 @@ a_COP="mtc0CAUSE2 mtc0EPC syscall break mfc0CONFIG badVAddr badVAddrMM" a_MMU="mmu_index mmu_tlbwi mmu_tlbp mmu_tlbwr mmu_context" a_EXC="mmu_refill mmu_refill2 mmu_refill3 mmu_inval mmu_inval2 mmu_mod mmu_mod2 mmu_double mmu_double2" -## these tests MUST be run with FAKE CACHES -# a_IOs="kbd7seg" diff --git a/cMIPS/vhdl/core.vhd b/cMIPS/vhdl/core.vhd index 896e2fc1a09974484cd7835dd364a1695ed78fdd..943c1694b6334e4128fcc1217c646b39777b39ae 100644 --- a/cMIPS/vhdl/core.vhd +++ b/cMIPS/vhdl/core.vhd @@ -513,7 +513,7 @@ architecture rtl of core is ('1','1',NIL, '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--25 ('1','1',NIL, '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--26 ('1','1',NIL, '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--27 - ('1','1',NIL, '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--28 + ('1','1',SPEC2,'0','0','0',opSPC,"001","00", '0', "00",cNOP,"00"),--28 ('1','1',NIL, '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--29 ('1','1',NIL, '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--30 ('1','1',SPEC3,'0','0','0',opSPC,"001","00", '0', "00",cNOP,"00"),--special3 @@ -1187,6 +1187,20 @@ begin i_csel := ctrl_word.c_sel; PCsel <= ctrl_word.PCsel; + when b"011100" => -- special2 + i_wreg := ctrl_word.wreg; + selB <= ctrl_word.selB; + muxC <= ctrl_word.muxC; + i_csel := ctrl_word.c_sel; + PCsel <= ctrl_word.PCsel; + case func is + when b"000010" => -- MUL R[rd] <= R[rs]*R[rt] + i_oper := opMUL; + when others => + i_oper := opNOP; + i_exception := exRESV_INSTR; + end case; + when b"011111" => -- special3 case func is when b"100000" => -- BSHFL diff --git a/cMIPS/vhdl/packageWires.vhd b/cMIPS/vhdl/packageWires.vhd index a2c5197c359dcd7835a739fbe29228827d06c9ca..f037ec07978166bf9d2fd30d1d151eb515080a76 100644 --- a/cMIPS/vhdl/packageWires.vhd +++ b/cMIPS/vhdl/packageWires.vhd @@ -78,7 +78,7 @@ package p_WIRES is opSLL, opSLLV, opSRL, opSRA, opSRLV, opSRAV, opMOVZ, opMOVN, opMFHI, opMTHI, opMFLO, opMTLO, - opMULT, opMULTU, opDIV, opDIVU, + opMULT, opMULTU, opDIV, opDIVU, opMUL, opADD, opADDU, opSUB, opSUBU, opAND, opOR, opXOR, opNOR, opSLT, opSLTU, opLUI, @@ -87,7 +87,7 @@ package p_WIRES is invalid_op); attribute ENUM_ENCODING of t_alu_fun : type is - "000000 000001 000010 000011 000100 000101 000110 000111 001000 001001 001010 001011 001100 001101 001110 001111 010000 010001 010010 010011 010100 010101 010110 010111 011000 011001 011010 011011 011100 011101 011110 011111 100000 100001 100010 100011 100100 100101 100110 100111 101000 101001"; + "000000 000001 000010 000011 000100 000101 000110 000111 001000 001001 001010 001011 001100 001101 001110 001111 010000 010001 010010 010011 010100 010101 010110 010111 011000 011001 011010 011011 011100 011101 011110 011111 100000 100001 100010 100011 100100 100101 100110 100111 101000 101001 101010"; type instr_type is (iALU,ADD,ADDU,SUB,SUBU,iAND,iOR,iXOR,iNOR, --8 RIMM,BLTZ,BGEZ, BLTZAL,BGEZAL, -- 13 @@ -103,12 +103,12 @@ package p_WIRES is MFHI,MTHI,MFLO,MTLO, MULT,MULTU,DIV,DIVU, -- 63 BREAK, SYSCALL, NOP, TEQ,TNE, TEQI,TNEI, -- 70 TLT,TLTU,TLTI,TLTIU, TGE,TGEU,TGEI,TGEIU, -- 78 - NIL,invalid_instr); -- 80 + SPEC2, NIL,invalid_instr); -- 81 attribute ENUM_ENCODING of instr_type : type is - "0000000 0000001 0000010 0000011 0000100 0000101 0000110 0000111 0001000 0001001 0001010 0001011 0001100 0001101 0001110 0001111 0010000 0010001 0010010 0010011 0010100 0010101 0010110 0010111 0011000 0011001 0011010 0011011 0011100 0011101 0011110 0011111 0100000 0100001 0100010 0100011 0100100 0100101 0100110 0100111 0101000 0101001 0101010 0101011 0101100 0101101 0101110 0101111 0110000 0110001 0110010 0110011 0110100 0110101 0110110 0110111 0111000 0111001 0111010 0111011 0111100 0111101 0111110 0111111 1000000 1000001 1000010 1000011 1000100 1000101 1000110 1000111 1001000 1001001 1001010 1001011 1001100 1001101 1001110 1001111 1010000"; + "0000000 0000001 0000010 0000011 0000100 0000101 0000110 0000111 0001000 0001001 0001010 0001011 0001100 0001101 0001110 0001111 0010000 0010001 0010010 0010011 0010100 0010101 0010110 0010111 0011000 0011001 0011010 0011011 0011100 0011101 0011110 0011111 0100000 0100001 0100010 0100011 0100100 0100101 0100110 0100111 0101000 0101001 0101010 0101011 0101100 0101101 0101110 0101111 0110000 0110001 0110010 0110011 0110100 0110101 0110110 0110111 0111000 0111001 0111010 0111011 0111100 0111101 0111110 0111111 1000000 1000001 1000010 1000011 1000100 1000101 1000110 1000111 1001000 1001001 1001010 1001011 1001100 1001101 1001110 1001111 1010000 1010001"; --- 1010001 1010010 1010011 1010100 1010101 1010110 1010111 +-- 1010010 1010011 1010100 1010101 1010110 1010111 -- 1011000 1011001 1011010 1011011 1011100 1011101 1011110 1011111 diff --git a/cMIPS/vhdl/units.vhd b/cMIPS/vhdl/units.vhd index e5cb7063313659983c640626f75daf2c0f0c23dd..73a16a7b1f6863eda0a729fa69e1268609450537 100644 --- a/cMIPS/vhdl/units.vhd +++ b/cMIPS/vhdl/units.vhd @@ -254,6 +254,7 @@ begin U_alu: process (A,B, fun, sh_left,sh_right,sh_lft_ins, mask, loc_HI,loc_LO, summ_diff, summ_diff_u, overflow) variable i_C, i_and, i_or: reg32; + variable i_prod : reg64; variable i_move_ok, B_is_zero : std_logic := 'L'; begin @@ -327,6 +328,9 @@ begin else i_C := x"FFFF" & B(15 downto 0); end if; + when opMUL => + i_prod := std_logic_vector(signed(A) * signed(B)); + i_C := i_prod(31 downto 0); when others => i_C := (others => 'X'); end case; @@ -348,6 +352,7 @@ begin port map (add_sub => addition, dataa => A, datab => B, result => summ_diff_u); + U_HILO: process (A,B, fun, loc_HI,loc_LO) variable i_hi,i_lo, i_quoc,i_rem: reg32; variable i_prod : reg64;