From 7a1b214332de6ec51abbe91323c70d7e8b7f2e06 Mon Sep 17 00:00:00 2001 From: Moritz Schneider Date: Wed, 7 Oct 2020 09:56:23 +0200 Subject: [PATCH] pmp: Fix for 32 XLEN (#537) * Fix wrong length PMP csrs * Fix 32bit pmpcfg csrs --- src/csr_regfile.sv | 80 ++++++++++++++++++++++++++-------------------- 1 file changed, 45 insertions(+), 35 deletions(-) diff --git a/src/csr_regfile.sv b/src/csr_regfile.sv index 2c65d0e11..628074f64 100644 --- a/src/csr_regfile.sv +++ b/src/csr_regfile.sv @@ -140,7 +140,7 @@ module csr_regfile import ariane_pkg::*; #( riscv::xlen_t instret_q, instret_d; riscv::pmpcfg_t [15:0] pmpcfg_q, pmpcfg_d; - logic [15:0][riscv::VLEN-3:0] pmpaddr_q, pmpaddr_d; + logic [15:0][riscv::PLEN-3:0] pmpaddr_q, pmpaddr_d; assign pmpcfg_o = pmpcfg_q[15:0]; @@ -287,22 +287,22 @@ module csr_regfile import ariane_pkg::*; #( // -> last bit of pmpaddr must be set 0/1 based on the mode: // NA4, NAPOT: 1 // TOR, OFF: 0 - riscv::CSR_PMPADDR0: csr_rdata = {10'b0, pmpaddr_q[0][riscv::VLEN-3:1], (pmpcfg_q[0].addr_mode[1] == 1'b1 ? 1'b1 : 1'b0)}; - riscv::CSR_PMPADDR1: csr_rdata = {10'b0, pmpaddr_q[1][riscv::VLEN-3:1], (pmpcfg_q[1].addr_mode[1] == 1'b1 ? 1'b1 : 1'b0)}; - riscv::CSR_PMPADDR2: csr_rdata = {10'b0, pmpaddr_q[2][riscv::VLEN-3:1], (pmpcfg_q[2].addr_mode[1] == 1'b1 ? 1'b1 : 1'b0)}; - riscv::CSR_PMPADDR3: csr_rdata = {10'b0, pmpaddr_q[3][riscv::VLEN-3:1], (pmpcfg_q[3].addr_mode[1] == 1'b1 ? 1'b1 : 1'b0)}; - riscv::CSR_PMPADDR4: csr_rdata = {10'b0, pmpaddr_q[4][riscv::VLEN-3:1], (pmpcfg_q[4].addr_mode[1] == 1'b1 ? 1'b1 : 1'b0)}; - riscv::CSR_PMPADDR5: csr_rdata = {10'b0, pmpaddr_q[5][riscv::VLEN-3:1], (pmpcfg_q[5].addr_mode[1] == 1'b1 ? 1'b1 : 1'b0)}; - riscv::CSR_PMPADDR6: csr_rdata = {10'b0, pmpaddr_q[6][riscv::VLEN-3:1], (pmpcfg_q[6].addr_mode[1] == 1'b1 ? 1'b1 : 1'b0)}; - riscv::CSR_PMPADDR7: csr_rdata = {10'b0, pmpaddr_q[7][riscv::VLEN-3:1], (pmpcfg_q[7].addr_mode[1] == 1'b1 ? 1'b1 : 1'b0)}; - riscv::CSR_PMPADDR8: csr_rdata = {10'b0, pmpaddr_q[8][riscv::VLEN-3:1], (pmpcfg_q[8].addr_mode[1] == 1'b1 ? 1'b1 : 1'b0)}; - riscv::CSR_PMPADDR9: csr_rdata = {10'b0, pmpaddr_q[9][riscv::VLEN-3:1], (pmpcfg_q[9].addr_mode[1] == 1'b1 ? 1'b1 : 1'b0)}; - riscv::CSR_PMPADDR10: csr_rdata = {10'b0, pmpaddr_q[10][riscv::VLEN-3:1], (pmpcfg_q[10].addr_mode[1] == 1'b1 ? 1'b1 : 1'b0)}; - riscv::CSR_PMPADDR11: csr_rdata = {10'b0, pmpaddr_q[11][riscv::VLEN-3:1], (pmpcfg_q[11].addr_mode[1] == 1'b1 ? 1'b1 : 1'b0)}; - riscv::CSR_PMPADDR12: csr_rdata = {10'b0, pmpaddr_q[12][riscv::VLEN-3:1], (pmpcfg_q[12].addr_mode[1] == 1'b1 ? 1'b1 : 1'b0)}; - riscv::CSR_PMPADDR13: csr_rdata = {10'b0, pmpaddr_q[13][riscv::VLEN-3:1], (pmpcfg_q[13].addr_mode[1] == 1'b1 ? 1'b1 : 1'b0)}; - riscv::CSR_PMPADDR14: csr_rdata = {10'b0, pmpaddr_q[14][riscv::VLEN-3:1], (pmpcfg_q[14].addr_mode[1] == 1'b1 ? 1'b1 : 1'b0)}; - riscv::CSR_PMPADDR15: csr_rdata = {10'b0, pmpaddr_q[15][riscv::VLEN-3:1], (pmpcfg_q[15].addr_mode[1] == 1'b1 ? 1'b1 : 1'b0)}; + riscv::CSR_PMPADDR0: csr_rdata = {10'b0, pmpaddr_q[0][riscv::PLEN-3:1], (pmpcfg_q[0].addr_mode[1] == 1'b1 ? 1'b1 : 1'b0)}; + riscv::CSR_PMPADDR1: csr_rdata = {10'b0, pmpaddr_q[1][riscv::PLEN-3:1], (pmpcfg_q[1].addr_mode[1] == 1'b1 ? 1'b1 : 1'b0)}; + riscv::CSR_PMPADDR2: csr_rdata = {10'b0, pmpaddr_q[2][riscv::PLEN-3:1], (pmpcfg_q[2].addr_mode[1] == 1'b1 ? 1'b1 : 1'b0)}; + riscv::CSR_PMPADDR3: csr_rdata = {10'b0, pmpaddr_q[3][riscv::PLEN-3:1], (pmpcfg_q[3].addr_mode[1] == 1'b1 ? 1'b1 : 1'b0)}; + riscv::CSR_PMPADDR4: csr_rdata = {10'b0, pmpaddr_q[4][riscv::PLEN-3:1], (pmpcfg_q[4].addr_mode[1] == 1'b1 ? 1'b1 : 1'b0)}; + riscv::CSR_PMPADDR5: csr_rdata = {10'b0, pmpaddr_q[5][riscv::PLEN-3:1], (pmpcfg_q[5].addr_mode[1] == 1'b1 ? 1'b1 : 1'b0)}; + riscv::CSR_PMPADDR6: csr_rdata = {10'b0, pmpaddr_q[6][riscv::PLEN-3:1], (pmpcfg_q[6].addr_mode[1] == 1'b1 ? 1'b1 : 1'b0)}; + riscv::CSR_PMPADDR7: csr_rdata = {10'b0, pmpaddr_q[7][riscv::PLEN-3:1], (pmpcfg_q[7].addr_mode[1] == 1'b1 ? 1'b1 : 1'b0)}; + riscv::CSR_PMPADDR8: csr_rdata = {10'b0, pmpaddr_q[8][riscv::PLEN-3:1], (pmpcfg_q[8].addr_mode[1] == 1'b1 ? 1'b1 : 1'b0)}; + riscv::CSR_PMPADDR9: csr_rdata = {10'b0, pmpaddr_q[9][riscv::PLEN-3:1], (pmpcfg_q[9].addr_mode[1] == 1'b1 ? 1'b1 : 1'b0)}; + riscv::CSR_PMPADDR10: csr_rdata = {10'b0, pmpaddr_q[10][riscv::PLEN-3:1], (pmpcfg_q[10].addr_mode[1] == 1'b1 ? 1'b1 : 1'b0)}; + riscv::CSR_PMPADDR11: csr_rdata = {10'b0, pmpaddr_q[11][riscv::PLEN-3:1], (pmpcfg_q[11].addr_mode[1] == 1'b1 ? 1'b1 : 1'b0)}; + riscv::CSR_PMPADDR12: csr_rdata = {10'b0, pmpaddr_q[12][riscv::PLEN-3:1], (pmpcfg_q[12].addr_mode[1] == 1'b1 ? 1'b1 : 1'b0)}; + riscv::CSR_PMPADDR13: csr_rdata = {10'b0, pmpaddr_q[13][riscv::PLEN-3:1], (pmpcfg_q[13].addr_mode[1] == 1'b1 ? 1'b1 : 1'b0)}; + riscv::CSR_PMPADDR14: csr_rdata = {10'b0, pmpaddr_q[14][riscv::PLEN-3:1], (pmpcfg_q[14].addr_mode[1] == 1'b1 ? 1'b1 : 1'b0)}; + riscv::CSR_PMPADDR15: csr_rdata = {10'b0, pmpaddr_q[15][riscv::PLEN-3:1], (pmpcfg_q[15].addr_mode[1] == 1'b1 ? 1'b1 : 1'b0)}; default: read_access_exception = 1'b1; endcase end @@ -595,24 +595,34 @@ module csr_regfile import ariane_pkg::*; #( // 1. refuse to update any locked entry // 2. also refuse to update the entry below a locked TOR entry // Note that writes to pmpcfg below a locked TOR entry are valid - riscv::CSR_PMPCFG0: for (int i = 0; i < 8; i++) if (!pmpcfg_q[i].locked) pmpcfg_d[i] = csr_wdata[i*8+:8]; - riscv::CSR_PMPCFG2: for (int i = 0; i < 8; i++) if (!pmpcfg_q[i+8].locked) pmpcfg_d[i+8] = csr_wdata[i*8+:8]; - riscv::CSR_PMPADDR0: if (!pmpcfg_q[ 0].locked && !(pmpcfg_q[ 1].locked && pmpcfg_q[ 1].addr_mode == riscv::TOR)) pmpaddr_d[0] = csr_wdata[riscv::VLEN-3:0]; - riscv::CSR_PMPADDR1: if (!pmpcfg_q[ 1].locked && !(pmpcfg_q[ 2].locked && pmpcfg_q[ 2].addr_mode == riscv::TOR)) pmpaddr_d[1] = csr_wdata[riscv::VLEN-3:0]; - riscv::CSR_PMPADDR2: if (!pmpcfg_q[ 2].locked && !(pmpcfg_q[ 3].locked && pmpcfg_q[ 3].addr_mode == riscv::TOR)) pmpaddr_d[2] = csr_wdata[riscv::VLEN-3:0]; - riscv::CSR_PMPADDR3: if (!pmpcfg_q[ 3].locked && !(pmpcfg_q[ 4].locked && pmpcfg_q[ 4].addr_mode == riscv::TOR)) pmpaddr_d[3] = csr_wdata[riscv::VLEN-3:0]; - riscv::CSR_PMPADDR4: if (!pmpcfg_q[ 4].locked && !(pmpcfg_q[ 5].locked && pmpcfg_q[ 5].addr_mode == riscv::TOR)) pmpaddr_d[4] = csr_wdata[riscv::VLEN-3:0]; - riscv::CSR_PMPADDR5: if (!pmpcfg_q[ 5].locked && !(pmpcfg_q[ 6].locked && pmpcfg_q[ 6].addr_mode == riscv::TOR)) pmpaddr_d[5] = csr_wdata[riscv::VLEN-3:0]; - riscv::CSR_PMPADDR6: if (!pmpcfg_q[ 6].locked && !(pmpcfg_q[ 7].locked && pmpcfg_q[ 7].addr_mode == riscv::TOR)) pmpaddr_d[6] = csr_wdata[riscv::VLEN-3:0]; - riscv::CSR_PMPADDR7: if (!pmpcfg_q[ 7].locked && !(pmpcfg_q[ 8].locked && pmpcfg_q[ 8].addr_mode == riscv::TOR)) pmpaddr_d[7] = csr_wdata[riscv::VLEN-3:0]; - riscv::CSR_PMPADDR8: if (!pmpcfg_q[ 8].locked && !(pmpcfg_q[ 9].locked && pmpcfg_q[ 9].addr_mode == riscv::TOR)) pmpaddr_d[8] = csr_wdata[riscv::VLEN-3:0]; - riscv::CSR_PMPADDR9: if (!pmpcfg_q[ 9].locked && !(pmpcfg_q[10].locked && pmpcfg_q[10].addr_mode == riscv::TOR)) pmpaddr_d[9] = csr_wdata[riscv::VLEN-3:0]; - riscv::CSR_PMPADDR10: if (!pmpcfg_q[10].locked && !(pmpcfg_q[11].locked && pmpcfg_q[11].addr_mode == riscv::TOR)) pmpaddr_d[10] = csr_wdata[riscv::VLEN-3:0]; - riscv::CSR_PMPADDR11: if (!pmpcfg_q[11].locked && !(pmpcfg_q[12].locked && pmpcfg_q[12].addr_mode == riscv::TOR)) pmpaddr_d[11] = csr_wdata[riscv::VLEN-3:0]; - riscv::CSR_PMPADDR12: if (!pmpcfg_q[12].locked && !(pmpcfg_q[13].locked && pmpcfg_q[13].addr_mode == riscv::TOR)) pmpaddr_d[12] = csr_wdata[riscv::VLEN-3:0]; - riscv::CSR_PMPADDR13: if (!pmpcfg_q[13].locked && !(pmpcfg_q[14].locked && pmpcfg_q[14].addr_mode == riscv::TOR)) pmpaddr_d[13] = csr_wdata[riscv::VLEN-3:0]; - riscv::CSR_PMPADDR14: if (!pmpcfg_q[14].locked && !(pmpcfg_q[15].locked && pmpcfg_q[15].addr_mode == riscv::TOR)) pmpaddr_d[14] = csr_wdata[riscv::VLEN-3:0]; - riscv::CSR_PMPADDR15: if (!pmpcfg_q[15].locked) pmpaddr_d[15] = csr_wdata[riscv::VLEN-3:0]; + riscv::CSR_PMPCFG0: for (int i = 0; i < (riscv::XLEN/8); i++) if (!pmpcfg_q[i].locked) pmpcfg_d[i] = csr_wdata[i*8+:8]; + riscv::CSR_PMPCFG1: begin + if (riscv::XLEN == 32) begin + for (int i = 0; i < 4; i++) if (!pmpcfg_q[i+4].locked) pmpcfg_d[i+4] = csr_wdata[i*8+:8]; + end + end + riscv::CSR_PMPCFG2: for (int i = 0; i < (riscv::XLEN/8); i++) if (!pmpcfg_q[i+8].locked) pmpcfg_d[i+8] = csr_wdata[i*8+:8]; + riscv::CSR_PMPCFG3: begin + if (riscv::XLEN == 32) begin + for (int i = 0; i < 4; i++) if (!pmpcfg_q[i+12].locked) pmpcfg_d[i+12] = csr_wdata[i*8+:8]; + end + end + riscv::CSR_PMPADDR0: if (!pmpcfg_q[ 0].locked && !(pmpcfg_q[ 1].locked && pmpcfg_q[ 1].addr_mode == riscv::TOR)) pmpaddr_d[0] = csr_wdata[riscv::PLEN-3:0]; + riscv::CSR_PMPADDR1: if (!pmpcfg_q[ 1].locked && !(pmpcfg_q[ 2].locked && pmpcfg_q[ 2].addr_mode == riscv::TOR)) pmpaddr_d[1] = csr_wdata[riscv::PLEN-3:0]; + riscv::CSR_PMPADDR2: if (!pmpcfg_q[ 2].locked && !(pmpcfg_q[ 3].locked && pmpcfg_q[ 3].addr_mode == riscv::TOR)) pmpaddr_d[2] = csr_wdata[riscv::PLEN-3:0]; + riscv::CSR_PMPADDR3: if (!pmpcfg_q[ 3].locked && !(pmpcfg_q[ 4].locked && pmpcfg_q[ 4].addr_mode == riscv::TOR)) pmpaddr_d[3] = csr_wdata[riscv::PLEN-3:0]; + riscv::CSR_PMPADDR4: if (!pmpcfg_q[ 4].locked && !(pmpcfg_q[ 5].locked && pmpcfg_q[ 5].addr_mode == riscv::TOR)) pmpaddr_d[4] = csr_wdata[riscv::PLEN-3:0]; + riscv::CSR_PMPADDR5: if (!pmpcfg_q[ 5].locked && !(pmpcfg_q[ 6].locked && pmpcfg_q[ 6].addr_mode == riscv::TOR)) pmpaddr_d[5] = csr_wdata[riscv::PLEN-3:0]; + riscv::CSR_PMPADDR6: if (!pmpcfg_q[ 6].locked && !(pmpcfg_q[ 7].locked && pmpcfg_q[ 7].addr_mode == riscv::TOR)) pmpaddr_d[6] = csr_wdata[riscv::PLEN-3:0]; + riscv::CSR_PMPADDR7: if (!pmpcfg_q[ 7].locked && !(pmpcfg_q[ 8].locked && pmpcfg_q[ 8].addr_mode == riscv::TOR)) pmpaddr_d[7] = csr_wdata[riscv::PLEN-3:0]; + riscv::CSR_PMPADDR8: if (!pmpcfg_q[ 8].locked && !(pmpcfg_q[ 9].locked && pmpcfg_q[ 9].addr_mode == riscv::TOR)) pmpaddr_d[8] = csr_wdata[riscv::PLEN-3:0]; + riscv::CSR_PMPADDR9: if (!pmpcfg_q[ 9].locked && !(pmpcfg_q[10].locked && pmpcfg_q[10].addr_mode == riscv::TOR)) pmpaddr_d[9] = csr_wdata[riscv::PLEN-3:0]; + riscv::CSR_PMPADDR10: if (!pmpcfg_q[10].locked && !(pmpcfg_q[11].locked && pmpcfg_q[11].addr_mode == riscv::TOR)) pmpaddr_d[10] = csr_wdata[riscv::PLEN-3:0]; + riscv::CSR_PMPADDR11: if (!pmpcfg_q[11].locked && !(pmpcfg_q[12].locked && pmpcfg_q[12].addr_mode == riscv::TOR)) pmpaddr_d[11] = csr_wdata[riscv::PLEN-3:0]; + riscv::CSR_PMPADDR12: if (!pmpcfg_q[12].locked && !(pmpcfg_q[13].locked && pmpcfg_q[13].addr_mode == riscv::TOR)) pmpaddr_d[12] = csr_wdata[riscv::PLEN-3:0]; + riscv::CSR_PMPADDR13: if (!pmpcfg_q[13].locked && !(pmpcfg_q[14].locked && pmpcfg_q[14].addr_mode == riscv::TOR)) pmpaddr_d[13] = csr_wdata[riscv::PLEN-3:0]; + riscv::CSR_PMPADDR14: if (!pmpcfg_q[14].locked && !(pmpcfg_q[15].locked && pmpcfg_q[15].addr_mode == riscv::TOR)) pmpaddr_d[14] = csr_wdata[riscv::PLEN-3:0]; + riscv::CSR_PMPADDR15: if (!pmpcfg_q[15].locked) pmpaddr_d[15] = csr_wdata[riscv::PLEN-3:0]; default: update_access_exception = 1'b1; endcase end