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

Add Find N'th Pattern component #187

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

Conversation

izzianyramli
Copy link

Description & Motivation

Similar to Find N'th bit from start/end, but FindPattern find an entire multi-bit pattern from start/end and returns it index

Related Issue(s)

#169

Testing

Test is included in test/find_pattern_test.dart

Backwards-compatibility

Is this a breaking change that will not be backwards-compatible? If yes, how so?

No

Documentation

Does the change require any updates to documentation? If so, where? Are they included?

Documentation added in doc/components/find.md

izzianyramli and others added 14 commits March 6, 2025 12:33
Signed-off-by: laeticiachee <[email protected]>
2. Fix test inputs

Signed-off-by: Ramli, Nurul Izziany <[email protected]>
2. Add error signal when pattern is not found

Signed-off-by: Ramli, Nurul Izziany <[email protected]>
Signed-off-by: Ramli, Nurul Izziany <[email protected]>
Signed-off-by: Ramli, Nurul Izziany <[email protected]>
Signed-off-by: Ramli, Nurul Izziany <[email protected]>
Signed-off-by: Ramli, Nurul Izziany <[email protected]>
@mkorbel1 mkorbel1 linked an issue Mar 7, 2025 that may be closed by this pull request
To find the nth pattern occurrence just pass in `bus` along with Logic pattern `pattern` passed in as an argument. Note that the `pattern` needs to be smaller than `bus`.

### Find Nth Pattern from start
To find the nth pattern occurrence just pass in `bus` along with Logic pattern `pattern` passed in as an argument. Note that the `pattern` needs to be smaller than `bus`.
Copy link
Contributor

Choose a reason for hiding this comment

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

while the doc comment above in this file is already repetitive and I know you're following the example, we can do a little better: let's not copy paste the same sentence in each section here, just put the relevant new documentation required to use the component

Copy link
Author

Choose a reason for hiding this comment

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

Will create a separate doc in find_pattern.md as the component description will be a bit different than as describe for Find component in find.md

@@ -36,3 +36,14 @@ To find the nth occurrence just pass in `bus` along with Logic value `n` passed
### Find Nth Zero

To find the nth occurrence just pass in `bus` along with Logic value `n` passed in as an argument. In addition to finding occurrence of Zero (`0`), set the argument `countOne` to `false`.

## Find Nth Pattern
To find the nth pattern occurrence just pass in `bus` along with Logic pattern `pattern` passed in as an argument. Note that the `pattern` needs to be smaller than `bus`.
Copy link
Contributor

Choose a reason for hiding this comment

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

it would be good to mention the name of the component in here FindPattern

Logic get index => output('index');

/// [error] is a getter for error in FindPattern
/// When your pattern is not found it will result in error `1`
Copy link
Contributor

Choose a reason for hiding this comment

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

It would be good to mention in the doc comment here that this signal only exists when generateError is true

}

// Initialize counter pattern occurrence to 0
Logic count = Const(0, width: bus.width);
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: technically, the width of this count only needs to be ~log2ceil of the bus width (to represent an index in bus)

final valCheck = busVal.eq(pattern);

// Check if pattern matches, count if found
count += ((valCheck.value.toInt() == 1) ? 1 : 0);
Copy link
Contributor

Choose a reason for hiding this comment

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

I think you mean count += valCheck directly -- it's already a 1-bit signal and you want to assign it synthesizably, not based on .toInt()

if (generateError) {
// If pattern is not found, return error
final isError =
(count.value.toInt() < nVal.value.toInt() || count.value.toInt() == 0)
Copy link
Contributor

Choose a reason for hiding this comment

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

Again, operate on the signals themselves. Something like isError = count.lt(nVal) | count.eq(0)

import 'package:rohd_hcl/rohd_hcl.dart';
import 'package:test/test.dart';

void main() {
Copy link
Contributor

Choose a reason for hiding this comment

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

suggestion: try writing at least one test where you do multiple different values on the bus, pattern, and n for the same hardware. this will help test against the type of .toInt() bugs that you have in your implementation

Copy link
Author

Choose a reason for hiding this comment

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

suggestion: try writing at least one test where you do multiple different values on the bus, pattern, and n for the same hardware. this will help test against the type of .toInt() bugs that you have in your implementation

Can you describe more what do you mean by multiple values for the same hardware here?

/// Outputs pin `index` contains position.
class FindPattern extends Module {
/// [index] is a getter for output of FindPattern
Logic get index => output('index');
Copy link
Contributor

Choose a reason for hiding this comment

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

It would be good to clarify in the doc comment what the index means exactly. For example, if you have a pattern 01, is the index the position of the 0 or the 1? Does it depend on the direction of start?

/// Outputs pin `index` contains position.
class FindPattern extends Module {
/// [index] is a getter for output of FindPattern
Logic get index => output('index');
Copy link
Contributor

Choose a reason for hiding this comment

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

What does the index output when there is an error? Would be good to document (even if you claim "undefined behavior")

///
/// Outputs pin `index` contains the position. Position starts from `0` based.
FindPattern(Logic bus, Logic pattern,
{bool start = true, Logic? n, this.generateError = false})
Copy link
Contributor

Choose a reason for hiding this comment

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

suggestion: a name of fromStart or something might be more clear

@izzianyramli izzianyramli requested a review from mkorbel1 March 8, 2025 09:52
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.

Find N'th pattern from the start/end
4 participants