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

Subversion Repositories ccsds_rxtxsoc

[/] [ccsds_rxtxsoc/] [trunk/] [ccsds_rxtx_crc.vhd] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 zguig52
-------------------------------
2
---- Project: EurySPACE CCSDS RX/TX with wishbone interface
3
---- Design Name: ccsds_rxtx_crc
4
---- Version: 1.0.0
5
---- Description:
6
---- CRC computation core
7
---- Input: 1 clk / nxt_dat_i <= '1' / dat_i <= "CRCCOMPUTEDDATA" / [pad_dat_val_i <= '1' / pad_dat_i <= "PADDINGDATA"]
8
---- Timing requirements: (CCSDS_RXTX_CRC_DATA_LENGTH+CCSDS_RXTX_CRC_LENGTH)*8+1 clock cycles for valid output CRC
9
---- Output: dat_val_o <= "1" / dat_o <= "CRCCOMPUTEDDATA" / crc_o <= "CRCCOMPUTED"
10
---- Ressources requirements: data computed registers + crc registers + padding data registers + busy state registers + data_valid state registers + crc data pointer registers = (CCSDS_RXTX_CRC_DATA_LENGTH+CCSDS_RXTX_CRC_LENGTH*2)*8 + 2 + |log(CCSDS_RXTX_CRC_DATA_LENGTH-1)/log(2)| + 1 registers
11
--TODO: ressources with inversions
12
-------------------------------
13
---- Author(s):
14
---- Guillaume REMBERT
15
-------------------------------
16
---- Licence:
17
---- MIT
18
-------------------------------
19
---- Changes list:
20
---- 2016/10/18: initial release
21
---- 2016/10/25: external padding data mode
22
---- 2016/10/30: ressources usage optimization
23
-------------------------------
24
--TODO: Implement DIRECT computation?
25
--TODO: CRC LENGTH not being multiple of Byte
26
 
27
-- CRC reference and explanations:
28
-- http://www.ross.net/crc/download/crc_v3.txt
29
 
30
-- Online data converters:
31
-- http://www.asciitohex.com/
32
 
33
-- Online CRC computers:
34
-- http://www.sunshine2k.de/coding/javascript/crc/crc_js.html
35
-- http://www.zorc.breitbandkatze.de/crc.html
36
-- NB: use nondirect configuration
37
 
38
-- COMMON STANDARDS CONFIGURATIONS:
39
-- http://reveng.sourceforge.net/crc-catalogue/
40
-- WARNING: some check values found there are linked to direct computation / cf: http://srecord.sourceforge.net/crc16-ccitt.html
41
--------------------
42
-- Check value: x"313233343536373839" <=> 123456789/ASCII
43
--------------------
44
-- CRC-8/DVB-S2
45
-- Width = 8 bits
46
-- Truncated polynomial = 0xd5
47
-- Initial value = 0x00
48
-- Input data reflected: false
49
-- Output CRC reflected: false
50
-- XOR final = 0x00
51
-- Check = 0xbc
52
--------------------
53
-- CRC-8/ITU/ATM
54
-- Width = 8 bits
55
-- Truncated polynomial = 0x07
56
-- Initial value = 0x00
57
-- Input data reflected: false
58
-- Output CRC reflected: false
59
-- XOR final = 0x55
60
-- Check = 0xa1
61
--------------------
62
-- CRC-8/LTE
63
-- Width = 8 bits
64
-- Truncated polynomial = 0x9b
65
-- Initial value = 0x00
66
-- Input data reflected: false
67
-- Output CRC reflected: false
68
-- XOR final = 0x00
69
-- Check = 0xea
70
--------------------
71
-- CRC-16/CCSDS/CCITT-FALSE
72
-- Width = 16 bits
73
-- Truncated polynomial = 0x1021
74
-- Initial value = 0xffff
75
-- Input data reflected: false
76
-- Output CRC reflected: false
77
-- XOR final = 0x0000
78
-- Check = 0xe5cc
79
--------------------
80
-- CRC-16/LTE
81
-- Width = 16 bits
82
-- Truncated polynomial = 0x1021
83
-- Initial value = 0x0000
84
-- Input data reflected: false
85
-- Output CRC reflected: false
86
-- XOR final = 0x0000
87
-- Check = 0x31c3
88
--------------------
89
-- CRC-16/CCITT-TRUE/KERMIT
90
-- Width = 16 bits
91
-- Truncated polynomial = 0x1021
92
-- Initial value = 0x0000
93
-- Input data reflected: true
94
-- Output CRC reflected: true
95
-- XOR final = 0x0000
96
-- Check = 0x2189
97
--------------------
98
-- CRC-16/UMTS
99
-- Width = 16 bits
100
-- Truncated polynomial = 0x8005
101
-- Initial value = 0x0000
102
-- Input data reflected: false
103
-- Output CRC reflected: false
104
-- XOR final = 0x0000
105
-- Check = 0xfee8
106
--------------------
107
-- CRC-16/X-25
108
-- Width = 16 bits
109
-- Truncated polynomial = 0x1021
110
-- Initial value = 0xffff
111
-- Input data reflected: true
112
-- Output CRC reflected: true
113
-- XOR final = 0xffff
114
-- Check = 0x2e5d
115
--------------------
116
-- CRC-32/ADCCP
117
-- Width = 32 bits
118
-- Truncated polynomial = 0x04c11db7
119
-- Initial value = 0xffffffff
120
-- Input data reflected: true
121
-- Output CRC reflected: true
122
-- XOR final = 0xffffffff
123
-- Check = 0x22896b0a
124
----------------
125
-- CRC-32/BZIP2
126
-- Width = 32 bits
127
-- Truncated polynomial = 0x04c11db7
128
-- Initial value = 0xffffffff
129
-- Input data reflected: false
130
-- Output CRC reflected: false
131
-- XOR final = 0xffffffff
132
-- Check = 0xfc891918
133
----------------
134
-- CRC-32/MPEG-2
135
-- Width = 32 bits
136
-- Truncated polynomial = 0x04c11db7
137
-- Initial value = 0xffffffff
138
-- Input data reflected: false
139
-- Output CRC reflected: false
140
-- XOR final = 0x00000000
141
-- Check = 0x373C5870
142
----------------
143
-- CRC-32/POSIX
144
-- Width = 32 bits
145
-- Truncated polynomial = 0x04c11db7
146
-- Initial value = 0x00000000
147
-- Input data reflected: false
148
-- Output CRC reflected: false
149
-- XOR final = 0xffffffff
150
-- Check = 0x765e7680
151
----------------
152
-- CRC-64/WE
153
-- Width = 64 bits
154
-- Truncated polynomial = 0x42f0e1eba9ea3693
155
-- Initial value = 0xffffffffffffffff
156
-- Input data reflected: false
157
-- Output CRC reflected: false
158
-- XOR final = 0xffffffffffffffff
159
-- Check = 0xd2c7a4d6f38185a4
160
----------------
161
-- CRC-64/XZ
162
-- Width = 64 bits
163
-- Truncated polynomial = 0x42f0e1eba9ea3693
164
-- Initial value = 0xffffffffffffffff
165
-- Input data reflected: true
166
-- Output CRC reflected: true
167
-- XOR final = 0xffffffffffffffff
168
-- Check = 0xecf36dfb73a6edf7
169
----------------
170
 
171
-- libraries used
172
library ieee;
173
use ieee.std_logic_1164.all;
174
use ieee.numeric_std.all;
175
library work;
176
use work.ccsds_rxtx_functions.all;
177
 
