diff --git a/sim/coverage b/sim/coverage new file mode 100755 index 000000000..038253911 --- /dev/null +++ b/sim/coverage @@ -0,0 +1,2 @@ +# recompile coverage tests and run coverage including them +pushd $WALLY/tests/coverage; make; popd; ./regression-wally -coverage diff --git a/sim/wave.do b/sim/wave.do index 6fd560251..047a0b163 100644 --- a/sim/wave.do +++ b/sim/wave.do @@ -65,14 +65,20 @@ add wave -noupdate -group {Execution Stage} /testbench/dut/core/ifu/PCE add wave -noupdate -group {Execution Stage} /testbench/dut/core/ifu/InstrE add wave -noupdate -group {Execution Stage} /testbench/InstrEName add wave -noupdate -group {Execution Stage} /testbench/dut/core/ieu/c/InstrValidE +add wave -noupdate -group {Execution Stage} /testbench/dut/core/ieu/dp/SrcAE +add wave -noupdate -group {Execution Stage} /testbench/dut/core/ieu/dp/SrcBE +add wave -noupdate -group {Execution Stage} /testbench/dut/core/ieu/dp/ALUResultE add wave -noupdate -expand -group {Memory Stage} /testbench/FunctionName/FunctionName/FunctionName add wave -noupdate -expand -group {Memory Stage} /testbench/dut/core/InstrValidM add wave -noupdate -expand -group {Memory Stage} /testbench/dut/core/PCM add wave -noupdate -expand -group {Memory Stage} /testbench/dut/core/InstrM add wave -noupdate -expand -group {Memory Stage} /testbench/InstrMName add wave -noupdate -expand -group {Memory Stage} /testbench/dut/core/lsu/IEUAdrM +add wave -noupdate -expand -group lsu /testbench/dut/core/lsu/ReadDataM +add wave -noupdate -expand -group lsu /testbench/dut/core/lsu/WriteDataM add wave -noupdate -group {WriteBack stage} /testbench/InstrW add wave -noupdate -group {WriteBack stage} /testbench/InstrWName +add wave -noupdate -group {Execution Stage} /testbench/dut/core/ieu/dp/ResultW add wave -noupdate -group CSRs /testbench/dut/core/priv/priv/csr/csrm/MCAUSE_REGW add wave -noupdate -group CSRs /testbench/dut/core/priv/priv/csr/MCOUNTEREN_REGW add wave -noupdate -group CSRs /testbench/dut/core/priv/priv/csr/MCOUNTINHIBIT_REGW diff --git a/src/cache/cachefsm.sv b/src/cache/cachefsm.sv index 124b92678..770579b67 100644 --- a/src/cache/cachefsm.sv +++ b/src/cache/cachefsm.sv @@ -106,8 +106,7 @@ module cachefsm import cvw::*; #(parameter cvw_t P, assign FlushFlag = FlushAdrFlag & FlushWayFlag; // outputs for the performance counters. - assign CacheAccess = (|CacheRW) & ((CurrState == STATE_READY & ~Stall & ~FlushStage) | - (CurrState == STATE_READ_HOLD & ~Stall & ~FlushStage)); // exclusion-tag: icache CacheW + assign CacheAccess = (|CacheRW) & ((CurrState == STATE_READY & ~Stall & ~FlushStage) | (CurrState == STATE_READ_HOLD & ~Stall & ~FlushStage)); // exclusion-tag: icache CacheW assign CacheMiss = CacheAccess & ~CacheHit; // special case on reset. When the fsm first exists reset the diff --git a/src/ieu/controller.sv b/src/ieu/controller.sv index e923f1e3f..32fdba23e 100644 --- a/src/ieu/controller.sv +++ b/src/ieu/controller.sv @@ -182,7 +182,6 @@ module controller import cvw::*; #(parameter cvw_t P) ( ((P.ZICBOZ_SUPPORTED & InstrD[31:20] == 12'd4 & ENVCFG_CBE[3]) | (P.ZICBOM_SUPPORTED & ((InstrD[31:20] == 12'd0 & (ENVCFG_CBE[1:0] != 2'b00))) | (InstrD[31:20] == 12'd1 | InstrD[31:20] == 12'd2) & ENVCFG_CBE[2])); - // *** need to get with enable bits such as MENVCFG_CBZE assign AFunctD = (Funct3D == 3'b010) | (P.XLEN == 64 & Funct3D == 3'b011); assign AMOFunctD = (InstrD[31:27] == 5'b00001) | (InstrD[31:27] == 5'b00000) | diff --git a/src/mmu/pmachecker.sv b/src/mmu/pmachecker.sv index ce129af51..119e88d8c 100644 --- a/src/mmu/pmachecker.sv +++ b/src/mmu/pmachecker.sv @@ -57,13 +57,13 @@ module pmachecker import cvw::*; #(parameter cvw_t P) ( adrdecs #(P) adrdecs(PhysicalAddress, AccessRW, AccessRX, AccessRWX, Size, SelRegions); // Only non-core RAM/ROM memory regions are cacheable. PBMT can override cachable; NC and IO are uncachable - assign CacheableRegion = SelRegions[8] | SelRegions[7] | SelRegions[6]; - assign Cacheable = (PBMemoryType == 2'b00) ? CacheableRegion : 0; // exclusion-tag: unused-cachable + assign CacheableRegion = SelRegions[8] | SelRegions[7] | SelRegions[6]; // exclusion-tag: unused-cachable + assign Cacheable = (PBMemoryType == 2'b00) ? CacheableRegion : 0; // Nonidemdempotent means access could have side effect and must not be done speculatively or redundantly // I/O is nonidempotent. PBMT can override PMA; NC is idempotent and IO is non-idempotent - assign IdempotentRegion = SelRegions[10] | SelRegions[9] | SelRegions[8] | SelRegions[7] | SelRegions[6]; - assign Idempotent = (PBMemoryType == 2'b00) ? IdempotentRegion : (PBMemoryType == 2'b01); // exclusion-tag: unused-idempotent + assign IdempotentRegion = SelRegions[10] | SelRegions[9] | SelRegions[8] | SelRegions[7] | SelRegions[6]; // exclusion-tag: unused-idempotent + assign Idempotent = (PBMemoryType == 2'b00) ? IdempotentRegion : (PBMemoryType == 2'b01); // Atomic operations are only allowed on RAM assign AtomicAllowed = SelRegions[10] | SelRegions[8] | SelRegions[6]; // exclusion-tag: unused-atomic diff --git a/src/mmu/tlb/tlb.sv b/src/mmu/tlb/tlb.sv index 8910f7d53..9619c958d 100644 --- a/src/mmu/tlb/tlb.sv +++ b/src/mmu/tlb/tlb.sv @@ -110,7 +110,7 @@ module tlb import cvw::*; #(parameter cvw_t P, .TLBMiss, .TLBHit, .TLBPageFault, .UpdateDA, .SV39Mode, .Translate, .PTE_N, .PBMemoryType); - tlblru #(TLB_ENTRIES) lru(.clk, .reset, .TLBWrite, .TLBFlush, .Matches, .CAMHit, .WriteEnables); + tlblru #(TLB_ENTRIES) lru(.clk, .reset, .TLBWrite, .TLBFlush, .Matches, .TLBHit, .WriteEnables); tlbcam #(P, TLB_ENTRIES, P.VPN_BITS + P.ASID_BITS, P.VPN_SEGMENT_BITS) tlbcam(.clk, .reset, .VPN, .PageTypeWriteVal, .SV39Mode, .TLBFlush, .WriteEnables, .PTE_Gs, .PTE_NAPOTs, .SATP_ASID, .Matches, .HitPageType, .CAMHit); diff --git a/src/mmu/tlb/tlblru.sv b/src/mmu/tlb/tlblru.sv index 4cabb33ab..18014155a 100644 --- a/src/mmu/tlb/tlblru.sv +++ b/src/mmu/tlb/tlblru.sv @@ -32,7 +32,7 @@ module tlblru #(parameter TLB_ENTRIES = 8) ( input logic TLBWrite, input logic TLBFlush, input logic [TLB_ENTRIES-1:0] Matches, - input logic CAMHit, + input logic TLBHit, output logic [TLB_ENTRIES-1:0] WriteEnables ); @@ -50,5 +50,5 @@ module tlblru #(parameter TLB_ENTRIES = 8) ( assign RUBitsAccessed = AccessLines | RUBits; assign AllUsed = &RUBitsAccessed; // if all recently used, then clear to none assign RUBitsNext = AllUsed ? 0 : RUBitsAccessed; - flopenr #(TLB_ENTRIES) lrustate(clk, reset, (CAMHit | TLBWrite), RUBitsNext, RUBits); + flopenr #(TLB_ENTRIES) lrustate(clk, reset, (TLBHit | TLBWrite), RUBitsNext, RUBits); endmodule diff --git a/tests/coverage/Makefile b/tests/coverage/Makefile index b2a2544d3..2f6002efc 100644 --- a/tests/coverage/Makefile +++ b/tests/coverage/Makefile @@ -17,7 +17,7 @@ all: $(OBJECTS) # Change many things if bit width isn't 64 %.elf: $(SRCDIR)/%.$(SEXT) WALLY-init-lib.h Makefile - riscv64-unknown-elf-gcc -g -o $@ -march=rv64gqc_zba_zbb_zbc_zbs_zfh -mabi=lp64 -mcmodel=medany \ + riscv64-unknown-elf-gcc -g -o $@ -march=rv64gqc_zba_zbb_zbc_zbs_zfh_zicboz_zicbop_zicbom -mabi=lp64 -mcmodel=medany \ -nostartfiles -T../../examples/link/link.ld $< riscv64-unknown-elf-objdump -S $@ > $@.objdump riscv64-unknown-elf-elf2hex --bit-width 64 --input $@ --output $@.memfile diff --git a/tests/coverage/WALLY-init-lib.h b/tests/coverage/WALLY-init-lib.h index b0f5a9654..55bfcf4e5 100644 --- a/tests/coverage/WALLY-init-lib.h +++ b/tests/coverage/WALLY-init-lib.h @@ -92,7 +92,10 @@ changeprivilege: trap_return: # return from trap handler csrr t0, mepc # get address of instruction that caused exception + li t1, 0x20000 + csrs mstatus, t1 # set mprv bit to fetch instruction with permission of code that trapped lh t0, 0(t0) # get instruction that caused exception + csrc mstatus, t1 # clear mprv bit to restore normal operation li t1, 3 and t0, t0, t1 # mask off upper bits beq t0, t1, instr32 # if lower 2 bits are 11, instruction is uncompresssed diff --git a/tests/coverage/ieu.S b/tests/coverage/ieu.S index cb0dae877..1e32a24ab 100644 --- a/tests/coverage/ieu.S +++ b/tests/coverage/ieu.S @@ -47,6 +47,13 @@ main: sc.w t0, a1, 0(a0) addi t0, t0, 1 + # test prefetch Hints (ori with destination x0) + ori x0, x0, 0 + ori x0, x0, 1 + ori x0, x0, 2 + ori x0, x0, 3 + + # Test illegal instructions are detected .word 0x80000033 // illegal R-type instruction .word 0x00007003 // illegal Load instruction @@ -66,6 +73,34 @@ main: .word 0x60F0101B // Illegal BMU similar to count word .word 0x6080101B // Illegal BMU similar to count word .word 0x6030101B // Illegal BMU similar to count word + .word 0x0000202F // Illegal similar to LR + .word 0x1010202F // Illegal similar to LR + .word 0x00402003 // illegal similar to CMO + .word 0x00202003 // illegal similar to CMO + .word 0xFF00302F // illegal Atomic instruction + .word 0xFF00402F // illegal Atomic instruction + .word 0x00000873 // illegal CSR instruction + + # Illegal CMO instructions because envcfg is 0 and system is in user Mode + li a0, 0 + ecall # switch to user mode + cbo.inval (x1) + cbo.clean (x1) + cbo.flush (x1) + cbo.zero (x1) + + li a0, 3 + ecall # switch back to machine mode + li x1, 0x50 + csrw menvcfg, x1 + csrw senvcfg, x1 + li a0, 0 + ecall # swtich to user mode + cbo.inval (x2) + cbo.clean (x3) + cbo.flush (x1) + + j done diff --git a/tests/coverage/tlbNAPOT.S b/tests/coverage/tlbNAPOT.S index e136f864a..09dc2abcd 100644 --- a/tests/coverage/tlbNAPOT.S +++ b/tests/coverage/tlbNAPOT.S @@ -31,6 +31,9 @@ # run-elf.bash find this in project description main: + li t5, 0x1 + slli t5, t5, 62 + csrs menvcfg, t5 # Page table root address at 0x80010000; SV48 li t5, 0x9000000000080010 csrw satp, t5 @@ -41,14 +44,25 @@ main: li a0, 1 ecall - li t0, 0x80215240 + li t4, 0x200000 # address step size + li a2, 0x80215240 # Test NAPOT pages + jal a1, looptest + li a2, 0xC0215240 # Test ill-formed NAPOT pages + jal a1, looptest + li a2, 0x40215240 # Test properly formed pages with 1 in PPN[3] that are not NAPOT + jal a1, looptest +# li t4, 0x1000 # address step size +# li a2, 0x80216000 # Test NAPOT pages +# jal a1, looptest + j done +looptest: + mv t0, a2 # base address li t2, 0 # i = 0 - li t3, 33 # Max amount of Loops = 32 - li t4, 0x200000 + li t3, 35 # Max amount of Loops = 34 li t5, 0x8082 # return instruction opcode -loop: bge t2, t3, finished # exit loop if i >= loops +loop: bge t2, t3, looptesti # exit loop if i >= loops sw t5, 0(t0) # store a return at this address to exercise DTLB lw t1, 0(t0) # read it back fence.i # synchronize with I$ @@ -57,8 +71,20 @@ loop: bge t2, t3, finished # exit loop if i >= loops addi t2, t2, 1 j loop +looptesti: + mv t0, a2 # base address + li t2, 0 # i = 0 + fence.i # synchronize with I$ + +# Exercise itlb by jumping to each of the return statements +loopi: bge t2, t3, finished # exit loop if i >= loops + jalr ra, t0 # jump to the return statement to exercise the ITLB + add t0, t0, t4 + addi t2, t2, 1 + j loopi + finished: - j done + jr a1 .data @@ -69,12 +95,13 @@ pagetable: # next page table at 0x80011000 .align 12 - .8byte 0x0000000000000000 - .8byte 0x00000000200048C1 - .8byte 0x00000000200048C1 + .8byte 0x0000000000000000 # gigapage at 0x00000000 + .8byte 0x00000000200058C1 # gigapage at 0x40000000 used for non-NAPOT with PPN bit 3 set + .8byte 0x00000000200048C1 # gigapage at 0x80000000 used for testing NAPOT huge pages + .8byte 0x00000000200050C1 # gigapage at 0xC0000000 mapped to ill-formed NAPOT with wrong PPN -# Next page table at 0x80012000 +# Next page table at 0x80012000 for gigapage at 0x80000000 .align 12 .8byte 0x0000000020004CC1 .8byte 0x0000000020004CC1 @@ -111,29 +138,32 @@ pagetable: .8byte 0x0000000020004CC1 .8byte 0x0000000020004CC1 .8byte 0x0000000020004CC1 + .8byte 0x0000000020004CC1 + .8byte 0x0000000020004CC1 + .8byte 0x0000000020004CC1 -# Leaf page table at 0x80013000 +# Leaf page table at 0x80013000 with NAPOT pages .align 12 #80000000 - .8byte 0x80000000200020CF - .8byte 0x80000000200020CF - .8byte 0x80000000200020CF - .8byte 0x80000000200020CF + .8byte 0xA0000000200020CF + .8byte 0xA0000000200020CF + .8byte 0xA0000000200020CF + .8byte 0xA0000000200020CF - .8byte 0x80000000200020CF - .8byte 0x80000000200020CF - .8byte 0x80000000200020CF - .8byte 0x80000000200020CF + .8byte 0xA0000000200020CF + .8byte 0xA0000000200020CF + .8byte 0xA0000000200020CF + .8byte 0xA0000000200020CF - .8byte 0x80000000200020CF - .8byte 0x80000000200020CF - .8byte 0x80000000200020CF - .8byte 0x80000000200020CF + .8byte 0xA0000000200020CF + .8byte 0xA0000000200020CF + .8byte 0xA0000000200020CF + .8byte 0xA0000000200020CF - .8byte 0x80000000200020CF - .8byte 0x80000000200020CF - .8byte 0x80000000200020CF - .8byte 0x80000000200020CF + .8byte 0xA0000000200020CF + .8byte 0xA0000000200020CF + .8byte 0xA0000000200020CF + .8byte 0xA0000000200020CF .8byte 0x80000000200060CF .8byte 0x80000000200060CF @@ -182,3 +212,182 @@ pagetable: .8byte 0x800000002000E0CF .8byte 0x800000002000E0CF + +# Next page table at 0x80014000: mega-sized, pointing to malformed NAPOT for gigapage at 0xC9000000 +.align 12 + .8byte 0x00000000200054C1 + .8byte 0x00000000200054C1 + .8byte 0x00000000200054C1 + .8byte 0x00000000200054C1 + .8byte 0x00000000200054C1 + .8byte 0x00000000200054C1 + .8byte 0x00000000200054C1 + .8byte 0x00000000200054C1 + .8byte 0x00000000200054C1 + .8byte 0x00000000200054C1 + .8byte 0x00000000200054C1 + .8byte 0x00000000200054C1 + .8byte 0x00000000200054C1 + .8byte 0x00000000200054C1 + .8byte 0x00000000200054C1 + .8byte 0x00000000200054C1 + .8byte 0x00000000200054C1 + .8byte 0x00000000200054C1 + .8byte 0x00000000200054C1 + .8byte 0x00000000200054C1 + .8byte 0x00000000200054C1 + .8byte 0x00000000200054C1 + .8byte 0x00000000200054C1 + .8byte 0x00000000200054C1 + .8byte 0x00000000200054C1 + .8byte 0x00000000200054C1 + .8byte 0x00000000200054C1 + .8byte 0x00000000200054C1 + .8byte 0x00000000200054C1 + .8byte 0x00000000200054C1 + .8byte 0x00000000200054C1 + .8byte 0x00000000200054C1 + .8byte 0x00000000200054C1 + .8byte 0x00000000200054C1 + .8byte 0x00000000200054C1 + .8byte 0x00000000200054C1 + .8byte 0x00000000200054C1 + .8byte 0x00000000200054C1 + +# Leaf page table at 0x80015000 with malformed NAPOT pages (wrong PPN) starting at 0xC0000000 +.align 12 + #80000000 + .8byte 0x80000000200000CF + .8byte 0x80000000200000CF + .8byte 0x80000000200000CF + .8byte 0x80000000200000CF + + .8byte 0x80000000200000CF + .8byte 0x80000000200000CF + .8byte 0x80000000200000CF + .8byte 0x80000000200000CF + + .8byte 0x80000000200000CF + .8byte 0x80000000200000CF + .8byte 0x80000000200000CF + .8byte 0x80000000200000CF + + .8byte 0x80000000200000CF + .8byte 0x80000000200000CF + .8byte 0x80000000200000CF + .8byte 0x80000000200000CF + + .8byte 0x80000000200000CF + .8byte 0x80000000200000CF + .8byte 0x80000000200000CF + .8byte 0x80000000200000CF + + .8byte 0x80000000200000CF + .8byte 0x80000000200000CF + .8byte 0x80000000200000CF + .8byte 0x80000000200000CF + + .8byte 0x80000000200000CF + .8byte 0x80000000200000CF + .8byte 0x80000000200000CF + .8byte 0x80000000200000CF + + .8byte 0x80000000200000CF + .8byte 0x80000000200000CF + .8byte 0x80000000200000CF + .8byte 0x80000000200000CF + + .8byte 0x80000000200000CF + .8byte 0x80000000200000CF + .8byte 0x80000000200000CF + .8byte 0x80000000200000CF + + +# Next page table at 0x80016000: mega-sized, pointing to properly formed PTE with 1 in PPN bit 3 for gigapage at 0x40000000 +.align 12 + .8byte 0x0000000020005CC1 + .8byte 0x0000000020005CC1 + .8byte 0x0000000020005CC1 + .8byte 0x0000000020005CC1 + .8byte 0x0000000020005CC1 + .8byte 0x0000000020005CC1 + .8byte 0x0000000020005CC1 + .8byte 0x0000000020005CC1 + .8byte 0x0000000020005CC1 + .8byte 0x0000000020005CC1 + .8byte 0x0000000020005CC1 + .8byte 0x0000000020005CC1 + .8byte 0x0000000020005CC1 + .8byte 0x0000000020005CC1 + .8byte 0x0000000020005CC1 + .8byte 0x0000000020005CC1 + .8byte 0x0000000020005CC1 + .8byte 0x0000000020005CC1 + .8byte 0x0000000020005CC1 + .8byte 0x0000000020005CC1 + .8byte 0x0000000020005CC1 + .8byte 0x0000000020005CC1 + .8byte 0x0000000020005CC1 + .8byte 0x0000000020005CC1 + .8byte 0x0000000020005CC1 + .8byte 0x0000000020005CC1 + .8byte 0x0000000020005CC1 + .8byte 0x0000000020005CC1 + .8byte 0x0000000020005CC1 + .8byte 0x0000000020005CC1 + .8byte 0x0000000020005CC1 + .8byte 0x0000000020005CC1 + .8byte 0x0000000020005CC1 + .8byte 0x0000000020005CC1 + .8byte 0x0000000020005CC1 + .8byte 0x0000000020005CC1 + .8byte 0x0000000020005CC1 + +# Leaf page table at 0x80017000 with properly formed PTE with bit 4 of PPN set but no NAPOT +.align 12 + #80000000 + .8byte 0x00000000200020CF + .8byte 0x00000000200060CF + .8byte 0x000000002000A0CF + .8byte 0x000000002000E0CF + + .8byte 0x00000000200020CF + .8byte 0x00000000200060CF + .8byte 0x000000002000A0CF + .8byte 0x000000002000E0CF + + .8byte 0x00000000200020CF + .8byte 0x00000000200060CF + .8byte 0x000000002000A0CF + .8byte 0x000000002000E0CF + + .8byte 0x00000000200020CF + .8byte 0x00000000200060CF + .8byte 0x000000002000A0CF + .8byte 0x000000002000E0CF + + .8byte 0x00000000200020CF + .8byte 0x00000000200060CF + .8byte 0x000000002000A0CF + .8byte 0x000000002000E0CF + + .8byte 0x00000000200020CF + .8byte 0x00000000200060CF + .8byte 0x000000002000A0CF + .8byte 0x000000002000E0CF + + .8byte 0x00000000200020CF + .8byte 0x00000000200060CF + .8byte 0x000000002000A0CF + .8byte 0x000000002000E0CF + + .8byte 0x00000000200020CF + .8byte 0x00000000200060CF + .8byte 0x000000002000A0CF + .8byte 0x000000002000E0CF + + .8byte 0x00000000200020CF + .8byte 0x00000000200060CF + .8byte 0x000000002000A0CF + .8byte 0x000000002000E0CF +