diff --git a/cMIPS/docs/installCrosscompiler b/cMIPS/docs/installCrosscompiler index 8426561132d0650848a070aee5ed8f65c65b2fd8..88c1e8c87d6025e54b11e2dec4784585134b889e 100644 --- a/cMIPS/docs/installCrosscompiler +++ b/cMIPS/docs/installCrosscompiler @@ -2,8 +2,8 @@ # to compile GCC, these three libraries may have to be fetched: -wget http://www.mpfr.org/mpfr-current/mpfr-3.1.2.tar.gz -wget http://www.multiprecision.org/mpc/download/mpc-1.0.tar.gz +wget http://www.mpfr.org/mpfr-current/mpfr-3.1.3.tar.gz +wget ftp://ftp.gnu.org/gnu/mpc/mpc-1.0.2.tar.gz wget ftp://ftp.gmplib.org/pub/gmp/gmp-6.0.0.tar.bz2 # and, according to instructions in @@ -23,7 +23,7 @@ umask 022 # check the latest version of binutils in http://ftp.gnu.org/gnu/binutils BINUTILS=binutils-2.25 -COMPILER=gcc-4.9.2 +COMPILER=gcc-5.1.0 wget -c http://ftp.gnu.org/gnu/binutils/${BINUTILS}.tar.bz2 wget -c http://ftp.gnu.org/gnu/gcc/${COMPILER}/${COMPILER}.tar.gz @@ -63,10 +63,14 @@ export MANPATH=${MANPATH}:${PREFIX}/man # and that ends the cross-compiler installation. - -# You may also want/need to install GHDL on your machine. As of March, +# You may also want/need to install GHDL on your machine. As of July, # 2015, there is no official Debian package. You must download the # unofficial package from Sourceforge at: # https://sourceforge.net/p/ghdl-updates/wiki/Debian%20Instructions/ # and pick the appropriate version for your computer (32 or 64 bit). - +# +# When doing dpkg -i ghdl*.deb it will complain about versions. +# What I have done is use the following DANGEROUS and RISKY command: +# dpkg --ignore-depends=ghdl*.deb -i ghdl*.deb +# this forces dpkg to ignore the dependencies for GHDL and install it +# with whatever version your machine has for gnat. The risk is yours. diff --git a/cMIPS/include/cMIPS.h b/cMIPS/include/cMIPS.h index 0a425ced8c044542093b4a25261694b5d69023e9..690735c1c45f866b4bc05345c7fa2e030e8d67f8 100644 --- a/cMIPS/include/cMIPS.h +++ b/cMIPS/include/cMIPS.h @@ -37,6 +37,9 @@ extern void startCounter(int, int); extern void stopCounter(void); extern int readCounter(void); +extern void enableInterr(void); +extern void disableInterr(void); + extern char *memcpy(char*, const char*, int); extern char *memset(char*, const int, int); diff --git a/cMIPS/tests/extCounterInt.c b/cMIPS/tests/extCounterInt.c index af0dc93eaaf2ae64280f646e3e205f01da854f18..f9c08e255173d819692c13b4e36876e04f43f3cf 100644 --- a/cMIPS/tests/extCounterInt.c +++ b/cMIPS/tests/extCounterInt.c @@ -7,7 +7,7 @@ #define FALSE (0==1) #define TRUE ~FALSE -extern _counter_val; +extern int _counter_val; int p[MAX]; diff --git a/cMIPS/tests/ll_sc.expected b/cMIPS/tests/ll_sc.expected index 62dee1bece51849f9c574b556bddba6b95de6b3e..76864aa6f952c3f95055a55900761f1eff0db6c8 100644 --- a/cMIPS/tests/ll_sc.expected +++ b/cMIPS/tests/ll_sc.expected @@ -1,19 +1,19 @@ 00000008 -00000001 +s 00000007 -00000001 +s 00000006 -00000001 +s 00000005 00000100 -00000000 -00000001 +s +s 00000003 -00000001 +s 00000002 +s 00000001 -00000001 -00000001 +s 00000000 ffffffff @@ -21,3 +21,7 @@ ffffffff ffffffff ok + +ok + +ok diff --git a/cMIPS/tests/ll_sc.s b/cMIPS/tests/ll_sc.s index b23653f345b677bc8943c79a966dee39fffab64a..02ef481951fde9632f79658522c89dc8560c5074 100644 --- a/cMIPS/tests/ll_sc.s +++ b/cMIPS/tests/ll_sc.s @@ -15,6 +15,7 @@ _start: nop nop j main nop + exit: _exit: nop # flush pipeline nop @@ -51,6 +52,8 @@ main: la $15,x_IO_BASE_ADDR # print $5=8 and count downwards li $6,4 li $t1,0 la $t0, x_DATA_BASE_ADDR + li $s0, 's' + li $s1, '\n' sw $zero, 0($t0) nop loop: sw $5, 0($15) # print-out $5 @@ -71,7 +74,8 @@ L: ll $t1, 0($t0) # load-linked fwd: addi $t2, $t1, 1 # increment value read by LL sc $t2, 0($t0) # try to store, checking for atomicity addiu $t0,$t0,4 # use a new address in each round - sw $t2, 0($15) # prints 0000.0001 if SC succeeds + sw $s0, x_IO_ADDR_RANGE($15) # prints 0000.0001 if SC succeeds + sw $s1, x_IO_ADDR_RANGE($15) # prints 0000.0001 if SC succeeds beq $t2, $zero, L # if not atomic (0), try again, does not print 4 sw $zero, 0($t0) # store zero to new address @@ -84,6 +88,12 @@ fwd: addi $t2, $t1, 1 # increment value read by LL sw $t2, 0($15) nop + li $k1, 0x00000000 # clear CAUSE + mtc0 $k1, cop0_CAUSE + li $k0,0x10000000 # RESET_STATUS, kernel mode, all else disabled + mtc0 $k0,cop0_STATUS + + ## ## do a SC to the same address as ll -- must succeed ## @@ -107,7 +117,6 @@ test1: li $30, '\n' # print a blank line to separate tests lw $a3, 0($t0) sw $a3, 0($15) # print out 0xff - ## ## try to sc to a different adress from ll -- must fail ## @@ -127,7 +136,7 @@ test2: li $30, '\n' # print a blank line to separate tests nop sc $a2, 4($t0) # different address from ll -- must fail - beq $a2, $zero, fail_ok + beq $a2, $zero, did_ok nop succ_nok: # should never come here @@ -135,16 +144,50 @@ succ_nok: # should never come here sw $a2, 0($15) # print out wrong value stored to data[1] beq $a3, $a2, error # sc did change data[1] nop + # sc ought to have failed, which is good - -fail_ok: # sc ought to have failed, which is good - li $30, 'o' +did_ok: jal fail_ok + nop + + ## + ## check forwarding from SC to ALU inputs + ## +fwdadd: li $30, '\n' # print a blank line to separate tests sw $30, x_IO_ADDR_RANGE($15) - li $30, 'k' - sw $30, x_IO_ADDR_RANGE($15) - li $30, '\n' # print a blank line + + la $t0, x_DATA_BASE_ADDR + li $a0, 0xffffffff # store -1 to data[0] + li $a1, 0x88442211 # store 88442211 to data[1] + sw $a0, 0($t0) + sw $a1, 4($t0) # address to store_c != addr to load_l + + ll $a2, 0($t0) + li $a2, 2048-1 # attempt to write 0x03ff to data[0] + sc $a3, 0($t0) # should succeed - a3 := 1 + addi $a3, $a3, -1 + bne $a3, $zero, error + nop + + jal fail_ok + nop + +fwdadd2: + li $30, '\n' # print a blank line to separate tests + sw $30, x_IO_ADDR_RANGE($15) + li $s5, 1 + + ll $a2, 0($t0) + li $a2, 64-1 # attempt to write 0x003f to data[1] + sc $a3, 4($t0) # should fail: a3 <-0 + addi $s6, $a3, 1 # s6 <- 0 + 1 + bne $s5, $s6, error # (0+1) == 1 ? + nop + + jal fail_ok + nop + j exit - sw $30, x_IO_ADDR_RANGE($15) + nop error: li $30, 'e' @@ -152,12 +195,22 @@ error: li $30, 'e' li $30, 'r' sw $30, x_IO_ADDR_RANGE($15) sw $30, x_IO_ADDR_RANGE($15) - li $31, 'o' - sw $31, x_IO_ADDR_RANGE($15) + li $28, 'o' + sw $28, x_IO_ADDR_RANGE($15) sw $30, x_IO_ADDR_RANGE($15) - li $31, '\n' # print a blank line + li $30, '\n' # print a blank line j exit - sw $31, x_IO_ADDR_RANGE($15) - + sw $30, x_IO_ADDR_RANGE($15) + + +fail_ok: + li $30, 'o' + sw $30, x_IO_ADDR_RANGE($15) + li $30, 'k' + sw $30, x_IO_ADDR_RANGE($15) + li $30, '\n' # print a blank line + jr $ra + sw $30, x_IO_ADDR_RANGE($15) + .end main diff --git a/cMIPS/tests/mult.expected b/cMIPS/tests/mult.expected index 417d4f803a5cfde006fae84f17af11a68c6b1ae8..b8afc80b402cd64493cff68478caf0025ce98954 100644 --- a/cMIPS/tests/mult.expected +++ b/cMIPS/tests/mult.expected @@ -18,3 +18,8 @@ 00000024 00000026 00000028 + +00000004 + +00000001 +00000010 diff --git a/cMIPS/tests/mult.s b/cMIPS/tests/mult.s index a5dc5bdcf8497e7ec90acc1899a0494dc26191aa..f5815f4a095c5b5b29b4c293cbb2184dbce0c678 100644 --- a/cMIPS/tests/mult.s +++ b/cMIPS/tests/mult.s @@ -1,20 +1,38 @@ .include "cMIPS.s" .text .align 2 - .set noat - .globl _start + .set noreorder + .globl _start,_exit .ent _start + _start: nop - la $15,x_IO_BASE_ADDR - li $3,1 - li $4,2 -incr: mult $3,$4 + la $15, x_IO_BASE_ADDR + li $3, 1 + li $4, 2 +incr: mult $3, $4 mflo $5 sw $5, 0($15) # print=2,4,6,8,...,x20,x22,x24,x26,x28 - addi $3,$3,1 - slti $22,$5,40 - bne $22,$0,incr + addi $3, $3, 1 + slti $22, $5, 40 + bne $22, $0, incr nop + + li $19, '\n' + sw $19, x_IO_ADDR_RANGE($15) + +multii: addi $4, $zero, 1 + mul $4, 4 # translates to MULT + MFLO + sw $4, 0($15) + + li $19, '\n' + sw $19, x_IO_ADDR_RANGE($15) + +sllii: addi $4, $zero, 1 + sll $5, $4, 4 + sw $4, 0($15) + sw $5, 0($15) + +_exit: nop nop nop nop diff --git a/cMIPS/tests/rand.c b/cMIPS/tests/rand.c index aecc4a91af6f267dae71f358584dc35aa13217f0..58936f24fe7014ed0ec36d0dc29088cf916218b3 100644 --- a/cMIPS/tests/rand.c +++ b/cMIPS/tests/rand.c @@ -20,7 +20,7 @@ #define MAX_NUM 100 #define SHOW (MAX_NUM / 5) -main(){ +void main(void){ int i, above, below, maxdif, newv; int median; diff --git a/cMIPS/vhdl/core.vhd b/cMIPS/vhdl/core.vhd index cd8c84112a0bbd5ecbb6d3965fe3ca1ab297fe03..2367c9cb8b755e71d949380bd163eb5fdbf8e47d 100644 --- a/cMIPS/vhdl/core.vhd +++ b/cMIPS/vhdl/core.vhd @@ -1253,18 +1253,20 @@ begin -- EXECUTION --------------------------------------------- - EX_FORWARDING_ALU: process (EX_a_rs,EX_a_rt,EX_a_c, + EX_FORWARDING_ALU: process (EX_a_rs,EX_a_rt,EX_a_c, EX_A,EX_B, + EX_exception, is_exception, LL_SC_abort_d, MM_a_c,MM_wreg,WB_a_c,WB_wreg, - MM_mfc0,MM_cop0_val, - EX_A,EX_B,MM_result,WB_C) + MM_mfc0,MM_cop0_val, MM_result,WB_C) variable i_A,i_B : reg32; begin FORWARD_A: if ((MM_wreg = '0')and(MM_a_c /= b"00000")and(MM_a_c = EX_a_rs)) then - if not(MM_mfc0) then - i_A := MM_result; - else + if MM_mfc0 then i_A := MM_cop0_val; + elsif is_exception = exSC then + i_A := x"0000000" & b"000" & not(LL_SC_abort_d); + else + i_A := MM_result; end if; elsif ((WB_wreg = '0')and(WB_a_c /= b"00000")and(WB_a_c = EX_a_rs)) then i_A := WB_C; @@ -1275,12 +1277,15 @@ begin -- assert false report -- DEBUG -- "FWD_A: alu_A="&SLV32HEX(alu_inp_A)&" alu_B="&SLV32HEX(alu_fwd_B); + FORWARD_B: if ((MM_wreg = '0')and(MM_a_c /= b"00000")and(MM_a_c = EX_a_rt)) then - if not(MM_mfc0) then - i_B := MM_result; - else + if MM_mfc0 then i_B := MM_cop0_val; + elsif is_exception = exSC then + i_B := x"0000000" & b"000" & not(LL_SC_abort_d); + else + i_B := MM_result; end if; elsif ((WB_wreg = '0')and(WB_a_c /= b"00000")and(WB_a_c = EX_a_rt)) then i_B := WB_C;