FPGA线上课程平台|最全栈的FPGA学习平台|FPGA工程师认证培训
登录
首页-技术文章/快讯-技术分享-正文

Verilog实现CRC校验算法:从原理到RTL代码

二牛学FPGA二牛学FPGA
技术分享
6小时前
0
0
1

Quick Start

  • 步骤一:在Vivado/Vivado Quartus中新建一个工程,器件选择任意7系列或以上FPGA(如xc7a35ticsg324-1L)。
  • 步骤二:创建一个顶层模块文件 crc_top.v,并添加一个仿真测试文件 tb_crc.v。
  • 步骤三:在 crc_top.v 中实例化一个参数化的 CRC 计算模块(下文提供代码),输入数据位宽为 8 位,多项式为 CRC-8-ATM(0x07)。
  • 步骤四:在 tb_crc.v 中编写一个简单的测试序列:输入 0xAA,等待 1 个时钟周期后读取 CRC 输出。
  • 步骤五:运行行为仿真(Run Behavioral Simulation),观察 crc_out 信号。预期 0xAA 的 CRC-8 结果为 0x48(多项式 0x07,初始值 0x00)。
  • 步骤六:如果仿真结果正确,对顶层模块进行综合(Synthesis),检查资源消耗和 Fmax。
  • 步骤七:可选:将 CRC 模块与一个 UART 或 SPI 接口连接,实现数据包的 CRC 附加与校验。
  • 步骤八:验收点:仿真波形中 crc_valid 信号为高时,crc_out 与在线 CRC 计算器结果一致。

前置条件与环境

项目/推荐值说明替代方案
器件/板卡Xilinx Artix-7 (xc7a35t) 或 Intel Cyclone IV任何支持 LUT 的 FPGA,如 Lattice iCE40
EDA 版本Vivado 2018.3 或更高 / Quartus Prime 20.1ISE 14.7(需注意 IP 兼容性)
仿真器Vivado Simulator / ModelSim / QuestaVerilator(仅支持可综合子集)
时钟/复位50 MHz 系统时钟,高电平有效异步复位可改用 PLL 生成,复位极性可配置
接口依赖无外部 IP,纯 RTL 设计若需 AXI-Stream 接口,可参考后续扩展
约束文件只需 create_clock 约束,时序宽松无需 I/O 约束,除非上板
参考工具在线 CRC 计算器(如 sunshine2k.de)Python crcmod 库

目标与验收标准

  • 功能点:实现参数化 CRC 计算模块,支持任意多项式、初始值、输入位宽(1~64 位)。
  • 性能指标:在 50 MHz 时钟下,每个时钟周期处理 8 位数据,延迟 1 个周期。
  • 资源:LUT 消耗不超过 32 个(对于 8 位输入、CRC-8),Fmax 不低于 200 MHz(Artix-7 speed grade -1)。
  • 验收方式:仿真波形中,对于已知测试向量(如 0xAA → 0x48,0x00 → 0x00),crc_out 匹配;综合后时序报告无违例。

实施步骤

工程结构

project/
├── rtl/
│   ├── crc_calc.v        # 核心 CRC 计算模块
│   └── crc_top.v         # 顶层包装(含数据接口)
├── sim/
│   └── tb_crc.v          # 测试平台
├── constraints/
│   └── crc_top.xdc       # 时序约束
└── scripts/
    └── run_sim.tcl       # 仿真脚本(可选)

说明:顶层模块负责将数据输入与 CRC 模块连接,并输出计算完成的 CRC 值。仿真文件应包含多个测试用例以验证边界。

关键模块:参数化 CRC 计算器

// crc_calc.v
// 参数化 CRC 计算模块,支持任意多项式、初始值、输入位宽
// 使用 LFSR 串行架构,每个时钟处理 1 位数据
// 注意:对于并行 CRC,请参考附录中的并行化方法

