CRC检错技术原理

**

一、CRC检错原理

**
CRC(cyclic redundancy check/code):循环冗余检错技术/循环冗余校验码;

《计算机网络 第五版》—谢希仁所著的教材通过例子对循环冗余检验原理的原理说明如下:
在发送端,先把数据划分为组,假定每组k个比特。现假定待传送的数据M=101001(k=6)。CRC运算就是在数据M的后面添加供差错检测用的n位冗余码,然后构成一个帧发送出去,一共发送(k+n)位。在所要发送的数据后面增加n位的冗余码,虽然增大了数据传输的开销,但却可以进行差错检测。当传输可能出现错误时,付出这种代价往往是很值得的。

这n位冗余码可用以下方法得出。用二进制的模2运算进行乘M的运算,这相当于在M后面添加n个0。得到的(k+n)位的数除以收发双方事先商定的长度为(n+1)位除数P,得出的商是Q而余数是R(n位,比P少一位)。关于除数P下面还要介绍。在图1所示的例子中,M=101001(即k=6)。假定除数P=1103(即n=3)。经模2除法运算后的结果是:商Q=110101(这个商并没有什么用处),而余数R=001。这个余数R就作为冗余码拼接在数据M的后面发送出去。这种为了进行检错而添加的冗余码常称为帧检验序列FCS(Frame Check Sequence)。因此加上FCS后发送的帧是101001001(即),共有(k+n)位。
在这里插入图片描述
顺便说一下,循环冗余检验CRC和帧检验序列FCS并不是同一概念。CRC是一种检错方法,而FCS是添加在数据后面的冗余码,在检错方法上可以选用CRC,但也可以不选用CRC。

在接受端把接收到的数据以帧为单位进行CRC检验:把收到的每一个帧都除以同样的除数P(模2运算),然后检查得到的余数R。

如果在传输过程中无差错,那么经过CRC检验后得出的余数R肯定是0。但如果出现误码,那么余数R仍等于零的概率是非常非常小的(可以通过不太复杂的概率计算得出)。
  总之,在接收端对收到的每一帧经过CRC检验后,有以下两种情况:
  1)若得出的余数R=0,则判定这个帧没有差错,即接受(accept);
  2)若余数R!=0,则判定这个帧有差错,即丢弃(discard)。  
  一种较方便的方法时用多项式来表示循环冗余检验过程。在上面的例子中,用多项式 表示上面的除数P=1101(最高位对应于,最低位对应于)。多项式P(X)称为生成多项式。现在广泛使用的生成多项式P(X)有以下几种:
在这里插入图片描述
小结:

小结一下上述教材内容所提到的内容:

1)什么叫"模2运算"?
  通过一个例子的话我想能够在你脑子里形成清晰的概念。假如一个数k被任意的数除,那么它产生的余数必定是在[0,n)区间中。即x mod n ∈ [0, n)。模2运算也是符合这种理论的,即模2运算就是指结果只能是在[0,2)区间中取整数值的运算,显然"模2运算"就是指结果只能为0、1的特殊二进制运算。
  2)为什么"模2运算"属于特殊二进制运算,必须突出"特殊"二字?
  第一点,"模2运算"和"二进制运算"名字本身就不同,因此类比的时候使用"特殊"二字;第二点,两者的运算其实是有区别,"模2运算"既不进位也不退位,而"二进制运算"和"十进制运算"均需要进、退位。
  3)循环冗余检验只是数学检错技术中的一种,还有奇偶校检等数学手段。而且循环冗余检验并不能保证100%正确,只能说接近100%。

**

二、CRC检错实战

**
在这里插入图片描述
首先分析生成多项式,显然n=3,因此循环冗余码应为3位二进制数。生成多项式代表的二进制除数P=1001,发送的数据为101110,则真实的被除数为101110000。进行减模2运算(异或运算)如下:
在这里插入图片描述
于是得到FCS为011,因此发送数据实际为101110011(除以1001余数为0,读者可自行尝试)。注意到,在运算的时候,每次都会往后退一位,即第一位每次都是被消掉的。

	注意:计算机网络通信中,我们对生成多项式(除数)作了统一的标准,即针对不同的帧,发送端网卡添加不同的FCS,而接受端网卡知道相应帧该用CRC-16还是CRC-32来检错。

