1.设计目的
进一步熟悉和掌握 Verilog HDL的基本语法,利用已学习的知识来完成CRC代码的设计,并通过仿真验证掌握开发软件的使用方法。
2.课程设计题目描述和要求
CRC即循环冗余校验码(Cyclic Redundancy Check),是数据通信领域中最常用的一种差错校验码,其特征是信息字段和校验字段的长度可以任意选定。本设计中采用的是串行数据接收并添加 CRC 校验位,要求能够正确完成数据的接收和并行输出,并能够在有效数据之后添加CRC校验位,能够正确地发送和接收数据。
3. 设计思想和过程
在设计CRC代码时首先要掌握CRC的基本原理。接收方和发送方事先有一个约定,也就是一串二进制数,在整个传输过程中,这个数始终保持不变。在发送方,利用生成多项式对信息多项式做模2除生成校验码。在接收方利用生成多项式对收到的编码多项式做模2除检测。整个算法应满足以下条件。
(1)生成多项式的最高位和最低位必须为1。
(2)当被传送信息(CRC码)任何一位发生错误时,被生成多项式做除后应该使余数不为0。
(3)不同位发生错误时,应该使余数不同。
在做除法的时候,CRC的除法使用的是模2的减法,最后实现的实际效果就是两个值的异或,按照除法的顺序完成余数的计算,但做除法中的减法步骤时使用异或操作就可以得到最后的结果。
代码:
odule cre( data send,ready_ s,data out, resend,data in,reset,data receive,ready r,clk,err);
parameter width=1, amount-12;
output [width* amount+4:0] data_ send;
output ready s;
output [width-1:0] data out;output resend;//resend-重发信 号输出高电平有效input [width-1:0]data_ in;
width.input reset;input [width* amount+4:0] data_ receive;
input ready_ r;
input err;
input clk;
crc_ send sendl (data_ send, ready_ s,data in,reset,clk);
erc_ receive receivel (data _out, resend, data send, ready_ r,clk,err);
endmodulemodule erc_ send(data_ send, ready_ s,data in,reset,clk);
parameter width=1, amount-12;
output [width*amount+4:0] data send;
output ready s;input [width1:0] data in;
input reset,clk;
reg [width* amount+4:0] data send;
reg ready s;
reg [width* amount:0] buf_ in;
reg lwidth* amount+4:0] buf data s;integer n,i;
begin
if (reset)n=0;elseif(n
buf_in=buf_in<
buf_in[width1:0]=data_in;n=n+1;
end
else
begin
buf in=buf_in<
buf_in[width1:0]=data_in;
buf_data_s[width*amount+4:5]=buf_in;
if(buf_in[11])buf_in[11:6]=buf_in[11:6]^6'b110101;
if(buf_in[10])buf_in[10:5]=buf_in[10:5]^6'b110101;
if(buf_in[9])buf_in[9:4]=buf_in[9:4]^6'b110101;
if(buf_in[8])buf_in[8:3]=buf_in[8:3]^6'b110101;
if(buf_in[7])buf_in[7:2]=buf_in[7:2]^6'b110101;
if(buf_in[6])buf_in[6:1]=buf_in[6:1]^6'b110101;
if(buf_in[5])buf_in[5:0]=buf_in[5:0]^6'b110101;
buf_data_s[4:0]=buf_in[4:0];
data_send[width*amount+4:0]=buf_data_s[width*amount+4:0];
n=0;
ready_s<=1;endendendmodulemodule crc_receive(data_out,resend,data_receive,ready_r,clk,err);
parameter width=1,amount=12;
output [width1:0] data_out;
output resend;input[width*amount+4:0] data_ receive;
input ready_r,clk,err;
beginif (reset)n=0;
else
if(n
buf_in=buf_in<
n=n+1;
end
else
begin
buf in=buf_in<
buf_in[width1:0]=data_in;
buf_data_s[width*amount+4:5]=buf_in;
if(buf_in[11])buf_in[11:6]=buf_in[11:6]^6'b110101;
if(buf_in[10])buf_in[10:5]=buf_in[10:5]^6'b110101;
if(buf_in[9])buf_in[9:4]=buf_in[9:4]^6'b110101;
if(buf_in[8])buf_in[8:3]=buf_in[8:3]^6'b110101;
if(buf_in[7])buf_in[7:2]=buf_in[7:2]^6'b110101;
if(buf_in[6])buf_in[6:1]=buf_in[6:1]^6'b110101;
if(buf_in[5])buf_in[5:0]=buf_in[5:0]^6'b110101;
buf_data_s[4:0]=buf_in[4:0];
data_send[width*amount+4:0]=buf_data_s[width*amount+4:0];
n=0;
ready_s<=1;endendendmodulemodule crc_receive(data_out,resend,data_receive,ready_r,clk,err);
parameter width=1,amount=12;output [width1:0] data_out;
output resend;
input[width*amount+4:0] data_ receive;
input ready_r,clk,err;reg [width1:0] data_out;reg resend;
reg [width*amount+4:0] buf_receive;
reg [width*amount:0] buf_data_r;
reg right;
integer m;
always @(posedge clk)
begin
if(ready_r)beginbuf_receive=data_receive;
if(err)buf_receive=data_receive;
if(err)buf_receive[16]=~buf_receive[16];
buf_data_r[width*amount:0]=buf_receive[width*amount+4:5];
if(buf_data_r[11])buf_data_r[11:6]=buf_data_r[11:6]^6'b110101;
if(buf_data_r[10])buf_data_r[10:5]=buf_data_r[10:5]^6'b110101;
if(buf_data_r[9])buf_data_r[9:4]=buf_data_r[9:4]^6'b110101;
if(buf_data_r[8])buf_data_r[8:3]=buf_data_r[8:3]^6'b110101;
if(buf_data_r[7])buf_data_r[7:2]=buf_data_r[7:2]^6'b110101;
if(buf_data_r[6])buf_data_r[6:1]=buf_data_r[6:1]^6'b110101;
if(buf_data_r[5])buf_data_r[5:0]=buf_data_r[5:0]^6'b110101;if(!(buf_data_r[4:0]^buf_receive[4:0]))beginright=1;
resend=0;data_out=buf_receive[16];
buf_receive=buf_receive<
endelsebeginright=0;
resend=1;
data_out='bz;
end
end
else if(right)
beginif(m
module crc_test;
reg data_in,rest,clk,err;
reg [15:0] shift;
wire [16:0] data_send;
wire ready;
always #50 clk=~clk;
initial
begin
clk=1;
err=0;
shift=16'h8000;
reset=0;#10 reset=1;
#20 reset=0;#9600 err=1;
#100 err=0;
#500000 $stop;
endalways @(posedge clk)begindata_in=shift[0];
shift=shift>>1;
shift[15]=shift[14]^shift[11];
if(!shift([15:12]);
shift[15:12]=4'b1000;
endcrc_send send(data_send,ready,data_in,reset,clk);
crc_receive receive(data_out,resend,data_send,ready,clk,err);
endmodule
截图: