CRC算法详解:模2除法在数据传输校验中的应用

版权申诉
0 下载量 101 浏览量 更新于2024-10-09 收藏 2KB RAR 举报
资源摘要信息:"CRC.rar_模2除" 在信息技术领域,循环冗余校验(Cyclic Redundancy Check,简称CRC)是一种广泛使用的错误检测码技术,用于检测数据传输或者数据存储过程中的错误。CRC的核心算法包括模2除法,它是一种在二进制域内进行的除法运算,运算时不考虑借位,而是采用异或(XOR)操作来完成。模2除法在CRC算法中用于生成校验码和检测数据中的错误。 在模2除法过程中,我们使用的是二进制运算,其中1+1=0和1+0=1,减法运算用的是异或运算。这个过程可以类比于我们熟悉的十进制除法,但是它的执行过程与十进制的除法有明显的区别。在模2除法中,我们使用一个称为生成多项式(generator polynomial)的预定义二进制数,用于在数据序列中添加冗余位,以便进行错误检测。 CRC算法的步骤如下: 1. 将用户输入的字符串首先转换成二进制信息字段。在这个过程中,每个字符都会根据其ASCII码或其他字符编码方案转换成相应的二进制数。 2. 为了开始生成校验码,将转换后的二进制信息字段左移固定位数(本例中是16位),以腾出空间用于添加计算得到的校验码。 3. 使用生成多项式对左移后的信息多项式进行模2除。在这个过程中,生成多项式的每个位都会与信息多项式的相应位进行比较,如果生成多项式较短,则会在其前面补零以匹配信息多项式的长度。 4. 进行异或运算(相当于模2除法中的减法操作)来计算余数。这个过程会持续到完成信息多项式的运算。 5. 将得到的余数(校验码)拼接在原始信息的左移空出的位置上。拼接后的数据就是发送端最终发送的信息。 在接收方,接收到的完整信息(原始信息加上校验码)会被使用相同的生成多项式进行模2除法。如果余数为零,则可以认为数据在传输过程中没有出现错误。如果余数不为零,则意味着数据在传输过程中出现了错误。 生成多项式是CRC算法中非常关键的一个因素,不同的多项式可以产生不同的检测能力和错误检测概率。在实际应用中,有许多标准的生成多项式用于不同的通信协议和数据存储系统。 标签“模2除”直接指向了上述算法中模2除法这一核心步骤,它是整个CRC算法实现的关键所在。模2除法之所以特别,是因为它在运算中不考虑进位和借位,这使得在二进制运算中,能够以异或操作代替传统的加减运算。 文件名“CRC.c”暗示了文件内容可能包含用C语言编写的源代码,这段代码可能用于实现CRC算法的某个部分,或者用于演示如何在计算机程序中应用CRC算法进行错误检测。通过分析该源代码文件,我们可以了解算法的具体实现细节,并进一步学习如何将理论应用于实际编程实践中。
2023-05-27 上传