178
--=============================================================================
179
-- Entity declaration for ccsds_tx / unitary rxtx crc inputs and outputs
180
--=============================================================================
181
entity ccsds_rxtx_crc is
182
  generic(
183
    constant CCSDS_RXTX_CRC_DATA_LENGTH: integer := 2; -- Data length - in Bytes
184
    constant CCSDS_RXTX_CRC_FINAL_XOR: std_logic_vector := x"0000"; -- Final XOR mask (0x0000 <=> No XOR)
185
    constant CCSDS_RXTX_CRC_INPUT_BYTES_REFLECTED: boolean := false; -- Reflect input byte by byte (used by standards)
186
    constant CCSDS_RXTX_CRC_INPUT_REFLECTED: boolean := false; -- Reflect input on overall data (not currently used by standards) / WARNING - take over input bytes reflected parameter if activated
187
    constant CCSDS_RXTX_CRC_LENGTH: integer := 2; -- CRC value depth - in Bytes
188
    constant CCSDS_RXTX_CRC_OUTPUT_REFLECTED: boolean := false; -- Reflect output
189
    constant CCSDS_RXTX_CRC_POLYNOMIAL: std_logic_vector        := x"1021"; -- Truncated polynomial / MSB <=> lower polynome (needs to be '1')
190
    constant CCSDS_RXTX_CRC_POLYNOMIAL_REFLECTED: boolean := false; -- Reflect polynomial
191
    constant CCSDS_RXTX_CRC_SEED: std_logic_vector := x"FFFF" -- Initial value from register
192
  );
193
  port(
194
    -- inputs
195
    clk_i: in std_logic;
196
    dat_i: in std_logic_vector(CCSDS_RXTX_CRC_DATA_LENGTH*8-1 downto 0);
197
    nxt_i: in std_logic;
198
    pad_dat_i: in std_logic_vector(CCSDS_RXTX_CRC_LENGTH*8-1 downto 0);
199
    pad_dat_val_i: in std_logic;
200
    rst_i: in std_logic;
201
    -- outputs
202
    bus_o: out std_logic;
203
    crc_o: out std_logic_vector(CCSDS_RXTX_CRC_LENGTH*8-1 downto 0);
204
    dat_o: out std_logic_vector(CCSDS_RXTX_CRC_DATA_LENGTH*8-1 downto 0);
205
    dat_val_o: out std_logic
206
  );
207
end ccsds_rxtx_crc;
208
 
209
--=============================================================================
210
-- architecture declaration / internal components and connections
211
--=============================================================================
212
architecture rtl of ccsds_rxtx_crc is
213
 
214
-- internal variable signals
215
  signal crc_busy: std_logic := '0';
216
  signal crc_data: std_logic_vector((CCSDS_RXTX_CRC_DATA_LENGTH+CCSDS_RXTX_CRC_LENGTH)*8-1 downto 0) := (others => '0');
217
  signal crc_memory: std_logic_vector(CCSDS_RXTX_CRC_LENGTH*8-1 downto 0) := CCSDS_RXTX_CRC_SEED;
218
 
219
-- components instanciation and mapping
220
  begin
221
     bus_o <= crc_busy;
222
     crc_o <= crc_memory;
223
     dat_o <= crc_data((CCSDS_RXTX_CRC_DATA_LENGTH+CCSDS_RXTX_CRC_LENGTH)*8-1 downto CCSDS_RXTX_CRC_LENGTH*8);
224
-- presynthesis checks
225
     CHKCRCP0 : if CCSDS_RXTX_CRC_SEED'length /= CCSDS_RXTX_CRC_LENGTH*8 generate
226
      process
227
      begin
228
        report "ERROR: CRC SEED VALUE LENGTH MUST BE EQUAL TO CRC LENGTH" severity failure;
229
              wait;
230
      end process;
231
    end generate CHKCRCP0;
232
    CHKCRCP1 : if CCSDS_RXTX_CRC_POLYNOMIAL'length /= CCSDS_RXTX_CRC_LENGTH*8 generate
233
      process
234
      begin
