在进行数据校验时我们会使用到crc(循环冗余校验)校验的方式,例如在以太网通信网络中会对信息进行编码和校验,生成码采用的就是33位的

crc-32:x32+x26+x23+...+x2+x+1; (104c11db7)。循环冗余校验码的计算是模2的除法运算。模2指的是运算的时候不进行借位和进位的操作。可以用下面的例子来说明。假如信息码为11011,生成码为101(2+1)则校验码的计算过程是

先把信息码左移两位(二进制),得1101100。

然后通过异或操作

1101100

101

---------

111100

101

---------

010100

101

--------

00000

这个计算结果为00

假如信信息码为1100时,余码就是01

110000

101

----

010000

101

--------

00100

101

------

001

所以根据上面的运算可以得出任何信息码的余码。

一般使用线性反馈移位寄存器LFSR或(LFSR2)来进行物理实现。这两种方式结构如下:

本篇文章我使用的是LFSR2结构,假如使用LFSR结构需要在先输入n位的0(n是冗余码的位数)。为简单起见推导过程使用的4位信息码,8位的冗余码,生成式为P={p7,p6,p5,p4,p3,p2,p1,p0},初始余码为X0={x0(7),x0(6),x0(5),x0(4),x0(3),x0(2),x0(1),x0(0)}。输入数据D={d3,d2,d1,d0};

则当输入一位d3时表达式;+表示异或

x1(7)=x0(6)+p7(x0(7)+d3)=p7x0(7)+x0(6)+p7d3;

x1(6)=x0(5)+p6(x0(7)+d3)=p6x0(7)+x0(5)+p6d3;

x1(5)=x0(4)+p5(x0(7)+d3)=p5x0(7)+x0(4)+p5d3;

x1(4)=x0(3)+p4(x0(7)+d3)=p4x0(7)+x0(3)+p4d3;

x1(3)=x0(2)+p3(x0(7)+d3)=p3x0(7)+x0(2)+p3d3;

x1(2)=x0(1)+p2(x0(7)+d3)=p2x0(7)+x0(1)+p2d3;

x1(1)=x0(0)+p1(x0(7)+d3)=p1x0(7)+x0(0)+p1d3;

x1(0)=p0(x0(7)+d3)=p0x0(7)+p0d3;

X1'=FX0'+P'd3;其中

F={ p7,1,0,0,0,0,0,0

p6,0,1,0,0,0,0,0

  p5,0,0,1,0,0,0,0

  p4,0,0,0,1,0,0,0

  p3,0,0,0,0,1,0,0

  p2,0,0,0,0,0,1,0

   p1,0,0,0,0,0,0,1

  p0,0,0,0,0,0,0,0}

同样可以得X2'=FX1'+P'd2;

X3'=FX2'+P'd1;

     X4'=FX3'+P'd0;

进而得X4'=F*F*F*F*X0+{F*F*F*P',F*F*P',F*P',P'}*D';

所以输入四位数据时最后余码的状态与初始的状态有关。

对于任意的n位并行信息码Xn=Fn*X0+{F(n-1)p'.....p'}D'。

下面是用表格对8位信息码,32位余码,生成码为0x04c11db7;

参考Excel表格。最后的结果为(左边为低位x0~x31)

以下为在verilog中的验证代码:

 module arc_8(input clk,output reg [:] crc);
