聊一聊CRC并行計算

CRC簡單算法和一種并行計算請參考《CRC原理與快速verilog仿真》
LFSR的定義請參考《多項式乘除法的LFSR實現(xiàn)》

1 單一寬度的并行CRC計算;

所謂單一寬度,比如每次要傳輸64bit數(shù)據(jù),需要做一次獨(dú)立的CRC計算冗尤;那么就適合本節(jié)的內(nèi)容。本節(jié)內(nèi)容僅僅提供一種解決思路,屬于思路拓展类嗤,通用方法參考第二節(jié);

首先我們看一下GF(2)的一個定理:

\begin{align} F(x) &= M(x) \oplus N(x) \\ \Rightarrow F(x)\% g(x) &=[M(x)\% g(x) ]\oplus [N(x)\% g(x)] \end{align}

F(X)可以被看作是輸入的序列辨宠,g(x)則是POLY多項式遗锣;

以DATA=8'hE6,POLY=5’b10011為例嗤形;
因輸入為8bit的數(shù)黄伊,而任意一個8bit的數(shù)都可以表示為:

\begin{align} b_70000000 &\oplus 0b_6000000\oplus 00b_500000\oplus 000b_40000\oplus \\ 0000b_3000&\oplus 00000b_200\oplus 000000b_10 \oplus 0000000b_0; \end{align}

把上面每一項記做cell_i,i\in(7,6,5,4,3,2,1,0),所以:
\begin{align} F(x)\%g(x)=cell_7\%g(x)\oplus cell_6\%g(x)\oplus ... \oplus cell_1\%g(x)\oplus cell_0\%g(x) \end{align}

即:DATA的CRC計算可以看作是各個cell分別對POLY做CRC計算派殷,然后再按位異或在一起还最。

每個cell對POLY對CRC計算取決于b_i的值:

  • b_i=0,則cell_i計算的CRC值為0,不參與整體的異或運(yùn)算毡惜;
  • b_i=1,則cell_i計算的CRC值為固定值拓轻,參與整體的異或運(yùn)算;

所有b_i=1時经伙,cell_i根據(jù)POLY=5'b10011計算的cell_crc如下表:

bit index cell cell_crc cell_crc_hex
7 1000_0000 1110 E
6 0100_0000 0111 7
5 0010_0000 1010 A
4 0001_0000 0101 5
3 0000_1000 1011 B
2 0000_0100 1100 C
1 0000_0010 0110 6
0 0000_0001 0011 3

可以畫出CRC的計算圖如下:


CRC并行計算圖1.png

從上圖也可以從另個角度推導(dǎo)出:
crc[3]=(bit7&1)\^(bit6&0)\^(bit5&1)\^(bit4&0)\^(bit3&1)\^(bit2&1)\^(bit1&0)\^(bit0&0) = bit7 ^ bit5 ^ bit3 ^ bit2;
以此類推CRC其他bit位扶叉,可以得到:

crc[3]=data[7]^data[5]^data[3]^data[2];
crc[2]=data[7]^data[6]^data[4]^data[2]^data[1];
crc[1]=data[7]^data[6]^data[5]^data[3]^data[1]^data[0];
crc[0]=data[6]^data[4]^data[3]^data[0];

注意此式只適合固定長度CRC計算,本文稱之為單一寬度的CRC計算帕膜,關(guān)于連續(xù)未知寬度的算法枣氧,下一節(jié)將給出推導(dǎo)過程。

2 不定寬度的CRC計算

所謂不定寬度垮刹,如網(wǎng)絡(luò)傳輸?shù)臄?shù)據(jù)达吞,是可以變換的,沒有固定的一個長度限制荒典;
對于這個問題酪劫,我還是喜歡從CRC定義的源頭來找答案

2.1 CRC的LFSR實現(xiàn)

通常CRC的多項式定義為:
\begin{align} crc(x)&=(m(x)*x^{r-1})\%g(x) \\ g(x)&= g_rx^r+g_{r-1}x^{r-1}+...+g_2x^2+g1_x^1+g0 \end{align}
g(x)也被稱為POLY多項式;
還以第一節(jié)例子為例(POLY=0b10011):
根據(jù)多項式乘除法的LFSR實現(xiàn)一文得到如下LFSR:

crc_lfsr.jpg

2.2 python推導(dǎo)出并行verilog代碼

其思路很簡單:

  1. 實現(xiàn)單bit輸入的LFSR寺董;
  2. 循環(huán)并行數(shù)據(jù)位寬覆糟;
  3. 消除冗余異或;

代碼如下:

#-------------------------------------------------------------------------
# user define parameter
POLY_W=32            #POLY WIDTH
POLY='0x04C11DB7'    #POLY in hex
DATA_W=8             #parallel data width
#-------------------------------------------------------------------------

#1 bit xor caculation
def xor(a,b):
    if a==b or str(a)==str(b):
        return('0')
    elif a=='0' and b=='1' or a==0 and b==1:
        return('1')
    elif a=='1' and b=='0' or a==1 and b==0:
        return('1')
    elif a=='0' or a==0:
        return(str(b))
    elif b=='0' or b==0:
        return(str(a))
    elif a!=b:
        return(str(a)+"^"+str(b))

