Skip to content

Commit

Permalink
[racl] Parse RACL config and generate top_racl_pkg.sv
Browse files Browse the repository at this point in the history
Signed-off-by: Robert Schilling <[email protected]>
  • Loading branch information
Razer6 committed Dec 17, 2024
1 parent 11988f6 commit 99ac57e
Show file tree
Hide file tree
Showing 11 changed files with 296 additions and 0 deletions.
55 changes: 55 additions & 0 deletions hw/top_darjeeling/rtl/autogen/top_racl_pkg.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// Copyright lowRISC contributors (OpenTitan project).
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
//
// ------------------- W A R N I N G: A U T O - G E N E R A T E D C O D E !! -------------------//
// PLEASE DO NOT HAND-EDIT THIS FILE. IT HAS BEEN AUTO-GENERATED WITH THE FOLLOWING COMMAND:
//
// util/topgen.py -t hw/top_darjeeling/data/top_darjeeling.hjson \
// -o hw/top_darjeeling/ \
// --rnd_cnst_seed \
// 1017106219537032642877583828875051302543807092889754935647094601236425074047


package top_racl_pkg;
// Number of RACL policies used
parameter int unsigned NrRaclPolicies = 1;

// RACL role type binary encoded
typedef logic [3:0] racl_role_t;

// CTN UID assigned the bus originator
typedef logic [7:0] ctn_uid_t;

// RACL permission and one-hot encoded role vector
typedef logic [2**$bits(racl_role_t)-1:0] racl_role_vec_t;

// RACL policy vector containing a read and write permission
typedef struct packed {
racl_role_vec_t read_perm;
racl_role_vec_t write_perm;
} racl_policy_t;

// RACL policy vector for distributing RACL policies from the RACL widget to the subscribing IP
typedef racl_policy_t [NrRaclPolicies-1:0] racl_policy_vec_t;

// RACL information logged in case of a denial
typedef struct packed {
racl_role_t racl_role;
ctn_uid_t ctn_uid;
// 0: Write access, 1: Read access
logic write_read;
} racl_error_log_t;

// Extract RACL role bits from the TLUL reserved user bits
function automatic racl_role_t tlul_extract_racl_role_bits(tlul_pkg::tl_a_user_t tl_req_user);
return racl_role_t'(tl_req_user.rsvd[11:8]);
endfunction

// Extract CTN UID bits from the TLUL reserved user bits
function automatic ctn_uid_t tlul_extract_ctn_uid_bits(tlul_pkg::tl_a_user_t tl_req_user);
return ctn_uid_t'(tl_req_user.rsvd[7:0]);
endfunction


endpackage
1 change: 1 addition & 0 deletions hw/top_darjeeling/top_darjeeling.core
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ filesets:
files_rtl_generic:
depend:
# Place the autogen packages first to avoid conflicts
- lowrisc:systems:top_darjeeling_racl_pkg
- lowrisc:opentitan:top_darjeeling_alert_handler_reg
- lowrisc:opentitan:top_darjeeling_pwrmgr_pkg
- lowrisc:ip:uart:0.1
Expand Down
21 changes: 21 additions & 0 deletions hw/top_darjeeling/top_darjeeling_racl_pkg.core
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
CAPI=2:
# Copyright lowRISC contributors (OpenTitan project).
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0
name: "lowrisc:systems:top_darjeeling_racl_pkg:0.1"
description: "Autogenerated top_darjeeling_racl_pkg used in RTL and DV."
virtual:
- lowrisc:systems:top_racl_pkg

filesets:
files_rtl:
depend:
- lowrisc:ip:tlul
files:
- rtl/autogen/top_racl_pkg.sv
file_type: systemVerilogSource

targets:
default: &default_target
filesets:
- files_rtl
55 changes: 55 additions & 0 deletions hw/top_earlgrey/rtl/autogen/top_racl_pkg.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// Copyright lowRISC contributors (OpenTitan project).
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
//
// ------------------- W A R N I N G: A U T O - G E N E R A T E D C O D E !! -------------------//
// PLEASE DO NOT HAND-EDIT THIS FILE. IT HAS BEEN AUTO-GENERATED WITH THE FOLLOWING COMMAND:
//
// util/topgen.py -t hw/top_earlgrey/data/top_earlgrey.hjson \
// -o hw/top_earlgrey/ \
// --rnd_cnst_seed \
// 1017106219537032642877583828875051302543807092889754935647094601236425074047


package top_racl_pkg;
// Number of RACL policies used
parameter int unsigned NrRaclPolicies = 1;

// RACL role type binary encoded
typedef logic [3:0] racl_role_t;

// CTN UID assigned the bus originator
typedef logic [7:0] ctn_uid_t;