reg [:]count=;
reg [:] fcs_temp,datatemp2;
reg [:] R ;
reg[:] step=;
reg [:]data_count=;
reg [:] num=;
reg on=;
reg [:] datatemp;
always@(posedge clk)
begin
case(step)
:begin if(on) step<=;else step<=;R<=;end
:begin
if(data_count<)begin // 主要是第一个循环0x60e84e34,验证的结果应该为0x7db9cbc8
case(num)
:begin datatemp<='h60;num<=1;on<=1;end
:begin datatemp <='he8;num<=2;end
:begin datatemp<='h4e;num<=3;end
:begin datatemp<='h34;num<=0;data_count<=data_count+1;end
endcase
step<=;end
else begin on<=; step<=;end end
:begin step<=;
//
fcs_temp[]<=R[]^R[];
//
fcs_temp[]<=R[]^ R[]^R[];
//
fcs_temp[]<=R[]^ R[]^R[]^R[];
//
fcs_temp[]<=R[]^R[]^R[]^R[];
//
fcs_temp[]<=R[]^R[]^R[]^R[]^R[];
//
fcs_temp[]<= R[]^R[]^R[]^ R[]^ R[];
//
fcs_temp[]<=R[]^R[]^R[];
//
fcs_temp[]<=R[]^R[]^R[]^R[];
//
fcs_temp[]<=R[]^R[]^R[]^R[];
//
fcs_temp[]<=R[]^R[];
//
fcs_temp[]<=R[]^R[];
//
fcs_temp[]<=R[]^ R[];
//
fcs_temp[]<=R[]^R[]^ R[];
//
fcs_temp[]<=R[]^ R[]^R[]^R[];
//
fcs_temp[]<=R[ ]^R[]^R[]^R[];
//
fcs_temp[]<=R[ ]^R[]^R[]^R[];
//
fcs_temp[]<=R[ ]^R[]^R[]^R[]^R[];
//
fcs_temp[]<=R[ ]^R[]^R[]^R[]^R[]^R[];
//
fcs_temp[]<=R[ ]^R[]^R[]^R[]^ R[]^ R[]^ R[];
//
fcs_temp[]<=R[ ]^R[]^R[]^R[]^R[]^R[]^R[];
//
fcs_temp[]<=R[ ]^R[]^R[]^R[]^R[];
//
fcs_temp[]<=R[ ]^R[]^R[]^R[]^R[];
//
fcs_temp[]<=R[ ]^R[]^R[]^R[]^R[];
//
fcs_temp[]<=R[ ]^R[]^R[]^R[]^R[];
//
fcs_temp[]<=R[]^R[]^R[]^R[]^R[];
//
fcs_temp[]<=R[]^R[]^R[]^R[]^R[]^R[];
//
fcs_temp[]<=R[]^R[]^R[]^R[]^R[]^R[]^R[];
//
fcs_temp[]<=R[]^R[]^R[]^R[]^R[];
//
fcs_temp[]<=R[]^R[]^R[]^R[];
//
fcs_temp[]<=R[]^R[]^R[]^R[]^R[];
//
fcs_temp[]<=R[]^R[]^R[]^R[];
//
fcs_temp[]<=R[]^R[];end :begin step<=;
datatemp2[]<=datatemp[ ];
datatemp2[]<=datatemp[ ]^datatemp[ ];
datatemp2[]<=datatemp[ ]^datatemp[ ]^datatemp[ ];
datatemp2[]<=datatemp[ ]^datatemp[ ]^datatemp[ ];
datatemp2[]<=datatemp[ ]^datatemp[ ]^datatemp[ ]^datatemp[ ];
datatemp2[]<=datatemp[ ]^datatemp[ ]^datatemp[ ]^datatemp[ ];
datatemp2[]<=datatemp[ ]^datatemp[ ];
datatemp2[]<=datatemp[ ]^datatemp[ ]^datatemp[ ];
datatemp2[]<=datatemp[ ]^datatemp[ ]^datatemp[ ];
datatemp2[]<=datatemp[ ];
datatemp2[]<=datatemp[ ];
datatemp2[]<=datatemp[ ];
datatemp2[]<=datatemp[ ]^datatemp[ ];
datatemp2[]<=datatemp[ ]^datatemp[ ]^datatemp[ ];
datatemp2[]<=datatemp[ ]^datatemp[ ]^datatemp[ ];
datatemp2[]<=datatemp[ ]^datatemp[ ]^datatemp[ ];
datatemp2[]<=datatemp[ ]^datatemp[ ]^datatemp[ ]^datatemp[ ];
datatemp2[]<=datatemp[ ]^datatemp[ ]^datatemp[ ]^datatemp[ ]^datatemp[ ];
datatemp2[]<=datatemp[ ]^datatemp[ ]^datatemp[ ]^datatemp[ ]^datatemp[ ]^datatemp[ ];
datatemp2[]<=datatemp[ ]^datatemp[ ]^datatemp[ ]^datatemp[ ]^datatemp[ ]^datatemp[ ];
datatemp2[]<=datatemp[ ]^datatemp[ ]^datatemp[ ]^datatemp[ ];
datatemp2[]<=datatemp[ ]^datatemp[ ]^datatemp[ ]^datatemp[ ];
datatemp2[]<=datatemp[ ]^datatemp[ ]^datatemp[ ]^datatemp[ ];
datatemp2[]<=datatemp[ ]^datatemp[ ]^datatemp[ ]^datatemp[ ];
datatemp2[]<=datatemp[ ]^datatemp[ ]^datatemp[ ]^datatemp[ ]^datatemp[ ];
datatemp2[]<=datatemp[ ]^datatemp[ ]^datatemp[ ]^datatemp[ ]^datatemp[ ]^datatemp[ ];
datatemp2[]<=datatemp[ ]^datatemp[ ]^datatemp[ ]^datatemp[ ]^datatemp[ ]^datatemp[ ]^datatemp[ ];
datatemp2[]<=datatemp[ ]^datatemp[ ]^datatemp[ ]^datatemp[ ]^datatemp[ ];
datatemp2[]<=datatemp[ ]^datatemp[ ]^datatemp[ ]^datatemp[ ];
datatemp2[]<=datatemp[ ]^datatemp[ ]^datatemp[ ]^datatemp[ ]^datatemp[ ];
datatemp2[]<=datatemp[ ]^datatemp[ ]^datatemp[ ]^datatemp[ ];
datatemp2[]<=datatemp[ ]^datatemp[ ];end :begin R<=fcs_temp^datatemp2; step<=;end
:begin step<=;crc<=~R;end
endcase
end
endmodule

modelsim 中显示结果