#implement crc caculation w/ serial bit input 
def crc_s(c,d):
    e=[0 for x in range(POLY_W)]     #e store the next crc value
    bfmt="{:0%sb}"%POLY_W            #binary format
    poly_b=bfmt.format(int(POLY,16)) #poly to binary w/ width of POLY_W
    t=xor(c[POLY_W-1],d)             #bit0 input
    idx=POLY_W-1
    for i in poly_b:
        if(idx==0):
            e[idx]=t
        elif(i=='1'):
            e[idx]=xor(c[idx-1],t)
        else:
            e[idx]=c[idx-1]
        idx=idx-1
    return e
        
#reduce the xor caculation in an array element;
def mparse(tmp):
    t=tmp.split("^")
    t.sort()
    t_new=[]
    tag="fill only 1 element"
    for ti in t:
        if t.count(ti)%2==0:
            pass
        elif ti!=tag:
            t_new.append(ti)
            tag=ti
    return "^".join(t_new)

#create the simbol array for data and crc
c=["c[%d]"%x for x in range(POLY_W)]         #crc index same as the array, from left to right lsb->msb
d=["d[%d]"%x for x in range(DATA_W-1,-1,-1)] #data index, invertion of the crc, from left to right msb->lsb

#parallel caculation
for di in d:
    c=crc_s(c,di)

#reduce the xor simbol
c_new=[]
for ci in c:
    c_new.append(mparse(ci))

#print the each fucntion
i=0
for cni in c_new:
    print("crc_cal[%d]=%s;"%(i,cni))
    i=i+1

3 FCS校驗

802.3給出了FCS校驗的定義遮咖,CRC的POLY多項式位32'h04CB_11D7:

  • 發(fā)送端:

    • 發(fā)送數(shù)據(jù)按byte翻轉(zhuǎn)滩字,bit7和bit0,bit6和bit1,以此類推麦箍;
    • CRC的初始值定位32'hFFFF_FFFF;
    • 計算出32bit CRC后漓藕,每個字節(jié)按字節(jié)翻轉(zhuǎn),注意高低byte不需要換位置内列,各byte內(nèi)部翻轉(zhuǎn)撵术;
    • 上一步驟完成后整體和32'hFFFF_FFFF異或;
    • 數(shù)據(jù)附加在報文后面發(fā)送话瞧;
  • 接收端校驗器設(shè)置

    • POLY和發(fā)送端一致嫩与;
    • 初值為32’hFFFF_FFFF;
    • 接收字節(jié)翻轉(zhuǎn);
  • 接收端校驗值1

    • 接收到FCS字段后交排,將FCS與32’hFFFF_FFFF異或后送入CRC校驗校驗器划滋,校驗結(jié)果為32'hFFFF_FFFF;
  • 接收端校驗值2

    • 接收到FCS字段后,不處理直接送入校驗器埃篓,得到32'hC704_DD7D為正確处坪;

4 小結(jié)

本文給出了固定寬度的CRC計算和不定寬度的CRC計算推導(dǎo),中間難免有差錯架专,歡迎大家指正同窘;

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市部脚,隨后出現(xiàn)的幾起案子想邦,更是在濱河造成了極大的恐慌,老刑警劉巖委刘,帶你破解...
    沈念sama閱讀 218,204評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件丧没,死亡現(xiàn)場離奇詭異,居然都是意外死亡锡移,警方通過查閱死者的電腦和手機(jī)呕童,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來淆珊,“玉大人夺饲,你說我怎么就攤上這事√椎伲” “怎么了钞支?”我有些...
    開封第一講書人閱讀 164,548評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長操刀。 經(jīng)常有香客問我,道長婴洼,這世上最難降的妖魔是什么骨坑? 我笑而不...
    開封第一講書人閱讀 58,657評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上欢唾,老公的妹妹穿的比我還像新娘且警。我一直安慰自己,他們只是感情好礁遣,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,689評論 6 392
  • 文/花漫 我一把揭開白布斑芜。 她就那樣靜靜地躺著,像睡著了一般祟霍。 火紅的嫁衣襯著肌膚如雪杏头。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,554評論 1 305
  • 那天沸呐,我揣著相機(jī)與錄音醇王,去河邊找鬼。 笑死崭添,一個胖子當(dāng)著我的面吹牛寓娩,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播呼渣,決...
    沈念sama閱讀 40,302評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼棘伴,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了屁置?” 一聲冷哼從身側(cè)響起焊夸,我...
    開封第一講書人閱讀 39,216評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎缰犁,沒想到半個月后淳地,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,661評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡帅容,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,851評論 3 336
  • 正文 我和宋清朗相戀三年颇象,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片并徘。...
    茶點(diǎn)故事閱讀 39,977評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡遣钳,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出麦乞,到底是詐尸還是另有隱情蕴茴,我是刑警寧澤,帶...
    沈念sama閱讀 35,697評論 5 347
  • 正文 年R本政府宣布姐直,位于F島的核電站倦淀,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏声畏。R本人自食惡果不足惜撞叽,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,306評論 3 330
  • 文/蒙蒙 一姻成、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧愿棋,春花似錦科展、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,898評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至甘邀,卻和暖如春琅攘,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背鹃答。 一陣腳步聲響...
    開封第一講書人閱讀 33,019評論 1 270
  • 我被黑心中介騙來泰國打工乎澄, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人测摔。 一個月前我還...
    沈念sama閱讀 48,138評論 3 370
  • 正文 我出身青樓置济,卻偏偏與公主長得像,于是被迫代替她去往敵國和親锋八。 傳聞我的和親對象是個殘疾皇子浙于,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,927評論 2 355