Verilog --crc16 modbus

1 、CRC 校验原理
CRC 的基本原理就是在一个 n 位二进制数据序列之后附加一个 r 位二进制检验码序列,从而构成一个总长为 p = n + r 位的二进制序列。这里附加在数据序列之后的 CRC 码与数据序列的内容之间存在某种特定的关系。
如果在数据传输过程中,由于噪声或传输特性不理想而使数据序列中的某一位或某些位发生错误,这种特定关系就会被破坏。可见在数据的接收端通过检查这种特定关系,可以很容易地实现对数据传输正确性的检验。

下面是verilog代码:

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer: cui
//
// Create Date: 2020/05/24 17:04:30
// Design Name:
// Module Name: CRC16_modbus
// Width:8
// Poly:0x8005
// Init:0xFFFF;
// Refin:True;
// Refout:True;
// Xorout:0x0000;
//
//////////////////////////////////////////////////////////////////////////////////module CRC16_modbus(input sys_clk,input rst_n,input[7:0] data_l,input vld,output crc_vld,output crc_reg);
reg[7:0] d;
always @(posedge sys_clk or negedge rst_n) beginif(~rst_n) begind<= 0;end else if(vld) begind<=data_n ;end
end
reg[15:0] crc;
reg[15:0] newcrc;
reg[15:0] nextCRC16_D8;
wire[15:0] c;
assign c=newcrc;
always @(posedge sys_clk or negedge rst_n) beginif(~rst_n) beginnewcrc<= 16'hFFFF;end else if(count==8'd5) beginnewcrc[0] = d[7] ^ d[6] ^ d[5] ^ d[4] ^ d[3] ^ d[2] ^ d[1] ^ d[0] ^ c[8] ^ c[9] ^ c[10] ^ c[11] ^ c[12] ^ c[13] ^ c[14] ^ c[15];newcrc[1] = d[7] ^ d[6] ^ d[5] ^ d[4] ^ d[3] ^ d[2] ^ d[1] ^ c[9] ^ c[10] ^ c[11] ^ c[12] ^ c[13] ^ c[14] ^ c[15];newcrc[2] = d[1] ^ d[0] ^ c[8] ^ c[9];newcrc[3] = d[2] ^ d[1] ^ c[9] ^ c[10];newcrc[4] = d[3] ^ d[2] ^ c[10] ^ c[11];newcrc[5] = d[4] ^ d[3] ^ c[11] ^ c[12];newcrc[6] = d[5] ^ d[4] ^ c[12] ^ c[13];newcrc[7] = d[6] ^ d[5] ^ c[13] ^ c[14];newcrc[8] = d[7] ^ d[6] ^ c[0] ^ c[14] ^ c[15];newcrc[9] = d[7] ^ c[1] ^ c[15];newcrc[10] = c[2];newcrc[11] = c[3];newcrc[12] = c[4];newcrc[13] = c[5];newcrc[14] = c[6];newcrc[15] = d[7] ^ d[6] ^ d[5] ^ d[4] ^ d[3] ^ d[2] ^ d[1] ^ d[0] ^ c[7] ^ c[8] ^ c[9] ^ c[10] ^ c[11] ^ c[12] ^ c[13] ^ c[14] ^ c[15];nextCRC16_D8 = newcrc;end
end
reg[7:0] count;
always @(posedge sys_clk or negedge rst_n) beginif(~rst_n) begincount<= 0;end else if(vld) begincount<=1 ;end else if (count==8'd8) begincount<=0;   end else if (count!==0) begincount<=count+1;end
end
reg[15:0] crc_reg;
reg crc_vld;
always @(posedge sys_clk or negedge rst_n) beginif(~rst_n) begincrc_reg<= 0;end else if(count==8'd8) begincrc_reg<=crc_n^xor_a ;crc_vld<=1;end else begin crc_vld<=0;end
end
parameter xor_a=16'd0;
wire[7:0] data_n;
assign data_n[7]=data_l[0];
assign data_n[6]=data_l[1];
assign data_n[5]=data_l[2];
assign data_n[4]=data_l[3];
assign data_n[3]=data_l[4];
assign data_n[2]=data_l[5];
assign data_n[1]=data_l[6];
assign data_n[0]=data_l[7];wire[15:0] crc_n;
assign crc_n[15]=nextCRC16_D8[0];
assign crc_n[14]=nextCRC16_D8[1];
assign crc_n[13]=nextCRC16_D8[2];
assign crc_n[12]=nextCRC16_D8[3];
assign crc_n[11]=nextCRC16_D8[4];
assign crc_n[10]=nextCRC16_D8[5];
assign crc_n[9]=nextCRC16_D8[6];
assign crc_n[8]=nextCRC16_D8[7];
assign crc_n[7]=nextCRC16_D8[8];
assign crc_n[6]=nextCRC16_D8[9];
assign crc_n[5]=nextCRC16_D8[10];
assign crc_n[4]=nextCRC16_D8[11];
assign crc_n[3]=nextCRC16_D8[12];
assign crc_n[2]=nextCRC16_D8[13];
assign crc_n[1]=nextCRC16_D8[14];
assign crc_n[0]=nextCRC16_D8[15];endmodule

testbench:

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Module Name: vtf_crc16_test
//////////////////////////////////////////////////////////////////////////////////module vtf_crc16_test;
// Inputs
reg sys_clk;
reg rst_n ;
// Outputs
wire crc_vld;
wire[15:0] crc_reg;
reg[7:0] data;
reg vld;
// Instantiate the Unit Under Test (UUT)
CRC16_modbus uut (.sys_clk(sys_clk),   .rst_n(rst_n),.vld(vld),.data_l(data),.crc_vld(crc_vld),.crc_reg(crc_reg));initial
begin
// Initialize Inputssys_clk = 0;rst_n = 0 ;vld=0;#1000 ;rst_n = 1;#10 begin data=8'h11;end #10 @(posedge sys_clk)begin vld=1;end#500 begin data=8'hFF;end#10 @(posedge sys_clk)begin vld=1;end#2000 begin $finish; end
end
//Create clock
always #10 sys_clk = ~ sys_clk;
always @(posedge sys_clk or negedge rst_n) beginif(~rst_n) beginvld<= 0;end else if(vld) beginvld<=0 ;end
endendmodule

仿真波形:

从波形中可以看出,发送0x11,得到的crc为4c7f,和使用crc计算器计算的是一致的。
crc计算器链接:http://www.ip33.com/crc.html
crc生成器链接:https://www.easics.com/webtools/crctool

Verilog --crc16 modbus相关推荐

  1. Java语言 CRC-16/MODBUS..16+x15+x2+1校验码生成

    CRC算法名称 多项式公式 宽度 多项式 初始值 结果异或值 输入值反转 输出值反转 CRC-16/MODBUS 16+x15+x2+1 16 8005 FFFF 0000 true true 查表法 ...

  2. CRC-16/MODBUS x16+x15+x2+1校验计算 C++

    CRC-16/MODBUS x16+x15+x2+1校验计算 #include <stdio.h> int main(void) {     unsigned short tmp = 0x ...

  3. CRC-16 Modbus代码

    CRC(循环冗余校验)在线计算 /* 二进制显示无符号int函数,number:十进制整数 */ unsigned int IntegerToBinary(unsigned int number){c ...

  4. C++与JAVA代码实现CRC-16/MODBUS算法,且与 http://www.ip33.com/crc.html 进行结果验证

    CRC-16/MODBUS的多项式为:x16+x15+x2+1(8005),宽度为16.运算时,首先将一个16位的寄存器预置为11111111 11111111,然后连续把数据帧中的每个字节中的8位与 ...

  5. 16进制(CRC16)(MODBUS RTU通讯)校验码在线计算器

    最近在项目上遇到,用485协议命令控制灯光继电器的开关需要计算16进制(CRC16)(MODBUS RTU通讯)校验码来写控制命令,这种在网上有现成的计算器,我们直接使用即可,以下为我用的一个计算器的 ...

  6. CRC16 Modbus计算原理与代码实现

    1.CRC16 Modbus计算原理 1) 预置 1 个 16 位的寄存器为十六进制FFFF(即全为 1) , 称此寄存器为 CRC寄存器. 2) 把第一个 8 位二进制数据 (通信信息帧的第一个字节 ...

  7. CRC-16 / MODBUS 校验计算方法

    CRC-16 / MODBUS : 1)CRC寄存器初始值为 FFFF:即16个字节全为1: 2)CRC-16 / MODBUS的多项式A001H (1010 0000 0000 0001B) 'H' ...

  8. 一文详解循环冗余校验校验算法(CRC校验)及C语言代码的实现 ---- 以CRC-16/MODBUS为例讲解

    一.概述 现在的产品开发过程中,无论是数据的储存还是传输,都需要确保数据的准确性,所以就需要在数据帧后面附加一串校验码,方便接收方使用校验码校验接收到的数据是否是正确的. 常用的校验方式有奇偶校验.异 ...

  9. crc java_java实现CRC16 MODBUS校验算法

    /*** 查表法计算CRC16校验 * *@paramdata 需要计算的字节数组*/ public static String getCRC3(byte[] data) {byte[] crc16_ ...

最新文章

  1. png图片压缩原理解析
  2. UVa11770 - Lighting Away(排序+DFS)
  3. python电影名称词云_python-词云
  4. ORA-06502: PL/SQL: 数字或值错误 : 字符串缓冲区太小解决办法
  5. 树莓派上传数据到onenet云平台
  6. (已解决)登录火狐浏览器账号后没有同步数据--博主的奇妙寻号之旅
  7. Matlab坐标图像隐藏横纵坐标的方法
  8. C语言指针操作字符数组demo
  9. MSDN Visual系列:利用关联来过滤MOSS中的BDC数据
  10. 微信公众号盈利模式_微信公众号的盈利模式有哪些?四种模式分享
  11. STM32F103 TIM4定时器
  12. 熵的理解(玻尔兹曼分布)
  13. QT5.15 安装教程
  14. python抢购软件/插件/脚本附完整源码
  15. 小技巧 - 如何在线下载 Google Play 里面的应用?
  16. Element-Ui 双重el-tabs组件选中第二层时,刷新导致第一层选中样式丢失问题以及解决方法
  17. catagory添加属性
  18. Java中的动态代理详解
  19. 这回稳了!广和通4G低功耗摄像头解决方案全新来袭
  20. AI文娱独角兽Video++极链科技完成C1轮,5个月融资10.7亿元

热门文章

  1. 微信小程序 textarea浮动键盘弹不出来错误
  2. Word中打不出来的符号公式
  3. 苹果电子邮件怎么注册_TestFlight适用于哪些平台,真的能打倒苹果企业签名吗...
  4. 【SSL证书】创建局域网或单机可信任证书
  5. 洛谷p2240部分部分背包问题c语言(数组实现)
  6. Python中Urlparse模块
  7. ValueError: x and y must have same first dimension, but have shapes (100,) and (0,)
  8. 【图神经网络DGL】GCN在Karate Club上的实战(消息传递范式 | 生成训练可视化动图)
  9. 宝塔面板mysql5.7安装失败_centos宝塔面板安装及常见错误处理(超级详细)
  10. matlab怎么计算出tan,matlab中“arctan”怎么表示?