10G以太网系统中的并行CRC编解码器的设计
摘要:为了解决10G以太网接入系统中大规模并行CRC编码器的设计问题,提出了矩阵法、代入法、流水线法等三种设计方法。以此为基础,给出了10G以太网接入系统CHC编码器的实现方案。具体计算表明,在10G以太网接入系统采用直接并行的CRC编码器是可行的。直接并行设计CRC编码器已经通过了EDA模拟,并成功地应用于10G以太网接入系统中。
关键词:10G 以太网 CRC 并行
通信系统不可避免地要受到各种干扰的影响,使接收端收到的信息与发送端发出的信息不一致,即接收端收到的信息产生了误码。为了降低数据通信线路传输的误码率,通常有改善数据通信线路传输质量和差错检测控制两种方法。差错检测控制的方法很多,本文讨论在10G以太网接人系统中并行实现CRC-32编解码的方法、并行CRC算法的Unfolding算法可以实现并行CRC的计算,但是并行电路所用的资源增加到了原来的J倍。8位并行CRC算法、并行CRC-16的编码逻辑、USB技术中并行CRC算法给出的并行算法都建立在公式递推的基础上。当并行深度较小时,递推算法比较适用。而当并行深度很大的情况下(10G以太网接人系统使用64比特并行数据通路),递推过程就显得过于烦琐而缺乏实用性。为此,本文提出了矩阵法、代入法和流水线法等三种算法,解决了深度并行情况下CRC算法的实现问题。利用本文提出的算法,可以得出64比特并行CRC计算的逻辑表达式,并用于10G以太网接入系统的设计。设M/(x)为信息多项式,G(x)为生成多项式。一般的CRC编码方法是:先将信息码多项式左移r位,即M(x)·xr,然后作模2除法
(M(x)· x r)/G(x)=Q(x)+R(x)/G(x) (1)
所得到的月(x)就是CRC校验码。以二进制码0x9595H的CRC-32编码为例:
javascript:window.open(this.src);" style="cursor:pointer;"/>
· 将信息码左移32比特变成0x959500000000H,记为m。
·CRC-32G的生成多项G(x)=x32+x26+x23+x22+x16+x12+xll+x10+x8+x7+x5+x4+x2+x+1,转换成16进制码为g=0x104C01DB7H。用m除以g(模2除法),所得余数0x3738F30BH就是0x9595H的CRC-32码。实现0x9595H的基本CRC-32编码的Matlab程序如下:
g(33:-1:1)=[1,0 0 0 0 0 1 0 0,1 1 0 0 0 0 0 1,0 0 0 1 1 1 0 1,1 0 1 1 0 1 1 1];
a(48:-1:1)=[1 0 0 1 0 1 0 1,1 0 0 1 0 1 0 1,0 0 0 0 0 0 0 0,0 0 0 0 0 0 0 0,0 0 0 0 0 0 0 0,0 0 0 0 0 0 0 0];
for i=48:-1:33,
if a(i)= =1
a(i:-1:i-32)=xor(a(i:-1:i-32),i(33:-1:1));
end
end
crc=a(32:-1:1)
如果想用以上CRC-32程序计算其他长为L的序列的基本CRC-32码,只需将数组α的上界和for循环中i的初始值改为32+L,并用该序列代替数组。开始的序列"1001010110010101"即可。用数字电路实现的串行CRC编码器如图1所示。图1中每个矩形表示D触发器。gi的取值范围是1或者0。取1时表示通路,取0时表示断路。进行基本CRC-32编码时,每个D触发器初始状态为0,从数据端串行输入二进制的信息码。信息码输入结束后,D触发器中锁存的数值就是信息码的基本CRC-32编码。此电路适用于信息码长为任意值的情况。在某些信息系统中以基本CRC产生算法为基础附加了新的规定。例如IEEE802.3协议规定,以太网的FES(帧校验序列)域以CRC-32为基础,并且在编码时首先将信息码的最初4个字节取反码,对目的地址、源地址、长度/类型域、数据域、PAD域求出基本CRC-32码之后再将结果取反,最后的结果才是FCS。同上述过程等价的另一种实现方法是将图1中所有D触发器的初值置1,这样结果不必取反。为使电路设计者验证其FCS编码正确,IEEE802.3还给出了一个样本,即:将序列0xBED723476B8FB3145EFB3559H重复126次,最后得到的FCS值应该为0x94D254ACH。10G以太网是IEEE802.3ae工作组提出的建议。它保持了以前以太网的帧结构,但是线速度达到了10Gbps的量级。为了降低10G以太网接入系统的功耗并达到芯片加工工艺的要求,必须采用并行数据通路。为计算FCS需要研究并行CRC算法。所设计的10G以太网接入系统采用64比特并行数据通路,因此本文主要讨论64比特并行CRC-32的实现方法。本文共介绍三种实现方法,其中矩阵法和代入法是基于组合逻辑的直接实现方法,第三种方法是基于流水线的实现方法。
javascript:window.open(this.src);" style="cursor:pointer;"/>
1 矩阵法
记图1中的32个D触发器的输出从右至左依次为d31,d30,…,d0。信息码元的输入端为i。令D=[d0d1…d31]T表示编码器当前所处的状态,I=[i63i62…i0]表示第1至第64个时钟的信息码元输入,向量Dˊ=[d0ˊd1ˊ,…d31ˊ] T表示编码器的下一个状态,D(64)表示64个时钟之后CRC编码器所处的状态。则设计64位并行CRC逻辑编码器,就是找出函数关系D(64)=f(D,I)。
do'=d31+i63
d1'=d0+d31+i63
d2'=d1+d31+i63
d3'=d2
…
d31'=d30
写成行列式,有D'=TD+Si63
其中:
javascript:window.open(this.src);" style="cursor:pointer;"/>
2个时钟之后编码器的状态为:
D''=TD'+Si62=T)TD+Si63)+Si62=T2D+TSi63+Si62
依此类推,有:
D(64)=T64D+T63Si63+T62Si62+…+TSi1+Si0 (2)
这里所有矩阵运算和代数运算中的加号的语义都是模2加法。为了。设计64位并行CRC电路,必须计算(2)式中的大规模矩阵乘法T64、T63S等。
2 代入法
矩阵法的优点在于其直观性。但是需要做大规模乘法运算。下面讨论的代入法能够得到与矩阵法相同的结果。同时可以避免大规模矩阵乘法运算。设8比特并行CRC-32电路的初始状态是d31,d30,…,d0,输入是i7,i6,…,j0,输出是z31,Z30,…,z0。利用前面所述的矩阵法,可以得出8比特并行CRC-32编码器的组合逻辑表达式。如表1所示。
即:
z31=d23+d29+i5;
z30=d22+d31+i7+d28+i4
…
z0=d24+d30+i6+i0
表1 8位行CRC逻辑表
z0 | d24,d30,i6,i0 |
z1 | d25,d31,i7,i1,d24,d30,i6,i0 |
z2 | d26,i2,d25,d31,i7,i1,d24,d30,i6,i0 |
z3 | d27,i3,d26,i2,d25,d31,i7,i1 |
z4 | d28,i4,d27,i3,d26,i2,d24,d30,i6,i0 |
z5 | d29,i5,d28,i4,d27,i3,d25,d31,i7,i1,d24,d30,i6,i0 |
z6 | d30,i6,d29,i5,d28,i4,d26,i2,d25,d31,i7,i1 |
z7 | d31,i7,d29,i5,d27,i3,d26,i2,d24,i0 |
z8 | d0,d28,i4,d27,i3,d25,i1,d24,i0 |
z9 | d1,d29,i5,d28,i4,d26,i2,d25,i1 |
z10 | d2,d29,i5,d27,i3,d26,i2,d24,i0 |
z11 | d3,d28,i4,d27,i3,d25,i1,d24,i0 |
z12 | d4,d29,i5,d28,i4,d26,i2,d25,i1,d24,d30,i6,i0 |
z13 | d5,d30,i6,d29,i5,d27,i3,d26,i2,d25,d31,i7,i1 |
z14 | d6,d31,i7,d30,i6,d28,i4,d27,i3,d26,i2 |
z15 | d7,d31,i7,d29,i5,d28,i4,d27,i3 |
z16 | d8,d29,i5,d28,i4,d24,i0 |
z17 | d9,d30,i6,d29,i5,d25,i1 |
z18 | d10,d31,i7,d30,i6,d26,i2 |
z19 | d11,d31,i7,d27,i3 |
z20 | d12,d28,i4 |
z21 | d13,d29,i5 |
z22 | d14,d24,i0 |
z23 | d15,d25,i1,d24,d30,i6,i0 |
z24 | d16,d26,i2,d25,d31,i7,i1 |
z25 | d17,d27,i3,d26,i2 |
z26 | d18,d28,i4,d27,i3,d24,d30,i6,i0 |
z27 | d19,d27,i5,d28,i4,d25,d31,i7,i1 |
z28 | d20,d30,i6,d29,i5,d26,i2 |
z29 | d21,d31,i7,d30,i6,d27,i3 |
z30 | d22,d31,i7,d28,i4 |
z31 | d23,d29,i5 |
下文用"+"表示按位模2和运算,"{,}"表示链接运算。从CRC的(1)式很容易得出以下算法:
算法1:已知序列N的CRC-32为A[31:0],序列B(=[b7,b6,…,b0])的CRC-32码为Y[31:0]。序列A[31:24]的CRC-32为X[31:0],则延拓序列{N,B}的CRC-32码为{Y[31:24]+X[31:24]+A[23:16],Y[23:16]+X[23:16]+A[15:8]+A[7:0],Y[7:0]+X[7:0]}。
推论:已知序列N的CRC-32为A[31:0],序列A[31:24]的CRC-32为X[31:0],则补0延拓序列{N,O}的CRC-32码为{X[31:24]+A[23:16]+A[15:8],X[15:8]+A[7:0],X[7:0]}。
利用上述算法构造APPEND模块,其端口A和B分别表示前导序列的CRC和延拓的8比特序列,则其输出端口Z为拓展之后序列的CRC。图2利用APPEND模块构造了级联结构的64比特并行CRC编码器。这种级联构造的编码器设计比较简单。其中间节点:
Z1(n)=f(r,d[0:7] n[31,0]
Z2(n)=f(Z1,d[8:15])=f(f(r,d[0:7]),d{8:15])
… (3)
javascript:window.open(this.src);" style="cursor:pointer;"/>