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

Refactor full_selection #4768

Open
wants to merge 22 commits into
base: main
Choose a base branch
from
Open

Conversation

KrystalDelusion
Copy link
Member

@KrystalDelusion KrystalDelusion commented Nov 25, 2024

What are the reasons/motivation for this change?
A full_selection currently includes boxed modules, but Design::selected_modules() silently ignores boxes. This has lead to a number of workarounds in the code for getting all unboxed selected modules.

Explain how this is achieved.

  • Change full_selection to not include (black)boxes. Non-full selections can contain blackboxes (but this will only happen with =patterns that ask for them explicitly).
  • Add complete_selection flag that has the previous meaning of full_selection, i.e. all modules including boxes for optimisation purposes and to simplify nested commands that expect boxed modules, like abc9.

Note:
Design::selected_modules() and Design::selected_whole_modules() are marked deprecated so I can track which passes have been updated to match the new selection semantics.

Optional (but probably for a separate pr):

  • Update existing iterations over Design::modules() to use Design::selected_modules() where relevant.
  • Update backends to be consistent w.r.t. selections (providing -selected where possible, otherwise working on the full design).

Open questions:

  • Should the prompt indicate when a selection includes boxes, similar to how it displays * when it's not a full selection?
  • What about something to differentiate between a full selection and a complete selection?
  • Is using * to mean "a subset of" confusing when using * in the selection means the opposite?

If applicable, please suggest to reviewers how they can test the change.

The `Design::selected_*()` methods no longer unconditionally skip boxed modules.  Instead, selections are now box and design aware.
The selection constructor now optionally takes a design pointer, and has a new `selects_boxes` flag.  If the selection has an assigned design, then `Selection::selected_*()` will only return true for boxed modules if the selects_boxes flag is set.  A warning is raised if a selection is checked and no design is set.  Selections can change design via the `Selection::optimize()` method.
Most places that iterate over `Design::modules()` and check `Selection::selected_module()` should instead use `Design::selected_modules()`.
Since boxed modules should only ever be selected explicitly, and `full_selection` (now) refers to all non-boxed modules, `Selection::optimize()` will clear the `full_selection` flag if the `selects_boxes` flag is enabled, and instead explicitly selects all modules (including boxed modules).  This also means that `full_selection` will only get automatically applied to a design without any boxed modules.

These changes necessitated a number of changes to `select.cc` in order to support this functionality when operating on selections, in particular when combining selections (e.g. by union or difference).
To minimize redundancy, a number of places that previously iterated over `design->modules()` now push the current selection to the design, use `design->selected_modules()`, and then pop the selection when done.

Introduce `RTLIL::NamedObject`, to allow for iterating over all members of a module with a single iterator instead of needing to iterate over wires, cells, memories, and processes separately.
Also implement `Module::selected_{memories, processes, members}()` to match wires and cells methods.  The `selected_members()` method combines each of the other `selected_*()` methods into a single list.
Now uses two enums, one to control whether or not to include partially selected
modules (and what to do if they are encountered), and one to control whether or
not to include boxed modules (and what to do if they are encountered).

Mark Design::selected{modules, whole_modules}() deprecated and make them
provide warnings on boxes. There are a lot of places that use them and I can't
always tell which ones support boxed modules and which don't.
If a selection contains a boxed module, but does not select boxes, it should be removed from the selection.
New methods on Design to push/pop selection instead of accessing the selection stack directly. Includes methods for pushing a full/complete/empty selection.
Also helper methods on modules to check `is_selected` and `is_selected_whole`.
Catch more uses of selection constructor without assigning a design.
Since it doesn't change anything and is just a lookup.
If the current selection is not the provided selection, push the provided selection.
cxxrtl `test_unconnected_output` and simple_abc9 `abc9.v` both expect boxed modules in the outputs, so make sure they work as expected.
Used to select all modules including boxes, set when both `full` and `boxes` are true in the constructor, pulling down `full_selection`.
Add `Selection::selects_all()` method as short hand for `full_selection || complete_selection`.
Update selection operations to account for complete selections.
Add static methods to `Selection` for creating a new empty/full/complete selection to make it clearer to users when doing so.
Use said static methods to replace most instances of the `Selection` constructor.
Update `Selection::optimize` to use
Or rather, say we're calling `select =*`, but actually bypass the select command to avoid the warning that can pop up if there is nothing to select.
Fixes quicklogic/pp3 problem with `dffepc` including processes.
Also means the preceding `proc` is safe to remove (and may result in some small speedup by doing so).
@KrystalDelusion KrystalDelusion changed the title Refactor selections Refactor full_selection Nov 27, 2024
Add a `log_assert` for it in `Design::check()`.
Remove unneeded checks in other places.
Change `top` pointer default to `nullptr` to avoid issues with `Design->top_module()` only operating on the current selection.

Calls to other passes (`bmuxmap` etc) will only operate on the current selection, and may cause problems when those cells are unprocessed, but this is consistent with the other backends that only operate on the full designs and will hopefully be fixed in another PR soon :)
Instead, change the default `Design::selected_modules()` to match the behaviour (i.e. `selected_unboxed_modules_warn()`) because it's a lot of files to touch and they don't really _need_ to be updated.
Also change `Design::selected_whole_modules()` users over to `Design::selected_unboxed_whole_modules()`, except `attrmap` because I'm not convinced it should be ignoring boxes.  So instead, leave the deprecation warning for that one use and come back to the pass another time.
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.

1 participant