235
        report "ERROR: CRC POLYNOMIAL LENGTH MUST BE EQUAL TO CRC LENGTH (SHORTENED VERSION / DON'T PUT MANDATORY HIGHER POLYNOME '1')" severity failure;
236
        wait;
237
      end process;
238
    end generate CHKCRCP1;
239
    CHKCRCP2 : if CCSDS_RXTX_CRC_POLYNOMIAL(CCSDS_RXTX_CRC_LENGTH*8-1) = '0' generate
240
      process
241
      begin
242
        report "ERROR: CRC POLYNOMIAL MSB MUST BE EQUAL TO '1': " & std_logic'image(CCSDS_RXTX_CRC_POLYNOMIAL(CCSDS_RXTX_CRC_LENGTH*8-1)) severity failure;
243
        wait;
244
      end process;
245
    end generate CHKCRCP2;
246
    CHKCRCP3 : if CCSDS_RXTX_CRC_INPUT_BYTES_REFLECTED = true and CCSDS_RXTX_CRC_INPUT_REFLECTED = true generate
247
      process
248
      begin
249
        report "ERROR: CRC INPUT DATA REFLECTION CANNOT BE DONE SIMULTANEOUSLY ON OVERALL DATA AND BYTE BY BYTE" severity failure;
250
        wait;
251
      end process;
252
    end generate CHKCRCP3;
253
-- internal processing
254
 
255
    --=============================================================================
256
    -- Begin of crcp
257
    -- Compute CRC based on input data
258
    --=============================================================================
259
    -- read: rst_i, nxt_i, pad_dat_i, pad_dat_val_i
260
    -- write: dat_val_o, crc_busy, crc_memory
261
    -- r/w: crc_data
262
    CRCP: process (clk_i)
263
    variable crc_data_pointer: integer range -2 to ((CCSDS_RXTX_CRC_DATA_LENGTH+CCSDS_RXTX_CRC_LENGTH)*8-1) := -2;
264
    begin
265
      -- on each clock rising edge
266
      if rising_edge(clk_i) then
267
        -- reset signal received
268
        if (rst_i = '1') then
269
          crc_busy <= '0';
270
          dat_val_o <= '0';
271
--          crc_memory <= CCSDS_RXTX_CRC_SEED;
272
--          crc_data <= (others => '0');
273
          crc_data_pointer := -2;
274
        else
275
          case crc_data_pointer is
276
            -- no current crc under computation
277
            when -2 =>
278
              dat_val_o <= '0';
279
              -- CRC computation required and 
280
              if (nxt_i = '1') then
281
                crc_busy <= '1';
282
                crc_memory <= CCSDS_RXTX_CRC_SEED;
283
                crc_data_pointer := (CCSDS_RXTX_CRC_DATA_LENGTH+CCSDS_RXTX_CRC_LENGTH)*8-1;
284
                if (CCSDS_RXTX_CRC_INPUT_REFLECTED) then
285
                  crc_data((CCSDS_RXTX_CRC_DATA_LENGTH+CCSDS_RXTX_CRC_LENGTH)*8-1 downto CCSDS_RXTX_CRC_LENGTH*8) <= reverse_std_logic_vector(dat_i);
286
                elsif (CCSDS_RXTX_CRC_INPUT_BYTES_REFLECTED) then
287
                  for data_pointer in CCSDS_RXTX_CRC_DATA_LENGTH+CCSDS_RXTX_CRC_LENGTH-1 downto CCSDS_RXTX_CRC_LENGTH loop
288
                    crc_data((data_pointer+1)*8-1 downto data_pointer*8) <= reverse_std_logic_vector(dat_i(((data_pointer+1-CCSDS_RXTX_CRC_LENGTH)*8-1) downto (data_pointer-CCSDS_RXTX_CRC_LENGTH)*8));
289
                  end loop;
290
                else
