打印

verilog语言实现crc16的串行和并行算法

[复制链接]
15181|19
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
yuhaijian112|  楼主 | 2012-7-3 15:35 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
沙发
GoldSunMonkey| | 2012-7-3 16:07 | 只看该作者
并行代码见下楼。
串行和并行类似支持,需要积攒8位后,然后CRC,然后在变成串行输出去。
以后别问代码了,没人能太多帮你的。

使用特权

评论回复
板凳
GoldSunMonkey| | 2012-7-3 16:07 | 只看该作者
module code_crc(clk,reset,data,out);
input clk,reset;
input[7:0] data;
output[15:0] out;
reg[15:0] out;
//变量声明
reg[16:0] s;
integer i;

always@(posedge clk)
begin
if(!reset)
  begin
s=17'b0;
out=16'b0;
  end
else
  begin
   s={data[7:0],9'b0};
begin
    for(i=7;i>0;i=i-1)
   begin
    if(s[16]==0)              //若第一位为0,左移一位;
     s=s<<1;
  else begin
    s=s^17'b11000000000000101;/*若第一位为1,则与生成多项式进行异或操作;*/
  s=s<<1;        //左移一位;
       end
   end
   out=s[15:0];               //s的后16位即为校验位;
end
  end
end
endmodule

使用特权

评论回复
地板
mr.king| | 2012-7-3 19:40 | 只看该作者
串行的我直接用硬件DFF+XOR方式做

使用特权

评论回复
5
GoldSunMonkey| | 2012-7-3 23:46 | 只看该作者
:lol

使用特权

评论回复
6
yuhaijian112|  楼主 | 2012-7-4 10:45 | 只看该作者
那CCITT-CRC16的反转。要怎样做啊?

使用特权

评论回复
7
yuhaijian112|  楼主 | 2012-7-4 10:48 | 只看该作者
对了,for循环能综合吗?

使用特权

评论回复
8
yuhaijian112|  楼主 | 2012-7-4 11:03 | 只看该作者
那CCITT-CRC16的反转。要怎样做啊?(不用for循环)

使用特权

评论回复
9
mr.king| | 2012-7-4 11:27 | 只看该作者
翻转就用反相器

使用特权

评论回复
10
mr.king| | 2012-7-4 11:28 | 只看该作者
ROCESS(crc16clk,crc16reset,crc16data)
        begin
                if crc16reset='0' then
                        crc16modout<="1111111111111111";
                elsif rising_edge(crc16clk) then
                        crc16modout(0)<=crc16modout(15) xor crc16data;
                        crc16modout(1)<=crc16modout(0);
                        crc16modout(2)<=crc16modout(1);
                        crc16modout(3)<=crc16modout(2);
                        crc16modout(4)<=crc16modout(3);
                        crc16modout(5)<=crc16modout(4) xor crc16modout(15) xor crc16data;
                        crc16modout(6)<=crc16modout(5);
                        crc16modout(7)<=crc16modout(6);
                        crc16modout(8)<=crc16modout(7);
                        crc16modout(9)<=crc16modout(8);
                        crc16modout(10)<=crc16modout(9);
                        crc16modout(11)<=crc16modout(10);
                        crc16modout(12)<=crc16modout(11) xor crc16modout(15) xor crc16data;
                        crc16modout(13)<=crc16modout(12);
                        crc16modout(14)<=crc16modout(13);
                        crc16modout(15)<=crc16modout(14);
                end if;
        end process;

使用特权

评论回复
11
GoldSunMonkey| | 2012-7-4 14:03 | 只看该作者
对了,for循环能综合吗?
yuhaijian112 发表于 2012-7-4 10:48
不能啊。

使用特权

评论回复
12
GoldSunMonkey| | 2012-7-4 14:04 | 只看该作者
ROCESS(crc16clk,crc16reset,crc16data)
        begin
                if crc16reset='0' then
                        crc16modout
mr.king 发表于 2012-7-4 11:28
谢谢分享。兄弟

使用特权

评论回复
13
yuhaijian112|  楼主 | 2012-7-4 14:40 | 只看该作者
////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 1999-2008 Easics NV.
// This source file may be used and distributed without restriction
// provided that this copyright statement is not removed from the file
// and that any derivative work contains the original copyright notice
// and the associated disclaimer.
//
// THIS SOURCE FILE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS
// OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
// WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// Purpose : synthesizable CRC function
//   * polynomial: (0 5 12 16)
//   * data width: 8
//
// Info : tools@easics.be
//        http://www.easics.com
////////////////////////////////////////////////////////////////////////////////
module CRC16_D8;

  // polynomial: (0 5 12 16)
  // data width: 8
  // convention: the first serial bit is D[7]
  function [15:0] nextCRC16_D8;

    input [7:0] Data;
    input [15:0] crc;
    reg [7:0] d;
    reg [15:0] c;
    reg [15:0] newcrc;
  begin
    d = Data;
    c = crc;

    newcrc[0] = d[4] ^ d[0] ^ c[8] ^ c[12];
    newcrc[1] = d[5] ^ d[1] ^ c[9] ^ c[13];
    newcrc[2] = d[6] ^ d[2] ^ c[10] ^ c[14];
    newcrc[3] = d[7] ^ d[3] ^ c[11] ^ c[15];
    newcrc[4] = d[4] ^ c[12];
    newcrc[5] = d[5] ^ d[4] ^ d[0] ^ c[8] ^ c[12] ^ c[13];
    newcrc[6] = d[6] ^ d[5] ^ d[1] ^ c[9] ^ c[13] ^ c[14];
    newcrc[7] = d[7] ^ d[6] ^ d[2] ^ c[10] ^ c[14] ^ c[15];
    newcrc[8] = d[7] ^ d[3] ^ c[0] ^ c[11] ^ c[15];
    newcrc[9] = d[4] ^ c[1] ^ c[12];
    newcrc[10] = d[5] ^ c[2] ^ c[13];
    newcrc[11] = d[6] ^ c[3] ^ c[14];
    newcrc[12] = d[7] ^ d[4] ^ d[0] ^ c[4] ^ c[8] ^ c[12] ^ c[15];
    newcrc[13] = d[5] ^ d[1] ^ c[5] ^ c[9] ^ c[13];
    newcrc[14] = d[6] ^ d[2] ^ c[6] ^ c[10] ^ c[14];
    newcrc[15] = d[7] ^ d[3] ^ c[7] ^ c[11] ^ c[15];
    nextCRC16_D8 = newcrc;
  end
  endfunction
endmodule

我想问一下这段程序中的公式(newcrc[0] = d[4] ^ d[0] ^ c[8] ^ c[12]; newcrc[1] = d[5] ^ d[1] ^ c[9] ^ c[13];。。。。。。)是怎样推出来的?

使用特权

评论回复
14
yuhaijian112|  楼主 | 2012-7-4 14:42 | 只看该作者
如果把它修改成串行输入,那程序该怎么写?

使用特权

评论回复
15
mr.king| | 2012-7-4 19:57 | 只看该作者
14# yuhaijian112
我那就是串行输入的,只是是并行输出,数据靠时钟打进来,16位并出当前结果

使用特权

评论回复
16
yuhaijian112|  楼主 | 2012-7-5 14:09 | 只看该作者
那有谁知道CCITT-CRC16的反转算法,串行的电路是怎样的?

使用特权

评论回复
17
GoldSunMonkey| | 2012-7-6 22:34 | 只看该作者
牛B,结帖一个分数也不给大家。

使用特权

评论回复
18
zhhtqb2b| | 2012-8-13 16:31 | 只看该作者
17# GoldSunMonkey


猴哥,你贴出来的CRC-16的代码在ISE里面算出来不正确,难道是我的testbench有问题吗?

使用特权

评论回复
19
zhhtqb2b| | 2012-8-13 16:58 | 只看该作者
17# GoldSunMonkey


比如 8'h04  和 8'h05 校验出来都是  16'h001E, 而正确结果应该分别是16'801B 和 16'h001E。

使用特权

评论回复
20
GoldSunMonkey| | 2012-8-13 22:27 | 只看该作者
:)自己找找原因吧。我也没验证。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

0

主题

16

帖子

0

粉丝