以8位并行数据为例确定crc-32的一般矩阵表示形式的更多相关文章

  1. openstack安装系列问题:window7 64位安装的virtualBox 只能选择32位的系统安装不能选择64位的系统安装

    个人原创,转载请注明作者,出处,否则依法追究法律责任 2017-10-03-12:22:22 现象:window7 64位安装的virtualBox 只能选择32位的系统安装不能选择64位的系统安装 ...

  2. win7 32位支持多大内存|win7 32位旗舰版最多能识别多少内存

    win7 32位支持多大内存|win7 32位旗舰版最多能识别多少内存 内存的大小决定系统运行速度,所以不少人认为只要内存加大就行了,其实这是不对的,因为win7 32位能支持的内存大小是有限制的,并 ...

  3. 统计一个16位二进制数中1的个数,并将结果以十六进制形式显示在屏幕上,用COM格式实现。

    问题 统计一个16位二进制数中1的个数,并将结果以十六进制形式显示在屏幕上,用COM格式实现. 代码 code segment assume cs:code org 100h main proc ne ...

  4. 【C语言】字节对齐问题(以32位系统为例)

    1. 什么是对齐? 现代计算机中内存空间都是按照字节(byte)划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定变量的时候经常在特定的内存地址访问,这就需要各类型 ...

  5. C/C++中浮点数格式学习——以IEEE75432位单精度为例

    这是浮点数的通常表示形式,在IEEE754中,单精度浮点数有如下形式: 位单精度 个比特存储. 位长 至23偏正值(实际的指数大小+127) 至0位编号(从右边开始为0) S为符号位,Exp为指数字, ...

  6. 各种15min(启动、横盘、破位)样例

    15min-m20=day m1.5 15min-m60=day m5 15min-m125=day m10 15min-m260=day m20 1.2017年6月8日 360  + 2018年11 ...

  7. Ubuntu 14.04(32位)安装Oracle 11g(32位)全过程

    1.将系统更新到最新:sudo apt-get updatesudo apt-get dist-upgrade2.安装Oracle所需的依赖包:sudo apt-get install automak ...

  8. 64位系统里的IIS运行32位ODP.NET的方法

    在64位Win7里的IIS里部署使用了ODP.NET的网站,Oracle的版本是11.20.3.20.直接部署会提示错误:在64位环境里使用了32位的程序.自己折腾了两天,最后才从别人的博客里找到解决 ...

  9. 关于oracle 11g 64位与 32位的 plsql、及其他32位应用程序共存的问题

    因为 plsql 不支持 64位 oracle 客户端,所以plsql 必须使用 oracle 的 32位 instanclient 包.  解压缩后放一个目录,例如: D:\Oracle\insta ...

随机推荐

  1. c++学习-----引用

    引用相当于给一个对象起个别名 必须初始化 引用只是与一个对象bind,所以引用无法改变 引用不是一个对象,所以没有引用的引用 引用的初始化值必须是一个对象,而不能是字面量或表达式 引用不是地址,所以引 ...

  2. k8s系列0--Kubernetes基础知识

    Kubernetes介绍 参考:Kubernetes核心组件解析 Pod是k8s的最小调度单元 每个pod有独立的IP,但是pod的IP是不可靠的,重新调度pod就会改变IP,service概念就是为 ...

  3. SQL Server系统函数:元数据函数

    原文:SQL Server系统函数:元数据函数 1.列的长度.列名 --列的长度 select COL_LENGTH('dbo.wct', --表名 'wcid') --列名 --列名 select ...

  4. EF6.0中出现未找到具有固定名称“System.Data.SqlClient”的 ADO.NET提供程序的实体框架提供程序解决办法

    在多工程项目中,由于EF封装在某一个工程里,那么该项目用于EF相关类库 EntityFramework.dll,以及EntityFramework.SqlServer.dll的引用 那么你一个启动工程 ...

  5. vue 集成 NEditor 富文本

    下载NEditor 放在  vue 项目下面 public  文件中. 安装    vue-neditor-wrap  执行命令 npm  install  vue-neditor-wrap 代码使用 ...

  6. Uwl.Admin开源框架(二)

    Uwl.Admin开源框架基于QuartzNet定时任务模块的实现 Quartz.NET官网地址:https://www.quartz-scheduler.net/ Quartz.NET文档地址:ht ...

  7. JSP开发 路径问题汇总

    //第一种 jsp 表达式 <%=request.getContextPath %> 获取到 web项目名的绝对路径 <!--使用绝对路径的方式引入CSS文件--> <l ...

  8. Python练习_考试第二次

    一. 选择题(32分) 1. python不支持的数据类型有:AA. charB. intC. floatD. list 2. Ex = ‘foo’y = 2print(x + y)A. fooB. ...

  9. Image Processing and Analysis_21_Scale Space:Scale-Space for Discrete Signals——1990

    此主要讨论图像处理与分析.虽然计算机视觉部分的有些内容比如特 征提取等也可以归结到图像分析中来,但鉴于它们与计算机视觉的紧密联系,以 及它们的出处,没有把它们纳入到图像处理与分析中来.同样,这里面也有 ...

  10. 【异常】java.sql.SQLException: Could not retrieve transaction read-only status from server Query

    1 详细异常 java.sql.SQLException: Could not retrieve transaction read-only status , ], [ChargingOrderRea ...