291
                    crc_data((CCSDS_RXTX_CRC_DATA_LENGTH+CCSDS_RXTX_CRC_LENGTH)*8-1 downto CCSDS_RXTX_CRC_LENGTH*8) <= dat_i;
292
                end if;
293
                if (pad_dat_val_i = '1') then
294
                  if (CCSDS_RXTX_CRC_OUTPUT_REFLECTED) then
295
                    crc_data(CCSDS_RXTX_CRC_LENGTH*8-1 downto 0) <= reverse_std_logic_vector(pad_dat_i);
296
                  else
297
                    crc_data(CCSDS_RXTX_CRC_LENGTH*8-1 downto 0) <= pad_dat_i;
298
                  end if;
299
                else
300
                  crc_data(CCSDS_RXTX_CRC_LENGTH*8-1 downto 0) <= (others => '0');
301
                end if;
302
              else
303
                -- nothing to be done
304
                crc_busy <= '0';
305
              end if;
306
            -- CRC is computed
307
            when -1 =>
308
              crc_busy <= '0';
309
              dat_val_o <= '1';
310
              crc_data_pointer := -2;
311
              if (CCSDS_RXTX_CRC_OUTPUT_REFLECTED) then
312
                crc_memory <= reverse_std_logic_vector(crc_memory xor CCSDS_RXTX_CRC_FINAL_XOR);
313
              else
314
                crc_memory <= (crc_memory xor CCSDS_RXTX_CRC_FINAL_XOR);
315
              end if;
316
              if (CCSDS_RXTX_CRC_INPUT_REFLECTED) then
317
                crc_data((CCSDS_RXTX_CRC_DATA_LENGTH+CCSDS_RXTX_CRC_LENGTH)*8-1 downto CCSDS_RXTX_CRC_LENGTH*8) <= reverse_std_logic_vector(crc_data((CCSDS_RXTX_CRC_DATA_LENGTH+CCSDS_RXTX_CRC_LENGTH)*8-1 downto CCSDS_RXTX_CRC_LENGTH*8));
318
              elsif (CCSDS_RXTX_CRC_INPUT_BYTES_REFLECTED) then
319
                for data_pointer in CCSDS_RXTX_CRC_DATA_LENGTH+CCSDS_RXTX_CRC_LENGTH-1 downto CCSDS_RXTX_CRC_LENGTH loop
320
                  crc_data(((data_pointer+1)*8-1) downto data_pointer*8) <= reverse_std_logic_vector(crc_data(((data_pointer+1)*8-1) downto data_pointer*8));
321
                end loop;
322
              end if;
323
            -- Computing CRC
324
            when others =>
325
              crc_busy <= '1';
326
              dat_val_o <= '0';
327
              -- MSB = 1 / register shifted output bit will be '1'
328
              if (crc_memory(CCSDS_RXTX_CRC_LENGTH*8-1) = '1') then
329
                if (CCSDS_RXTX_CRC_POLYNOMIAL_REFLECTED) then
330
                  crc_memory <= (std_logic_vector(resize(unsigned(crc_memory),CCSDS_RXTX_CRC_LENGTH*8-1)) & crc_data(crc_data_pointer)) xor reverse_std_logic_vector(CCSDS_RXTX_CRC_POLYNOMIAL);
331
                else
332
                  crc_memory <= (std_logic_vector(resize(unsigned(crc_memory),CCSDS_RXTX_CRC_LENGTH*8-1)) & crc_data(crc_data_pointer)) xor CCSDS_RXTX_CRC_POLYNOMIAL;
333
                end if;
334
              else
335
                crc_memory <= (std_logic_vector(resize(unsigned(crc_memory),CCSDS_RXTX_CRC_LENGTH*8-1)) & crc_data(crc_data_pointer));
336
              end if;
337
              crc_data_pointer := crc_data_pointer - 1;
338
          end case;
339
        end if;
340
      end if;
341
    end process;
342
end rtl;

powered by: WebSVN 2.1.0

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