参考:
手写MIPI(一):MIPI-CSI-2 RAW10笔记_mipi csi-CSDN博客
图像处理项目记录 - NoNounknow - 博客园 (cnblogs.com)
【通俗易懂的通信】信道编码之——汉明码_汉明编码-CSDN博客
MIPI包的结构:
MIPI数据包的包头使用ECC来校验数据的传输是否正确。
所以解析MIPI数据必须用到ECC。
什么是ECC?
冗余位:
“冗余位”是一种二进制位,它被用来添加到需要传输的数据信息中,以确保信息在传输过程中不会发生丢失或者改变。
对于“冗余位”究竟需要多少位这个问题,我们有一个公式可以用来计算:
其中,r指的是冗余位究竟需要多少位,而m指的是传输的数据的二进制位数。
假设传输的数据的二进制位数是7位,那么冗余位的个数就可以通过上面的公式来计算:
= 2^4 ≥ 7 + 4 + 1
因此,我们的至少需要4个二进制位作为“冗余位”。
奇偶校验位
一个奇偶校验位是用来添加至二进制数据中的比特位,他通过确保整个二进制数据信息中“1”的个数是奇数还是偶数,来判断数据是否在传输过程中发生的改变。因此,存在两种类型的检测方式:
奇校验
在奇校验检测方式中,对于需要发送的数据信息比特,检查其中1的个数。如果这串比特中1的个数是奇数,为了保证加上“冗余位“后,””整串数据中1的个数最后为奇数,可想而知,冗余位上应该设置为“0”。如果在没有添加“冗余位”之前,数据比特流中的1的个数为偶数,那么为了最后把1的个数凑成一个奇数,冗余位上应该设置为1。
偶校验
同理,在偶校验检测方式中,对于需要发送的数据信息比特,仍然检查其中1的个数。如果这串比特中1的个数是奇数,为了保证加上“冗余位“后,””整串数据中1的个数最后为偶数,可想而知,冗余位上应该设置为“1”。如果在没有添加“冗余位”之前,数据比特流中的1的个数为偶数,那么为了最后把1的个数凑成一个偶数,冗余位上应该设置为0。
缺陷:
“奇偶校验法”仍然存在下面两条缺点:
一、虽然知道数据在传输过程中发生了改变,但并不知道是哪一位发生了改变,因而无法纠正错误,只能要求发送方重新发送一遍数据。
二、“奇偶校验法”只能发现1位,3位,5位。。。。。。奇数个二进制位发生改变,假设数据传输过程中有2位发生改变,则“奇偶校验法”并不能发现数据已经被更改了,仍然认为数据是无误的。
汉明码
汉明码其实就是“奇偶校验法”的升级版,它是多个“奇偶校验法”的组合糅合在一起,但是奇偶校验位的位置不一定再是最后一位了,而是有其他的计算方法。
假设我们需要传输的数据信息是由7位二进制位组成,通过之前内容我们已经算出来了至少需要4位冗余位。
因此,整个信息流有11个二进制位。其中有7位数据位和4位“奇偶校验位”。
所有2的幂次位(2^0=1,2^1=2,2^2=4,2^3=8……)作为“奇偶校验位”,因此,第1位,第2位,第4位,第8位为奇偶校验位,其他的7位为数据位。
从右往左(低位往高位)数,第一位是“1”的索引有:1011,1001,0111,0101,0011,0001
分别对应的10进制索引为:11,9,7,5,3,1,那么,这几位上面的数据位和1号“奇偶校验位”构成了一组。
通过对分组进行校验,即可知道具体的错误出现在哪并且进行纠错。
MIPI的ECC校验:
汉明码使用奇偶校验来纠正一个错误或检测两个错误,但它们不能同时执行这两项操作,因此需要添加一个额外的奇偶校验位。所使用的代码被构建为允许相同的校正子纠正 64 位序列中的前 24 位,并且这些校正子为 6 位宽。为了以紧凑的方式指定奇偶校验的编码和校正子的解码,使用以下矩阵:
WIKI
矩阵中的每个单元代表一个综合症,前二十四个单元(橙色行)使用前三位或前五位来构建综合症。矩阵中的每个综合症都是 MSB 左对齐:
顶行定义了数据位置位的 3 个 LSB,左列定义了数据位置位的 3 个 MSB(总共 64 位位置)。
例如第 37 位位置编码为 0b100_101,并具有校正子 0x68。
为了导出 24 位的奇偶校验 P0,橙色行中的 P0 将定义相应的位位置是否用于 P0 奇偶校验。
第i个海明码校验码Pi位于第2^(i-1)位.比如第一个校验码在第一位,而第三个校验码在第四位。
Hanmming-Modified Code(30,24)
据此可实现代码:
module ECC_Calculate_Haming #( parameter Data_bit_width = 24, parameter Redundant_bit_width = 8 )( input wire [Data_bit_width -1:0] I_Data , output wire [Redundant_bit_width-1:0] O_ECC ); reg [Redundant_bit_width-1:0] r_O_ECC; assign O_ECC = r_O_ECC; always@(*) begin r_O_ECC[7] <= 1'b0; r_O_ECC[6] <= 1'b0; r_O_ECC[5] <= ^{I_Data[10], I_Data[11], I_Data[12], I_Data[13], I_Data[14], I_Data[15], I_Data[16], I_Data[17], I_Data[18], I_Data[19], I_Data[21], I_Data[22], I_Data[23]}; r_O_ECC[4] <= ^{I_Data[ 4], I_Data[ 5], I_Data[ 6], I_Data[ 7], I_Data[ 8], I_Data[ 9], I_Data[16], I_Data[17], I_Data[18], I_Data[19], I_Data[20], I_Data[22], I_Data[23]}; r_O_ECC[3] <= ^{I_Data[ 1], I_Data[ 2], I_Data[ 3], I_Data[ 7], I_Data[ 8], I_Data[ 9], I_Data[13], I_Data[14], I_Data[15], I_Data[19], I_Data[20], I_Data[21], I_Data[23]}; r_O_ECC[2] <= ^{I_Data[ 0], I_Data[ 2], I_Data[ 3], I_Data[ 5], I_Data[ 6], I_Data[ 9], I_Data[11], I_Data[12], I_Data[15], I_Data[18], I_Data[20], I_Data[21], I_Data[22]}; r_O_ECC[1] <= ^{I_Data[ 0], I_Data[ 1], I_Data[ 3], I_Data[ 4], I_Data[ 6], I_Data[ 8], I_Data[10], I_Data[12], I_Data[14], I_Data[17], I_Data[20], I_Data[21], I_Data[22], I_Data[23]}; r_O_ECC[0] <= ^{I_Data[ 0], I_Data[ 1], I_Data[ 2], I_Data[ 4], I_Data[ 5], I_Data[ 7], I_Data[10], I_Data[11], I_Data[13], I_Data[16], I_Data[20], I_Data[21], I_Data[22], I_Data[23]}; end endmodule
标签:CSI2,ECC,个数,校验,奇偶校验,MIPI,数据,冗余 From: https://www.cnblogs.com/VerweileDoch/p/18105669