/* * fcs.v * * Copyright (C) 2018, 2019 Mind Chasers Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * function: FCS checksum * * */ `timescale 1ns /10ps //////////////////////////////////////////////////////////////////////////////// // 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: x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x^1 + 1 // * data width: 8 // // Info : tools@easics.be // http://www.easics.com //////////////////////////////////////////////////////////////////////////////// /* * a) The first 32 bits of the frame are complemented. * b) The n bits of the MAC frame considered to be the coefficients of a polynomial M(x) of degree n � 1. * The first bit of the Destination Address field corresponds to the x(n�1) term * and the last bit of the MAC Client Data field (or Pad field if present) corresponds to the x0 term. * c) M(x) is multiplied by x**32 and divided by G(x), producing a remainder R(x) of degree = 31. * d) The coefficients of R(x) are considered to be a 32-bit sequence. * e) The bit sequence is complemented and the result is the CRC. * f) FCS should be trnansmitted msbit first ( opposite of the rest of MAC frame ) */ module fcs( input rstn, input clk, // control interface input init, input enable, // addr & data input [1:0] addr, input [0:7] din, output [7:0] dout ); reg [31:0] crc; reg [7:0] d; assign dout = ~{ d[0],d[1],d[2],d[3],d[4],d[5],d[6],d[7] }; always @(*) begin case(addr) 2'b00: d <= crc[31:24]; 2'b01: d <= crc[23:16]; 2'b10: d <= crc[15:8]; 2'b11: d <= crc[7:0]; endcase end always @(posedge clk or negedge rstn) if(!rstn) crc <= 32'hffffffff; else if (init) crc <= 32'hffffffff; else if (enable) crc <= nextCRC32_D8(din,crc); // {d[0],d[1],d[2],d[3],d[4],d[5],d[6],d[7]} // polynomial: x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x^1 + 1 // data width: 8 // convention: the first serial bit is D[7] function [31:0] nextCRC32_D8; input [0:7] Data; input [31:0] crc; reg [0:7] d; reg [31:0] c; reg [31:0] newcrc; begin d = Data; c = crc; newcrc[0] = d[6] ^ d[0] ^ c[24] ^ c[30]; newcrc[1] = d[7] ^ d[6] ^ d[1] ^ d[0] ^ c[24] ^ c[25] ^ c[30] ^ c[31]; newcrc[2] = d[7] ^ d[6] ^ d[2] ^ d[1] ^ d[0] ^ c[24] ^ c[25] ^ c[26] ^ c[30] ^ c[31]; newcrc[3] = d[7] ^ d[3] ^ d[2] ^ d[1] ^ c[25] ^ c[26] ^ c[27] ^ c[31]; newcrc[4] = d[6] ^ d[4] ^ d[3] ^ d[2] ^ d[0] ^ c[24] ^ c[26] ^ c[27] ^ c[28] ^ c[30]; newcrc[5] = d[7] ^ d[6] ^ d[5] ^ d[4] ^ d[3] ^ d[1] ^ d[0] ^ c[24] ^ c[25] ^ c[27] ^ c[28] ^ c[29] ^ c[30] ^ c[31]; newcrc[6] = d[7] ^ d[6] ^ d[5] ^ d[4] ^ d[2] ^ d[1] ^ c[25] ^ c[26] ^ c[28] ^ c[29] ^ c[30] ^ c[31]; newcrc[7] = d[7] ^ d[5] ^ d[3] ^ d[2] ^ d[0] ^ c[24] ^ c[26] ^ c[27] ^ c[29] ^ c[31]; newcrc[8] = d[4] ^ d[3] ^ d[1] ^ d[0] ^ c[0] ^ c[24] ^ c[25] ^ c[27] ^ c[28]; newcrc[9] = d[5] ^ d[4] ^ d[2] ^ d[1] ^ c[1] ^ c[25] ^ c[26] ^ c[28] ^ c[29]; newcrc[10] = d[5] ^ d[3] ^ d[2] ^ d[0] ^ c[2] ^ c[24] ^ c[26] ^ c[27] ^ c[29]; newcrc[11] = d[4] ^ d[3] ^ d[1] ^ d[0] ^ c[3] ^ c[24] ^ c[25] ^ c[27] ^ c[28]; newcrc[12] = d[6] ^ d[5] ^ d[4] ^ d[2] ^ d[1] ^ d[0] ^ c[4] ^ c[24] ^ c[25] ^ c[26] ^ c[28] ^ c[29] ^ c[30]; newcrc[13] = d[7] ^ d[6] ^ d[5] ^ d[3] ^ d[2] ^ d[1] ^ c[5] ^ c[25] ^ c[26] ^ c[27] ^ c[29] ^ c[30] ^ c[31]; newcrc[14] = d[7] ^ d[6] ^ d[4] ^ d[3] ^ d[2] ^ c[6] ^ c[26] ^ c[27] ^ c[28] ^ c[30] ^ c[31]; newcrc[15] = d[7] ^ d[5] ^ d[4] ^ d[3] ^ c[7] ^ c[27] ^ c[28] ^ c[29] ^ c[31]; newcrc[16] = d[5] ^ d[4] ^ d[0] ^ c[8] ^ c[24] ^ c[28] ^ c[29]; newcrc[17] = d[6] ^ d[5] ^ d[1] ^ c[9] ^ c[25] ^ c[29] ^ c[30]; newcrc[18] = d[7] ^ d[6] ^ d[2] ^ c[10] ^ c[26] ^ c[30] ^ c[31]; newcrc[19] = d[7] ^ d[3] ^ c[11] ^ c[27] ^ c[31]; newcrc[20] = d[4] ^ c[12] ^ c[28]; newcrc[21] = d[5] ^ c[13] ^ c[29]; newcrc[22] = d[0] ^ c[14] ^ c[24]; newcrc[23] = d[6] ^ d[1] ^ d[0] ^ c[15] ^ c[24] ^ c[25] ^ c[30]; newcrc[24] = d[7] ^ d[2] ^ d[1] ^ c[16] ^ c[25] ^ c[26] ^ c[31]; newcrc[25] = d[3] ^ d[2] ^ c[17] ^ c[26] ^ c[27]; newcrc[26] = d[6] ^ d[4] ^ d[3] ^ d[0] ^ c[18] ^ c[24] ^ c[27] ^ c[28] ^ c[30]; newcrc[27] = d[7] ^ d[5] ^ d[4] ^ d[1] ^ c[19] ^ c[25] ^ c[28] ^ c[29] ^ c[31]; newcrc[28] = d[6] ^ d[5] ^ d[2] ^ c[20] ^ c[26] ^ c[29] ^ c[30]; newcrc[29] = d[7] ^ d[6] ^ d[3] ^ c[21] ^ c[27] ^ c[30] ^ c[31]; newcrc[30] = d[7] ^ d[4] ^ c[22] ^ c[28] ^ c[31]; newcrc[31] = d[5] ^ c[23] ^ c[29]; nextCRC32_D8 = newcrc; end endfunction endmodule