HammingEccReceiver constructor

HammingEccReceiver(
  1. Logic transmission, {
  2. String name = 'hamming_ecc_rx',
  3. HammingType hammingType = HammingType.sec,
})

Consumes a transmission which includes a code that can check whether the originalData contains errors and possibly correct it to correctedData, depending on the specified hammingType.

Implementation

HammingEccReceiver(super.transmission,
    {super.name = 'hamming_ecc_rx', this.hammingType = HammingType.sec})
    : super(
        codeWidth: _codeWidthFromTransmissionWidth(
                transmission.width - hammingType._extraParityBits) +
            hammingType._extraParityBits,
        definitionName: 'hamming_ecc_receiver_${hammingType.name}',
        supportsErrorCorrection: hammingType.hasCorrection,
      ) {
  final tx = HammingEccTransmitter(originalData, hammingType: hammingType);
  final hammingCode =
      hammingType.hasExtraParityBit ? code.getRange(0, -1) : code;
  final expectedHammingCode =
      tx.hammingType.hasExtraParityBit ? tx.code.getRange(0, -1) : tx.code;

  _syndrome <= hammingCode ^ expectedHammingCode;
  final hammingError = _syndrome.or();

  final hammingTransmissionWidth =
      transmission.width - hammingType._extraParityBits;

  if (hammingType.hasCorrection) {
    final correction =
        Logic(name: 'correction', width: hammingTransmissionWidth)
          ..gets(
            (Const(1, width: hammingTransmissionWidth + 1) << _syndrome)
                .getRange(1),
          );

    final encodingToDataMap = _encodingToData();

    _correctedData <=
        [
          for (var i = 1; i <= hammingTransmissionWidth; i++)
            if (encodingToDataMap.containsKey(i))
              Logic(name: 'd${encodingToDataMap[i]! + 1}')
                ..gets(originalData[encodingToDataMap[i]] ^ correction[i - 1])
        ].rswizzle();
  }

  Logic? extraErr;
  if (hammingType.hasExtraParityBit) {
    extraErr = ParityReceiver(transmission).uncorrectableError;
  }

  switch (hammingType) {
    case HammingType.sec:
      _correctableError <= hammingError;
      _uncorrectableError <= Const(0);
    case HammingType.sedded:
      _correctableError <= Const(0);
      _uncorrectableError <= hammingError;
    case HammingType.secded:
      // error location(s) -> meaning
      //  ---------------- | ----------------
      // extra & !hamming  -> bit flip on extra parity, hamming can ignore
      //                      correctable single-bit
      // extra & hamming   -> error on hamming region occurred,
      //                      correctable single-bit
      // !extra & !hamming -> no error
      // !extra & hamming  -> extra parity has no error, but hamming does
      //                      double-bit error, uncorrectable
      _correctableError <= extraErr!;
      _uncorrectableError <= ~extraErr & hammingError;
    case HammingType.seddedted:
      _correctableError <= Const(0);
      _uncorrectableError <= extraErr! | hammingError;
  }
}