From 8955f7fb27f14999634a0d65ba12f5fc315d0f7a Mon Sep 17 00:00:00 2001
From: Roberto Hexsel <roberto@inf.ufpr.br>
Date: Sat, 16 May 2015 19:45:20 -0300
Subject: [PATCH] more TLB tests

---
 cMIPS/include/cMIPS.h            |   2 +-
 cMIPS/include/cMIPS.ld           |   2 +-
 cMIPS/include/cMIPS.s            |   2 +-
 cMIPS/include/start.s            |   1 +
 cMIPS/tests/badVAddrMM.expected  |  10 +-
 cMIPS/tests/doTests.sh           |   2 +-
 cMIPS/tests/lwFWDsw2.expected    |  42 ++---
 cMIPS/tests/mmu_double.s         |  24 ++-
 cMIPS/tests/mmu_inval.s          |   4 +-
 cMIPS/tests/mmu_inval2.expected  |   3 +
 cMIPS/tests/mmu_inval2.s         | 178 +++++++++++++++++++++
 cMIPS/tests/mmu_refill2.expected |   5 +
 cMIPS/tests/mmu_refill2.s        | 263 +++++++++++++++++++++++++++++++
 cMIPS/tests/mmu_tlbwi.expected   |   6 +-
 cMIPS/vhdl/core.vhd              |  50 +++---
 cMIPS/vhdl/packageMemory.vhd     |   3 +-
 16 files changed, 524 insertions(+), 73 deletions(-)
 create mode 100644 cMIPS/tests/mmu_inval2.expected
 create mode 100644 cMIPS/tests/mmu_inval2.s
 create mode 100644 cMIPS/tests/mmu_refill2.expected
 create mode 100644 cMIPS/tests/mmu_refill2.s

diff --git a/cMIPS/include/cMIPS.h b/cMIPS/include/cMIPS.h
index a48386f..0a425ce 100644
--- a/cMIPS/include/cMIPS.h
+++ b/cMIPS/include/cMIPS.h
@@ -1,6 +1,6 @@
 
 #define x_INST_BASE_ADDR 0x00000000
-#define x_DATA_BASE_ADDR 0x04000000
+#define x_DATA_BASE_ADDR 0x00040000
 #define x_IO_BASE_ADDR   0x0F000000
 #define x_IO_MEM_SZ      0x00002000
 #define x_IO_ADDR_RANGE  0x00000020
diff --git a/cMIPS/include/cMIPS.ld b/cMIPS/include/cMIPS.ld
index d698f31..2d76a0e 100644
--- a/cMIPS/include/cMIPS.ld
+++ b/cMIPS/include/cMIPS.ld
@@ -2,7 +2,7 @@ SECTIONS
 {
        . = 0x00000000; /* x_INST_BASE_ADDR */
        .text : { *(.text .text.*) }
-       . = 0x04000000; /* x_DATA_BASE_ADDR */
+       . = 0x00040000; /* x_DATA_BASE_ADDR */
        .data    : { *(.data .data.*) }
        .rodata  : { *(.rodata .rodata.*) }
        .rodata1 : { *(.rodata1) }
diff --git a/cMIPS/include/cMIPS.s b/cMIPS/include/cMIPS.s
index 4fca90a..a325093 100644
--- a/cMIPS/include/cMIPS.s
+++ b/cMIPS/include/cMIPS.s
@@ -3,7 +3,7 @@
         .set x_INST_BASE_ADDR,0x00000000
         .set x_INST_MEM_SZ,0x00004000
 
-        .set x_DATA_BASE_ADDR,0x04000000
+        .set x_DATA_BASE_ADDR,0x00040000
         .set x_DATA_MEM_SZ,0x00004000
 	
         .set x_IO_BASE_ADDR,0x0F000000
diff --git a/cMIPS/include/start.s b/cMIPS/include/start.s
index defb8b4..a15163e 100644
--- a/cMIPS/include/start.s
+++ b/cMIPS/include/start.s
@@ -268,3 +268,4 @@ excp_0200ret:
 	# normal code starts here -- do not edit next line
 	.org x_ENTRY_POINT,0
 
+
diff --git a/cMIPS/tests/badVAddrMM.expected b/cMIPS/tests/badVAddrMM.expected
index e806d1a..26284fb 100644
--- a/cMIPS/tests/badVAddrMM.expected
+++ b/cMIPS/tests/badVAddrMM.expected
@@ -23,19 +23,19 @@
 [
 08800010
 00000358
-04000001
+00040001
 ]
 00000002
 [
 08800010
 00000358
-04000002
+00040002
 ]
 00000001
 [
 08800010
 00000358
-04000003
+00040003
 ]
 00000000
 
@@ -60,13 +60,13 @@
 [
 08800010
 000003f0
-04000001
+00040001
 ]
 00000002
 00000002
 [
 08800010
 00000410
-04000003
+00040003
 ]
 00000001
diff --git a/cMIPS/tests/doTests.sh b/cMIPS/tests/doTests.sh
index eb0b7d0..2c1a368 100755
--- a/cMIPS/tests/doTests.sh
+++ b/cMIPS/tests/doTests.sh
@@ -73,7 +73,7 @@ a_MEM="lwSweepRAM"
 a_CTR="teq_tne tlt_tlti tltu_tgeu eiDI ll_sc overflow"
 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_inval mmu_mod mmu_double"
+a_EXC="mmu_refill mmu_refill2 mmu_inval mmu_inval2 mmu_mod mmu_double"
 
 ## these tests MUST be run with FAKE CACHES
 # a_IOs="kbd7seg" 
diff --git a/cMIPS/tests/lwFWDsw2.expected b/cMIPS/tests/lwFWDsw2.expected
index 058d8bb..5438082 100644
--- a/cMIPS/tests/lwFWDsw2.expected
+++ b/cMIPS/tests/lwFWDsw2.expected
@@ -1,41 +1,41 @@
-04000010
+00040010
 fffffff6
-04000014
+00040014
 fffffff7
-04000018
+00040018
 fffffff8
-0400001c
+0004001c
 fffffff9
-04000020
+00040020
 fffffffa
-04000024
+00040024
 fffffffb
-04000028
+00040028
 fffffffc
-0400002c
+0004002c
 fffffffd
-04000030
+00040030
 fffffffe
-04000034
+00040034
 ffffffff
-04000038
+00040038
 00000000
-0400003c
+0004003c
 00000001
-04000040
+00040040
 00000002
-04000044
+00040044
 00000003
-04000048
+00040048
 00000004
-0400004c
+0004004c
 00000005
-04000050
+00040050
 00000006
-04000054
+00040054
 00000007
-04000058
+00040058
 00000008
-0400005c
+0004005c
 00000009
-04000060
+00040060
diff --git a/cMIPS/tests/mmu_double.s b/cMIPS/tests/mmu_double.s
index a6242e5..656fc7f 100644
--- a/cMIPS/tests/mmu_double.s
+++ b/cMIPS/tests/mmu_double.s
@@ -39,6 +39,8 @@
 	## set STATUS, cop0, no interrupts enabled
 _start:	li   $k0, 0x10000000
         mtc0 $k0, cop0_STATUS
+	li   $k0, MMU_WIRED
+        mtc0 $k0, cop0_Wired
 
 	j main
 	nop
@@ -59,7 +61,7 @@ _excp_100:  mfc0 $k1, cop0_Context
         mtc0 $k0, cop0_EntryLo0    # EntryLo0 <- k0 = even element
         mtc0 $k1, cop0_EntryLo1    # EntryLo1 <- k1 = odd element
         ehb
-        tlbwr                      # update TLB
+        tlbwi                      # write indexed for not overwriting PTable
 	li   $30, 't'
 	sw   $30, x_IO_ADDR_RANGE($20)	
 	li   $30, 'h'
@@ -103,8 +105,8 @@ _excp_180: tlbp         # probe for the guilty entry
         li   $30, '\n'
         sw   $30, x_IO_ADDR_RANGE($20)
 
-        eret
-        .end _excp_180
+        eret			# return to EPC saved on the first fault
+        .end _excp_180		#   the second fault refills TLB
 
 	
 	##
@@ -138,15 +140,13 @@ main:	la   $20, x_IO_BASE_ADDR
 	tlbr
 
 	mfc0 $6, cop0_EntryLo0
-	# sw   $6, 0($20)
 	mfc0 $7, cop0_EntryLo1
-	# sw   $7, 0($20)
 
 	# 1st entry: PPN0 & PPN1 ROM
 	sw  $6, 0($4)
 	sw  $0, 4($4)
 	sw  $7, 8($4)
-	sw  $0, 12($4)
+	sw  $0, 0xc($4)
 
 	li $5, 7              # 2nd ROM mapping
 	mtc0 $5, cop0_Index
@@ -154,15 +154,13 @@ main:	la   $20, x_IO_BASE_ADDR
 	tlbr
 
 	mfc0 $6, cop0_EntryLo0
-	# sw   $6, 0($20)
 	mfc0 $7, cop0_EntryLo1
-	# sw   $7, 0($20)
 
 	# 2nd entry: PPN2 & PPN3 ROM
-	sw  $6, 16($4)
-	sw  $0, 20($4)
-	sw  $7, 24($4)
-	sw  $0, 28($4)
+	sw  $6, 0x10($4)
+	sw  $0, 0x14($4)
+	sw  $7, 0x18($4)
+	sw  $0, 0x1c($4)
 
 	# load Context with PTbase
 	mtc0 $4, cop0_Context
@@ -173,9 +171,7 @@ main:	la   $20, x_IO_BASE_ADDR
 	sll  $9, $9, 8
 
 	mfc0 $8, cop0_EntryHi
-	
 	add  $8, $9, $8     # change tag
-
 	mtc0 $8, cop0_EntryHi
 
 	tlbwi		    # and write it back to TLB
diff --git a/cMIPS/tests/mmu_inval.s b/cMIPS/tests/mmu_inval.s
index 31f3fb6..5334859 100644
--- a/cMIPS/tests/mmu_inval.s
+++ b/cMIPS/tests/mmu_inval.s
@@ -53,8 +53,8 @@ _start:	li   $k0, 0x10000000
         .set noreorder
         .set noat
 
-	## EntryHi holds VPN2(31..13), probe the TLB for the offending entry
-excp:
+
+excp:			# EntryHi holds VPN2(31..13)
 _excp:	tlbp		# probe for the guilty entry
 
 	nop
diff --git a/cMIPS/tests/mmu_inval2.expected b/cMIPS/tests/mmu_inval2.expected
new file mode 100644
index 0000000..32e5a88
--- /dev/null
+++ b/cMIPS/tests/mmu_inval2.expected
@@ -0,0 +1,3 @@
+there
+and back again
+
diff --git a/cMIPS/tests/mmu_inval2.s b/cMIPS/tests/mmu_inval2.s
new file mode 100644
index 0000000..6461141
--- /dev/null
+++ b/cMIPS/tests/mmu_inval2.s
@@ -0,0 +1,178 @@
+	##
+	## Perform a store to a clean page, then set the mapping as dirty
+	##
+	##
+	## EntryHi     : EntryLo0           : EntryLo1
+	## VPN2 g ASID : PPN0 ccc0 d0 v0 g0 : PPN1 ccc1 d1 v1 g1
+
+	.include "cMIPS.s"
+
+	.set MMU_WIRED,    2  ### do not change mapping for base of ROM, I/O
+
+        # New entries cannot overwrite tlb[0,1] which map base of ROM, I/O
+
+        # EntryHi cannot have an ASID different from zero, otw TLB misses
+        .set entryHi_1,  0x00012000 #                 pfn0  zzcc cdvg
+        .set entryLo0_1, 0x0000091b #  x0 x0 x0 x0 x0 1001  0001 1011 x91b
+        .set entryLo1_1, 0x00000c1b #  x0 x0 x0 x0 x0 1100  0001 1011 xc1b
+
+        .set entryHi_2,  0x00014000 #                 pfn0  zzcc cdvg
+        .set entryLo0_2, 0x00001016 #  x0 x0 x0 x0 x1 0000  0001 0110 x1016
+        .set entryLo1_2, 0x0000141e #  x0 x0 x0 x0 x1 0100  0001 1110 x141e
+
+        .set entryHi_3,  0x00016000 #                 pfn0  zzcc cdvg
+        .set entryLo0_3, 0x0000191f #  x0 x0 x0 x0 x1 1001  0001 1111 x191f
+        .set entryLo1_3, 0x00001d3f #  x0 x0 x0 x0 x1 1101  0011 1111 x1d3f
+
+        .set entryHi_4,  0x00018000 #                 pfn0  zzcc cdvg
+        .set entryLo0_4, 0x00000012 #  x0 x0 x0 x0 x0 0000  0001 0010 x12
+        .set entryLo1_4, 0x00000412 #  x0 x0 x0 x0 x0 0100  0001 0010 x412
+
+	.text
+	.align 2
+	.set noreorder
+	.set noat
+	.org x_INST_BASE_ADDR,0
+	.globl _start
+	.ent _start
+
+	## set STATUS, cop0, no interrupts enabled
+_start:	li   $k0, 0x10000000
+        mtc0 $k0, cop0_STATUS
+
+	j main
+	nop
+	.end _start
+	
+	##
+        ##================================================================
+        ## general exception vector_0180
+        ##
+        .org x_EXCEPTION_0180,0
+        .ent _excp
+        .set noreorder
+        .set noat
+
+
+excp:			# EntryHi holds VPN2(31..13)
+_excp:	tlbp		# probe for the guilty entry
+
+	nop
+
+	tlbr		# it will surely hit, just use Index to point at it
+
+	mfc0 $k1, cop0_EntryLo0
+
+	ori  $k1, $k1, 0x0002	# make V=1
+
+	mtc0 $k1, cop0_EntryLo0
+
+	tlbwi			# write entry back
+
+	li   $30, 't'
+	sw   $30, x_IO_ADDR_RANGE($20)
+	li   $30, 'h'
+	sw   $30, x_IO_ADDR_RANGE($20)
+	li   $30, 'e'
+	sw   $30, x_IO_ADDR_RANGE($20)
+	li   $30, 'r'
+	sw   $30, x_IO_ADDR_RANGE($20)
+	li   $30, 'e'
+	sw   $30, x_IO_ADDR_RANGE($20)
+	li   $30, '\n'
+	sw   $30, x_IO_ADDR_RANGE($20)
+
+	eret
+        .end _excp
+
+	##
+        ##================================================================
+        ## normal code starts here
+	##
+        .org x_ENTRY_POINT,0
+
+	.ent main
+main:	la   $20, x_IO_BASE_ADDR
+
+
+	## read tlb[5] (2nd RAM mapping) and clear the V bit
+	li $5, 5
+	mtc0 $5, cop0_Index
+
+	tlbr
+
+	mfc0 $6, cop0_EntryLo0
+	
+	addi $7, $zero, -3      # 0xffff.fffd = 1111.1111.1111.1011
+	and  $8, $7, $6		# clear D bit
+
+	mtc0 $8, cop0_EntryLo0
+	
+	mfc0 $9, cop0_EntryHi
+
+	tlbwi			# write entry back to TLB
+
+	
+	## cause an exception by writing to that same page 
+	
+	la  $10, 0xffffe000	# mask off non-VPN bits
+	and $10, $10, $9
+	bne $10, $zero, dest	# cause exception at branch delay slot
+	sw  $1, 16($10)
+
+	li   $30, '@'
+	sw   $30, x_IO_ADDR_RANGE($20)
+	sw   $30, x_IO_ADDR_RANGE($20)
+	sw   $30, x_IO_ADDR_RANGE($20)
+	li   $30, '\n'
+	sw   $30, x_IO_ADDR_RANGE($20)
+
+	nop
+dest:	nop
+	
+	
+	li   $30, 'a'
+	sw   $30, x_IO_ADDR_RANGE($20)
+	li   $30, 'n'
+	sw   $30, x_IO_ADDR_RANGE($20)
+	li   $30, 'd'
+	sw   $30, x_IO_ADDR_RANGE($20)
+	li   $30, ' '
+	sw   $30, x_IO_ADDR_RANGE($20)
+	li   $30, 'b'
+	sw   $30, x_IO_ADDR_RANGE($20)
+	li   $30, 'a'
+	sw   $30, x_IO_ADDR_RANGE($20)
+	li   $30, 'c'
+	sw   $30, x_IO_ADDR_RANGE($20)
+	li   $30, 'k'
+	sw   $30, x_IO_ADDR_RANGE($20)
+	li   $30, ' '
+	sw   $30, x_IO_ADDR_RANGE($20)
+	li   $30, 'a'
+	sw   $30, x_IO_ADDR_RANGE($20)
+	li   $30, 'g'
+	sw   $30, x_IO_ADDR_RANGE($20)
+	li   $30, 'a'
+	sw   $30, x_IO_ADDR_RANGE($20)
+	li   $30, 'i'
+	sw   $30, x_IO_ADDR_RANGE($20)
+	li   $30, 'n'
+	sw   $30, x_IO_ADDR_RANGE($20)
+	li   $30, '\n'
+	sw   $30, x_IO_ADDR_RANGE($20)
+	sw   $30, x_IO_ADDR_RANGE($20)
+
+	
+	nop
+	nop
+        nop
+	nop
+	nop
+        nop
+        wait
+	nop
+	nop
+
+	.end main
+
diff --git a/cMIPS/tests/mmu_refill2.expected b/cMIPS/tests/mmu_refill2.expected
new file mode 100644
index 0000000..3750498
--- /dev/null
+++ b/cMIPS/tests/mmu_refill2.expected
@@ -0,0 +1,5 @@
+here
+here
+there
+and back again
+
diff --git a/cMIPS/tests/mmu_refill2.s b/cMIPS/tests/mmu_refill2.s
new file mode 100644
index 0000000..7fff9e9
--- /dev/null
+++ b/cMIPS/tests/mmu_refill2.s
@@ -0,0 +1,263 @@
+	##
+	## Cause a TLB miss on a LOAD, then copy a mapping from page table
+	##   cause a second miss by overwriting TLB[7] which maps ROM
+	##
+	## faulting LOAD is on a branch delay slot
+	##
+	## EntryHi     : EntryLo0           : EntryLo1
+	## VPN2 g ASID : PPN0 ccc0 d0 v0 g0 : PPN1 ccc1 d1 v1 g1
+
+	.include "cMIPS.s"
+
+        # New entries cannot overwrite tlb[0,1] which map base of ROM, I/O
+
+        # EntryHi cannot have an ASID different from zero, otw TLB misses
+        .set entryHi_1,  0x00012000 #                 pfn0  zzcc cdvg
+        .set entryLo0_1, 0x0000091b #  x0 x0 x0 x0 x0 1001  0001 1011 x91b
+        .set entryLo1_1, 0x00000c1b #  x0 x0 x0 x0 x0 1100  0001 1011 xc1b
+
+        .set entryHi_2,  0x00014000 #                 pfn0  zzcc cdvg
+        .set entryLo0_2, 0x00001016 #  x0 x0 x0 x0 x1 0000  0001 0110 x1016
+        .set entryLo1_2, 0x0000141e #  x0 x0 x0 x0 x1 0100  0001 1110 x141e
+
+        .set entryHi_3,  0x00016000 #                 pfn0  zzcc cdvg
+        .set entryLo0_3, 0x0000191f #  x0 x0 x0 x0 x1 1001  0001 1111 x191f
+        .set entryLo1_3, 0x00001d3f #  x0 x0 x0 x0 x1 1101  0011 1111 x1d3f
+
+        .set entryHi_4,  0x00018000 #                 pfn0  zzcc cdvg
+        .set entryLo0_4, 0x00000012 #  x0 x0 x0 x0 x0 0000  0001 0010 x12
+        .set entryLo1_4, 0x00000412 #  x0 x0 x0 x0 x0 0100  0001 0010 x412
+
+	.set MMU_WIRED,  2  ### do not change mapping for base of ROM, I/O
+	
+	.text
+	.align 2
+	.set noreorder
+	.set noat
+	.org x_INST_BASE_ADDR,0
+	.globl _start
+	.ent _start
+
+	## set STATUS, cop0, no interrupts enabled
+_start:	li   $k0, 0x10000000
+        mtc0 $k0, cop0_STATUS
+
+	li   $k0, MMU_WIRED
+	mtc0 $k0, cop0_Wired
+
+	j main
+	nop
+	.end _start
+	
+	##
+        ##================================================================
+        ## exception vector_0000 TLBrefill, from See MIPS Run pg 145
+        ##
+        .org x_EXCEPTION_0000,0
+        .ent _excp
+        .set noreorder
+        .set noat
+
+_excp:  mfc0 $k1, cop0_Context
+        lw   $k0, 0($k1)           # k0 <- TP[Context.lo]
+        lw   $k1, 8($k1)           # k1 <- TP[Context.hi]
+        mtc0 $k0, cop0_EntryLo0    # EntryLo0 <- k0 = even element
+        mtc0 $k1, cop0_EntryLo1    # EntryLo1 <- k1 = odd element
+	##
+	## cause another miss on 2nd ROM mapping
+	##
+	li   $k0, 7		   
+	mtc0 $k0, cop0_Index
+	ehb
+        tlbwi                      # update TLB
+	li   $30, 'h'
+	sw   $30, x_IO_ADDR_RANGE($20)	
+	li   $30, 'e'
+	sw   $30, x_IO_ADDR_RANGE($20)	
+	li   $30, 'r'
+	sw   $30, x_IO_ADDR_RANGE($20)	
+	li   $30, 'e'
+	sw   $30, x_IO_ADDR_RANGE($20)	
+	li   $30, '\n'
+	sw   $30, x_IO_ADDR_RANGE($20)	
+	eret
+        .end _excp
+
+	##
+        ##================================================================
+        ## normal code starts here
+	##
+        .org x_ENTRY_POINT,0
+
+	
+	## dirty trick: there is not enough memory for a full PT, thus
+	##   we set the PT at the bottom of RAM addresses and have
+	##   Context pointing into that address range
+
+	.set PTbase, x_DATA_BASE_ADDR
+	.ent main
+main:	la   $20, x_IO_BASE_ADDR
+	
+	##
+	## setup a PageTable
+	##
+	## 16 bytes per entry:  
+	## EntryLo0                     : EntryLo1
+	## PPN0 ccc0 d0 v0 g0 0000.0000 : PPN1 ccc1 d1 v1 g1 0000.0000
+	##
+
+	# load Context with PTbase
+	la   $4, PTbase
+	mtc0 $4, cop0_Context
+	
+	# 1st entry: PPN0 & PPN1 ROM
+	li   $5, 0            # 1st ROM mapping
+	mtc0 $5, cop0_Index
+	nop
+	tlbr
+
+	mfc0 $6, cop0_EntryLo0
+	# sw   $6, 0($20)
+	mfc0 $7, cop0_EntryLo1
+	# sw   $7, 0($20)
+
+	sw  $6, 0x0($4)
+	sw  $0, 0x4($4)
+	sw  $7, 0x8($4)
+	sw  $0, 0xc($4)
+
+	
+	# 2nd entry: PPN2 & PPN3 ROM
+	li $5, 7              # 2nd ROM mapping
+	mtc0 $5, cop0_Index
+	nop
+	tlbr
+
+	mfc0 $6, cop0_EntryLo0
+	# sw   $6, 0($20)
+	mfc0 $7, cop0_EntryLo1
+	# sw   $7, 0($20)
+
+
+	sw  $6, 0x10($4)
+	sw  $0, 0x14($4)
+	sw  $7, 0x18($4)
+	sw  $0, 0x1c($4)
+
+
+	# 1024th entry: PPN4 & PPN5 RAM
+	li   $5, 6           # 3rd RAM mapping
+	mtc0 $5, cop0_Index
+	nop
+	tlbr
+
+	mfc0 $6, cop0_EntryLo0
+	# sw   $6, 0($20)
+	mfc0 $7, cop0_EntryLo1
+	# sw   $7, 0($20)
+
+	.set ram6_displ,((x_DATA_BASE_ADDR + 6*4096)>>(13-4)) ## num(VPN2)*16
+
+	# li $1, ram6_displ
+	# sw $1, 0($20)
+	
+	sw  $6, ram6_displ+0($4)
+	sw  $0, ram6_displ+4($4)
+	sw  $7, ram6_displ+8($4)
+	sw  $0, ram6_displ+12($4)
+	
+	
+	## change mapping for 3rd RAM TLB entry, thus causing a miss
+
+	li   $9, 0x8000
+	sll  $9, $9, 8
+
+	mfc0 $8, cop0_EntryHi
+	add  $8, $9, $8     # change tag
+	mtc0 $8, cop0_EntryHi
+
+	tlbwi		    # and write it back to TLB (Index = 6)
+
+	##
+	## cause miss on the load in the delay slot - miss on 6th RAM page
+	##
+	li  $15, (x_DATA_BASE_ADDR + 6*4096) # VPN2
+		
+last:	jal there
+	lw  $16, 0($15)
+
+	
+	li   $30, 'a'
+	sw   $30, x_IO_ADDR_RANGE($20)
+	li   $30, 'n'
+	sw   $30, x_IO_ADDR_RANGE($20)
+	li   $30, 'd'
+	sw   $30, x_IO_ADDR_RANGE($20)
+	li   $30, ' '
+	sw   $30, x_IO_ADDR_RANGE($20)
+	li   $30, 'b'
+	sw   $30, x_IO_ADDR_RANGE($20)
+	li   $30, 'a'
+	sw   $30, x_IO_ADDR_RANGE($20)
+	li   $30, 'c'
+	sw   $30, x_IO_ADDR_RANGE($20)
+	li   $30, 'k'
+	sw   $30, x_IO_ADDR_RANGE($20)
+	li   $30, ' '
+	sw   $30, x_IO_ADDR_RANGE($20)
+	li   $30, 'a'
+	sw   $30, x_IO_ADDR_RANGE($20)
+	li   $30, 'g'
+	sw   $30, x_IO_ADDR_RANGE($20)
+	li   $30, 'a'
+	sw   $30, x_IO_ADDR_RANGE($20)
+	li   $30, 'i'
+	sw   $30, x_IO_ADDR_RANGE($20)
+	li   $30, 'n'
+	sw   $30, x_IO_ADDR_RANGE($20)
+	li   $30, '\n'
+	sw   $30, x_IO_ADDR_RANGE($20)
+	sw   $30, x_IO_ADDR_RANGE($20)
+
+	
+	nop
+	nop
+        nop
+	nop
+	nop
+        nop
+        wait
+	nop
+	nop
+
+	
+	.org (x_INST_BASE_ADDR + 2*4096), 0
+
+there:	li   $30, 't'
+	sw   $30, x_IO_ADDR_RANGE($20)
+	li   $30, 'h'
+	sw   $30, x_IO_ADDR_RANGE($20)
+	li   $30, 'e'
+	sw   $30, x_IO_ADDR_RANGE($20)
+	li   $30, 'r'
+	sw   $30, x_IO_ADDR_RANGE($20)
+	li   $30, 'e'
+	sw   $30, x_IO_ADDR_RANGE($20)
+	li   $30, '\n'
+	sw   $30, x_IO_ADDR_RANGE($20)
+
+	jr   $31
+	nop
+	
+	
+	nop
+	nop
+        nop
+	nop
+	nop
+        nop
+        wait
+	nop
+	nop
+	.end main
+
diff --git a/cMIPS/tests/mmu_tlbwi.expected b/cMIPS/tests/mmu_tlbwi.expected
index d445911..58187be 100644
--- a/cMIPS/tests/mmu_tlbwi.expected
+++ b/cMIPS/tests/mmu_tlbwi.expected
@@ -28,9 +28,9 @@
 0000091b
 00000c1b
 6
-04006000
-00100187
-001001c7
+00046000
+00001187
+000011c7
 7
 00002000
 00000087
diff --git a/cMIPS/vhdl/core.vhd b/cMIPS/vhdl/core.vhd
index 5fbae21..7651494 100644
--- a/cMIPS/vhdl/core.vhd
+++ b/cMIPS/vhdl/core.vhd
@@ -158,7 +158,7 @@ architecture rtl of core is
   signal exception,EX_exception,is_exception : exception_type := exNOP;
   signal ExcCode : reg5 := cop0code_NULL;
   signal exception_num,exception_dec,TLB_excp_num : integer; -- for debugging only
-  signal next_instr_in_delay_slot,EX_is_delayslot : std_logic;
+  signal next_instr_in_delay_slot,EX_is_delayslot, is_delayslot : std_logic;
   signal cop0_sel, EX_cop0_sel, epc_source : reg3;
   signal cop0_reg,EX_cop0_reg : reg5;
   signal cop0_inp, RF_cop0_val,EX_cop0_val,MM_cop0_val,WB_cop0_val : reg32;
@@ -204,7 +204,6 @@ architecture rtl of core is
   signal tlb_dat4_1, tlb_dat5_1, tlb_dat6_1, tlb_dat7_1 : mmu_dat_reg;
 
   signal tlb_entryLo0, tlb_entryLo1, phy_i_addr, phy_d_addr : reg32;
-  signal tlb_context_inp : std_logic_vector(VABITS-1 downto PAGE_SZ_BITS+1);
   
   -- other components ------------ 
   
@@ -1669,6 +1668,9 @@ begin
 
   -- EX execute exception ---------------------------------------------
 
+  U_HOLD_DELAY_SLOT: FFD port map (clk,rst,'1',EX_is_delayslot, is_delayslot);
+
+  
   -- check for overflow in EX, send it to MM for later processing
   ex_trapped <= '1' when (EX_can_trap = b"10" and ovfl = '1') else '0';
 
@@ -1686,7 +1688,7 @@ begin
   COP0_DECODE_EXCEPTION_AND_UPDATE_STATUS:
   process (EX_a_rt, is_exception, EX_trap_instr, 
            EX_cop0_reg, EX_cop0_sel, EX_nmi, EX_interrupt,EX_int_req,
-           next_instr_in_delay_slot, EX_is_delayslot,
+           next_instr_in_delay_slot, EX_is_delayslot, is_delayslot,
            cop0_inp, EX_tr_is_equal, EX_tr_less_than,
            INDEX, RANDOM, EntryLo0, EntryLo1, CONTEXT, PAGEMASK, WIRED,
            EntryHi, COUNT, COMPARE, STATUS, CAUSE, EPC, BadVAddr,
@@ -1891,12 +1893,12 @@ begin
           ExcCode <= cop0code_AdEL;
         end if;
         if is_exception = IFaddressError then
-          i_nullify       := '1';       -- nullify instructions in IF,RF
+          i_nullify := '1';             -- nullify instructions in IF,RF
         end if;
-        i_epc_source    := b"010";      -- bad address is in EXCP_EX_PC
+        i_epc_source := b"010";         -- bad address is in EXCP_EX_PC
         
       when exEHB =>                     -- stall processor to clear hazards
-        i_stall    := '1';
+        i_stall := '1';
 
 
       when exTLBP | exTLBR | exTLBWI | exTLBWR =>  -- TLB access
@@ -1915,17 +1917,17 @@ begin
             end if;
           when exTLBrefillRD =>
             ExcCode <= cop0code_TLBL;
-            if EX_is_delayslot = '1' then   -- instr is in delay slot
-              i_epc_source := b"010";       -- EX_PC, re-execute branch/jump
+            if is_delayslot = '1' then      -- instr is in delay slot
+              i_epc_source := b"011";       -- EX_PC, re-execute branch/jump
             else
-              i_epc_source := b"001";       -- RF_PC
+              i_epc_source := b"010";       -- RF_PC
             end if;
           when exTLBrefillWR =>
             ExcCode <= cop0code_TLBS;
-            if EX_is_delayslot = '1' then   -- instr is in delay slot
-              i_epc_source := b"010";       -- EX_PC, re-execute branch/jump
+            if is_delayslot = '1' then      -- instr is in delay slot
+              i_epc_source := b"011";       -- EX_PC, re-execute branch/jump
             else
-              i_epc_source := b"001";       -- RF_PC
+              i_epc_source := b"010";       -- RF_PC
             end if;
           when others => null;
         end case;
@@ -1949,21 +1951,21 @@ begin
             end if;
           when exTLBinvalRD | exTLBdblFaultRD =>
             ExcCode <= cop0code_TLBL;
-            if EX_is_delayslot = '1' then   -- instr is in delay slot
+            if is_delayslot = '1' then      -- instr is in delay slot
               i_epc_source := b"011";       -- MM_PC, re-execute branch/jump
             else
               i_epc_source := b"010";       -- EX_PC
             end if;
           when exTLBinvalWR | exTLBdblFaultWR =>
             ExcCode <= cop0code_TLBS;
-            if EX_is_delayslot = '1' then   -- instr is in delay slot
+            if is_delayslot = '1' then      -- instr is in delay slot
               i_epc_source := b"011";       -- MM_PC, re-execute branch/jump
             else
               i_epc_source := b"010";       -- EX_PC
             end if;
           when exTLBmod =>
             ExcCode <= cop0code_Mod;
-            if EX_is_delayslot = '1' then   -- instr is in delay slot
+            if is_delayslot = '1' then      -- instr is in delay slot
               i_epc_source := b"011";       -- MM_PC, re-execute branch/jump
             else
               i_epc_source := b"010";       -- EX_PC
@@ -2320,15 +2322,19 @@ begin
   context_upd_pte <= '0' when (update = '1' and update_reg = cop0reg_Context)
                      else '1';
 
-  MMU_ContextPTE: registerN generic map(9, ContextPTE_init)
+  -- MMU_ContextPTE: registerN generic map(9, ContextPTE_init)
+  --   port map (clk, rst, context_upd_pte,
+  --             cop0_inp(31 downto 23), Context(31 downto 23));
+  MMU_ContextPTE: registerN generic map(14, b"00000000000000")
     port map (clk, rst, context_upd_pte,
-              cop0_inp(31 downto 23), Context(31 downto 23));
+              cop0_inp(31 downto 18), Context(31 downto 18));
 
   context_upd_bad <= '0' when tlb_exception else '1';
-  tlb_context_inp <= tlb_excp_VA;
   
-  MMU_ContextBAD: registerN generic map(19, b"0000000000000000000")
-    port map (clk, rst, context_upd_bad, tlb_context_inp, Context(22 downto 4));
+  -- MMU_ContextBAD: registerN generic map(19, b"0000000000000000000")
+  --   port map (clk, rst, context_upd_bad, tlb_context_inp, Context(22 downto 4));
+  MMU_ContextBAD: registerN generic map(14, b"00000000000000")
+    port map (clk, rst, context_upd_bad, tlb_excp_VA(VA_HI_BIT-5 downto VA_LO_BIT), Context(17 downto 4));
 
   Context(3 downto 0) <= b"0000";
 
@@ -2403,7 +2409,7 @@ begin
     elsif hit_mm then
 
       if (EX_aVal = '0' and hit_mm_v = '0') then      -- check for TLBinvalid
-        if EX_aVal = '0' then
+        if EX_wrmem = '0' then
           TLB_excp_type <= exTLBinvalWR;
         else
           TLB_excp_type <= exTLBinvalRD;
@@ -2725,7 +2731,7 @@ begin
     port map (clk, rst, tlb_tag6_updt, tlb_tag_inp, tlb_tag6);
 
   MMU_DAT6_0: registerN generic map(DAT_REG_BITS, MMU_ini_dat_RAM6)  -- d=1,v=1,g=1
-    port map (clk, rst, tlb_dat6_updt, tlb_dat1_inp, tlb_dat6_0);
+    port map (clk, rst, tlb_dat6_updt, tlb_dat0_inp, tlb_dat6_0);
   MMU_DAT6_1: registerN generic map(DAT_REG_BITS, MMU_ini_dat_RAM7)  -- d=1,v=1,g=1
     port map (clk, rst, tlb_dat6_updt, tlb_dat1_inp, tlb_dat6_1);
 
diff --git a/cMIPS/vhdl/packageMemory.vhd b/cMIPS/vhdl/packageMemory.vhd
index 5df5092..16999ef 100644
--- a/cMIPS/vhdl/packageMemory.vhd
+++ b/cMIPS/vhdl/packageMemory.vhd
@@ -42,7 +42,7 @@ package p_MEMORY is
   --  you may change the values, not names nor formatting              --
   constant x_INST_BASE_ADDR : reg32   := x"00000000";
   constant x_INST_MEM_SZ    : reg32   := x"00004000";  
-  constant x_DATA_BASE_ADDR : reg32   := x"04000000";  
+  constant x_DATA_BASE_ADDR : reg32   := x"00040000";  
   constant x_DATA_MEM_SZ    : reg32   := x"00004000";
   constant x_IO_BASE_ADDR   : reg32   := x"0F000000";
   constant x_IO_MEM_SZ      : reg32   := x"00002000";
@@ -294,7 +294,6 @@ package p_MEMORY is
    x_IO_PPN_1(PABITS-1 downto PAGE_SZ_BITS) & b"000111"; -- d,v,g=1
 
   
-  -- constant mmu_PageMask : reg32 := x"00000000";  -- pg 68, 1k pages only
   constant mmu_PageMask : reg32 := x"00001800";  -- pg 68, 4k pages only
 
   
-- 
GitLab