// CRC-32 
module CRC32_mod( data_in, clk, data_out, reset);
output data_out;
input data_in, clk, reset;

// Shift Register and modulo 2 outputs declaration
reg [ 31 : 0 ] crc_reg;
reg [ 13 : 0 ] mod_out;
reg data_out;

// Block Internal Wiring Declaration

always @ (posedge clk)
if (!reset)
begin
   crc_reg = 32'b0; // "out" is  supposed to be the serial output
   mod_out = 14'b0;
end
else
begin
  // take care of that "=" is different from "<=" where the first one
  // indicate a blocking behaviour which is used for combinational logic
  // and the second indicates non-blocking behaviour which is used for 
  // sequential circuits
mod_out[13]     = data_in ^ crc_reg[31];
crc_reg[31:27] <= crc_reg[30:26];
crc_reg[26]    <= mod_out[12];
mod_out[12]     = mod_out[13] ^ crc_reg[25];
crc_reg[25]    <= crc_reg[24];
crc_reg[24]    <= crc_reg[23];
crc_reg[23]    <= mod_out[11];
mod_out[11]     = mod_out[13] ^ crc_reg[22];
crc_reg[22]    <= mod_out[10];
mod_out[10]     = mod_out[13] ^ crc_reg[21];
crc_reg[21:17] <= crc_reg[20:16];
crc_reg[16]    <= mod_out[9];
mod_out[9]      = mod_out[13] ^ crc_reg[15];
crc_reg[15:13] <= crc_reg[14:12];
crc_reg[12]    <= mod_out[8];
mod_out[8]      = mod_out[13] ^ crc_reg[11];
crc_reg[11]    <= mod_out[7];
mod_out[7]      = mod_out[13] ^ crc_reg[10];
crc_reg[10]    <= mod_out[6];
mod_out[6]      = mod_out[13] ^ crc_reg[9];
crc_reg[9]     <= crc_reg[8];
crc_reg[8]     <= mod_out[5];
mod_out[5]      = mod_out[13] ^ crc_reg[7];
crc_reg[7]     <= mod_out[4];
mod_out[4]      = mod_out[13] ^ crc_reg[6];
crc_reg[6]     <= crc_reg[5];
crc_reg[5]     <= mod_out[3];
mod_out[3]      = mod_out[13] ^ crc_reg[4];
crc_reg[4]     <= mod_out[2];
mod_out[2]      = mod_out[13] ^ crc_reg[3];
crc_reg[3]     <= crc_reg[2];
crc_reg[2]     <= mod_out[1];
mod_out[1]      = mod_out[13] ^ crc_reg[1];
crc_reg[1]     <= mod_out[0];
mod_out[0]      = mod_out[13] ^ crc_reg[0];
end
endmodule