validate method

void validate()

Method to validate the configuration of register top module.

Must check that its blocks are mutually valid. Note that this method does not call the validate method of the individual blocks. It is assumed that block validation is called separately (i.e., in CsrBlock HW construction).

Implementation

void validate() {
  // at least 1 block
  if (blocks.isEmpty) {
    throw CsrValidationException(
        'Csr top module $name has no register blocks.');
  }

  // no two blocks with the same name
  // no two blocks with the same base address
  // no two blocks with base addresses that are too close together
  // also compute the max min address bits across the blocks
  final issues = <String>[];
  var maxMinAddrBits = 0;
  for (var i = 0; i < blocks.length; i++) {
    final currMaxMin = blocks[i].minAddrBits();
    if (currMaxMin > maxMinAddrBits) {
      maxMinAddrBits = currMaxMin;
    }

    for (var j = i + 1; j < blocks.length; j++) {
      if (blocks[i].name == blocks[j].name) {
        issues.add('Register block ${blocks[i].name} is duplicated.');
      }

      if (blocks[i].baseAddr == blocks[j].baseAddr) {
        issues.add(
            'Register block ${blocks[i].name} has a duplicate base address.');
      } else if ((blocks[i].baseAddr - blocks[j].baseAddr).abs().bitLength <
          blockOffsetWidth) {
        issues.add(
            'Register blocks ${blocks[i].name} and ${blocks[j].name} are '
            'too close together per the block offset width.');
      }
    }
  }
  if (issues.isNotEmpty) {
    throw CsrValidationException(issues.join('\n'));
  }

  // is the block offset width big enough to address
  // every register in every block
  if (blockOffsetWidth < maxMinAddrBits) {
    throw CsrValidationException(
        'Block offset width is too small to address all register in all '
        'blocks in the module. The minimum offset width is $maxMinAddrBits.');
  }
}