module usb3_crc_hp(

input	wire	[31:0] 	di,
input	wire			crc_en,
output	wire	[15:0] 	crc_out,
input	wire			rst,
input	wire			clk

);

reg [15:0]	q;
wire [15:0]	c;
wire [31:0] d = {	di[0 ],di[1 ],di[2 ],di[3 ],di[4 ],di[5 ],di[6 ],di[7],
					di[8 ],di[9 ],di[10],di[11],di[12],di[13],di[14],di[15],
					di[16],di[17],di[18],di[19],di[20],di[21],di[22],di[23],
					di[24],di[25],di[26],di[27],di[28],di[29],di[30],di[31]};
assign crc_out = ~{	q[0], q[1], q[2], q[3], q[4], q[5], q[6], q[7], 
					q[8], q[9], q[10],q[11],q[12],q[13],q[14],q[15]};

assign	c[0] = q[4] ^ q[5] ^ q[7] ^ q[10] ^ q[12] ^ q[13] ^ q[15] ^ d[0] ^ d[4] ^ d[8] ^ d[12] ^ d[13] ^ d[15] ^ d[20] ^ d[21] ^ d[23] ^ d[26] ^ d[28] ^ d[29] ^ d[31];
assign	c[1] = q[0] ^ q[4] ^ q[6] ^ q[7] ^ q[8] ^ q[10] ^ q[11] ^ q[12] ^ q[14] ^ q[15] ^ d[0] ^ d[1] ^ d[4] ^ d[5] ^ d[8] ^ d[9] ^ d[12] ^ d[14] ^ d[15] ^ d[16] ^ d[20] ^ d[22] ^ d[23] ^ d[24] ^ d[26] ^ d[27] ^ d[28] ^ d[30] ^ d[31];
assign	c[2] = q[0] ^ q[1] ^ q[5] ^ q[7] ^ q[8] ^ q[9] ^ q[11] ^ q[12] ^ q[13] ^ q[15] ^ d[1] ^ d[2] ^ d[5] ^ d[6] ^ d[9] ^ d[10] ^ d[13] ^ d[15] ^ d[16] ^ d[17] ^ d[21] ^ d[23] ^ d[24] ^ d[25] ^ d[27] ^ d[28] ^ d[29] ^ d[31];
assign	c[3] = q[0] ^ q[1] ^ q[2] ^ q[4] ^ q[5] ^ q[6] ^ q[7] ^ q[8] ^ q[9] ^ q[14] ^ q[15] ^ d[0] ^ d[2] ^ d[3] ^ d[4] ^ d[6] ^ d[7] ^ d[8] ^ d[10] ^ d[11] ^ d[12] ^ d[13] ^ d[14] ^ d[15] ^ d[16] ^ d[17] ^ d[18] ^ d[20] ^ d[21] ^ d[22] ^ d[23] ^ d[24] ^ d[25] ^ d[30] ^ d[31];
assign	c[4] = q[0] ^ q[1] ^ q[2] ^ q[3] ^ q[5] ^ q[6] ^ q[7] ^ q[8] ^ q[9] ^ q[10] ^ q[15] ^ d[1] ^ d[3] ^ d[4] ^ d[5] ^ d[7] ^ d[8] ^ d[9] ^ d[11] ^ d[12] ^ d[13] ^ d[14] ^ d[15] ^ d[16] ^ d[17] ^ d[18] ^ d[19] ^ d[21] ^ d[22] ^ d[23] ^ d[24] ^ d[25] ^ d[26] ^ d[31];
assign	c[5] = q[0] ^ q[1] ^ q[2] ^ q[3] ^ q[4] ^ q[6] ^ q[7] ^ q[8] ^ q[9] ^ q[10] ^ q[11] ^ d[2] ^ d[4] ^ d[5] ^ d[6] ^ d[8] ^ d[9] ^ d[10] ^ d[12] ^ d[13] ^ d[14] ^ d[15] ^ d[16] ^ d[17] ^ d[18] ^ d[19] ^ d[20] ^ d[22] ^ d[23] ^ d[24] ^ d[25] ^ d[26] ^ d[27];
assign	c[6] = q[0] ^ q[1] ^ q[2] ^ q[3] ^ q[4] ^ q[5] ^ q[7] ^ q[8] ^ q[9] ^ q[10] ^ q[11] ^ q[12] ^ d[3] ^ d[5] ^ d[6] ^ d[7] ^ d[9] ^ d[10] ^ d[11] ^ d[13] ^ d[14] ^ d[15] ^ d[16] ^ d[17] ^ d[18] ^ d[19] ^ d[20] ^ d[21] ^ d[23] ^ d[24] ^ d[25] ^ d[26] ^ d[27] ^ d[28];
assign	c[7] = q[0] ^ q[1] ^ q[2] ^ q[3] ^ q[4] ^ q[5] ^ q[6] ^ q[8] ^ q[9] ^ q[10] ^ q[11] ^ q[12] ^ q[13] ^ d[4] ^ d[6] ^ d[7] ^ d[8] ^ d[10] ^ d[11] ^ d[12] ^ d[14] ^ d[15] ^ d[16] ^ d[17] ^ d[18] ^ d[19] ^ d[20] ^ d[21] ^ d[22] ^ d[24] ^ d[25] ^ d[26] ^ d[27] ^ d[28] ^ d[29];
assign	c[8] = q[0] ^ q[1] ^ q[2] ^ q[3] ^ q[4] ^ q[5] ^ q[6] ^ q[7] ^ q[9] ^ q[10] ^ q[11] ^ q[12] ^ q[13] ^ q[14] ^ d[5] ^ d[7] ^ d[8] ^ d[9] ^ d[11] ^ d[12] ^ d[13] ^ d[15] ^ d[16] ^ d[17] ^ d[18] ^ d[19] ^ d[20] ^ d[21] ^ d[22] ^ d[23] ^ d[25] ^ d[26] ^ d[27] ^ d[28] ^ d[29] ^ d[30];
assign	c[9] = q[0] ^ q[1] ^ q[2] ^ q[3] ^ q[4] ^ q[5] ^ q[6] ^ q[7] ^ q[8] ^ q[10] ^ q[11] ^ q[12] ^ q[13] ^ q[14] ^ q[15] ^ d[6] ^ d[8] ^ d[9] ^ d[10] ^ d[12] ^ d[13] ^ d[14] ^ d[16] ^ d[17] ^ d[18] ^ d[19] ^ d[20] ^ d[21] ^ d[22] ^ d[23] ^ d[24] ^ d[26] ^ d[27] ^ d[28] ^ d[29] ^ d[30] ^ d[31];
assign	c[10] = q[1] ^ q[2] ^ q[3] ^ q[4] ^ q[5] ^ q[6] ^ q[7] ^ q[8] ^ q[9] ^ q[11] ^ q[12] ^ q[13] ^ q[14] ^ q[15] ^ d[7] ^ d[9] ^ d[10] ^ d[11] ^ d[13] ^ d[14] ^ d[15] ^ d[17] ^ d[18] ^ d[19] ^ d[20] ^ d[21] ^ d[22] ^ d[23] ^ d[24] ^ d[25] ^ d[27] ^ d[28] ^ d[29] ^ d[30] ^ d[31]; 
assign  c[11] = q[0] ^ q[2] ^ q[3] ^ q[4] ^ q[5] ^ q[6] ^ q[7] ^ q[8] ^ q[9] ^ q[10] ^ q[12] ^ q[13] ^ q[14] ^ q[15] ^ d[8] ^ d[10] ^ d[11] ^ d[12] ^ d[14] ^ d[15] ^ d[16] ^ d[18] ^ d[19] ^ d[20] ^ d[21] ^ d[22] ^ d[23] ^ d[24] ^ d[25] ^ d[26] ^ d[28] ^ d[29] ^ d[30] ^ d[31];
assign	c[12] = q[0] ^ q[1] ^ q[3] ^ q[6] ^ q[8] ^ q[9] ^ q[11] ^ q[12] ^ q[14] ^ d[0] ^ d[4] ^ d[8] ^ d[9] ^ d[11] ^ d[16] ^ d[17] ^ d[19] ^ d[22] ^ d[24] ^ d[25] ^ d[27] ^ d[28] ^ d[30];
assign	c[13] = q[1] ^ q[2] ^ q[4] ^ q[7] ^ q[9] ^ q[10] ^ q[12] ^ q[13] ^ q[15] ^ d[1] ^ d[5] ^ d[9] ^ d[10] ^ d[12] ^ d[17] ^ d[18] ^ d[20] ^ d[23] ^ d[25] ^ d[26] ^ d[28] ^ d[29] ^ d[31];
assign	c[14] = q[2] ^ q[3] ^ q[5] ^ q[8] ^ q[10] ^ q[11] ^ q[13] ^ q[14] ^ d[2] ^ d[6] ^ d[10] ^ d[11] ^ d[13] ^ d[18] ^ d[19] ^ d[21] ^ d[24] ^ d[26] ^ d[27] ^ d[29] ^ d[30];
assign	c[15] = q[3] ^ q[4] ^ q[6] ^ q[9] ^ q[11] ^ q[12] ^ q[14] ^ q[15] ^ d[3] ^ d[7] ^ d[11] ^ d[12] ^ d[14] ^ d[19] ^ d[20] ^ d[22] ^ d[25] ^ d[27] ^ d[28] ^ d[30] ^ d[31];

always @(posedge clk, posedge rst) begin
	if(rst) begin
		q <= {16{1'b1}};
	end
	else begin
		q <= crc_en ? c : q;
	end
end

endmodule