Skip to content

Commit 18a7bb2

Browse files
[racl,raclgen,topgen] Deduplicate RACL templates
Signed-off-by: David Schrammel <davidschrammel@rivosinc.com>
1 parent 9926f91 commit 18a7bb2

File tree

7 files changed

+124
-214
lines changed

7 files changed

+124
-214
lines changed

hw/top_darjeeling/templates/toplevel.sv.tpl

Lines changed: 1 addition & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -486,44 +486,7 @@ max_intrwidth = (max(len(x.name) for x in block.interrupts)
486486
%>\
487487
% if m["param_list"] or block.alerts:
488488
${m["type"]} #(
489-
<%doc>
490-
Note: The RACL parameters must be generated identically across multiple files.
491-
Thus, this template needs to be manually synced between the following files:
492-
util/raclgen.py
493-
util/topgen/templates/toplevel_racl_pkg.sv.tpl
494-
hw/top_darjeeling/templates/toplevel.sv.tpl
495-
hw/top_earlgrey/templates/toplevel.sv.tpl
496-
hw/top_englishbreakfast/templates/toplevel.sv.tpl
497-
</%doc>\
498-
% if m.get('racl_mappings'):
499-
.EnableRacl(1'b1),
500-
.RaclErrorRsp(${"1'b1" if top['racl']['error_response'] else "1'b0"}),
501-
% for if_name in m['racl_mappings'].keys():
502-
<%
503-
register_mapping = m['racl_mappings'][if_name]['register_mapping']
504-
window_mapping = m['racl_mappings'][if_name]['window_mapping']
505-
range_mapping = m['racl_mappings'][if_name]['range_mapping']
506-
racl_group = m['racl_mappings'][if_name]['racl_group']
507-
group_suffix = f"_{racl_group.upper()}" if racl_group and racl_group != "Null" else ""
508-
if_suffix = f"_{if_name.upper()}" if if_name else ""
509-
if_suffix2 = f"{if_name.title()}" if if_name else ""
510-
policy_sel_name = f"RACL_POLICY_SEL_{m['name'].upper()}{group_suffix}{if_suffix}"
511-
%>\
512-
% if len(register_mapping) > 0:
513-
.RaclPolicySelVec${if_suffix2}(${policy_sel_name}),
514-
% endif
515-
% for window_name, policy_idx in window_mapping.items():
516-
.RaclPolicySelWin${if_suffix2}${window_name.replace("_","").title()}(${policy_sel_name}_WIN_${window_name.upper()}),
517-
% endfor
518-
% if len(range_mapping) > 0:
519-
.RaclPolicySelRanges${if_suffix2}Num(top_racl_pkg::${policy_sel_name}_NUM_RANGES),
520-
.RaclPolicySelRanges${if_suffix2}(top_racl_pkg::${policy_sel_name}_RANGES),
521-
% endif
522-
% endfor
523-
% endif
524-
% if m.get('template_type') == 'racl_ctrl':
525-
.RaclErrorRsp(${"1'b1" if top['racl']['error_response'] else "1'b0"}),
526-
% endif
489+
<%include file="/toplevel_racl.tpl" args="m=m,top=top"/>\
527490
% if block.alerts:
528491
<%
529492
w = len(block.alerts)

hw/top_earlgrey/templates/toplevel.sv.tpl

Lines changed: 1 addition & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -502,44 +502,7 @@ max_intrwidth = (max(len(x.name) for x in block.interrupts)
502502
%>\
503503
% if m["param_list"] or block.alerts:
504504
${m["type"]} #(
505-
<%doc>
506-
Note: The RACL parameters must be generated identically across multiple files.
507-
Thus, this template needs to be manually synced between the following files:
508-
util/raclgen.py
509-
util/topgen/templates/toplevel_racl_pkg.sv.tpl
510-
hw/top_darjeeling/templates/toplevel.sv.tpl
511-
hw/top_earlgrey/templates/toplevel.sv.tpl
512-
hw/top_englishbreakfast/templates/toplevel.sv.tpl
513-
</%doc>\
514-
% if 'racl_mappings' in m:
515-
.EnableRacl(1'b1),
516-
.RaclErrorRsp(${"1'b1" if top['racl']['error_response'] else "1'b0"}),
517-
% for if_name in m['racl_mappings'].keys():
518-
<%
519-
register_mapping = m['racl_mappings'][if_name]['register_mapping']
520-
window_mapping = m['racl_mappings'][if_name]['window_mapping']
521-
range_mapping = m['racl_mappings'][if_name]['range_mapping']
522-
racl_group = m['racl_mappings'][if_name]['racl_group']
523-
group_suffix = f"_{racl_group.upper()}" if racl_group and racl_group != "Null" else ""
524-
if_suffix = f"_{if_name.upper()}" if if_name else ""
525-
if_suffix2 = f"{if_name.title()}" if if_name else ""
526-
policy_sel_name = f"RACL_POLICY_SEL_{m['name'].upper()}{group_suffix}{if_suffix}"
527-
%>\
528-
% if len(register_mapping) > 0:
529-
.RaclPolicySelVec${if_suffix2}(${policy_sel_name}),
530-
% endif
531-
% for window_name, policy_idx in window_mapping.items():
532-
.RaclPolicySelWin${if_suffix2}${window_name.replace("_","").title()}(${policy_sel_name}_WIN_${window_name.upper()}),
533-
% endfor
534-
% if len(range_mapping) > 0:
535-
.RaclPolicySelRanges${if_suffix2}Num(top_racl_pkg::${policy_sel_name}_NUM_RANGES),
536-
.RaclPolicySelRanges${if_suffix2}(top_racl_pkg::${policy_sel_name}_RANGES),
537-
% endif
538-
% endfor
539-
% endif
540-
% if m.get('template_type') == 'racl_ctrl':
541-
.RaclErrorRsp(${"1'b1" if top['racl']['error_response'] else "1'b0"}),
542-
% endif
505+
<%include file="/toplevel_racl.tpl" args="m=m,top=top"/>\
543506
% if block.alerts:
544507
<%
545508
w = len(block.alerts)

util/raclgen.py

Lines changed: 9 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -53,76 +53,15 @@ def main():
5353
register_mapping, window_mapping, range_mapping, racl_group, policy_names\
5454
= parse_racl_mapping(parsed_racl_config, args.mapping, args.if_name, ip_block)
5555

56-
template = """\
57-
<%doc>
58-
Note: The RACL parameters must be generated identically across multiple files.
59-
Thus, this template needs to be manually synced between the following files:
60-
util/raclgen.py
61-
util/topgen/templates/toplevel_racl_pkg.sv.tpl
62-
hw/top_darjeeling/templates/toplevel.sv.tpl
63-
hw/top_earlgrey/templates/toplevel.sv.tpl
64-
hw/top_englishbreakfast/templates/toplevel.sv.tpl
65-
</%doc>\
66-
<% import raclgen.lib as raclgen %>\
67-
<% import math %>\
68-
<% policy_idx_len = math.ceil(math.log10(max(1,len(policy_names)+1))) %>\
69-
<% group_suffix = f"_{racl_group.upper()}" if racl_group and racl_group != "Null" else "" %>\
70-
<% if_suffix = f"_{if_name.upper()}" if if_name else "" %>\
71-
<% reg_name_len = max( (len(name) for name in register_mapping.keys()), default=0 ) %>\
72-
<% window_name_len = max( (len(name) for name in window_mapping.keys()), default=0 ) %>\
73-
<% policy_sel_name = f"RACL_POLICY_SEL_{module_name.upper()}{group_suffix}{if_suffix}" %>\
74-
/**
75-
* Policy selection vector for ${module_name}
76-
* TLUL interface name: ${if_name}
77-
* RACL group: ${racl_group}
78-
% if len(register_mapping) > 0:
79-
* Register to policy mapping:
80-
% for reg_name, policy_idx in register_mapping.items():
81-
* ${f"{reg_name}:".ljust(reg_name_len+1)} ${policy_names[policy_idx]} \
82-
(Idx ${f"{policy_idx}".rjust(policy_idx_len)})
83-
% endfor
84-
% endif
85-
% if len(window_mapping) > 0:
86-
* Window to policy mapping:
87-
% for window_name, policy_idx in window_mapping.items():
88-
* ${f"{window_name}:".ljust(window_name_len+1)} ${policy_names[policy_idx]} \
89-
(Idx ${f"{policy_idx}".rjust(policy_idx_len)})
90-
% endfor
91-
% endif
92-
% if len(range_mapping) > 0:
93-
* Range to policy mapping:
94-
% for range in range_mapping:
95-
* ${f"0x{range['base']:08x}"} -- ${f"0x{(range['base']+range['size']):08x}"} \
96-
policy: ${policy_names[range['policy']]} (Idx ${f"{range['policy']}".rjust(policy_idx_len)})
97-
% endfor
98-
% endif
99-
*/
100-
% if len(register_mapping) > 0:
101-
<% policy_sel_value = "'{" + ", ".join(map(str, reversed(register_mapping.values()))) + "};" %>\
102-
parameter racl_policy_sel_t ${policy_sel_name} [${len(register_mapping)}] = ${policy_sel_value}
103-
% endif
104-
% for window_name, policy_idx in window_mapping.items():
105-
parameter racl_policy_sel_t ${policy_sel_name}_WIN_${window_name.upper()} = ${policy_idx};
106-
% endfor
107-
% if len(range_mapping) > 0:
108-
parameter racl_policy_sel_t ${policy_sel_name}_NUM_RANGES = ${len(range_mapping)};
109-
<% value = ",\\n".join(map(raclgen.format_parameter_range_value, range_mapping)) %>\
110-
parameter racl_range_t ${policy_sel_name}_RANGES [${len(range_mapping)}] = '{
111-
${value}
112-
};
113-
% endif
114-
115-
"""
116-
117-
print(
118-
Template(template).render(m=ip_block,
119-
if_name=args.if_name,
120-
register_mapping=register_mapping,
121-
window_mapping=window_mapping,
122-
range_mapping=range_mapping,
123-
policy_names=policy_names,
124-
module_name=ip_block.name,
125-
racl_group=racl_group).rstrip())
56+
print(Template(filename='util/topgen/templates/toplevel_racl_pkg_parameters.tpl').render(
57+
register_mapping=register_mapping,
58+
window_mapping=window_mapping,
59+
range_mapping=range_mapping,
60+
policy_names=policy_names,
61+
racl_group=racl_group,
62+
module_name=ip_block.name,
63+
if_name=args.if_name
64+
).rstrip())
12665

12766

12867
if __name__ == '__main__':

util/topgen.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
from design.lib.OtpMemMap import OtpMemMap
2424
from mako import exceptions
2525
from mako.template import Template
26+
from mako.lookup import TemplateLookup
2627
from raclgen.lib import DEFAULT_RACL_CONFIG
2728
from reggen import access, gen_rtl, gen_sec_cm_testplan, window
2829
from reggen.countermeasure import CounterMeasure
@@ -138,7 +139,7 @@ def ipgen_render(template_name: str, topname: str, params: Dict[str, object],
138139

139140
def generate_top(top: Dict[str, object], name_to_block: Dict[str, IpBlock],
140141
tpl_filename: str, **kwargs: Dict[str, object]) -> None:
141-
top_tpl = Template(filename=tpl_filename)
142+
top_tpl = Template(filename=tpl_filename, lookup=TemplateLookup([TOPGEN_TEMPLATE_PATH, "/"]))
142143

143144
try:
144145
return top_tpl.render(top=top, name_to_block=name_to_block, **kwargs)
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
## Copyright lowRISC contributors (OpenTitan project).
2+
## Licensed under the Apache License, Version 2.0, see LICENSE for details.
3+
## SPDX-License-Identifier: Apache-2.0
4+
<%page args="m, top"/>\
5+
% if m.get('racl_mappings'):
6+
.EnableRacl(1'b1),
7+
.RaclErrorRsp(${"1'b1" if top['racl']['error_response'] else "1'b0"}),
8+
% for if_name, mappings in m['racl_mappings'].items():
9+
<%
10+
register_mapping = mappings.get('register_mapping', {})
11+
window_mapping = mappings.get('window_mapping', {})
12+
range_mapping = mappings.get('range_mapping', [])
13+
racl_group = mappings.get('racl_group')
14+
group_suffix = f"_{racl_group.upper()}" if racl_group and racl_group != "Null" else ""
15+
if_suffix = f"_{if_name.upper()}" if if_name else ""
16+
if_suffix2 = f"{if_name.title()}" if if_name else ""
17+
policy_sel_name = f"RACL_POLICY_SEL_{m['name'].upper()}{group_suffix}{if_suffix}"
18+
%>\
19+
% if len(register_mapping) > 0:
20+
.RaclPolicySelVec${if_suffix2}(${policy_sel_name}),
21+
% endif
22+
% for window_name, policy_idx in window_mapping.items():
23+
.RaclPolicySelWin${if_suffix2}${window_name.replace("_","").title()}(${policy_sel_name}_WIN_${window_name.upper()}),
24+
% endfor
25+
% if len(range_mapping) > 0:
26+
.RaclPolicySelRanges${if_suffix2}Num(${policy_sel_name}_NUM_RANGES),
27+
.RaclPolicySelRanges${if_suffix2}(${policy_sel_name}_RANGES),
28+
% endif
29+
% endfor
30+
% endif
31+
% if m.get('template_type') == 'racl_ctrl':
32+
.RaclErrorRsp(${"1'b1" if top['racl']['error_response'] else "1'b0"}),
33+
% endif

util/topgen/templates/toplevel_racl_pkg.sv.tpl

Lines changed: 22 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -7,25 +7,18 @@ ${gencmd}
77
package top_${topcfg["name"]}_racl_pkg;
88
import top_racl_pkg::*;
99

10-
<%doc>
11-
Note: The RACL parameters must be generated identically across multiple files.
12-
Thus, this template needs to be manually synced between the following files:
13-
util/raclgen.py
14-
util/topgen/templates/toplevel_racl_pkg.sv.tpl
15-
hw/top_darjeeling/templates/toplevel.sv.tpl
16-
hw/top_earlgrey/templates/toplevel.sv.tpl
17-
hw/top_englishbreakfast/templates/toplevel.sv.tpl
18-
</%doc>\
1910
<% import raclgen.lib as raclgen %>\
2011
<% import math %>\
2112
% if 'racl' in topcfg:
2213
/**
2314
* RACL groups:
24-
% for racl_group in topcfg['racl']['policies']:
25-
<% policy_names = [policy['name'] for policy in topcfg['racl']['policies'][racl_group]] %>\
26-
<% policy_name_len = max( (len(name) for name in policy_names) ) %>\
27-
<% policy_idx_len = math.ceil(math.log10(max(1,len(policy_names)+1))) %>\
15+
% for racl_group in racl_config['policies']:
2816
* ${racl_group}
17+
<%
18+
policy_names = [policy['name'] for policy in racl_config['policies'][racl_group]]
19+
policy_name_len = max( (len(name) for name in policy_names) )
20+
policy_idx_len = math.ceil(math.log10(max(1,len(policy_names)+1)))
21+
%>\
2922
% for policy_idx, policy_name in enumerate(policy_names):
3023
* ${f"{policy_name}".ljust(policy_name_len)} (Idx ${f"{policy_idx}".rjust(policy_idx_len)})
3124
% endfor
@@ -34,60 +27,22 @@ package top_${topcfg["name"]}_racl_pkg;
3427

3528
% endif
3629
% for m in topcfg['module']:
37-
% if 'racl_mappings' in m:
38-
% for if_name in m['racl_mappings'].keys():
39-
<% register_mapping = m['racl_mappings'][if_name]['register_mapping'] %>\
40-
<% window_mapping = m['racl_mappings'][if_name]['window_mapping'] %>\
41-
<% range_mapping = m['racl_mappings'][if_name]['range_mapping'] %>\
42-
<% racl_group = m['racl_mappings'][if_name]['racl_group'] %>\
43-
<% group_suffix = f"_{racl_group.upper()}" if racl_group and racl_group != "Null" else "" %>\
44-
<% if_suffix = f"_{if_name.upper()}" if if_name else "" %>\
45-
<% reg_name_len = max( (len(name) for name in register_mapping.keys()), default=0 ) %>\
46-
<% window_name_len = max( (len(name) for name in window_mapping.keys()), default=0 ) %>\
47-
<% policy_sel_name = f"RACL_POLICY_SEL_{m['name'].upper()}{group_suffix}{if_suffix}" %>\
48-
/**
49-
* Policy selection vector for ${m["name"]}
50-
* TLUL interface name: ${if_name}
51-
* RACL group: ${racl_group}
52-
% if len(register_mapping) > 0:
53-
* Register to policy mapping:
54-
% for reg_name, policy_idx in register_mapping.items():
55-
* ${f"{reg_name}:".ljust(reg_name_len+1)} ${policy_names[policy_idx]} (Idx ${f"{policy_idx}".rjust(policy_idx_len)})
56-
% endfor
57-
% endif
58-
% if len(window_mapping) > 0:
59-
* Window to policy mapping:
60-
% for window_name, policy_idx in window_mapping.items():
61-
* ${f"{window_name}:".ljust(window_name_len+1)} ${policy_names[policy_idx]} (Idx ${f"{policy_idx}".rjust(policy_idx_len)})
62-
% endfor
63-
% endif
64-
% if len(range_mapping) > 0:
65-
* Range to policy mapping:
66-
% for range in range_mapping:
67-
* ${f"0x{range['base']:08x}"} -- ${f"0x{(range['base']+range['size']):08x}"} \
68-
policy: ${policy_names[range['policy']]} (Idx ${f"{range['policy']}".rjust(policy_idx_len)})
69-
% endfor
70-
% endif
71-
*/
72-
% if len(register_mapping) > 0:
73-
<% policy_sel_value = ", ".join(map(str, reversed(register_mapping.values())))%>\
74-
<% policy_sel_value = "\n ".join(textwrap.wrap(policy_sel_value, 94))%>\
75-
parameter racl_policy_sel_t ${policy_sel_name} [${len(register_mapping)}] = '{
76-
${policy_sel_value}
77-
};
78-
% endif
79-
% for window_name, policy_idx in window_mapping.items():
80-
parameter racl_policy_sel_t ${policy_sel_name}_WIN_${window_name.upper()} = ${policy_idx};
81-
% endfor
82-
% if len(range_mapping) > 0:
83-
parameter racl_policy_sel_t ${policy_sel_name}_NUM_RANGES = ${len(range_mapping)};
84-
<% value = ",\\n".join(map(raclgen.format_parameter_range_value, range_mapping)) %>\
85-
parameter racl_range_t ${policy_sel_name}_RANGES [${len(range_mapping)}] = '{
86-
${value}
87-
};
88-
% endif
30+
% for if_name, mapping in m.get('racl_mappings', {}).items():
31+
<%
32+
racl_group = mapping['racl_group']
33+
policy_names = [policy['name'] for policy in racl_config['policies'][racl_group]]
34+
racl_tpl_args = {
35+
"register_mapping" : mapping.get('register_mapping', {}),
36+
"window_mapping" : mapping.get('window_mapping', {}),
37+
"range_mapping" : mapping.get('range_mapping', []),
38+
"policy_names" : policy_names,
39+
"racl_group" : racl_group,
40+
"module_name" : m['name'],
41+
"if_name" : if_name
42+
}
43+
%>\
44+
<%include file="toplevel_racl_pkg_parameters.tpl" args="**racl_tpl_args"/>\
8945

90-
% endfor
91-
% endif
46+
% endfor
9247
% endfor
9348
endpackage
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
## Copyright lowRISC contributors (OpenTitan project).
2+
## Licensed under the Apache License, Version 2.0, see LICENSE for details.
3+
## SPDX-License-Identifier: Apache-2.0
4+
<%page args="register_mapping, window_mapping, range_mapping, policy_names, racl_group, module_name, if_name"/>\
5+
<% import textwrap %>\
6+
<% import math %>\
7+
<% policy_idx_len = math.ceil(math.log10(max(1,len(policy_names)+1))) %>\
8+
<% group_suffix = f"_{racl_group.upper()}" if racl_group and racl_group != "Null" else "" %>\
9+
<% if_suffix = f"_{if_name.upper()}" if if_name else "" %>\
10+
<% reg_name_len = max( (len(name) for name in register_mapping.keys()), default=0 ) %>\
11+
<% window_name_len = max( (len(name) for name in window_mapping.keys()), default=0 ) %>\
12+
<% policy_sel_name = f"RACL_POLICY_SEL_{module_name.upper()}{group_suffix}{if_suffix}" %>\
13+
/**
14+
* Policy selection vector for ${module_name}
15+
* TLUL interface name: ${if_name}
16+
* RACL group: ${racl_group}
17+
% if len(register_mapping) > 0:
18+
* Register to policy mapping:
19+
% for reg_name, policy_idx in register_mapping.items():
20+
* ${f"{reg_name}:".ljust(reg_name_len+1)} ${policy_names[policy_idx]} \
21+
(Idx ${f"{policy_idx}".rjust(policy_idx_len)})
22+
% endfor
23+
% endif
24+
% if len(window_mapping) > 0:
25+
* Window to policy mapping:
26+
% for window_name, policy_idx in window_mapping.items():
27+
* ${f"{window_name}:".ljust(window_name_len+1)} ${policy_names[policy_idx]} \
28+
(Idx ${f"{policy_idx}".rjust(policy_idx_len)})
29+
% endfor
30+
% endif
31+
% if len(range_mapping) > 0:
32+
* Range to policy mapping:
33+
% for range in range_mapping:
34+
* ${f"0x{range['base']:08x}"} -- ${f"0x{(range['base']+range['size']):08x}"} \
35+
policy: ${policy_names[range['policy']]} (Idx ${f"{range['policy']}".rjust(policy_idx_len)})
36+
% endfor
37+
% endif
38+
*/
39+
% if len(register_mapping) > 0:
40+
<% policy_sel_value = ", ".join(map(str, reversed(register_mapping.values())))%>\
41+
<% policy_sel_value = "\n ".join(textwrap.wrap(policy_sel_value, 94))%>\
42+
parameter racl_policy_sel_t ${policy_sel_name} [${len(register_mapping)}] = '{
43+
${policy_sel_value}
44+
};
45+
% endif
46+
% for window_name, policy_idx in window_mapping.items():
47+
parameter racl_policy_sel_t ${policy_sel_name}_WIN_${window_name.upper()} = ${policy_idx};
48+
% endfor
49+
% if len(range_mapping) > 0:
50+
parameter racl_policy_sel_t ${policy_sel_name}_NUM_RANGES = ${len(range_mapping)};
51+
<% fmt_range = "'{{base:'h{base:x},mask:'h{mask:x},policy:{policy}}}" %>\
52+
<% value = ",\n".join(map(fmt_range.format_map, range_mapping)) %>\
53+
parameter racl_range_t ${policy_sel_name}_RANGES [${len(range_mapping)}] = '{
54+
${value}
55+
};
56+
% endif

0 commit comments

Comments
 (0)