page contents

FPGA/IC常用的Python库:CRC计算

在 FPGA/IC 设计中,CRC 校验是一个常见的问题,广泛应用于以太网、SATA、PCIe 等高速通信协议中。许多工程师在验证阶段常常困扰于如何高效检测 CRC 的正确性,尤其是在大数据流、高压力场景下。

attachments-2025-05-hKoopFWJ681d5837ef69a.jpg在 FPGA/IC 设计中,CRC 校验是一个常见的问题,广泛应用于以太网、SATA、PCIe 等高速通信协议中。许多工程师在验证阶段常常困扰于如何高效检测 CRC 的正确性,尤其是在大数据流、高压力场景下。

其实,我们可以借助 Python 来大大简化这一过程。Python 拥有成熟的 CRC 计算库,可以将响应的数据流导出为 TXT 文件,再由 Python 脚本进行 CRC 校验。同时,如果使用 Cocotb 等基于 Python 的硬件仿真平台,还可以直接在仿真过程中集成 CRC 验证逻辑,从而实现更高效、更灵活的验证方法。

介绍

crcmod是一个用于生成计算循环冗余校验(CRC)的Python模块,支持8、16、24、32和64位CRC。它提供纯Python实现和可选的C扩展加速计算,用户可自定义多项式或使用预定义算法,并支持生成其他语言(如C/C++)的CRC计算代码。

安装

C扩展

确保系统已安装Python开发工具及C编译器(如GCC、Clang或Windows的MinGW/MSVC),具体可参考Python官方文档关于构建C扩展的指南。

如果没有可自行安装

LINUX:

# Debian/Ubuntu

sudo apt-get install build-essential python3-dev

# CentOS

sudo yum groupinstall "Development Tools" && sudo yum install python3-develWINDOWS:

需要安装适合的C/C++编译器和编译选项支持,例如GCC或Visual Studio。安装crcmod库

pip install crcmod  # 基础安装离线安装

下载 Source Distribution , crcmod-1.7.tar.gz (89.7 kB view details)

https://pypi.org/project/crcmod/1.7/#filesLINUX:

python setup.py installWINDOWS:

python setup.py build --compiler=mingw32 install验证安装

运行单元测试确认安装正确

import crcmod.test

crcmod.test.run()使用

基础使用:mkCrcFun函数工厂

通过mkCrcFun()创建CRC计算函数,需指定多项式(poly)与其他可选参数:

import crcmod


# 创建自定义CRC-32函数(多项式0x104C11DB7,初始值0,异或输出0xFFFFFFFF)

crc32_func = crcmod.mkCrcFun(0x104C11DB7, initCrc=0, rev=True, xorOut=0xFFFFFFFF)

# 计算字节串CRC

data = b'\x12\x34\x56\x78\xaa\xbb\xcc\dd'

crc_value = crc32_func(data)

print(hex(crc_value))  # 输出:0x32214a75参数说明:

poly:多项式(整数形式,如32位多项式0x104C11DB7)。

initCrc:初始值(默认全1,避免忽略前导0,大端模式,对于反向算法(rev=True),需先将初始值反转(按位序)后再参与计算)。

rev:是否反转算法(表示输入反转且输出反转默认True,常见于CRC-32)。

xorOut:最终异或值(如CRC-32通常为0xFFFFFFFF)。

example:

crcmod的初值和硬件的初值是有出入的,硬件是处理之后的初值,crcmod是处理之前的初值

rev=True ,initCrc=0x00000001,xorOut=0xFFFFFFFF:在硬件上是,输入反转 (REFIN)且输出反转(REFOUT) ,取反 80000000 异或 7FFFFFFF
• rev=False,initCrc=0x00000001,xorOut=0xFFFFFFFF:在硬件上是,输入不反转(REFIN)且输出不反转(REFOUT),不取反 00000001 异或 FFFFFFFE
• rev=True ,initCrc=0x00000001,xorOut=0x00000000:在硬件上是,输入反转 (REFIN)且输出反转(REFOUT) ,取反 80000000 异或 80000000
• rev=False,initCrc=0x00000001,xorOut=0x00000000:在硬件上是,输入不反转(REFIN)且输出不反转(REFOUT),不取反 00000001 异或 00000001
所以在crc-32时:
rev=True,initCrc=0x00000000,xorOut=0xFFFFFFFF
实际硬件应该是:
REFIN=True,REFOUT=True,initCrc=0xFFFFFFFF,xorOut=0xFFFFFFFF
也就是说如果是硬件初值或者crc在线计算网站应该写加粗值
类接口:Crc类
通过Crc类实现类似hashlib的链式调用,支持分块更新:
# 实例化CRC对象
crc32 = crcmod.Crc(0x104C11DB7, initCrc=0, rev=True, xorOut=0xFFFFFFFF)
crc32.update(b'\x12\x34\x56\x78')        # 更新数据块1
crc32.update(b'\xaa\xbb\xcc\dd')       # 更新数据块2
print(hex(crc32.crcValue))  # 输出:0x32214A75
print(crc32.hexdigest())    # 输出:32214A75(十六进制字符串)方法:
update(data):追加数据。
digest():返回二进制校验值。
hexdigest():返回十六进制字符串。
new() / copy():克隆实例(保留参数,重置/保留当前状态)。
调用mkPredefinedCrcFun()直接使用标准算法(如CRC-32):
from crcmod.predefined import mkPredefinedCrcFun

# 通过名称调用预定义算法
crc32_func = mkPredefinedCrcFun('crc-32')
crc_value = crc32_func(b'\x12\x34\x56\x78\xaa\xbb\xcc\dd')
print(hex(crc_value))  # 输出:0x32214a75分块计算与状态管理
from crcmod.predefined import mkPredefinedCrcFun

# 初始化
crc_func = mkPredefinedCrcFun('crc-32')

# 分块计算
crc_part1 = crc_func(b'\x12\x34\x56\x78')
crc_total = crc_func(b'\xaa\xbb\xcc\dd', crc_part1)
print(hex(crc_total))  # 输出与整体计算相同 0x32214a75注意
Python 3输入类型:必须使用bytes或支持缓冲协议的对象(如bytearray)。
性能优化:安装C扩展可加速计算(默认尝试构建,否则使用纯Python实现)。
自定义校验值:结合多项式、反转标志等参数适配不同协议需求。

更多相关技术内容咨询欢迎前往并持续关注好学星城论坛了解详情。

想高效系统的学习Python编程语言,推荐大家关注一个微信公众号:Python编程学习圈。每天分享行业资讯、技术干货供大家阅读,关注即可免费领取整套Python入门到进阶的学习资料以及教程,感兴趣的小伙伴赶紧行动起来吧。

attachments-2022-05-rLS4AIF8628ee5f3b7e12.jpg

  • 发表于 2025-05-09 09:20
  • 阅读 ( 57 )
  • 分类:Python开发

你可能感兴趣的文章

相关问题

0 条评论

请先 登录 后评论
小柒
小柒

2140 篇文章

作家榜 »

  1. 轩辕小不懂 2403 文章
  2. 小柒 2140 文章
  3. Pack 1303 文章
  4. Nen 576 文章
  5. 王昭君 209 文章
  6. 文双 71 文章
  7. 小威 64 文章
  8. Cara 36 文章