FindPattern constructor
Find a position for a fixed-width pattern in a bus.
Takes in search pattern pattern and a boolean fromStart to
determine the search direction.
If fromStart is true, the search starts from the beginning of the bus.
If fromStart is false, the search starts from the end of the bus.
By default, FindPattern will look for the first occurrence
of the pattern and returns an output index containing the position.
If n is given, FindPattern will find the N'th occurrence
of the pattern.
n starts from 0 as the first occurrence.
index position starts from 0 as the first position in bus.
For example, if bus is 10000001 and pattern is 01, the index
will be 0 if fromStart is true as the pattern is found at the
0th position from the start of the bus. Otherwise, if fromStart is
false, the index will be 6 as the pattern is found at the
6th position from end of the bus.
index will be 0 when pattern is not found.
Implementation
FindPattern(Logic bus, Logic pattern,
{bool fromStart = true,
Logic? n,
this.generateError = false,
super.reserveName,
super.reserveDefinitionName,
String? definitionName})
: super(
definitionName: definitionName ??
'FindPattern_W${bus.width}_P${pattern.width}') {
bus = addInput('bus', bus, width: bus.width);
pattern = addInput('pattern', pattern, width: pattern.width);
// A list to store the index of the found pattern
final indexList = <Logic>[];
if (n != null) {
n = addInput('n', n, width: n.width);
}
// Initialize counter pattern occurrence to 0
Logic count = Const(0, width: log2Ceil(bus.width + 1));
final nVal = ((n ?? Const(0)) + 1).zeroExtend(count.width);
for (var i = 0; i <= bus.width - pattern.width; i = i + 1) {
int minBit;
int maxBit;
if (fromStart) {
// Read from start of bus
minBit = i;
maxBit = i + pattern.width;
} else {
// Read from end of bus
minBit = bus.width - i - pattern.width;
maxBit = bus.width - i;
}
// Check if pattern matches, add to count
final valCheck = bus.getRange(minBit, maxBit).eq(pattern);
count += valCheck.zeroExtend(count.width);
// Append result to the index list
indexList.add(valCheck & nVal.eq(count));
}
final indexBinary = OneHotToBinary(indexList.rswizzle());
final bin = indexBinary.binary;
addOutput('index', width: bin.width);
index <= bin;
if (generateError) {
// If pattern is not found, return error
addOutput('error');
error! <= count.lt(nVal) | count.eq(0);
}
}