CRC生成与校验的设计实现.docx
《CRC生成与校验的设计实现.docx》由会员分享,可在线阅读,更多相关《CRC生成与校验的设计实现.docx(15页珍藏版)》请在冰豆网上搜索。
![CRC生成与校验的设计实现.docx](https://file1.bdocx.com/fileroot1/2023-1/4/4fd9129b-20e8-45f2-97d1-a15593d13568/4fd9129b-20e8-45f2-97d1-a15593d135681.gif)
CRC生成与校验的设计实现
沈阳航空航天大学
课程设计报告
课程设计名称:
计算机组成原理课程设计
课程设计题目:
CRC生成与校验的设计实现
院(系):
计算机学院
专业:
计算机科学与技术
班级:
学号:
姓名:
指导教师:
说明:
结论(优秀、良好、中等、及格、不及格)作为相关教环节考核必要依据;格式不符合要求;数据不实,不予通过。
报告和电子数据必须作为实验现象重复的关键依据。
学术诚信声明
本人声明:
所呈交的报告(含电子版及数据文件)是我个人在导师指导下独立进行设计工作及取得的研究结果。
尽我所知,除了文中特别加以标注或致谢中所罗列的内容以外,报告中不包含其他人己经发表或撰写过的研究结果,也不包含其它教育机构使用过的材料。
与我一同工作的同学对本研究所做的任何贡献均己在报告中做了明确的说明并表示了谢意。
报告资料及实验数据若有不实之处,本人愿意接受本教学环节“不及格”和“重修或重做”的评分结论并承担相关一切后果。
本人签名:
日期:
年月日
课程设计总结:
一开始老师的要求要用modelsim进行仿真,不得不安装新的软件,各种尝试进行破解终于是能使用了。
然后借《VerilogHDL设计与实战》学习verilog,发现和c语言很类似,从初步构思到一步步完善直到最后完成整个课程设计,让我更好的巩固了自己所学的知识。
翻阅图书去学习一些没有接触过的知识让我更好的了解了这门课程,增强的实践动手能力。
在老师和同学的帮助下,从编程到仿真一步一步的去实现课设任务。
本学期开设的计算机组成原理课程,让我不但从概念上掌握了计算机内部的工作机制,并且能够学以致用,自主完成这次课程设计。
虽然过程中有迷茫,但是作为一名合格的学生,我坚信我可以做到。
在老师和同学的帮助下,我没有胆怯,一步步踏踏实实的完成老师分配的工作。
不抛弃不放弃,坚持不懈,只有这样的态度,在面对无论是来自学习还是生活的困难,我们才能克服它们,完成自我的升华。
指导教师评语:
指导教师(签字):
年月日
课程设计成绩
第1章总体设计方案
1.1设计原理
CRC码即循环冗余码,可以发现信息在存储或传送过程中连续出现的多为错误代码,在磁介质存储器和计算机之间的通信方面得到广泛应用。
CRC码由k位数据D和r位校验码P组成,设被校验的数据
是一个k位的二进制代码,将它表示为一个(k-1)阶的多项式:
(1-1)
将D左移r位的目的是给D右边添加r个0,形成(k+r)位长度二进制代码,其多项式形式为M(x)×
。
求校验码P的多项式R(X)的方法如下:
(1-2)
Q(x)是商,R(x)是余数,R(x)所对应的二进制代码是校验码P。
可以证明存在一个最高次幂为n-k=r的多项式G(x),称G(x)为生成多项式。
由式(1-2)可以推导出
(1-3)
由式(1-3)可知,CRC码可被G(x)整除,余数必然为0。
接收方将收到的CRC码被G(x)除,若余数为0,则表明传送过程中没有错误发生;若余数不为0,则表明传送过程中有错误发生。
1.2设计思路
课程设计的要求是数据位数为4位的二进制数,生成多项式G(x)也是4位的二进制数,故CRC码由4位信息码和3位校验码组成。
输入的4位信息码和4位生成多项式分别保存在inf和gx里,通过verilog编程进行模2除,可计算出最终的余数即为3位检验码,然后将信息码和检验码合在一起保存在outcrc中输出,得到的就是要求的CRC码。
将outcrc中的数据与先前的gx进行模2除,最终得到的余数temp。
在gx=1011时余数与发生错误的位数的关系如表1所示。
表1gx=1011时的出错模式
Q6
Q5
Q4
Q3
Q2
Q1
Q0
余数
出错位
正确
1
1
0
0
0
1
0
0
0
0
无
错误
1
1
0
0
0
1
1
0
0
1
Q0
1
1
0
0
0
0
0
0
1
0
Q1
1
1
0
0
1
1
0
1
0
0
Q2
1
1
0
1
0
1
0
0
1
1
Q3
1
1
1
0
0
1
0
1
1
0
Q4
1
0
0
0
0
1
0
1
1
1
Q5
0
1
0
0
0
1
0
1
0
1
Q6
1.3设计环境
在QuartusII中用verilog编写程序得到电路图,再在modelsim中进行仿真。
QuartusII界面如图1所示。
图1QuartusII界面
ModelSim仿真软件界面如图2所示。
图2ModelSim界面
第2章详细设计方案
在quartusII中用verilog编程,用四位的对象inf保存输入的信息数据,四位的对象gx保存输入的生成多项式,七位的reg类型的对象outcrc保存要输出的crc码,四位的reg类型的对象temp保存再次模二除的被除数。
2.1CRC码的生成
在always进程中,生成crc码时首先将4位的信息数据inf直接赋值给crc码的4位高位;之后将inf值赋给temp作为第一次模二运算的被除数;如果被除数的最高位为1时,就将temp[2]与gx[2]做异或运算结果赋值给temp[3],temp[1]与gx[1]异或赋给temp[2],temp[0]与gx[0]异或赋给temp[1],temp[0]直接赋值为0;如果被除数最高位为0时,就将temp[2]的值赋给temp[3],temp[1]的值赋给temp[2],temp[0]的值赋给temp[1],temp[0]直接赋值为0;做四次这样的运算,结束循环;将最后一次的temp的高三位赋值给outcrc的低三位。
此时的outcrc里的值就是要的crc码。
具体的流程图如图3所示。
图3CRC码生成
2.2CRC码的检测
检测crc码时,将outcrc的高四位值赋给temp作为第一次模二运算的被除数;之后的运算同crc码生成时计算最终的余数方法类似,只需要将temp的值做一下改变,若是最后一次循环就将temp[0]直接赋值为0,若不是最后一次循环,就将outcrc[i-4]的值赋给temp[0];循环四次后得到的temp的高三位就是最终的余数。
因为最常用的生成多项式G(X)的值是1011,因此只对gx==1011这一种情况做纠错。
用case语句根据表1的内容将对应出错位数值取反就可的到正确的信息,resultchack的值为1表示一开始的crc码是正确的,为0表示一开始时不正确的。
具体的流程图如图4所示。
图4CRC码检测
第3章调试与仿真
3.1程序调试
1、编写的verilog程序在quartusII中编译时出错。
解决:
根据错误提示发现在case语句中不应该是begin......end而应该直接在case语句结束后加endcase。
2、在modelsim中仿真时,仿真图的outcrc及inf的值一直是不变的。
解决:
在crc的testbench文件里将开头的`timescale1ps/1ps改为`timescale1ns/1ps。
3、生成的crc码与手工计算所得的值不一样。
解决:
将最终的余数也输出,与手工计算过程比较,发现输出的余数是手工计算的倒数第二个余数,再检查发现是循环计算余数时循环次数少了一次。
3.2程序测试及结果分析
如图5所示在检测信号为低电平时,只生成crc码outcrc,不检验,故resultcheck没有值。
图5检测信号低电平仿真图
在inf为0001之前检测信号check为高电平时,生成的crc码outcrc是经过检测后的矫正后得到的值,故在inf为0001之前check会由原来的低电平变成成高电平。
仿真图如图6所示。
图6检测信号高电平仿真图
输入的inf信息的值从0110—1111仿真图如图7所示。
图7检测信号高电平仿真图
在quartusII中运行编写的verilog程序,在task框中选择NetlistViewer文件夹双击RTLViewer,得到如图8的电路图
图8CRC电路图
参考文献
[1]刘福奇.VerilogHDL设计与实战[M].北京:
北京航空航天大学出版社,2012.09
[2]范延滨.微型计算机系统原理、接口与EDA设计技术[M].北京:
北京邮电大学出版社,2006
[3]唐朔飞.计算机组成原理(第二版)[M].北京:
高等教育出版社,2008
[4]白中英.计算机组成原理(第四版)[M].北京:
科学出版社,2009
[5]胡越明.计算机组成与设计[M].北京:
科学出版社,2006
[6]江国强.EAD技术习题与实验[M].北京:
电子工业出版社,2005
附录(源代码)
CRC源代码
modulecrc(inf,gx,check,outcrc,resultcheck);//(7,4)码生成
input[3:
0]inf;//4位信息位
input[3:
0]gx;//4位生成多项式
inputcheck;
output[6:
0]outcrc;//7位生成码
outputresultcheck;
reg[6:
0]outcrc;
reg[3:
0]temp;
regresultcheck;
integeri;
always@(inf)
begin
outcrc[6]=inf[3];outcrc[5]=inf[2];outcrc[4]=inf[1];outcrc[3]=inf[0];
temp[3]=inf[3];temp[2]=inf[2];temp[1]=inf[1];temp[0]=inf[0];//temp赋初值
/*************************计算最终的余数***********************/
for(i=0;i<4;i=i+1)
begin
if(temp[3]==1)//中间余数最高位为1时与gx异或
begin
temp[3]=temp[2]^gx[2];
temp[2]=temp[1]^gx[1];
temp[1]=temp[0]^gx[0];
temp[0]=1'b0;
end
else//中间余数最高位为0时直接赋值
begin
temp[3]=temp[2];
temp[2]=temp[1];
temp[1]=temp[0];
temp[0]=1'b0;
end
end
outcrc[2]=temp[3];
outcrc[1]=temp[2];
outcrc[0]=temp[1];
if(check==1'b1)//检测crc
begin
temp[3]=outcrc[6];temp[2]=outcrc[5];temp[1]=outcrc[4];temp[0]=outcrc[3];//temp赋初值
/*******************************计算最终的余数***********************/
for(i=6;i>2;i=i-1)
begin
if(temp[3]==1)//中间余数最高位为1时与gx异或
begin
temp[3]=temp[2]^gx[2];
temp[2]=temp[1]^gx[1];
temp[1]=temp[0]^gx[0];
if(i==3)
temp[0]=1'b0;
else
temp[0]=outcrc[i-4];
end
else//中间余数最高位为0时直接赋值
begin
temp[3]=temp[2];
temp[2]=temp[1];
temp[1]=temp[0];
if(i==3)
begin
temp[0]=1'b0;
end
else
begin
temp[0]=outcrc[i-4];
end
end
end
if(gx==4'b1011)
begin
case(temp[3:
1])
3'b000:
;
3'b001:
outcrc[0]=~outcrc[0];
3'b010:
outcrc[1]=~outcrc[1];
3'b011:
outcrc[3]=~outcrc[3];
3'b100:
outcrc[2]=~outcrc[2];
3'b101:
outcrc[6]=~outcrc[6];
3'b110:
outcrc[4]=~outcrc[4];
3'b111:
outcrc[5]=~outcrc[5];
endcase
end
if(temp==4'b0000)
begin
resultcheck=1'b1;
end
else
begin
resultcheck=1'b0;
end
end
end
endmodule
CRC测试代码
`timescale1ns/1ps
modulecrc_vlg_tst();
//constants
//generalpurposeregisters
regeachvec;
//testvectorinputregisters
reg[3:
0]gx;
reg[3:
0]inf;
regcheck;
//wires
wire[6:
0]outcrc;
wireresultcheck;
//assignstatements(ifany)
crci1(
//portmap-connectionbetweenmasterportsandsignals/registers
.gx(gx),
.inf(inf),
.check(check),
.outcrc(outcrc),
.resultcheck(resultcheck)
);
initial
begin
//codethatexecutesonlyonce
//insertcodehere-->begin
gx=4'b1011;
inf=4'b0000;
check=1'b0;
//-->end
$display("Runningtestbench");
end
always
//optionalsensitivitylist
//@(event1orevent2or....eventn)
begin
//codeexecutesforeveryeventonsensitivitylist
//insertcodehere-->begin
gx=4'b1011;
#1inf=4'b0000;
#1inf=4'b0001;
#1check=1'b1;
#1inf=4'b0010;
#1inf=4'b0011;
#1inf=4'b0100;
#1inf=4'b0101;
#1inf=4'b0110;
#1inf=4'b0111;
#1inf=4'b1000;
#1inf=4'b1001;
#1inf=4'b1010;
#1inf=4'b1011;
#1inf=4'b1100;
#1inf=4'b1101;
#1inf=4'b1110;
#1inf=4'b1111;
//gx=4'b1101;
@eachvec;
//-->end
end
endmodu