OpenCores
URL https://opencores.org/ocsvn/fade_ether_protocol/fade_ether_protocol/trunk

Subversion Repositories fade_ether_protocol

[/] [fade_ether_protocol/] [trunk/] [stable_jumbo_frames_version/] [fpga/] [src/] [crc_gen2.py] - Blame information for rev 40

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 15 wzab
#!/usr/bin/python
2
# This is the public domain code written by Wojciech M. Zabolotny
3
# ( wzab(at)ise.pw.edu.pl )
4
# The functionality has been inspired by the CRC Tool available
5
# at http://www.easics.com/webtools/crctool , however the code
6
# has been written independently.
7
# In fact I have decided to write this code, when I was not able to
8
# generate CRC with the crctool for a particular non-typical length
9
# of data word.
10
# The program crc_gen.py generates the VHDL code for CRC update for given
11
# length of the data vector.
12
# The length of the CRC results from the coefficient of the CRC polynomial.
13
# The arguments are as follows:
14
# 1st: Function name. The package name is created by prefixing it with
15
#        pkg_
16
# 2nd: L - for data fed LSB first, M for data fed MSB first
17
# 3rd: the width of the data bus,
18
# 4th and next: the coefficients of the polynomial (the exponents in fact).
19
# For example, to generate the expression for CRC7 for 12bit data transmitted LSB first
20
# you should call:
21
# crc_gen.py crc7_d12 L 12 7 3 0
22
# To generate CRC-12 for 16 bit data transmitted MSB first, you should call:
23
# crc_gen.py crc12_d16 M 16 12 11 3 2 1 0
24
# The generated code implements a package with the function calculating
25
# the new value of the CRC from the previous value of the CRC and
26
# the data word.
27
import sys
28
fun_name=sys.argv[1]
29
pkg_name = "pkg_"+fun_name
30
data_order=sys.argv[2]
31
if data_order != 'L' and data_order != 'M':
32
    print "The second argument must be 'L' or 'M', not the '"+data_order+"'"
33
    sys.exit(1)
34
data_len=int(sys.argv[3])
35
poly=[]
36
for i in range(4,len(sys.argv)):
37
    poly.append(int(sys.argv[i]))
38
crc_len=max(poly)
39
 
40
#The class "xor_result" implements result of xor-ing of multiple
41
# CRC and DATA bits
42
# dirty trick: the class relies on global variables crc_len and data_len
43
class xor_result:
44
    def __init__(self,c=-1,d=-1):
45
        self.c=crc_len*[0]
46
        self.d=data_len*[0]
47
        if(c>-1):
48
            self.c[c]=1
49
        if(d>-1):
50
            self.d[d]=1
51
    def copy(self):
52
        res=xor_result()
53
        for i in range(0,crc_len):
54
            res.c[i]=self.c[i]
55
        for i in range(0,data_len):
56
            res.d[i]=self.d[i]
57
        return res
58
    # The new XOR operator
59
    def __xor__(self,x):
60
        res=xor_result()
61
        for i in range(0,crc_len):
62
            res.c[i]=self.c[i]^x.c[i]
63
        for i in range(0,data_len):
64
            res.d[i]=self.d[i]^x.d[i]
65
        return res
66
    def tostr(self):
67
        res=""
68
        for i in range(0,crc_len):
69
            if self.c[i]==1:
70
                if res=="":
71
                    res+="c("+str(i)+")"
72
                else:
73
                    res+=" xor c("+str(i)+")"
74
        for i in range(0,data_len):
75
            if self.d[i]==1:
76
                if res=="":
77
                    res+="d("+str(i)+")"
78
                else:
79
                    res+=" xor d("+str(i)+")"
80
        return res
81
 
82
 
83
#Now we create the CRC vector, which initially contains only the bits
84
#of the initial value of the CRC
85
CRC=[ xor_result(c=i) for i in range(0,crc_len) ]
86
#And the data vector
87
DATA=[ xor_result(d=i) for i in range(0,data_len) ]
88
#Now we pass the data through the CRC polynomial
89
if data_order == 'L':
90
    d_range = range(0,data_len)
91
    ord_name = "LSB"
92
elif data_order == 'M':
93
    d_range = range(data_len-1,-1,-1)
94
    ord_name = "MSB"
95
else:
96
    print "Internal error"
97
    sys.exit(1)
98
for i in d_range:
99
    #We create the vector for the new CRC
100
    NCRC = [ xor_result() for k in range(0,crc_len) ]
101
    #First - the basic shift operation
102
    for j in range(1,crc_len):
103
        NCRC[j]=CRC[j-1].copy()
104
    #Now we add the feedback
105
    FB=DATA[i] ^ CRC[crc_len-1]
106
    for j in poly:
107
        if j == crc_len:
108
            # This does not require any action
109
            pass
110
        else:
111
            NCRC[j]=NCRC[j] ^ FB
112
    CRC=NCRC
113
pkg_text = '''library ieee;
114
use ieee.std_logic_1164.all;
115
package ''' + pkg_name +" is\n"
116
pkg_text += "  -- CRC update for "+str(crc_len)+"-bit CRC and "+\
117
    str(data_len)+"-bit data ("+ord_name+" first)\n"
118
pkg_text += "  -- The CRC polynomial exponents: "+str(poly)+"\n"
119
fun_decl = '  function ' + fun_name +"(\n" +\
120
'   din : std_logic_vector('+str(data_len-1)+' downto 0);\n'+\
121
'   crc : std_logic_vector('+str(crc_len-1)+' downto 0))\n'+\
122
'  return std_logic_vector'
123
pkg_text += fun_decl+';\n'
124
pkg_text += 'end '+pkg_name+';\n\n'
125
pkg_text +=  "package body " + pkg_name +" is\n"
126
pkg_text += fun_decl + ' is \n'
127
pkg_text += '    variable c,n : std_logic_vector(' + str(crc_len-1)+' downto 0);\n'
128
pkg_text += '    variable d : std_logic_vector(' + str(data_len-1)+' downto 0);\n'
129
pkg_text += '  begin\n'
130
pkg_text += '    c := crc;\n    d := din; \n'
131
for i in range(0,len(CRC)):
132
    pkg_text += "      n("+str(i)+") := "+CRC[i].tostr()+";\n"
133
pkg_text += '    return n;\n'
134
pkg_text += '  end '+fun_name+";\n"
135
pkg_text += 'end '+pkg_name+";\n"
136
print pkg_text

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.