CRC循环冗余校验码并行+串行.docx
《CRC循环冗余校验码并行+串行.docx》由会员分享,可在线阅读,更多相关《CRC循环冗余校验码并行+串行.docx(32页珍藏版)》请在冰豆网上搜索。
CRC循环冗余校验码并行+串行
课程报告
设计课题:
CRC循环冗余校验码
姓
名:
陈舒凌,高冉
专
业:
电子信息工程
学
号:
1115108007
1115106012
日
期
2013年11月20日一2013年12月1日
指导教师:
傅文渊老师
华侨大学信息科学与工程学院电子工程系
CRC循环冗余校验码
实验目的:
设计一个在数字传输中常用的校验、纠错模块:
循环冗余校验CRC模块,学
习使用FPGA器件完成数据传输中的差错控制
实验内容:
采用的CRC生成多项式为X5+X4+X2+1,校验码为5位,有效信息数据为12
位。
A、根据以上信息,编写硬件描述语言完成上述功能,给出仿真波形。
B、CRC校验生成模块和CRC校验查错模块连接在一起,协调工作。
引出必要的观察信号,
锁定引脚,并在EDA实验系统上实现之。
C、如果输入数据、输出CRC码都是串行的,设计该如何实现?
给出你的方案,并通过硬件验证。
模2运算的原理
模2减法是不带借位的二进制减法运算。
这样,两个二进制位相运算时,这两个位的值就能确定运算结果,
不受前一次运算的影响,也不对下一次造成影响。
模2除法运算定义为:
0-1=01-1=1
多位二进制模2除法也类似于普通意义上的多位二进制除法,但是在如何确定商的问题上两者采用不同的
规则。
后者按带借位的二进制减法,根据余数减除数够减与否确定商1还是商0,若够减则商1,否则商0。
多位模2除法采用模2减法,不带借位的二进制减法,因此考虑余数够减除数与否是没有意义的。
实
际上,在CRC运算中,总能保证除数的首位为1,则模2除法运算的商是由余数首位与除数首位的模2除法运算结果确定。
因为除数首位总是1,按照模2除法运算法则,那么余数首位是1就商1,是0就商0。
例如1100100-1011=1110……110,列竖式计算:
1110
1011〕1100100
—1011
引言随着工业控制系统网络化的不断发展,建立可靠、稳定、高速的通信网络已成为控
制系统的必然要求。
然而,在数字通信中可靠与快速往往是一对矛盾。
若要求快速,
则必然使得每个数据码元所占地时间缩短、波形变窄、能量减少,从而在受到干扰后产生错误的可能性增加,传送信息的可靠性下降。
若是要求可靠,贝U使得传送消息的速率变慢。
其中差错检测和纠错控制是保证高可靠性的一种切实方法。
在各种通信领域,多项式编码循环冗余码CRC简单且误判概率很低,被普遍应用。
实现方法CRC码是由两部分组成,前部分是信息码,就是需要校验的信息,后部分是校验码,如果CRC码共长n个bit,信息码长k个bit,就称为(n,k)码。
它的编码规则是:
1)、首先将原信息码(kbit)左移r位(k+r=n)
2)、运用一个生成多项式g(x)(也可看成二进制数)用模2除上面的式子,得到的
余数就是校验码
生成CRC码的基本原理:
任意一个由二进制位串组成的代码都可以和一个系数仅为
‘0'和’1'取值的多项式——对应。
例如:
代码1010111对应的多项式为x6+x4+x2+x+1,而多项式为x5+x3+x2+x+1对应的代码101111。
程序设计的原理
并行输入输出CRC校验生成模块:
libraryIEEE;
useieee.numeric_std.all;
useIEEE.STD_LOGIC_1164.ALL;
useIEEE.STD_LOGIC_ARITH.ALL;
useIEEE.STD_LOGIC_UNSIGNED.ALL;
entitycrcversion2is
Port(sdata:
inSTD_LOGIC_VECTOR(11downtoQ);messagebits
clk:
inSTD_LOGIC;
redundant:
outSTD_LOGIC_VECTOR(4downto0};-redundantbits
dataid:
instd」ogic;
hsend:
outstd_logic;
datacrco:
outSTD_LOGIC_VECTOR(16downto(---messagewithredundantbits
endcrcversion2;
architectureBehavioralofcrcversion2is
beginprocess(clk)
variablev:
std_logic_vector(16downto0);
variableu:
std」ogic_vector(16downto0);
variablei,j:
integer:
=0;
variablew:
std」ogic_vector(16downto0);
constantmulticoef:
STD_LOGIC_VECTOR(5downto0):
="110101";
---crcpolynomial
begin
ifclk'eventandclk='1'then
if(dataid='1')then「
w(16downto5):
=sdata(11downto0);---v有m+(n-1)个位
forjin4downto0loop
w(j):
='0';,第1段
endloop;
elsif(dataid='0')thenw(16downtoO):
=(others=>'O');
endif;
v(16downto0):
=w(16downto0);
u(16downto11):
=multicoef(5downto0);'第2段
u(10downto0):
=(others=>'0');
J
foriin11downto0loop---移位m次,为得到余数部分的n-1个位if(v(16)='1')then
v:
=vxoru;
elsenull;--什么也不做,第3段
endif;
v:
=to_stdlogicvector(to_bitvector(v)sll1);
endloop;丿
redundant<=v(16downto12);-——redundantbits
datacrco(16downto5)<=w(16downto5);》第4段
datacrco(4downto0)<=v(16downto12);
hsend<='1';---totalmessage
endif;
endprocess;
endBehavioral;
思路段1.在时钟上升沿到来时,把输入sdata的12个位赋给w的前12个位,
后5个位都置0,构成一个17位。
要是dataid是0,那不把sdata赋值给w,w置0。
段2.把w赋值给v,v便会参与我们的模2除法。
要是w都为0,v模2运算后肯定也是0。
到时第4段里分别把w前12位给datacrco前12位,v的前5给datacrco的后5个位。
这时也把我们的multicoeff扩展到17个位的u,把后11个位也都赋0。
(这个后来想想下还是可以把v和u用12个位异或就好,只要移位够12次,那v剩下的前5位就是余数)
段3•根据模2除法,做异或时我们的被除项的第一位必须是1才能做。
若v的第一个
位是1,v和u异或再赋回给v[由于u(110101...)和v的第一个位是
1,异或完v的第一个位一定变成0],然后再把v移前一位,后面补0便可
否则便不异或,v直接就移前一位。
共要移位12次才能获得我们5个位的余数。
因此我们使用12次循环的loop语句。
在每一次上升沿到,做12次的异或移位,不异或也移位,就会移了12个位。
这里使用的移位方法是向左位移的语句sll,
由于这个语句只能是给bit类型用,而我们的v是一个vector,那先强制转换成bit再转换去vector。
当然这里可以用移位寄存器法来实现,
v(17downto1):
=v(16downto0);
v(0):
='0';
段4.最后,段3loop语句做完后,v的前5个位是余数,赋给redundant,
分别把w前12位的原信息数据给datacrco前12位,v的前5给datacrco的个位,datacrco便是我们的crc码了。
Hsend<=''
并联CRC校验生成模块仿真波形
dataid=1时,信号sdata才能输入进行运算,将余数redundant接在datacrco的后面,作为输出;
dataid=0时,信号sdata不能输入,不能进行运算,给输出datacrc0,redundant都赋值成零。
并行输入输出的校验模块:
libraryIEEE;
useieee.numeric_std.all;
useIEEE.STD_LOGIC_1164.ALL;
useIEEE.STD_LOGIC_ARITH.ALL;
useIEEE.STD_LOGIC_UNSIGNED.ALL;
entitycrc0version2is
Port(rdata:
outSTD_LOGIC_VECTOR(11downto0)-messagebitsclk:
inSTD_LOGIC;
datacrci:
inSTD_LOGIC_VECTOR(16downto0);datafini:
outSTD_LOGIC;
hrecv:
instd_logic;
error:
outbit);---messagewithredundantbits
endcrc0version2;
architectureBehavioralofcrcOversion2is
beginprocess(clk)
variablev:
std」ogic_vector(16downto0);
variableu:
std」ogic_vector(16downto0);
variablei:
integer:
=0;
variablew:
std_logic_vector(16downto0);
constantmulticoef:
STD_LOGIC_VECTOR(5downto0):
="110101--crcpolynomial
begin
ifclk'eventandclk='1'then、
if(hrecv='1')then
w(16downto0):
=datacrci(16downto0);---v有m+(n-1)个位第1段
elsif(hrecv='0')then厂
w(16downto0):
=(others=>'0');
endif;丿
v(16downto0):
=w(16downto0);
u(16downto11):
=multicoef(5downto0);a第2段
u(10downto0):
=(others=>'0');
foriin16downto0loop---移位17次,为得到看是否能被整除、
if(v(16)='1')then
v:
=vxoru;
elsenull;
endif;
v:
=to_stdlogicvector(to_bitvector(v)sll1);endloop;
if(v(16downto0)="00000000000000000")then^error<='0';
rdata<=w(16downto5);
datafini<='1';
elseerror<='1';
rdata<=(others=>'0');
datafini<='0';
endif;丿
endif;
endprocess;endBehavioral;
思路校验这模块基本上是在接收模块的基础上改过来而已。
这时的输入是一
个17个位的crc码,输出会是crc吗的前12个位,即是我们的原信息数
据。
所以只说段3和段4。
段3.在loop语句里,若第一位是1,输入的17个位v便和我们扩展成17位的multicoef(110101)做异或,然后向左移位,否则便不做异或,直接向左移位。
要是能整除,v没有余数,都为0。
要是不能整除,v就不会都是0.
段4.要是能整除,v没有余数,v都为0,error便输出0,把原先还没参与模2除法的w的前12个位赋给输出rdata。
要是不能整除,v就不会都是0,那error便输出1,把rdata都赋0。
并行CRC校验检错模块仿真波形
4
]ps
80?
叫
ns
叫nS
迦卩
ns400lQns
48Ci°n:
s56OPns
840.卩皿7:
雄
A
0ps
U/0
dk
w
onm
urn
iwm
JWl
wu
uw
JWW
埶
0ilatiCTci
[ooooiioiiiioinoo^oooiiiiiimXooooioioioiaifJioiXioocoohioiioooooX
■iia!
衬19
datafini
Illi
11
111
1
1
111
111
11
1]1
ill
|i|
1|a
Iv|
11
1II
11l>4
trror
J
111II
H■
II1
111
1
■1
1
—
iii
111
II1
11
1II
11II1
fl
III*
hrtcv
muuniiiuiaiiuaiiiMiiiiiiMiiiaiKiiMiii.HiiiiHainim
iIgI
II1
i1H
||
1
」[
11II
iici
111
1■■
1p1
I11
1I■
il|
11
II1
1II
H1
1
III
-+
田rdata
L
iiii
OOOOOOODOOCO
||
1
山叩00111011
Xi
1II
当hrecv=1时,接收输入信号datacrci进行除法运算,datacrci能被110101整除时,error为0。
完成标志位datafini为1,输出信号rdata为原来要校验的信号;datacrci不能被110101整除时error为1,完成标志位0,输出信号rdata为0;
并行总的电路
并行总的电路的仿真波形
)P百
SO.0m
1
池卩ns换卩"
5°-
Qns
㈣…
叫
7ZO.Ons
[1
Dp£J
clk
mnnnjwm
m1
d盘tifini
-
ini11iliin1
■ai■・ji■cii
1III11111II
■'■1II11■[1
11I11II1
■ai■■ai
dataid
error
■1
■
■Illi
i■ci
■■i
nail
国
&
IOIQOIIIOOo!
Xi
10101000111X
101011110001X
1ai
oooooooooo
13redundenl
匸
11101
F!
00001
II■II1
V.
丿imniinnnm
i
■ii
ooooo
矜23
田5dmF
:
iciooiuooci
XU010*******X10101111000
i~~—
KOOOOODOOOi
输入标志位dataid为1,输入数据才能进行运算。
时钟信号到来,开始进行运算,校验之后输出原来要校验的数据,输出余数,错误警报
也为置为0
Nodsfwt
Di'CCl-Or
IJMifOr
】QRsnc
ef&ouu
TgtrZ
R?
r%biSC
GitW
1
Ack
luX
PIN?
D1N5
UMS—L:
de^idO
rj.
OcMacrm
Output
dc-3ul:
}
3
i#1eiUi:
LlM
mm阳uij
冲
2々nd
OUiPLlf
[.阿LV"LMeruit)
5
i±dj"idoiLM
Output
D4JS11
J'dteuio
redjr)danL[x.0]
6
Output
FIN斗
01Hl
IJ'VL'fHl仙和uh)
rcdldndlBn:
[^r0]
7
3rvdLndnc^J
Ouiput
MN」?
4
B4J41
mm如旳圭阿LLL詛!
•切ul》
「H」ndin:
[^.0]|
B
a™dLndiflr[l]
Output
化Ml
rpddndanT[^.Q]
m
a-乩為1:
【■二
Output
Plh-^l
m
31科LEL(d&M
redjnda,i.[-.Q]
1C
L^out
PIh24
BlNil
3"dcTJLl-)
11
令口和和
Unkrcwn
PINJS4
3
03J4J
33\H.dt^Ll:
;
i2
©ratHi"
Unkrc^n
PIN7
HI.N3
ijaxr门*七1.卜:
1
1:
Unkrown
PTN?
]
3
R^J41
J3'¥Lrrn.
T
©dp;*
lAnlirflwn
3
0?
N3
31MLE园為斶
15
使用了模式0
串行输入输出的接收模块:
libraryIEEE;
useieee.numeric_std.all;
useIEEE.STD_LOGIC_1164.ALL;
useIEEE.STD_LOGIC_ARITH.ALL;
useIEEE.STD_LOGIC_UNSIGNED.ALL;
entitycrcseriesversion3is
Port(sdata:
inSTD_LOGIC;---messagebits
datald:
instd_logic;
clk:
inSTD_LOGIC;
redundant:
outSTD_LOGIC_VECTOR(4downto0)--redundantbitsdatacrco:
outSTD_LOGIC---messagewithredundantbitshsend:
outstd_logic);
endcrcseriesversion3;
architectureBehavioralofcrcseriesversion3isbeginprocess(clk)
variablev:
std」ogic_vector(16downto0);
variabled:
std_logic_vector(16downto0);
variableu:
std」ogic_vector(16downto0);
variableq:
std」ogic_vector(16downto0);
variablei,j:
integer:
=0;
variablecount:
integer:
=0;
variablecount2:
integer:
=0;
variablet:
STD_LOGIC_VECTOR(16downto0);
variablec:
std_logic:
='1';
variabley:
std_logic_vector(16downto0);
variableg:
integer:
=0;
constantmulticoef:
STD_LOGIC_VECTOR(5downto0):
="110101";---crcpolynomialbegin
ifclk'eventandclk='1'thenif(count<17anddatald='1')
thencount:
=count+1;
if(count<=12)
thenv(17-count):
=(sdata);---v有m+(n-1)个位elsif(count>12)
thenv(17-count):
='0';
endif;endif;
if(count=17)then
y(16downto0):
=v(16downto0);
count:
=0;第2段
g:
=g+1;
endif;--u(16downto11):
=multicoef(5downto0);
u(10downto0):
=(others=>'0');第3段
hsend<='0';
if(c='1')then
d(16downto0):
=y(16downto0);
q(16downto0):
=d(16downto0);
foriin11downto0loop---移位12次,为得到余数部分的if(q(16)='1')then
q:
=qxoru;第4段
elsenull;
endif;
q:
=to_stdlogicvector(to_bitvector(q)sll1);
endloop;
endif;
redundant<=q(16downto12);----redundantbits
t(16downto5):
=d(16downto5);第5段