//XW_crc_p.v `pragma protect begin module DW_crc_p( data_in, crc_in, crc_ok, crc_out ); parameter integer data_width = 16; parameter integer poly_size = 16; parameter integer crc_cfg = 7; parameter integer bit_order = 3; parameter integer poly_coef0 = 4129; parameter integer poly_coef1 = 0; parameter integer poly_coef2 = 0; parameter integer poly_coef3 = 0; input [data_width-1:0] data_in; input [poly_size-1:0] crc_in; output crc_ok; output [poly_size-1:0] crc_out; `define DW_max_data_crc_1 (data_width>poly_size?data_width:poly_size) wire [poly_size-1:0] crc_in_inv; wire [poly_size-1:0] crc_reg; wire [poly_size-1:0] crc_out_inv; wire [poly_size-1:0] crc_chk_crc_in; reg [poly_size-1:0] crc_inv_alt; reg [poly_size-1:0] crc_polynomial; `include "bit_order_crc_function.inc" `include "bit_order_data_function.inc" `include "calculate_crc_w_in_function.inc" `include "calculate_crc_function.inc" `include "calculate_crc_crc_function.inc" generate //begin genvar bit_idx; reg [63:0] crc_polynomial64; reg [15:0] coef0; reg [15:0] coef1; reg [15:0] coef2; reg [15:0] coef3; assign coef0= poly_coef0; assign coef0= poly_coef1; assign coef0= poly_coef2; assign coef0= poly_coef3; assign crc_polynomial64 = {coef3, coef2, coef1, coef0}; assign crc_pollynomial = crc_polynomial64[poly_size-1:0]; case(crc_cfg/2) 0: assign crc_inv_alt = {poly_size{1'b0}}; 1: for(bit_idx = 0; bit_idx<poly_sizel bit_idx=bit_idx+1) assign crc_inv_alt[bit_idx] = (bit_idx % 2)? 1'b0:1'b1; 2: for(bit_idx=0; bit_idx<poly_size; bit_idx=bit_idx+1) assign crc_inv_alt[bit_idx] = (bit_idx % 2)?1'b1:1'b0; 3: assign crc_inv_alt = { poly_size{1'b1}}; endcase endgenerate assign crc_in_inv = bit_order_crc(crc_in) ^ crc_inv_alt; assign crc_reg = calculate_crc(bit_order_data(data_in)); assign crc_out_inv = crc_reg; assign crc_out = bit_order_crc(crc_out_inv)^ crc_inv_alt; assign crc_chk_crc_in = calculate_crc_crc(crc_reg, crc_in_inv); assign crc_ok = (crc_chk_crc_in ==0); `undef DW_max_data_crc_1 endmodule `pragma protect end can you write a testbench for this piece of CRC verilog code so that this verilog file and the testbench can be used togerther by vcs to verify the correctness of this verilog file?

2023-06-14 上传

import serial import modbus_tk.defines as cst from modbus_tk import modbus_rtu import struct # 打开两个串口 com1 = serial.Serial(port='com2', baudrate=38400, bytesize=8, parity='N', stopbits=1) com2 = serial.Serial(port='com3', baudrate=38400, bytesize=8, parity='N', stopbits=1) # 创建Modbus RTU主机(master) master = modbus_rtu.RtuMaster(com1) master.set_timeout(1.0) master.set_verbose(True) # 读取保持寄存器数据 red = master.execute(1, cst.READ_HOLDING_REGISTERS, 0, 9) print(red) # 将字节数组划分为若干个长度为4的子数组 # def hex_f(a,b): # # g1=b # # z=a+g1#高低16位组合 # # z1=hex(z)[2:]#取0x后边的部分 # # # print(z1) # # return struct.unpack('!f', z1.decode('hex'))[0]#返回浮点数 # # e = hex_f(red[0],red[1]) # # print(e) red1 = master.execute(1, cst.READ_HOLDING_REGISTERS, 0, 9)[0] # 这里可以修改需要读取的功能码 print(red1) new = int(red1 * 0.8) print(new) red =master.execute(1, function_code=cst.WRITE_MULTIPLE_REGISTERS, starting_address=0, output_value=[new]) # 读取输入寄存器数据 input_regs = master.execute(1, cst.READ_INPUT_REGISTERS, 0, 9) print(input_regs,1) # 读取输入线圈数据 input_bits = master.execute(1, cst.READ_COILS, 0, 9) print(input_bits,2) # 读取输出线圈数据 output_bits = master.execute(1, cst.READ_DISCRETE_INPUTS, 0, 9) print(output_bits,3) # 将所有读取数据打包为Modbus RTU消息并写入com2串口 data = red + input_regs + input_bits + output_bits com2.write(master._do_crc(data)) # 关闭串口 com1.close() com2.close()AttributeError: 'RtuMaster' object has no attribute '_do_crc'咋修改不报错

2023-05-27 上传
2023-05-27 上传