许多系统都使用一个奇偶校验位作为错误检测的手段,比如我们最常用的串口传输就使用了这种校验方法。
一个奇偶校验位附加到多位数据中,使得这组数中的1的个数总是偶数或总是奇数。其中,一个偶校验位使得数据中1的总数为偶数,而一个奇校验位使得1的总数为奇数。
对于一个给定的系统,要么运行偶校验,要么运行奇校验,而不能同时使用这两者。
比如在进行串口传输时,我们要么定义数据为偶校验,要么定义成奇校验。对于所接受的每一个多位数据做检查时,如果是偶校验,检查发现收到的数据不是偶数个1,则说明数据发生了错误。反之,如果是奇校验,如果检查发现收到的数据不是奇数个1,则也说明数据发生了错误。
作为对奇偶校验位怎么附加到数据编码中的一个说明,下表列出了每个BCD数的奇偶校验位。
偶校验(Even Parity) | 奇校验(Odd Parity) | ||
校验位P | BCD码 | 校验位P | BCD码 |
0 | 0000 | 1 | 0000 |
1 | 0001 | 0 | 0001 |
1 | 0010 | 0 | 0010 |
0 | 0011 | 1 | 0011 |
1 | 0100 | 0 | 0100 |
0 | 0101 | 1 | 0101 |
0 | 0110 | 1 | 0110 |
1 | 0111 | 0 | 0111 |
1 | 1000 | 0 | 1000 |
0 | 1001 | 1 | 1001 |
奇偶校验位可以附加到数码的开头或结尾,这取决于系统的设计。注意:1的总数,包含奇偶校验位上的1,对于偶校验总是偶数,对于奇校验总是奇数。
奇偶校验位提供了单个位错误的检测机制(或者说是任意奇数个错误,但这种概率很低),但是不能检测一个数据中的两个错误。
比如,我们希望传输BCD编码0101(奇偶校验可以应用于任何位数,这里使用4位作为说明)。
如果我们想用偶校验方式来传输,则所传输的总数码为00101,如果接受系统只检测到奇数个1,那么说明数据接收错误:
如果我们想用奇校验方式来传输,则所传输的总数码为10101,如果接受系统只检测到偶数个1,那么说明数据接收错误:
那么问题来了,接收系统是通过什么电路来检测数据含有偶数个或者奇数个1呢?实际上实现方式很简单:就是博主小飞在verilog专栏内中介绍的单目运算符(位异或^)。
位异或的结果为1,则表明一个多位数据中含有奇数个1.
位异或的结果为0,则表明一个多位数据中含有偶数个1.
确定发送端的奇偶校验位是发送0还是1也是如此原理~