Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Physical Memory Protection unit #119

Merged
merged 28 commits into from
Oct 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
e788eeb
design/dec: Add PMP CSRs addresses and regenerate CSR address decodin…
koluckirafal Aug 24, 2023
3cbfa75
design/dec: Add PMP CSRs implementation
koluckirafal Aug 24, 2023
1ab8cb4
design/dec: Zero unused bits in pmpcfg CSR, fix locking logic
koluckirafal Aug 28, 2023
3d1c8af
configs: Fix PMP entries number selection
koluckirafal Aug 29, 2023
3a4bdd2
design/dec: Move PMP CSR contents to the port
koluckirafal Aug 24, 2023
3f2086d
design, testbench: Add initial PMP unit implementation
koluckirafal Sep 11, 2023
ee81daa
design/ifu: Pass address and error signals to the ports, add initial …
koluckirafal Sep 12, 2023
2fa2555
design/dec: Shorten `pmpaddr` CSR internally to 30 bits
koluckirafal Sep 12, 2023
dcac646
design/include: Convert `pmpcfg` mode field to enum, add memory acces…
koluckirafal Sep 12, 2023
f67f69d
design: Adapt PMP to VeeR-EL2 addressing, connect IFU to PMP
koluckirafal Sep 12, 2023
c18094d
design/lsu: Connect LSU to PMP
koluckirafal Sep 14, 2023
3660177
design: Fix PMP type channels
koluckirafal Sep 15, 2023
f02c737
design/dec: Lock `PMPADDR(n-1)` CSR when PMP entry `n` is locked and …
koluckirafal Sep 25, 2023
5224f8c
design/{lsu/, include/, el2_veer.sv}: Test only valid LSU requests
koluckirafal Sep 25, 2023
96294f8
tools, .gitignore: Remove/ignore *.sym files
koluckirafal Sep 20, 2023
0e40018
testbench/tests: Add `pmp` test skeleton
koluckirafal Sep 18, 2023
6b06b94
testbench/tests/pmp: Add fault handling logic
koluckirafal Sep 19, 2023
6ea8a0c
testbench/tests/pmp: Add second stack for exception handler
koluckirafal Sep 20, 2023
ce8128a
testbench/tests/pmp: Add load and exec tests
koluckirafal Sep 20, 2023
846f454
testbench/tests/pmp: Add PMP CSR handling
koluckirafal Sep 21, 2023
766bbb8
testbench/tests/pmp: Setup PMP in test functions
koluckirafal Sep 22, 2023
8a019b1
testbench/tests/pmp: Lock entries when setting up, prevent exec test …
koluckirafal Sep 25, 2023
298013f
testbench/tests/pmp: Fix execution test and switch to defines when co…
koluckirafal Sep 26, 2023
891af0f
.github/workflows: Add PMP program to regression tests
koluckirafal Sep 28, 2023
de114b6
Apply Verible on modified sources
robertszczepanski Oct 3, 2023
bcbb0bc
Add block level tests for PMP
robertszczepanski Sep 22, 2023
203f84e
Add simulation generated files to gitignore
robertszczepanski Oct 3, 2023
afbf4d0
Run PMP block level test in CI
robertszczepanski Oct 4, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/test-regression.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
test: ["hello_world", "hello_world_dccm", "hello_world_iccm", "cmark", "cmark_dccm", "cmark_iccm", "dhry"]
test: ["hello_world", "hello_world_dccm", "hello_world_iccm", "cmark", "cmark_dccm", "cmark_iccm", "dhry", "pmp"]
coverage: ["branch", "toggle"] #TODO: add functional coverage
env:
DEBIAN_FRONTEND: "noninteractive"
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/test-uarch.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ jobs:
- "block/iccm"
- "block/dccm"
- "block/lib_axi4_to_ahb"
- "block/pmp"
env:
CCACHE_DIR: "/opt/verification/.cache/"
VERILATOR_VERSION: v5.010
Expand Down
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,17 @@ obj_dir
*.log
*.exe
*.swp
*.sym
verilator-build
program.hex
snapshots
__pycache__
sim_build
sim-build*
venv
results.xml
verification/sim
verilator-cocotb-build
*.dat
*.xml
*.json
20 changes: 14 additions & 6 deletions configs/veer.config
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,8 @@ Parameters that can be set by the end user:
if 1, minimize clock-gating to facilitate FPGA builds
-text_in_iccm = {0, 1}
Don't add ICCM preload code in generated link.ld
-set=pmp_entries = {0, 1, ..., 64 }
number of PMP entries