上代码:

`timescale  1ns/1ps
module CRC(
    input wire clk,
    input wire rstn,
    input wire req,
    input wire [5:0] i_data,
    input wire [3:0] i_crc,
    output reg [8:0] o_data_fcs,
    output reg o_vld
);
reg [5:0] i_data_r;//缓存
reg [3:0] i_crc_r;//缓存
reg start;
reg [9-4-1:0] data_middle_shift;
reg [3:0] fcs_r;
reg [5:0] count;

always @(posedge clk or negedge rstn ) begin
    if(~rstn)begin
        i_data_r<='b0;
        i_crc_r<='b0;
        start<='b0;
    end
    else if(req & ~start)begin
        i_data_r<=i_data;
        i_crc_r<=i_crc;
        start<='b1;
    end
    else if(start && o_vld)begin
        start<='b0;
    end
end

//利用移位寄存器实现模2运算输入
always @(posedge clk or negedge rstn ) begin
    if(~rstn)begin
        data_middle_shift<='b0;
    end
    else if(req)begin
        data_middle_shift<={i_data[1:0],3'b000};
    end
    else if(start && count!='b0)begin
        data_middle_shift<={data_middle_shift[3:0],1'b0};
    end
end
//控制异或运算次数
always @(posedge clk or negedge rstn ) begin
    if(~rstn)begin
        count<='b0;
    end
    else if(req)begin
        count<='d5;
    end
    else if(start&&count=='d0)begin
        count<='d5;
    end
    else if(start)begin
        count<=count-'b1;
    end

end

//模2运算
always @(posedge clk or negedge rstn ) begin
    if(~rstn)begin
        fcs_r<='b0;
    end
    else if(req)begin
        if(i_data[5])
            fcs_r<=i_data[5:2]^i_crc;
        else begin
            fcs_r<=i_data[5:2];
        end
    end
    else if(start)begin
        if(fcs_r[2])
            fcs_r<={fcs_r[2:0],data_middle_shift[4]}^i_crc_r;
        else begin
            fcs_r<={fcs_r[2:0],data_middle_shift[4]};
        end
    end
end

always @(posedge clk or negedge rstn ) begin 
    if(~rstn)begin
        o_vld<='b0;
    end
    else if(count=='b1 && start)begin
        o_vld<='b1;
    end
    else
        o_vld<='b0;
end

always @(posedge clk or negedge rstn ) begin
    if(~rstn)begin
        o_data_fcs<='b0;
    end
    else if(o_vld)begin
        o_data_fcs<={i_data_r,fcs_r[2:0]};
    end
    else
        o_data_fcs<=o_data_fcs;
end
endmodule

tb:

`timescale  1ns/1ps
module tb_crc();
reg clk;
reg rstn;
reg req;
reg [5:0] i_data;
reg [3:0] i_crc;
wire [8:0] o_data_fcs;
wire o_vld;
    
initial begin
	clk<=1;
	rstn=1;
    #(20)
	rstn=0;
	#100;
	rstn<=1;
end
always #10 clk=~clk;
    
initial begin
req<='b0;
i_data<=6'b101110;
i_crc<='b1001;
#(120) req<='b1;
#(20) req<='b0;
end
    
    

CRC cr_inst(
    .clk(clk),
    .rstn(rstn),
    .req(req),
    .i_data(i_data),
    .i_crc(i_crc),
    .o_data_fcs(o_data_fcs),
    .o_vld(o_vld)
);


endmodule

