Source code for hwtLib.logic.crcUtils

import re
from copy import copy


[docs]def parsePolyStr_parse_n(string): "Parse the number part of a polynomial string term" if not string: return 1 elif string == '-': return -1 elif string == '+': return 1 else: if re.match("\s*\+\s*1\s*", string): return 1 return int(string)
[docs]def parsePolyStr_parse_p(string): "Parse the power part of a polynomial string term" pat = re.compile('x\^?(\d+)?') if not string: return 0 res = pat.findall(string)[0] if not res: return 1 return int(res)
[docs]def parsePolyStr(polyStr, width): coefs = [0 for _ in range(width)] """\ Do very, very primitive polynom parsing of a string into a list of coefficients. 'x' is the only term considered for the polynomial, and this routine can only handle terms of the form: 7x^2 + 6x - 5 and will choke on seemingly simple forms such as x^2*7 - 1 or x**2 - 1 :return: list of coefficients """ termpat = re.compile('([-+]?\s*\d*\.?\d*)(x?\^?(\d+)?)') res_dict = {} for n, powStr, _ in termpat.findall(polyStr): n, p = n.strip(), powStr.strip() if not n and not p: continue n, p = parsePolyStr_parse_n(n), parsePolyStr_parse_p(p) if p in res_dict: res_dict[p] += n else: res_dict[p] = n for key, value in res_dict.items(): coefs[key] = value return coefs
[docs]def crc_serial_shift(num_bits_to_shift, polySize, coefs, lfsr_cur, dataWidth, data_cur): """ :param polySize: bit size of polynomial :param coefs: array of 1,0 which representing the polynomial :param lfsr_cur: array with single 1 flag which specifies for which bit we are currently counting the crc :pram dataWidth: bit widtho of input signal to this crc round :pram data_cur: ray with single 1 flag which specifies for which bit we are currently counting the crc """ assert num_bits_to_shift <= dataWidth lfsr_next = copy(lfsr_cur) lfsr_poly_size = len(coefs) for j in range(num_bits_to_shift): # shift the entire LFSR lfsr_upper_bit = lfsr_next[lfsr_poly_size - 1] for i in range(lfsr_poly_size - 1, 0, -1): if coefs[i]: lfsr_next[i] = lfsr_next[i - 1] ^ lfsr_upper_bit ^ data_cur[j] else: lfsr_next[i] = lfsr_next[i - 1] lfsr_next[0] = lfsr_upper_bit ^ data_cur[j] return lfsr_next
[docs]def buildCrcMatrix_dataMatrix(coefs, polyWidth, dataWidth): """ generate LSFR reg, matrix[MxN] :param coefs: Polynomial coefficients :param polyWidth: number of bits of Polynomial :param dataWidth: number of bits of data signal """ reg_cur = [0 for _ in range(polyWidth)] data_cur = [0 for _ in range(dataWidth)] data_matrix = [[0 for _ in range(dataWidth)] for _ in range(polyWidth)] for m1 in range(dataWidth): # set flag for crc_serial_shift data_cur[m1] = 1 if m1: # clean last flag data_cur[m1 - 1] = 0 _data_matrix = crc_serial_shift(dataWidth, polyWidth, coefs, reg_cur, dataWidth, data_cur) for n2, b in enumerate(_data_matrix): if b: # dataWidth - m1 - 1 data_matrix[n2][m1] = 1 return data_matrix
[docs]def buildCrcMatrix_reg0Matrix(coefs, polyWidth, dataWidth): reg_cur = [0 for _ in range(polyWidth)] data_cur = [0 for _ in range(dataWidth)] reg_matrix = [[0 for _ in range(polyWidth)] for _ in range(polyWidth)] # lfsr reg to lfsr reg connections for n1 in range(polyWidth): reg_cur[n1] = 1 if n1: reg_cur[n1 - 1] = 0 reg_next = crc_serial_shift(dataWidth, polyWidth, coefs, reg_cur, dataWidth, data_cur) for n2, b in enumerate(reg_next): if b: reg_matrix[n2][n1] = 1 return reg_matrix
[docs]def buildCrcMatrix(coefs, polyWidth, dataWidth): regMatrix = buildCrcMatrix_reg0Matrix(coefs, polyWidth, dataWidth) dataMatrix = buildCrcMatrix_dataMatrix(coefs, polyWidth, dataWidth) return regMatrix, dataMatrix