小学霸修炼秘籍之FPGA篇--CRC16校验码的计算(Verilog)

小学霸这次做的项目需要Modbue -TCP协议转化为Modbus- RTU协议并通过串口输出,RTU协议中在数据发送的最后需要发送CRC16 校验码,关于CRC16校验码的计算方式有很多种,在此小学霸用的是移位计算法,具体的步骤是:

1、预置一个值为0XFFFF的16位寄存器,即CRC寄存器;

2、将第一个八位数据与16 CRC寄存器的第八位相异或,结果仍存于CRC寄存器中;

3、将CRC寄存器的内容右移一位,最高位补0 ;

4、若移出位为0则重复3步骤再右移一次,若移出为1,则CRC寄存器与0XA001进行异或;

5、重复3   4  步骤直到八位数据处理完成。

6、重复2--5步骤将通信消息帧下一字节处理,直至处理完成;

处理完成后在发送CRC校验位时,要先发送低字节,后发送高字节;

Verilog实现程序为:

module CRC_count(clk,rst_n,CRC_out,signal_read,signal_write,arm_device_rddata,data_1,
signal_start,signal_start_status,signal_CRC_start,cnt_reg,cnt_data,
CRC,num_data);


input clk;
input rst_n;
input signal_read;
input signal_write;
input [7:0] arm_device_rddata;
output [15:0] CRC_out;
input [7:0] data_1;
input signal_start;
output signal_start_status;
output signal_CRC_start;
output cnt_reg;
output cnt_data;   //测试标志
output CRC;
input [7:0] num_data;


integer i;

reg signal_start_reg1,signal_start_reg2;
wire signal_start_status,signal_start_status1;
reg [7:0] cnt_reg ;
reg [7:0] cnt_data;
reg [15:0] CRC_out;




reg [15:0] CRC = 16'hffff;
reg [15:0] data_buffer = 16'ha001;
reg signal_CRC_start;




always@(posedge clk)
begin
signal_start_reg1 <= signal_start;
signal_start_reg2 <= signal_start_reg1;
end


assign signal_start_status = signal_start_reg1 && (~signal_start_reg2);  
assign signal_start_status1 = signal_start_reg2 && (~signal_start_reg1);  


always@(posedge clk)
begin
if(signal_start_status == 1)
begin
CRC = CRC ^ data_1;
signal_CRC_start <= 1;
cnt_data <= cnt_data + 1;

end
else
if(cnt_reg == 8)
begin
signal_CRC_start <= 0;
cnt_reg <= 0;
if(signal_read == 1 && cnt_data == 5)
begin
CRC_out <= CRC;
CRC <= 16'hffff;
cnt_data <= 0;
end
else
if(signal_write == 1 && cnt_data == 7 && num_data == 2)
begin
CRC_out <= CRC;
CRC <= 16'hffff;
cnt_data <= 0;
end
else
if(signal_write == 1 && cnt_data == 6 && num_data == 1)
begin
CRC_out <= CRC;
CRC <= 16'hffff;
cnt_data <= 0;
end

end
else
if(signal_CRC_start == 1)
begin
for(i=7;i>=0;i=i-1)
begin
cnt_reg = cnt_reg +1;
if(CRC[0] == 0)
begin
CRC = CRC>>1;
end
else
if(CRC[0] == 1)
begin
CRC = (CRC>>1)^ data_buffer;
end
end
end


end



endmodule



最后推荐一个计算CRC16校验码的计算器,在程序运行完可以做一下校对:http://www.3158bbs.com/tool-59.html


  • 4
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值