From f3058f94c62d6de43a3228491488d148e6d2775e Mon Sep 17 00:00:00 2001 From: Kip Macsai-Goren Date: Fri, 8 Oct 2021 15:33:18 -0700 Subject: [PATCH 2/3] removed loops and simplified mask generation logic. PMP's now pass my tests and linux tests up to around 300M instructions. --- wally-pipelined/src/mmu/pmpadrdec.sv | 27 +++++++-------------------- wally-pipelined/src/mmu/pmpchecker.sv | 7 ++++--- 2 files changed, 11 insertions(+), 23 deletions(-) diff --git a/wally-pipelined/src/mmu/pmpadrdec.sv b/wally-pipelined/src/mmu/pmpadrdec.sv index 618167827..4f747ffb2 100644 --- a/wally-pipelined/src/mmu/pmpadrdec.sv +++ b/wally-pipelined/src/mmu/pmpadrdec.sv @@ -34,10 +34,8 @@ module pmpadrdec ( input logic [7:0] PMPCfg, input logic [`XLEN-1:0] PMPAdr, input logic PAgePMPAdrIn, -// input logic NoLowerMatchIn, input logic FirstMatch, output logic PAgePMPAdrOut, -// output logic NoLowerMatchOut, output logic Match, Active, output logic L, X, W, R ); @@ -48,7 +46,6 @@ module pmpadrdec ( logic TORMatch, NAMatch; logic PAltPMPAdr; -// logic FirstMatch; logic [`PA_BITS-1:0] CurrentAdrFull; logic [1:0] AdrMode; @@ -67,25 +64,15 @@ module pmpadrdec ( assign TORMatch = PAgePMPAdrIn && PAltPMPAdr; // Naturally aligned regions - logic [`PA_BITS-1:0] NAMask; - //genvar i; - - // create a mask of which bits to ignore - // generate - // assign Mask[1:0] = 2'b11; - // assign Mask[2] = (AdrMode == NAPOT); // mask has 0s in upper bis for NA4 region - // for (i=3; i < `PA_BITS; i=i+1) begin:mask - // assign Mask[i] = Mask[i-1] & PMPAdr[i-3]; // NAPOT mask: 1's indicate bits to ignore - // end - // endgenerate + logic [`PA_BITS-1:0] NAMask, NABase; assign NAMask[1:0] = {2'b11}; - - prioritythemometer #(`PA_BITS-2) namaskgen( - .a({PMPAdr[`PA_BITS-4:0], (AdrMode == NAPOT)}), - .y(NAMask[`PA_BITS-1:2])); - - assign NAMatch = &((PhysicalAddress ~^ CurrentAdrFull) | NAMask); + assign NAMask[`PA_BITS-1:2] = (PMPAdr[`PA_BITS-3:0] + {{(`PA_BITS-3){1'b0}}, (AdrMode == NAPOT)}) ^ PMPAdr[`PA_BITS-3:0]; + // generates a mask where the bottom k bits are 1, corresponding to a size of 2^k bytes for this memory region. + // This assumes we're using at least an NA4 region, but works for any size NAPOT region. + assign NABase = {(PMPAdr[`PA_BITS-3:0] & ~NAMask[`PA_BITS-1:2]), 2'b00}; // base physical address of the pmp. + + assign NAMatch = &((NABase ~^ PhysicalAddress) | NAMask); // check if upper bits of base address match, ignore lower bits correspoonding to inside the memory range assign Match = (AdrMode == TOR) ? TORMatch : (AdrMode == NA4 || AdrMode == NAPOT) ? NAMatch : diff --git a/wally-pipelined/src/mmu/pmpchecker.sv b/wally-pipelined/src/mmu/pmpchecker.sv index 7dc37163c..11cb7ccbb 100644 --- a/wally-pipelined/src/mmu/pmpchecker.sv +++ b/wally-pipelined/src/mmu/pmpchecker.sv @@ -54,8 +54,9 @@ module pmpchecker ( // Bit i is high when the address falls in PMP region i logic EnforcePMP; - logic [7:0] PMPCfg[`PMP_ENTRIES-1:0]; - logic [`PMP_ENTRIES-1:0] Match, FirstMatch; // PMP Entry matches +// logic [7:0] PMPCfg[`PMP_ENTRIES-1:0]; + logic [`PMP_ENTRIES-1:0] Match; // physical address matches one of the pmp ranges + logic [`PMP_ENTRIES-1:0] FirstMatch; // onehot encoding for the first pmpaddr to match the current address. logic [`PMP_ENTRIES-1:0] Active; // PMP register i is non-null logic [`PMP_ENTRIES-1:0] L, X, W, R; // PMP matches and has flag set logic [`PMP_ENTRIES-1:0] PAgePMPAdr; // for TOR PMP matching, PhysicalAddress > PMPAdr[i] @@ -69,7 +70,7 @@ module pmpchecker ( .PAgePMPAdrOut(PAgePMPAdr), .FirstMatch, .Match, .Active, .L, .X, .W, .R); - priorityonehot #(`PMP_ENTRIES) pmppriority(.a(Match), .y(FirstMatch)); // Take the ripple gates/signals out of the pmpadrdec and into another unit. + priorityonehot #(`PMP_ENTRIES) pmppriority(.a(Match), .y(FirstMatch)); // combine the match signal from all the adress decoders to find the first one that matches. // Only enforce PMP checking for S and U modes when at least one PMP is active or in Machine mode when L bit is set in selected region assign EnforcePMP = (PrivilegeModeW == `M_MODE) ? |L : |Active; From 303beaa083b877f999e909732198a74263b58c08 Mon Sep 17 00:00:00 2001 From: Kip Macsai-Goren Date: Fri, 8 Oct 2021 15:40:18 -0700 Subject: [PATCH 3/3] updated pmp output to correspond to test changes, commented out execute tests until cache/fence interaction works fully. --- wally-pipelined/testbench/testbench-imperas.sv | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/wally-pipelined/testbench/testbench-imperas.sv b/wally-pipelined/testbench/testbench-imperas.sv index 3f6d449e0..40719351c 100644 --- a/wally-pipelined/testbench/testbench-imperas.sv +++ b/wally-pipelined/testbench/testbench-imperas.sv @@ -46,14 +46,14 @@ module testbench(); string tests32mmu[] = '{ "rv32mmu/WALLY-MMU-SV32", "3000" - //"rv32mmu/WALLY-PMA", "3000", + //"rv32mmu/WALLY-PMP", "3000", //"rv32mmu/WALLY-PMA", "3000" }; string tests64mmu[] = '{ "rv64mmu/WALLY-MMU-SV48", "3000", - "rv64mmu/WALLY-MMU-SV39", "3000" - //"rv64mmu/WALLY-PMA", "3000", + "rv64mmu/WALLY-MMU-SV39", "3000", + "rv64mmu/WALLY-PMP", "3000" //"rv64mmu/WALLY-PMA", "3000" }; @@ -539,8 +539,8 @@ string tests32f[] = '{ if (`F_SUPPORTED) tests = {tests64f, tests}; if (`D_SUPPORTED) tests = {tests64d, tests}; if (`MEM_VIRTMEM) tests = {tests64mmu, tests}; - if (`A_SUPPORTED) tests = {tests64a, tests}; - if (`M_SUPPORTED) tests = {tests64m, tests}; + //if (`A_SUPPORTED) tests = {tests64a, tests}; + //if (`M_SUPPORTED) tests = {tests64m, tests}; end //tests = {tests64a, tests}; end else begin // RV32 @@ -676,7 +676,7 @@ string tests32f[] = '{ errors = errors+1; $display(" Error on test %s result %d: adr = %h sim (D$) %h sim (TIM) = %h, signature = %h", tests[test], i, (testadr+i)*(`XLEN/8), DCacheFlushFSM.ShadowRAM[testadr+i], dut.uncore.dtim.RAM[testadr+i], signature[i]); - $stop;//***debug + //$stop;//***debug end end i = i + 1;