赞
踩
一种信道编码技术,用来检测数据传输或者保存后可能出现的错误,其使用模2除法进行校验,计算速度快,检错能力强,有不同的标准参数模型,标准越高则检错能力和精度越好。
(以CRC-5为例(初值00)):其生成多项式为X5+X3+1 输入输出无需翻转。设数据串为100101
根据多项式画出标准电路
D0 <= data_in ^ D4 ;
D1 <= D0 ;
D2 <= D1 ;
D3 <= data_in ^ D4 ^D2 ;
D4 <= D3 ;
Data-in | D0 | D1 | D2 | D3 | D4 |
0 | 0 | 0 | 0 | 0 | 0 |
1 | 1 | 0 | 0 | 1 | 0 |
0 | 0 | 1 | 0 | 0 | 1 |
0 | 1 | 0 | 1 | 1 | 0 |
1 | 1 | 1 | 0 | 0 | 1 |
0 | 1 | 1 | 1 | 1 | 0 |
1 | 1 | 1 | 1 | 0 | 1 |
当6个时钟周期结束后,D4-D0的值即是CRC校验码10111
- module crc (
- input [5:0] data_in , //输入待检测数据
- output [4:0] crc_data , //CRC校验码输出
- input rst ,
- input clk ,
- output wire [4:0] result , // 最后用来检验的余数
- output wire [10:0] string_data // 定义输出的CRC数据串
- ) ;
-
-
- reg [4:0] reminder_1 , reminder_2 , //两组中间变量, 用来储存电路现态和次态的值
- mod1 , mod2 ;
-
-
- wire [5:0] data ;
- integer i =0 ;
- integer j = 0;
-
-
- assign string_data = {crc_data[0],crc_data[1],crc_data[2],crc_data[3],crc_data[4],data_in[0],data_in[1],data_in[2],data_in[3],data_in[4],data_in[5]} ; //将输入数据和CRC校验码拼接
- assign data = {data_in[0],data_in[1],data_in[2],data_in[3],data_in[4],data_in[5]} ; //储存输入数据100101
- assign crc_data= {reminder_2[4],reminder_2[3],reminder_2[2],reminder_2[1],reminder_2[0]} ; //将中间变量数据传入CRC值
- assign result = {mod2[4],mod2[3],mod2[2],mod2[1],mod2[0]} ; //余数
-
- always @ (*) begin
-
- reminder_1[0] <= data [i] ^ reminder_2 [4] ; //根据电路图写出关系式
- reminder_1[1] <= reminder_2 [0] ; //D0 <= data_in ^ D4
- reminder_1[2] <= reminder_2 [1] ; //D1 <= D0
- reminder_1[3] <= data [i] ^ reminder_2 [4] ^ reminder_2 [2] ; //D2 <= D1
- reminder_1[4] <= reminder_2 [3] ; //D3 <= data_in ^ D4 ^D2
- //D4 <= D3
- mod1[0] <= string_data [j] ^ mod2 [4] ;
- mod1[1] <= mod2 [0] ;
- mod1[2] <= mod2 [1] ;
- mod1[3] <= string_data [j] ^ mod2 [4] ^ mod2 [2] ;
- mod1[4] <= mod2 [3] ;
-
-
-
- end
-
- always @ (posedge clk or posedge rst ) begin
- if(rst) begin
- reminder_2 <= {5{1'b0}} ; //复位使电路状态清0
- mod2 <= {5{1'b0}};
- end
- else if (i <= 5 && j<=10)begin
- mod2 <= mod1 ;
- reminder_2 <= reminder_1 ; // i递增,控制data_in的顺序进入 (LSB)
- i = i +1 ; // j递增,控制string_data的顺序进入 (LSB)
- j = j + 1;
- end
- else if (i > 5 && j>10)begin
- mod2 <= mod2 ;
- reminder_2 <=reminder_2 ;
- end
- else begin
- reminder_2 <=reminder_2 ;
- mod2 <= mod1 ;
- j = j+1 ;
- end
-
- end
-
- endmodule
- `timescale 1 ps/ 1 ps
- module crc_vlg_tst();
-
- reg clk;
- reg [5:0] data_in;
- reg rst;
-
- wire [4:0] crc_data;
- wire [4:0] result ;
- wire [10:0] string_data ;
-
-
-
-
- crc i1 (
-
- .clk(clk),
- .crc_data(crc_data),
- .data_in(data_in),
- .rst(rst) ,
- .string_data(string_data) ,
- .result(result)
-
- );
- always #10 clk = ~clk ;
- initial
- begin
- clk = 0;
- rst = 1 ;
- data_in <= 6'b100101 ;
- #20
- rst = 0 ;
-
-
- $display("Running testbench");
- end
-
- endmodule
可以看到对于拼接CRC校验码后的数据串,通过电路,最后留下的余数为00000,证明数据无误,且通过在线计算得到CRC校验码无误。
刚开始研究,代码较为繁琐,如有错误,欢迎大神沟通指正!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。