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