FindPattern constructor

FindPattern(
  1. Logic bus,
  2. Logic pattern, {
  3. bool fromStart = true,
  4. Logic? n,
  5. bool generateError = false,
})

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