Quick Start
- 步骤一:新建Vivado工程,选择器件(如xc7z020clg484-1),添加一个空的Verilog模块。
- 步骤二:编写奇偶校验模块:输入8位数据data_i,输出奇校验位parity_odd和偶校验位parity_even。使用^归约运算符:assign parity_odd = ^data_i; assign parity_even = ~parity_odd。
- 步骤三:编写CRC-8校验模块:输入8位数据data_i和8位初始值crc_init,输出8位CRC结果crc_o。使用LFSR结构,多项式x^8 + x^2 + x + 1(0x07)。
- 步骤四:编写testbench,为奇偶校验模块输入0x55、0xAA、0xFF,观察parity_odd和parity_even波形。
- 步骤五:为CRC模块输入data_i=0xAB,crc_init=0x00,预期crc_o=0x5A(按多项式0x07计算)。运行仿真。
- 步骤六:在Vivado中运行综合,检查资源报告:奇偶校验消耗0个LUT(仅组合逻辑),CRC-8消耗约8-10个LUT。
- 步骤七:将CRC模块实例化到顶层,连接板级时钟和复位,生成比特流并下载到FPGA开发板(可选)。
- 步骤八:验收:仿真波形中奇偶校验位与预期一致;CRC结果与在线计算器(如https://crccalc.com)对比一致。
前置条件与环境
| 项目/推荐值 | 说明 | 替代方案 |
|---|---|---|
| 器件/板卡 | Xilinx Artix-7 (xc7a35t) 或 Zynq-7000 | Altera Cyclone IV 或 Lattice iCE40 |
| EDA版本 | Vivado 2020.1 或更高版本 | Quartus Prime 18.0+ / Lattice Diamond |
| 仿真器 | Vivado Simulator (xsim) | ModelSim / Questa / Verilator (仅仿真) |
| 时钟/复位 | 系统时钟100MHz,异步复位低有效 | 50MHz或200MHz均可,复位极性可配置 |
| 接口依赖 | 无外部接口依赖,纯组合或时序逻辑 | 若需上板验证,需连接LED或UART输出结果 |
| 约束文件 | 仅需时钟周期约束(create_clock -period 10 [get_ports clk]) | 若为纯组合逻辑,无需约束 |
目标与验收标准
- 功能点:奇偶校验模块正确计算奇偶位;CRC模块按指定多项式计算8位校验和。
- 性能指标:奇偶校验无延迟(组合逻辑);CRC-8在100MHz时钟下延迟不超过2个时钟周期(流水线实现)。
- 资源消耗:奇偶校验0 LUT;CRC-8 ≤ 12 LUT。
- 验收方式:仿真波形中对比预期值;综合报告确认时序无违例(WNS≥0)。
实施步骤
1. 工程结构与模块划分
- 创建三个文件:parity_check.v(奇偶校验)、crc8_check.v(CRC-8)、top.v(顶层实例化)。
- 目录结构:src/(RTL源码)、sim/(testbench)、constr/(XDC约束)。
- 预期结果:Vivado中“Add Sources”后无语法错误。
2. 关键模块实现
奇偶校验模块:使用Verilog归约运算符^,一行代码完成。
// parity_check.v
module parity_check (
input wire [7:0] data_i,
output wire parity_odd,
output wire parity_even
);
assign parity_odd = ^data_i; // 奇校验:1的个数为奇数时输出1
assign parity_even = ~parity_odd; // 偶校验:取反
endmoduleCRC-8模块:使用线性反馈移位寄存器(LFSR)实现,多项式x^8 + x^2 + x + 1(0x07)。注意初始值可配置。
// crc8_check.v
module crc8_check (
input wire clk,
input wire rst_n,
input wire data_valid,
input wire [7:0] data_i,
output reg [7:0] crc_o
);
wire [7:0] next_crc;
assign next_crc[0] = crc_o[7] ^ data_i[0];
assign next_crc[1] = crc_o[0] ^ crc_o[7] ^ data_i[1];
assign next_crc[2] = crc_o[1] ^ crc_o[7] ^ data_i[2];
assign next_crc[3] = crc_o[2] ^ data_i[3];
assign next_crc[4] = crc_o[3] ^ data_i[4];
assign next_crc[5] = crc_o[4] ^ data_i[5];
assign next_crc[6] = crc_o[5] ^ data_i[6];
assign next_crc[7] = crc_o[6] ^ data_i[7];
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
crc_o <= 8'h00;
else if (data_valid)
crc_o <= next_crc;
end
endmodule注意:此实现为串行CRC,每个时钟处理1位。若需并行CRC-8(8位数据一次处理),需展开LFSR逻辑。
3. 时序与约束
create_clock -period 10 [get_ports clk]。