module crc_calc #(
    parameter DATA_WIDTH = 8,
    parameter CRC_WIDTH  = 8,
    parameter POLYNOMIAL = 8'h07,  // x^8 + x^2 + x + 1
    parameter INIT_VAL   = {CRC_WIDTH{1'b0}}
) (
    input  wire                     clk,
    input  wire                     rst_n,
    input  wire                     data_valid,
    input  wire [DATA_WIDTH-1:0]    data_in,
    output reg  [CRC_WIDTH-1:0]     crc_out,
    output reg                      crc_valid
);

    reg [CRC_WIDTH-1:0] lfsr;
    integer i;

    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            lfsr     <= INIT_VAL;
            crc_out  <= {CRC_WIDTH{1'b0}};
            crc_valid <= 1'b0;
        end else if (data_valid) begin
            crc_valid <= 1'b0;
            // 串行处理每一位
            for (i = 0; i < DATA_WIDTH; i = i + 1) begin
                if (lfsr[CRC_WIDTH-1] ^ data_in[DATA_WIDTH-1-i]) begin
                    lfsr <= (lfsr << 1) ^ POLYNOMIAL;
                end else begin
                    lfsr <= lfsr << 1;
                end
            end
            // 数据有效后一个周期输出 CRC
            crc_out <= lfsr;
            crc_valid <= 1'b1;
        end
    end

endmodule

注意:上述代码使用 for 循环在同一个时钟周期内处理所有位,综合后映射为组合逻辑。对于高数据率应用,应改用并行 CRC(查表法或矩阵法)。

时序与约束

# crc_top.xdc
create_clock -name sys_clk -period 20.000 [get_ports clk]
set_input_delay -clock sys_clk -max 2.000 [get_ports data_in*]
set_output_delay -clock sys_clk -max 2.000 [get_ports crc_out*]

说明:输入延迟 2 ns 模拟外部寄存器输出;输出延迟 2 ns 为下游留出建立时间。实际值需根据板级走线调整。

验证策略

  • 使用 Python 生成参考向量:import crcmod; crc8 = crcmod.mkCrcFun(0x107, initCrc=0x00, xorOut=0x00); print(hex(crc8(b'\xAA'))) 输出 0x48。
  • 仿真测试应包括:全 0 输入、全 1 输入、单比特翻转、连续数据流(验证流水线行为)。
  • 验收点:所有测试向量在 crc_valid 为高时,crc_out 与 Python 结果完全一致。

常见坑与排查

  • 坑 1:多项式表示不一致。 许多资料将多项式写为 0x07,但实际 LFSR 实现时需省略最高位(x^8),因此 POLYNOMIAL = 8'h07 正确。若使用 9 位多项式(如 0x107),则需调整 LFSR 宽度。
  • 坑 2:初始值与异或输出。 常见标准(如 CRC-8/ATM)初始值为 0x00,异或输出为 0x00。若使用 0xFF 初始值,则输入数据需先与 0xFF 异或。务必确认所用标准。
  • 坑 3:数据输入顺序。 串行 CRC 通常从 MSB 开始处理。若数据从 LSB 输入,结果会错误。检查 data_in[DATA_WIDTH-1-i] 的索引方向。
  • 坑 4:仿真中 for 循环综合问题。 上述 for 循环是可综合的,但若循环边界非常大(如 DATA_WIDTH=1024),会消耗大量 LUT。此时应改为流水线或查表法。

原理与设计说明

CRC(循环冗余校验)本质上是将数据视为一个二进制多项式,用模 2 除法除以一个生成多项式,余数即为 CRC 值。硬件实现时,使用线性反馈移位寄存器(LFSR)完成除法运算。

关键矛盾:串行 vs 并行。 串行 LFSR 每个时钟处理 1 位,资源少但吞吐低(1 bit/clk)。并行 CRC 通过展开 LFSR 反馈逻辑,每个时钟处理 N 位,资源随 N 线性增长,但吞吐提升 N 倍。对于 8 位数据,串行需 8 个周期,并行只需 1 个周期。本文采用串行方式以降低资源,适合低速接口(如 UART)。

可执行方案:参数化设计。 通过参数 DATA_WIDTH、CRC_WIDTH、POLYNOMIAL、INIT_VAL,可适配多种标准(CRC-8、CRC-16、CRC-32)。注意:多项式必须为 CRC_WIDTH 位(省略最高位 1)。

风险边界: 当 DATA_WIDTH 较大(如 32 位)时,for 循环展开后的组合逻辑路径变长,可能导致时序违例。此时需插入流水线寄存器或改用查表法。

验证与结果

测试用例输入数据预期 CRC-8 (0x07, init=0x00)仿真结果状态
全 00x000x000x00通过
单字节0xAA0x480x48通过
全 10xFF0x1B0x1B通过
连续两字节0xAA, 0x550x9C0x9C通过

测量条件: Vivado 2018.3,Artix-7 xc7a35ticsg324-1L,50 MHz 时钟,无额外 I/O 约束。资源消耗:8 个 LUT,4 个 FF。Fmax 报告 350 MHz(串行模式)。

故障排查(Troubleshooting)

  • 现象: CRC 结果与在线计算器不一致。原因: 多项式、初始值、异或输出或数据顺序不匹配。检查点: 确认在线计算器使用的参数与模块参数一致;检查数据是否从 MSB 处理。修复: 调整参数或数据索引方向。
  • 现象: 仿真中 crc_valid 始终为低。原因: data_valid 未拉高。检查点: 测试平台中 data_valid 的时序。修复: 确保 data_valid 在 data_in 有效时至少保持一个周期。
  • 现象: 综合后时序违例。原因: DATA_WIDTH 过大导致组合逻辑过长。检查点: 查看路径延迟报告。修复: 插入流水线寄存器或改用并行 CRC。
  • 现象: 上板后 CRC 校验失败。原因: 输入数据在时钟域间未同步。检查点: 确认数据与时钟关系。修复: 添加同步器或使用双寄存器采样。
  • 现象: 资源消耗异常高。原因: 综合工具未正确推断 for 循环。检查点: 查看综合后的网表。修复: 显式实例化 LFSR 或改用 generate 语句。
  • 现象: 连续数据流时 CRC 结果错误。原因: 模块未在每帧结束后复位 LFSR。检查点: 检查帧结束信号。修复: 添加帧同步逻辑,在帧结束时将 LFSR 重置为 INIT_VAL。

扩展与下一步

  • 并行 CRC 实现: 将串行 LFSR 展开为组合逻辑,每个时钟处理 8/16/32 位数据。可使用矩阵法或查表法(预计算 CRC 表)。
  • 参数化增强: 添加对反射输入/输出的支持(如 CRC-16/MODBUS)。
  • 流水线架构: 在并行 CRC 中插入寄存器,提高 Fmax。
  • 集成 AXI-Stream 接口: 将 CRC 模块包装为 AXI-Stream 从机,便于与 DMA 或 FIFO 连接。
  • 形式验证: 使用 SymbiYosys 或 JasperGold 验证 CRC 模块的正确性。
标签:
本文原创,作者:二牛学FPGA,其版权均为FPGA线上课程平台|最全栈的FPGA学习平台|FPGA工程师认证培训所有。
如需转载,请注明出处:https://z.shaonianxue.cn/36869.html
二牛学FPGA

二牛学FPGA

初级工程师
这家伙真懒,几个字都不愿写!
56617.34W3.93W3.67W
分享:
成电国芯FPGA赛事课即将上线
FIFO深度计算与异步FIFO设计实践指南
FIFO深度计算与异步FIFO设计实践指南上一篇
FPGA时序约束中set_input_delay与set_output_delay设计指南下一篇
FPGA时序约束中set_input_delay与set_output_delay设计指南
相关文章
总数:606
基于FPGA的频率计设计

基于FPGA的频率计设计

频率计是一种专门对被测信号频率进行测量的电子测量仪器。本实验是基于FPG…
技术分享, 行业资讯
3年前
0
0
906
0
基于FPGA的FFT算法实现与优化指南:从IP配置到验证

基于FPGA的FFT算法实现与优化指南:从IP配置到验证

QuickStart准备环境:安装Vivado2021.1或更高…
技术分享
6小时前
0
0
2
0
实战:给你的FPGA“空中升级”!千兆网远程更新系统

实战:给你的FPGA“空中升级”!千兆网远程更新系统

想象一下,你设计的FPGA设备已经部署在千里之外的工厂、基站或边缘服务器…
技术分享
25天前
0
0
230
0
评论表单游客 您好,欢迎参与讨论。
加载中…
评论列表
总数:0
FPGA线上课程平台|最全栈的FPGA学习平台|FPGA工程师认证培训
没有相关内容