// RACL permission and one-hot encoded role vector
typedef logic [2**$bits(racl_role_t)-1:0] racl_role_vec_t;

// RACL policy vector containing a read and write permission
typedef struct packed {
racl_role_vec_t read_perm;
racl_role_vec_t write_perm;
} racl_policy_t;

// RACL policy vector for distributing RACL policies from the RACL widget to the subscribing IP
typedef racl_policy_t [NrRaclPolicies-1:0] racl_policy_vec_t;

// RACL information logged in case of a denial
typedef struct packed {
racl_role_t racl_role;
ctn_uid_t ctn_uid;
// 0: Write access, 1: Read access
logic write_read;
} racl_error_log_t;

// Extract RACL role bits from the TLUL reserved user bits
function automatic racl_role_t tlul_extract_racl_role_bits(tlul_pkg::tl_a_user_t tl_req_user);
return racl_role_t'(tl_req_user.rsvd[11:8]);
endfunction

// Extract CTN UID bits from the TLUL reserved user bits
function automatic ctn_uid_t tlul_extract_ctn_uid_bits(tlul_pkg::tl_a_user_t tl_req_user);
return ctn_uid_t'(tl_req_user.rsvd[7:0]);
endfunction


endpackage
1 change: 1 addition & 0 deletions hw/top_earlgrey/top_earlgrey.core
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ filesets:
files_rtl_generic:
depend:
# Place the autogen packages first to avoid conflicts
- lowrisc:systems:top_earlgrey_racl_pkg
- lowrisc:opentitan:top_earlgrey_alert_handler_reg
- lowrisc:opentitan:top_earlgrey_pwrmgr_pkg
- lowrisc:ip:uart:0.1
Expand Down
21 changes: 21 additions & 0 deletions hw/top_earlgrey/top_earlgrey_racl_pkg.core
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
CAPI=2:
# Copyright lowRISC contributors (OpenTitan project).
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0
name: "lowrisc:systems:top_earlgrey_racl_pkg:0.1"
description: "Autogenerated top_earlgrey_racl_pkg used in RTL and DV."
virtual:
- lowrisc:systems:top_racl_pkg

filesets:
files_rtl:
depend:
- lowrisc:ip:tlul
files:
- rtl/autogen/top_racl_pkg.sv
file_type: systemVerilogSource

targets:
default: &default_target
filesets:
- files_rtl
3 changes: 3 additions & 0 deletions util/raclgen/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Copyright lowRISC contributors (OpenTitan project).
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0
51 changes: 51 additions & 0 deletions util/raclgen/lib.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Copyright lowRISC contributors (OpenTitan project).
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0

import hjson
import sys
from reggen.validate import check_keys

# Required fields for the RACL hjson
racl_required = {
'roles': ['l', 'List, specifying all RACL roles'],
'policies': ['g', 'Dict, specifying the policies of all RACL groups']
}


# Default configuration to render the RACL package for systems that don't use RACL but need the
# type definitions
DEFAULT_RACL_CONFIG = {
'nr_policies': 1,
'policies': {},
}


def parse_racl_config(config_file: str):
try:
with open(config_file, 'r') as f_racl_config:
racl_config = hjson.load(f_racl_config)
except OSError:
raise SystemExit(sys.exc_info()[1])

# TODO further error handling
error = check_keys(racl_config, racl_required, [], [], 'RACL Config')
if error:
raise SystemExit(f"Error occured while validating {config_file}")

# Determine the maximum number of policies over all RACL groups for RTL
# RTL needs to create the vectors based on the largest group
racl_config['nr_policies'] = max(len(policies) for policies in racl_config['policies'].values())

for racl_group, policies in racl_config['policies'].items():
for policy in policies:
def compute_policy_value(permission: str):
permission_value = 0
for role in policy[permission]:
role_id = racl_config['roles'][role]['role_id']
permission_value += 2**role_id
return permission_value

policy['rd_default'] = compute_policy_value('allowed_rd')
policy['wr_default'] = compute_policy_value('allowed_wr')
return racl_config
19 changes: 19 additions & 0 deletions util/topgen.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
IpTemplate, TemplateRenderError)
from mako import exceptions
from mako.template import Template
from raclgen.lib import DEFAULT_RACL_CONFIG, parse_racl_config
from reggen import access, gen_rtl, gen_sec_cm_testplan, window
from reggen.countermeasure import CounterMeasure
from reggen.inter_signal import InterSignal
Expand Down Expand Up @@ -526,6 +527,15 @@ def generate_ac_range_check(topcfg: Dict[str, object], out_path: Path) -> None:
ipgen_render("ac_range_check", topname, params, out_path)


