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(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);
}
}