[secded_gen] Add an ecc_encode_some function This is equivalent to calling ecc_encode lots of times in succession but avoids having to pick a code and calculate bitmasks each time. Signed-off-by: Rupert Swarbrick <rswarbrick@lowrisc.org>
diff --git a/util/design/secded_gen.py b/util/design/secded_gen.py index 06b9b19..93e2e57 100755 --- a/util/design/secded_gen.py +++ b/util/design/secded_gen.py
@@ -18,7 +18,7 @@ import random import hjson import subprocess -from typing import Tuple +from typing import List, Tuple from pathlib import Path COPYRIGHT = """// Copyright lowRISC contributors. @@ -350,11 +350,7 @@ return error -def ecc_encode(codetype: str, k: int, dataword: int) -> Tuple[int, int]: - log.info(f"Encoding ECC for {hex(dataword)}") - - assert 0 <= dataword < (1 << k) - +def _ecc_pick_code(codetype: str, k: int) -> Tuple[int, List[int], int]: # first check to see if bit width is supported among configuration config = hjson.load(SECDED_CFG_PATH.open()) @@ -367,10 +363,16 @@ codes = gen_code(codetype, k, m) bitmasks = calc_bitmasks(k, m, codes, False) invert = 1 if codetype in ['inv_hsiao', 'inv_hamming'] else 0 - break - else: - # error if k not supported - raise Exception(f'ECC for length {k} of type {codetype} unsupported') + return (m, bitmasks, invert) + + # error if k not supported + raise Exception(f'ECC for length {k} of type {codetype} unsupported') + + +def _ecc_encode(k: int, + m: int, bitmasks: List[int], invert: int, + dataword: int) -> int: + assert 0 <= dataword < (1 << k) # represent supplied dataword as a binary string word_bin = format(dataword, '0' + str(k) + 'b') @@ -392,6 +394,14 @@ # Add ECC bit inversion if needed (see print_enc function). bit ^= (invert & k % 2) codeword = str(bit) + codeword + return codeword + + +def ecc_encode(codetype: str, k: int, dataword: int) -> Tuple[int, int]: + log.info(f"Encoding ECC for {hex(dataword)}") + + m, bitmasks, invert = _ecc_pick_code(codetype, k) + codeword = _ecc_encode(k, m, bitmasks, invert, dataword) # Debug printouts log.debug(f'original hex: {hex(dataword)}') @@ -399,6 +409,15 @@ return int(codeword, 2), m +def ecc_encode_some(codetype: str, + k: int, + datawords: int) -> Tuple[List[int], int]: + m, bitmasks, invert = _ecc_pick_code(codetype, k) + codewords = [int(_ecc_encode(k, m, bitmasks, invert, w), 2) + for w in datawords] + return codewords, m + + def gen_code(codetype, k, m): # The hsiao_code generator uses (pseudo)random values to pick good ECC # constants. Rather than exposing the seed, we pick a fixed one here to