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
|