测试结果:计数到0输出crc校验码:101110011
在这里插入图片描述

  • 3
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: LIN总线技术原理PDF是关于LIN总线技术的工作原理的电子文档。LIN(Local Interconnect Network)总线是一种用于车辆电子系统中低速通信的串行总线标准。 LIN总线技术原理PDF介绍了LIN总线的基本原理和工作方式。LIN总线采用主从结构,主节点发送命令,从节点接收和执行命令。主节点负责控制总线的访问和数据传输。 LIN总线技术通过主节点发送帧,从节点接收并执行帧中的命令。帧由起始位、标识符、数据位、校验位等组成。帧的结构遵循LIN总线协议规定的格式。 LIN总线技术原理PDF还介绍了LIN总线的通信速率和协议特性。LIN总线的通信速率相对较低,通常在10kbps到20kbps之间,适用于车辆电子系统中的低速通信。LIN总线采用了检错校验和帧计时等机制,以确保数据的可靠性和有效性。 此外,LIN总线技术原理PDF还介绍了LIN总线的应用场景和优势。LIN总线技术在汽车领域得到广泛应用,用于连接各种车辆电子控制单元,如仪表板控制模块、门控制模块等。相比于其他高速总线标准,LIN总线技术具有低成本、低功耗、简单实用等优点。 综上所述,LIN总线技术原理PDF介绍了LIN总线的基本原理、工作方式、通信特性和应用场景。这份电子文档对于学习和理解LIN总线技术的相关知识非常有帮助。 ### 回答2: LIN总线技术原理PDF是一种用于汽车电子系统中的通信协议,用于连接车辆的各种电子设备。其原理是通过一对差分线来传递信息,其中一个线路传输高电平信号,而另一个线路传输低电平信号。这种差分传输方式可以减少电磁干扰和信号损失。 LIN总线技术搭建在主从架构上。主设备是指负责协调总线上所有从设备通信的控制单元,而从设备是指连接在主设备上的所有其他电子设备。主设备通过发送帧来与从设备通信,帧中包含有关数据传输的信息。 主设备和从设备之间的通信是基于时间划分多路复用的方式。主设备发送帧的时候,从设备会在固定的时间间隔内对帧进行响应。这样可以确保多个从设备在同一总线上同时通信而不发生冲突。 此外,LIN总线技术还提供了错误检测和纠正机制。帧中包含校验位,用于检测传输过程中是否发生错误,从而保证数据的可靠性。如果发现错误,主设备可以要求从设备重新发送数据,或者纠正错误。 总的来说,LIN总线技术是一种简单而可靠的汽车电子通信协议。它通过差分传输、主从架构和时间划分多路复用来实现车辆电子设备之间的数据传输和通信。通过提供错误检测和纠正机制,LIN总线技术可以提高数据传输的可靠性,适用于需要低速、简单且成本较低的应用场景。 ### 回答3: LIN总线技术原理PDF是一种用于汽车电子系统之间进行通信的协议。它是一种低速、短距离通信协议,主要用于车身控制模块之间的通信。LIN总线技术可以实现多个从节点与一个主节点之间的通信。 LIN总线技术原理主要包括总线结构、数据传输和错误检测。 首先,LIN总线是一种单总线结构,主节点和从节点通过同一条总线连接。主节点负责向从节点发送指令,而从节点负责接收指令并执行相应的操作。 其次,数据传输是通过在总线上发送和接收数据帧来实现的。数据帧由同步字段、标识符、数据域和校验字段组成。同步字段用于同步主从节点,标识符用于标识不同的数据帧,数据域用于传输数据,校验字段用于检测数据传输中的错误。 最后,错误检测是通过在数据帧中使用校验字段来实现的。校验字段通常使用循环冗余校验(CRC)算法计算得到,用于检测数据传输过程中是否存在错误。如果接收到的校验字段与计算得到的校验字段不一致,就说明数据传输发生错误,需要重新发送数据帧。 综上所述,LIN总线技术原理PDF是一种用于汽车电子系统之间通信的协议。它通过总线结构、数据传输和错误检测来实现主从节点之间的通信,为汽车电子系统提供可靠的数据传输。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值