# Generate RACL collateral
def generate_racl(topcfg: Dict[str, object], out_path: Path) -> None:
# Not all tops use RACL
if 'racl_config' not in topcfg:
return

topcfg['racl'] = parse_racl_config(topcfg['racl_config'])


def generate_top_only(top_only_dict: Dict[str, bool], out_path: Path,
top_name: str, alt_hjson_path: str) -> None:
log.info("Generating top only modules")
Expand Down Expand Up @@ -866,6 +876,9 @@ def _process_top(
# Generate ac_range_check
generate_ac_range_check(completecfg, out_path)

# Generate RACL collateral
generate_racl(completecfg, out_path)

# Generate top only modules
# These modules are not ipgen, but are not in hw/ip
generate_top_only(top_only_dict, cfg_path, top_name, args.hjson_path)
Expand Down Expand Up @@ -1249,6 +1262,12 @@ def render_template(template_path: str, rendered_path: Path,
out_path / f"rtl/autogen/{top_name}_rnd_cnst_pkg.sv",
gencmd=gencmd)

racl_config = completecfg['racl'] if 'racl' in completecfg else DEFAULT_RACL_CONFIG
render_template(TOPGEN_TEMPLATE_PATH / 'toplevel_racl_pkg.sv.tpl',
out_path / 'rtl' / 'autogen' / 'top_racl_pkg.sv',
gencmd=gencmd,
racl_config=racl_config)

# Since SW does not use FuseSoC and instead expects those files always
# to be in hw/top_{topname}/sw/autogen, we currently create these files
# twice:
Expand Down
68 changes: 68 additions & 0 deletions util/topgen/templates/toplevel_racl_pkg.sv.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// Copyright lowRISC contributors (OpenTitan project).
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
${gencmd}

package top_racl_pkg;
// Number of RACL policies used
parameter int unsigned NrRaclPolicies = ${racl_config['nr_policies']};

// RACL role type binary encoded
typedef logic [3:0] racl_role_t;

// CTN UID assigned the bus originator
typedef logic [7:0] ctn_uid_t;

// RACL permission and one-hot encoded role vector
typedef logic [2**$bits(racl_role_t)-1:0] racl_role_vec_t;

// RACL policy vector containing a read and write permission
typedef struct packed {
racl_role_vec_t read_perm;
racl_role_vec_t write_perm;
} racl_policy_t;

// RACL policy vector for distributing RACL policies from the RACL widget to the subscribing IP
typedef racl_policy_t [NrRaclPolicies-1:0] racl_policy_vec_t;

// RACL information logged in case of a denial
typedef struct packed {
racl_role_t racl_role;
ctn_uid_t ctn_uid;
// 0: Write access, 1: Read access
logic write_read;
} racl_error_log_t;

// Extract RACL role bits from the TLUL reserved user bits
function automatic racl_role_t tlul_extract_racl_role_bits(tlul_pkg::tl_a_user_t tl_req_user);
return racl_role_t'(tl_req_user.rsvd[11:8]);
endfunction

// Extract CTN UID bits from the TLUL reserved user bits
function automatic ctn_uid_t tlul_extract_ctn_uid_bits(tlul_pkg::tl_a_user_t tl_req_user);
return ctn_uid_t'(tl_req_user.rsvd[7:0]);
endfunction

% for racl_group, policies in racl_config['policies'].items():
<% prefix = "" if len(racl_config['policies'].keys()) == 1 else f"{racl_group.upper()}_" %>\
/**
* Policies for group ${racl_group}
*/

% for policy in policies:
/*
* Policy ${policy['name']} allowed READ roles:
* ${', '.join(policy['allowed_wr'])}
*/
parameter racl_policy_t RACL_POLICY_${prefix}${policy['name'].upper()}_RD_DEFAULT = 16'h${f"{policy['rd_default']:x}"};

/**
* Policy ${policy['name']} allowed WRITE roles:
* ${', '.join(policy['allowed_wr'])}
*/
parameter racl_policy_t RACL_POLICY_${prefix}${policy['name'].upper()}_WR_DEFAULT = 16'h${f"{policy['wr_default']:x}"};

% endfor
% endfor

endpackage
1 change: 1 addition & 0 deletions util/topgen/validate.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
'num_cores': ['pn', "number of computing units"],
'power': ['g', 'power domains supported by the design'],
'port': ['g', 'assign special attributes to specific ports'],
'racl_config': ['s', 'Path to a RACL configuration HJSON file'],
'rnd_cnst_seed': ['int', "Seed for random netlist constant computation"],
'unmanaged_resets': ['l', 'List of unmanaged external resets']
}
Expand Down

0 comments on commit 99ac57e

Please sign in to comment.