aboutsummaryrefslogtreecommitdiffstats
path: root/fpga/usrp3/lib/axi/crc_xnor.v
blob: c0923be66748301032e8ade43f4ffd357af414d0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
//
// Copyright 2017 Ettus Research LLC
// Copyright 2018 Ettus Research, a National Instruments Company
//
// SPDX-License-Identifier: LGPL-3.0-or-later
//
// Generates an LFSR based on a given seed value
// Note that not all length LFSRs are supported in the file
// For xnor LSFR equations please refer to following link:
// https://www.xilinx.com/support/documentation/application_notes/xapp210.pdf

// All indexing will be from 1 to match indexing used in table from app note above


module crc_xnor #(
  parameter INPUT_WIDTH=64,
  parameter OUTPUT_WIDTH=8
) (
   input clk,
   input [INPUT_WIDTH:1] input_data,
   input rst,
   input hold,
   output [OUTPUT_WIDTH:1] crc_out
);

    wire [INPUT_WIDTH:1] current_lfsr;
    reg  [INPUT_WIDTH:1] current_lfsr_r;

    // LFSR based on table given by Xilinx
    generate if (INPUT_WIDTH == 64) begin
        assign current_lfsr[1] = current_lfsr_r[64] ^ current_lfsr_r[63] ^ current_lfsr_r[61] ^ current_lfsr_r[60];
        assign current_lfsr[INPUT_WIDTH:2] = current_lfsr_r[INPUT_WIDTH-1:1]; 
    end else begin
        fake_error_thrower invalid_width_parameter();
    end endgenerate

   always @(posedge clk) begin
      if (rst) begin
         current_lfsr_r <= input_data;
      end else if(~hold) begin
         current_lfsr_r <= current_lfsr ^ input_data;
      end
   end

    // Sum reduce based on output width
    generate if(INPUT_WIDTH == 64 && OUTPUT_WIDTH == 16) begin
        assign crc_out =    current_lfsr_r[INPUT_WIDTH:INPUT_WIDTH/4*3+1]+current_lfsr_r[INPUT_WIDTH/4*3:INPUT_WIDTH/4*2+1]+
                            current_lfsr_r[INPUT_WIDTH/4*2:INPUT_WIDTH/4+1]+current_lfsr_r[INPUT_WIDTH/4:1];
    end else if(INPUT_WIDTH == 64 && OUTPUT_WIDTH == 32) begin
        assign crc_out =    current_lfsr_r[INPUT_WIDTH:INPUT_WIDTH/2+1]+current_lfsr_r[INPUT_WIDTH/2:1];
    end else begin
        fake_error_thrower invalid_width_parameter();
    end endgenerate
      
   

endmodule