Additionally the following may be set for bus masters and slaves using the -set=var=value option:
Expand Down Expand Up @@ -266,6 +268,7 @@ my $text_in_iccm = 0;

my $lsu2dma = 0;

my $pmp_entries=16;

$ret_stack_size=8;
$btb_enable=1;
Expand Down Expand Up @@ -815,13 +818,15 @@ my @perf_events = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
45, 46, 47, 48, 49, 50, 54, 55, 56,
512, 513, 514, 515, 516);

foreach my $i (0 .. 3) {
$csr{"pmpcfg$i"} = { "exists" => "false" };
}
# FIXME: PMP CSR handling

foreach my $i (0 .. 15) {
$csr{"pmpaddr$i"} = { "exists" => "false" };
}
#foreach my $i (0 .. 3) {
# $csr{"pmpcfg$i"} = { "exists" => "false" };
#}

#foreach my $i (0 .. 15) {
# $csr{"pmpaddr$i"} = { "exists" => "false" };
#}

# }}}
# Main config hash, with default values
Expand Down Expand Up @@ -1035,6 +1040,7 @@ our %config = (#{{{
"SDVT_AHB" => "$ahb",
},
"protection" => { # Design parms, Overridable - static MPU
"pmp_entries" => "$pmp_entries",
"inst_access_enable0" => "0x0",
"inst_access_addr0" => "0x00000000",
"inst_access_mask0" => "0xffffffff",
Expand Down Expand Up @@ -1134,6 +1140,7 @@ our %verilog_parms = (
"bitmanip_zbr" => '1',
"fast_interrupt_redirect" => '1',

"pmp_entries" => '7',
"inst_access_enable0" => '1',
"inst_access_addr0" => '32',
"inst_access_mask0" => '32',
Expand Down Expand Up @@ -1357,6 +1364,7 @@ if ($config{core}{div_new}==0 && $config{core}{div_bit}!=1) {
die("$helpusage\n\nFAIL: div_new=0 requires div_bit=1 ILLEGAL !!!\n\n");
}

$c=$config{protection}{pmp_entries}; if (!($c==64 || $c==16 || $c==0)) { die("$helpusage\n\nFAIL: pmp_entries must be either 0, 16 or 64 !!!\n\n"); }
$c=$config{protection}{inst_access_addr0}; if ((hex($c)&0x3f) != 0) { die("$helpusage\n\nFAIL: inst_access_addr0 lower 6b must be 0s $c !!!\n\n"); }
$c=$config{protection}{inst_access_addr1}; if ((hex($c)&0x3f) != 0) { die("$helpusage\n\nFAIL: inst_access_addr1 lower 6b must be 0s !!!\n\n"); }
$c=$config{protection}{inst_access_addr2}; if ((hex($c)&0x3f) != 0) { die("$helpusage\n\nFAIL: inst_access_addr2 lower 6b must be 0s !!!\n\n"); }
Expand Down
16 changes: 16 additions & 0 deletions design/dec/csrdecode
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,11 @@ csr_perfvi = [00110011....]
csr_mcountinhibit = [001100100000]
csr_mfdht = [011111001110]
csr_mfdhs = [011111001111]
csr_pmpcfg = [00111010....]
csr_pmpaddr0 = [00111011....]
csr_pmpaddr16 = [00111100....]
csr_pmpaddr32 = [00111101....]
csr_pmpaddr48 = [00111110....]

.input

Expand Down Expand Up @@ -171,6 +176,11 @@ csr_dicad0h
csr_dicad0
csr_dicad1
csr_dicago
csr_pmpcfg
csr_pmpaddr0
csr_pmpaddr16
csr_pmpaddr32
csr_pmpaddr48
valid_only
presync
postsync
Expand Down Expand Up @@ -256,4 +266,10 @@ csr[ csr_perfvg ] = { valid_only }
csr[ csr_perfvh ] = { valid_only }
csr[ csr_perfvi ] = { valid_only }

csr[ csr_pmpcfg ] = { csr_pmpcfg }
csr[ csr_pmpaddr0 ] = { csr_pmpaddr0 }
csr[ csr_pmpaddr16 ] = { csr_pmpaddr16 }
csr[ csr_pmpaddr32 ] = { csr_pmpaddr32 }
csr[ csr_pmpaddr48 ] = { csr_pmpaddr48 }

.end
603 changes: 308 additions & 295 deletions design/dec/el2_dec.sv

Large diffs are not rendered by default.

148 changes: 148 additions & 0 deletions design/dec/el2_dec_pmp_ctl.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright 2023 Antmicro <www.antmicro.com>
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.


//********************************************************************************
// el2_dec_pmp_ctl.sv
//
//
// Function: Physical Memory Protection CSRs
// Comments:
//
//********************************************************************************


module el2_dec_pmp_ctl
import el2_pkg::*;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[verible-verilog-format] reported by reviewdog 🐶

Suggested change
import el2_pkg::*;
import el2_pkg::*;

#(
`include "el2_param.vh"
)
(
input logic clk,
input logic free_l2clk,
input logic csr_wr_clk,
input logic rst_l,
input logic dec_csr_wen_r_mod, // csr write enable at wb
input logic [11:0] dec_csr_wraddr_r, // write address for csr
input logic [31:0] dec_csr_wrdata_r, // csr write data at wb
input logic [11:0] dec_csr_rdaddr_d, // read address for csr

input logic csr_pmpcfg,
input logic csr_pmpaddr0,
input logic csr_pmpaddr16,
input logic csr_pmpaddr32,
input logic csr_pmpaddr48,

input logic dec_pause_state, // Paused
input logic dec_tlu_pmu_fw_halted, // pmu/fw halted
input logic internal_dbg_halt_timers, // debug halted

output logic [31:0] dec_pmp_rddata_d, // pmp CSR read data
output logic dec_pmp_read_d, // pmp CSR address match

output el2_pmp_cfg_pkt_t pmp_pmpcfg [pt.PMP_ENTRIES],
output logic [31:0] pmp_pmpaddr [pt.PMP_ENTRIES],

input logic scan_mode
);

logic wr_pmpcfg_r;
logic [3:0] wr_pmpcfg_group;

logic wr_pmpaddr0_sel;
logic wr_pmpaddr16_sel;
logic wr_pmpaddr32_sel;
logic wr_pmpaddr48_sel;
logic wr_pmpaddr_r;
logic [1:0] wr_pmpaddr_quarter;
logic [5:0] wr_pmpaddr_address;

logic [3:0] pmp_quarter_rdaddr;
logic [31:0] pmp_pmpcfg_rddata;

// ----------------------------------------------------------------------
// PMPCFGx (RW)
// [31:24] : PMP entry (x*4 + 3) configuration
// [23:16] : PMP entry (x*4 + 2) configuration
// [15:8] : PMP entry (x*4 + 1) configuration
// [7:0] : PMP entry (x*4 + 0) configuration

localparam PMPCFG = 12'h3a0;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ [verible-verilog-lint] reported by reviewdog 🐶
Explicitly define a storage type for every parameter and localparam, (PMPCFG). [Style: constants] [explicit-parameter-storage-type]


assign wr_pmpcfg_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:4] == PMPCFG[11:4]);
assign wr_pmpcfg_group = dec_csr_wraddr_r[3:0]; // selects group of 4 pmpcfg entries (group 1 -> entries 4-7; up to 16 groups)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ [verible-verilog-lint] reported by reviewdog 🐶
Line length exceeds max: 100; is: 129 [Style: line-length] [line-length]


for (genvar entry_idx = 0; entry_idx < pt.PMP_ENTRIES; entry_idx++) begin : gen_pmpcfg_ff
rvdffe #(8) pmpcfg_ff (.*, .clk(free_l2clk),
.en(wr_pmpcfg_r & (wr_pmpcfg_group == entry_idx[5:2]) & (~pmp_pmpcfg[entry_idx].lock)),

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ [verible-verilog-lint] reported by reviewdog 🐶
Line length exceeds max: 100; is: 113 [Style: line-length] [line-length]

.din(dec_csr_wrdata_r[(entry_idx[1:0]*8)+7:(entry_idx[1:0]*8)+0] & 8'b10011111),

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ [verible-verilog-lint] reported by reviewdog 🐶
Line length exceeds max: 100; is: 106 [Style: line-length] [line-length]

.dout(pmp_pmpcfg[entry_idx]));
end

// ----------------------------------------------------------------------
// PMPADDRx (RW)
// [31:0] : PMP entry (x) address selector (word addressing)
//
// NOTE: VeeR-EL2 uses 32-bit physical addressing, register bits 31:30 mapping
// to bits 33:32 of the physical address are always set to 0. (WARL)

localparam PMPADDR0 = 12'h3b0;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ [verible-verilog-lint] reported by reviewdog 🐶
Explicitly define a storage type for every parameter and localparam, (PMPADDR0). [Style: constants] [explicit-parameter-storage-type]

localparam PMPADDR16 = 12'h3c0;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ [verible-verilog-lint] reported by reviewdog 🐶
Explicitly define a storage type for every parameter and localparam, (PMPADDR16). [Style: constants] [explicit-parameter-storage-type]

localparam PMPADDR32 = 12'h3d0;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ [verible-verilog-lint] reported by reviewdog 🐶
Explicitly define a storage type for every parameter and localparam, (PMPADDR32). [Style: constants] [explicit-parameter-storage-type]

localparam PMPADDR48 = 12'h3e0;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ [verible-verilog-lint] reported by reviewdog 🐶
Explicitly define a storage type for every parameter and localparam, (PMPADDR48). [Style: constants] [explicit-parameter-storage-type]


assign wr_pmpaddr0_sel = dec_csr_wraddr_r[11:4] == PMPADDR0[11:4];
assign wr_pmpaddr16_sel = dec_csr_wraddr_r[11:4] == PMPADDR16[11:4];
assign wr_pmpaddr32_sel = dec_csr_wraddr_r[11:4] == PMPADDR32[11:4];
assign wr_pmpaddr48_sel = dec_csr_wraddr_r[11:4] == PMPADDR48[11:4];
assign wr_pmpaddr_r = dec_csr_wen_r_mod & (wr_pmpaddr0_sel | wr_pmpaddr16_sel | wr_pmpaddr32_sel | wr_pmpaddr48_sel);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ [verible-verilog-lint] reported by reviewdog 🐶
Line length exceeds max: 100; is: 120 [Style: line-length] [line-length]


assign wr_pmpaddr_quarter[0] = wr_pmpaddr16_sel | wr_pmpaddr48_sel;
assign wr_pmpaddr_quarter[1] = wr_pmpaddr32_sel | wr_pmpaddr48_sel;
assign wr_pmpaddr_address = {wr_pmpaddr_quarter, dec_csr_wraddr_r[3:0]}; // entry address

for (genvar entry_idx = 0; entry_idx < pt.PMP_ENTRIES; entry_idx++) begin : gen_pmpaddr_ff
logic pmpaddr_lock;
logic pmpaddr_lock_next;
assign pmpaddr_lock_next = ((entry_idx+1 < pt.PMP_ENTRIES)
Comment on lines +30 to +119

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[verible-verilog-format] reported by reviewdog 🐶

Suggested change
`include "el2_param.vh"
)
(
input logic clk,
input logic free_l2clk,
input logic csr_wr_clk,
input logic rst_l,
input logic dec_csr_wen_r_mod, // csr write enable at wb
input logic [11:0] dec_csr_wraddr_r, // write address for csr
input logic [31:0] dec_csr_wrdata_r, // csr write data at wb
input logic [11:0] dec_csr_rdaddr_d, // read address for csr
input logic csr_pmpcfg,
input logic csr_pmpaddr0,
input logic csr_pmpaddr16,
input logic csr_pmpaddr32,
input logic csr_pmpaddr48,
input logic dec_pause_state, // Paused
input logic dec_tlu_pmu_fw_halted, // pmu/fw halted
input logic internal_dbg_halt_timers, // debug halted
output logic [31:0] dec_pmp_rddata_d, // pmp CSR read data
output logic dec_pmp_read_d, // pmp CSR address match
output el2_pmp_cfg_pkt_t pmp_pmpcfg [pt.PMP_ENTRIES],
output logic [31:0] pmp_pmpaddr [pt.PMP_ENTRIES],
input logic scan_mode
);
logic wr_pmpcfg_r;
logic [3:0] wr_pmpcfg_group;
logic wr_pmpaddr0_sel;
logic wr_pmpaddr16_sel;
logic wr_pmpaddr32_sel;
logic wr_pmpaddr48_sel;
logic wr_pmpaddr_r;
logic [1:0] wr_pmpaddr_quarter;
logic [5:0] wr_pmpaddr_address;
logic [3:0] pmp_quarter_rdaddr;
logic [31:0] pmp_pmpcfg_rddata;
// ----------------------------------------------------------------------
// PMPCFGx (RW)
// [31:24] : PMP entry (x*4 + 3) configuration
// [23:16] : PMP entry (x*4 + 2) configuration
// [15:8] : PMP entry (x*4 + 1) configuration
// [7:0] : PMP entry (x*4 + 0) configuration
localparam PMPCFG = 12'h3a0;
assign wr_pmpcfg_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:4] == PMPCFG[11:4]);
assign wr_pmpcfg_group = dec_csr_wraddr_r[3:0]; // selects group of 4 pmpcfg entries (group 1 -> entries 4-7; up to 16 groups)
for (genvar entry_idx = 0; entry_idx < pt.PMP_ENTRIES; entry_idx++) begin : gen_pmpcfg_ff
rvdffe #(8) pmpcfg_ff (.*, .clk(free_l2clk),
.en(wr_pmpcfg_r & (wr_pmpcfg_group == entry_idx[5:2]) & (~pmp_pmpcfg[entry_idx].lock)),
.din(dec_csr_wrdata_r[(entry_idx[1:0]*8)+7:(entry_idx[1:0]*8)+0] & 8'b10011111),
.dout(pmp_pmpcfg[entry_idx]));
end
// ----------------------------------------------------------------------
// PMPADDRx (RW)
// [31:0] : PMP entry (x) address selector (word addressing)
//
// NOTE: VeeR-EL2 uses 32-bit physical addressing, register bits 31:30 mapping
// to bits 33:32 of the physical address are always set to 0. (WARL)
localparam PMPADDR0 = 12'h3b0;
localparam PMPADDR16 = 12'h3c0;
localparam PMPADDR32 = 12'h3d0;
localparam PMPADDR48 = 12'h3e0;
assign wr_pmpaddr0_sel = dec_csr_wraddr_r[11:4] == PMPADDR0[11:4];
assign wr_pmpaddr16_sel = dec_csr_wraddr_r[11:4] == PMPADDR16[11:4];
assign wr_pmpaddr32_sel = dec_csr_wraddr_r[11:4] == PMPADDR32[11:4];
assign wr_pmpaddr48_sel = dec_csr_wraddr_r[11:4] == PMPADDR48[11:4];
assign wr_pmpaddr_r = dec_csr_wen_r_mod & (wr_pmpaddr0_sel | wr_pmpaddr16_sel | wr_pmpaddr32_sel | wr_pmpaddr48_sel);
assign wr_pmpaddr_quarter[0] = wr_pmpaddr16_sel | wr_pmpaddr48_sel;
assign wr_pmpaddr_quarter[1] = wr_pmpaddr32_sel | wr_pmpaddr48_sel;
assign wr_pmpaddr_address = {wr_pmpaddr_quarter, dec_csr_wraddr_r[3:0]}; // entry address
for (genvar entry_idx = 0; entry_idx < pt.PMP_ENTRIES; entry_idx++) begin : gen_pmpaddr_ff
logic pmpaddr_lock;
logic pmpaddr_lock_next;
assign pmpaddr_lock_next = ((entry_idx+1 < pt.PMP_ENTRIES)
`include "el2_param.vh"
) (
input logic clk,
input logic free_l2clk,
input logic csr_wr_clk,
input logic rst_l,
input logic dec_csr_wen_r_mod, // csr write enable at wb
input logic [11:0] dec_csr_wraddr_r, // write address for csr
input logic [31:0] dec_csr_wrdata_r, // csr write data at wb
input logic [11:0] dec_csr_rdaddr_d, // read address for csr
input logic csr_pmpcfg,
input logic csr_pmpaddr0,
input logic csr_pmpaddr16,
input logic csr_pmpaddr32,
input logic csr_pmpaddr48,
input logic dec_pause_state, // Paused
input logic dec_tlu_pmu_fw_halted, // pmu/fw halted
input logic internal_dbg_halt_timers, // debug halted
output logic [31:0] dec_pmp_rddata_d, // pmp CSR read data
output logic dec_pmp_read_d, // pmp CSR address match
output el2_pmp_cfg_pkt_t pmp_pmpcfg [pt.PMP_ENTRIES],
output logic [31:0] pmp_pmpaddr[pt.PMP_ENTRIES],
input logic scan_mode
);
logic wr_pmpcfg_r;
logic [3:0] wr_pmpcfg_group;
logic wr_pmpaddr0_sel;
logic wr_pmpaddr16_sel;
logic wr_pmpaddr32_sel;
logic wr_pmpaddr48_sel;
logic wr_pmpaddr_r;
logic [1:0] wr_pmpaddr_quarter;
logic [5:0] wr_pmpaddr_address;
logic [3:0] pmp_quarter_rdaddr;
logic [31:0] pmp_pmpcfg_rddata;
// ----------------------------------------------------------------------
// PMPCFGx (RW)
// [31:24] : PMP entry (x*4 + 3) configuration
// [23:16] : PMP entry (x*4 + 2) configuration
// [15:8] : PMP entry (x*4 + 1) configuration
// [7:0] : PMP entry (x*4 + 0) configuration
localparam PMPCFG = 12'h3a0;
assign wr_pmpcfg_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:4] == PMPCFG[11:4]);
assign wr_pmpcfg_group = dec_csr_wraddr_r[3:0]; // selects group of 4 pmpcfg entries (group 1 -> entries 4-7; up to 16 groups)
for (genvar entry_idx = 0; entry_idx < pt.PMP_ENTRIES; entry_idx++) begin : gen_pmpcfg_ff
rvdffe #(8) pmpcfg_ff (
.*,
.clk (free_l2clk),
.en (wr_pmpcfg_r & (wr_pmpcfg_group == entry_idx[5:2]) & (~pmp_pmpcfg[entry_idx].lock)),
.din (dec_csr_wrdata_r[(entry_idx[1:0]*8)+7:(entry_idx[1:0]*8)+0] & 8'b10011111),
.dout(pmp_pmpcfg[entry_idx])
);
end
// ----------------------------------------------------------------------
// PMPADDRx (RW)
// [31:0] : PMP entry (x) address selector (word addressing)
//
// NOTE: VeeR-EL2 uses 32-bit physical addressing, register bits 31:30 mapping
// to bits 33:32 of the physical address are always set to 0. (WARL)
localparam PMPADDR0 = 12'h3b0;
localparam PMPADDR16 = 12'h3c0;
localparam PMPADDR32 = 12'h3d0;
localparam PMPADDR48 = 12'h3e0;
assign wr_pmpaddr0_sel = dec_csr_wraddr_r[11:4] == PMPADDR0[11:4];
assign wr_pmpaddr16_sel = dec_csr_wraddr_r[11:4] == PMPADDR16[11:4];
assign wr_pmpaddr32_sel = dec_csr_wraddr_r[11:4] == PMPADDR32[11:4];
assign wr_pmpaddr48_sel = dec_csr_wraddr_r[11:4] == PMPADDR48[11:4];
assign wr_pmpaddr_r = dec_csr_wen_r_mod & (wr_pmpaddr0_sel | wr_pmpaddr16_sel | wr_pmpaddr32_sel | wr_pmpaddr48_sel);
assign wr_pmpaddr_quarter[0] = wr_pmpaddr16_sel | wr_pmpaddr48_sel;
assign wr_pmpaddr_quarter[1] = wr_pmpaddr32_sel | wr_pmpaddr48_sel;
assign wr_pmpaddr_address = {wr_pmpaddr_quarter, dec_csr_wraddr_r[3:0]}; // entry address
for (genvar entry_idx = 0; entry_idx < pt.PMP_ENTRIES; entry_idx++) begin : gen_pmpaddr_ff
logic pmpaddr_lock;
logic pmpaddr_lock_next;
assign pmpaddr_lock_next = ((entry_idx+1 < pt.PMP_ENTRIES)

? (pmp_pmpcfg[entry_idx+1].lock
& pmp_pmpcfg[entry_idx+1].mode == TOR)
: 1'b0);
assign pmpaddr_lock = pmp_pmpcfg[entry_idx].lock | pmpaddr_lock_next;
assign pmp_pmpaddr[entry_idx][31:30] = 2'b00;
rvdffe #(30) pmpaddr_ff (.*, .clk(free_l2clk),
.en(wr_pmpaddr_r & (wr_pmpaddr_address == entry_idx)
& (~pmpaddr_lock)),
.din(dec_csr_wrdata_r[29:0]),
.dout(pmp_pmpaddr[entry_idx][29:0]));
end

// CSR read mux

assign pmp_quarter_rdaddr = dec_csr_rdaddr_d[3:0];
assign pmp_pmpcfg_rddata = { pmp_pmpcfg[{pmp_quarter_rdaddr, 2'h3}],
pmp_pmpcfg[{pmp_quarter_rdaddr, 2'h2}],
pmp_pmpcfg[{pmp_quarter_rdaddr, 2'h1}],
pmp_pmpcfg[{pmp_quarter_rdaddr, 2'h0}]
};
assign dec_pmp_read_d = csr_pmpcfg | csr_pmpaddr0 | csr_pmpaddr16 | csr_pmpaddr32 | csr_pmpaddr48;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ [verible-verilog-lint] reported by reviewdog 🐶
Line length exceeds max: 100; is: 109 [Style: line-length] [line-length]

assign dec_pmp_rddata_d[31:0] = ( ({32{csr_pmpcfg}} & pmp_pmpcfg_rddata) |
Comment on lines +123 to +141

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[verible-verilog-format] reported by reviewdog 🐶

Suggested change
assign pmpaddr_lock = pmp_pmpcfg[entry_idx].lock | pmpaddr_lock_next;
assign pmp_pmpaddr[entry_idx][31:30] = 2'b00;
rvdffe #(30) pmpaddr_ff (.*, .clk(free_l2clk),
.en(wr_pmpaddr_r & (wr_pmpaddr_address == entry_idx)
& (~pmpaddr_lock)),
.din(dec_csr_wrdata_r[29:0]),
.dout(pmp_pmpaddr[entry_idx][29:0]));
end
// CSR read mux
assign pmp_quarter_rdaddr = dec_csr_rdaddr_d[3:0];
assign pmp_pmpcfg_rddata = { pmp_pmpcfg[{pmp_quarter_rdaddr, 2'h3}],
pmp_pmpcfg[{pmp_quarter_rdaddr, 2'h2}],
pmp_pmpcfg[{pmp_quarter_rdaddr, 2'h1}],
pmp_pmpcfg[{pmp_quarter_rdaddr, 2'h0}]
};
assign dec_pmp_read_d = csr_pmpcfg | csr_pmpaddr0 | csr_pmpaddr16 | csr_pmpaddr32 | csr_pmpaddr48;
assign dec_pmp_rddata_d[31:0] = ( ({32{csr_pmpcfg}} & pmp_pmpcfg_rddata) |
assign pmpaddr_lock = pmp_pmpcfg[entry_idx].lock | pmpaddr_lock_next;
assign pmp_pmpaddr[entry_idx][31:30] = 2'b00;
rvdffe #(30) pmpaddr_ff (
.*,
.clk (free_l2clk),
.en (wr_pmpaddr_r & (wr_pmpaddr_address == entry_idx) & (~pmpaddr_lock)),
.din (dec_csr_wrdata_r[29:0]),
.dout(pmp_pmpaddr[entry_idx][29:0])
);
end
// CSR read mux
assign pmp_quarter_rdaddr = dec_csr_rdaddr_d[3:0];
assign pmp_pmpcfg_rddata = {
pmp_pmpcfg[{pmp_quarter_rdaddr, 2'h3}],
pmp_pmpcfg[{pmp_quarter_rdaddr, 2'h2}],
pmp_pmpcfg[{pmp_quarter_rdaddr, 2'h1}],
pmp_pmpcfg[{pmp_quarter_rdaddr, 2'h0}]
};
assign dec_pmp_read_d = csr_pmpcfg | csr_pmpaddr0 | csr_pmpaddr16 | csr_pmpaddr32 | csr_pmpaddr48;
assign dec_pmp_rddata_d[31:0] = ( ({32{csr_pmpcfg}} & pmp_pmpcfg_rddata) |

({32{csr_pmpaddr0}} & pmp_pmpaddr[{2'h0, pmp_quarter_rdaddr}]) |

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ [verible-verilog-lint] reported by reviewdog 🐶
Line length exceeds max: 100; is: 102 [Style: line-length] [line-length]

({32{csr_pmpaddr16}} & pmp_pmpaddr[{2'h1, pmp_quarter_rdaddr}]) |

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ [verible-verilog-lint] reported by reviewdog 🐶
Line length exceeds max: 100; is: 102 [Style: line-length] [line-length]

({32{csr_pmpaddr32}} & pmp_pmpaddr[{2'h2, pmp_quarter_rdaddr}]) |

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ [verible-verilog-lint] reported by reviewdog 🐶
Line length exceeds max: 100; is: 102 [Style: line-length] [line-length]

({32{csr_pmpaddr48}} & pmp_pmpaddr[{2'h3, pmp_quarter_rdaddr}])
);

endmodule // dec_pmp_ctl

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[verible-verilog-format] reported by reviewdog 🐶

Suggested change
endmodule // dec_pmp_ctl
endmodule // dec_pmp_ctl

Loading
Loading