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

[RACL] Parse mappings and auto-connect RACL #25749

Open
wants to merge 5 commits into
base: master
Choose a base branch
from

Conversation

Razer6
Copy link
Member

@Razer6 Razer6 commented Dec 25, 2024

This PR adds support for parsing the RACL config. In the first place, a *-connection is implemented, mapping all registers to a single RACL policy. The RACL policies are distributed to subscribing IPs. A selection vector in the form of a parameter selects the right policy from the policy vector.

RACL is applied to PWM first.

@Razer6 Razer6 force-pushed the racl-connections branch 3 times, most recently from 3ab664e to 22a4113 Compare December 25, 2024 20:45
@Razer6 Razer6 force-pushed the racl-connections branch 3 times, most recently from e9ce170 to 89730cc Compare December 26, 2024 13:01
@Razer6 Razer6 force-pushed the racl-connections branch 2 times, most recently from 4318722 to 6b1e47c Compare December 27, 2024 12:50
@Razer6 Razer6 marked this pull request as ready for review December 29, 2024 16:13
@Razer6 Razer6 requested a review from msfschaffner as a code owner December 29, 2024 16:13
@Razer6 Razer6 removed the request for review from msfschaffner December 29, 2024 16:14
Copy link
Contributor

@rswarbrick rswarbrick left a comment

Choose a reason for hiding this comment

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

A partial review so far, sorry (just the first two commits)

if len(mapping) != 1:
raise SystemExit('Mapping file must be a single-element dict mapping the RACL group to the '
'register mapping')
racl_group = list(mapping.keys())[0]
Copy link
Contributor

Choose a reason for hiding this comment

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

We might want to check that racl_group is a string too?

Comment on lines +72 to +73
racl_group = list(mapping.keys())[0]
register_mapping = list(mapping.values())[0]
Copy link
Contributor

Choose a reason for hiding this comment

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

Since we know the length, this might be easier with something like racl_group, register_mapping = mapping.items()[0] ?

Comment on lines +72 to +73
racl_group = list(mapping.keys())[0]
register_mapping = list(mapping.values())[0]
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we also need to check that register_mapping is a dict?

# Special handling of the all star assignment:
# "*": POLICY
# Assigns all registers to a given policy
if len(register_mapping) == 1 and list(register_mapping.keys())[0] == "*":
Copy link
Contributor

Choose a reason for hiding this comment

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

Possibly easier: if list(register_mapping.keys()) == ["*"] ?

if policy_idx == -1:
raise SystemExit(f'RACL policy {policy_name} not defined in RACL config')

if if_name not in ip_block.reg_blocks:
Copy link
Contributor

Choose a reason for hiding this comment

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

I'd probably be inclined to assign ip_block.reg_blocks.get(if_name) to something and then check for None here, which avoids needing to do the look-up again as the next operation.

Comment on lines +542 to +543
if 'racl_mappings' in m:
for if_name, mapping_path in m['racl_mappings'].items():
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe for if_name, mapping_path in m.get('racl_mappings', {}).items(), which will avoid a layer of indentation.

util/topgen.py Show resolved Hide resolved
# Auto connect RACL subscribing IPs to the assocated racl_ctrl IP
if 'racl' in topcfg:
# Find the RACL control of the defined group. This currently only works for the default
# RACL ctrl module when there is a single instance. This limitiation currently comes from
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: Spelling of "limitation"


if racl_mapping and racl_mappings:
raise ValueError("Cannot specify both 'racl_mapping' and 'racl_mappings'")

Copy link
Contributor

Choose a reason for hiding this comment

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

I'd suggest converting racl_mapping to a value for racl_mappings here, which will make the code below a bit easier to read.

@@ -3112,121 +3147,184 @@ module pwm_reg_top (
addr_hit[20] = (reg_addr == PWM_BLINK_PARAM_3_OFFSET);
addr_hit[21] = (reg_addr == PWM_BLINK_PARAM_4_OFFSET);
addr_hit[22] = (reg_addr == PWM_BLINK_PARAM_5_OFFSET);

if (EnableRacl) begin : gen_racl_hit
racl_addr_hit_read [ 0] = addr_hit[ 0] & (|(racl_policies_i[RaclPolicySelVec[ 0]].read_perm & racl_role_vec));
Copy link
Contributor

Choose a reason for hiding this comment

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

I've not tried this, but could we move the looping into the SystemVerilog instead of the Python? I think we end up with something like this, which is a bit more obvious to read, rather shorter and doesn't need line length waivers.

    if (EnableRacl) begin : gen_racl_hit
      for (int unsigned slice_idx = 0; slice_idx < 23; slice_idx++) begin
        racl_addr_hit_read[slice_idx] =
            addr_hit[slice_idx] & (|(racl_policies_i[RaclPolicySelVec[slice_idx]].read_perm
                                     & racl_role_vec));
        racl_addr_hit_write[slice_idx] =
            addr_hit[slice_idx] & (|(racl_policies_i[RaclPolicySelVec[slice_idx]].write_perm
                                     & racl_role_vec));
      end
    end else begin : gen_no_racl
      racl_addr_hit_read  = addr_hit;
      racl_addr_hit_write = addr_hit;
    end

# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0

# These lines are too long due to generated code
Copy link
Contributor

Choose a reason for hiding this comment

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

As a note: if we can simplify the generated reg-top as I'm suggesting then we won't need this waiver entry.

.reg2hw (reg2hw),
.racl_policies_i (racl_policies_i),
.racl_error_o (racl_error_o),
.racl_error_log_o (racl_error_log_o),
Copy link
Contributor

Choose a reason for hiding this comment

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

It's not a big issue, but do we really need to go that far to the right? I think I'd probably have expected just one space after the longest name (this one).

act: "rcv",
package: "top_racl_pkg",
desc: '''
Policy vector distributed to the subscribing RACL IPs.
Copy link
Contributor

Choose a reason for hiding this comment

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

I wonder whether this text needs changing slightly. It looks a bit like PWM is the block that's distributing something (which is backwards). If I've got this right, PWM is a subscribing IP, so maybe something like "RACL policy vector, used by the IP to control register access permissions." ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants