AXI数据流计算CRC8的代码


module crc8_coder_8bit(
input 				clk,
input 				rst_n,
input 				din_last,
input				din_valid,
input		[7:0]	din_data,
output 	reg			dout_last,
output	reg			dout_valid,
output 	reg	[7:0]	dout_data
);

parameter [7:0]	POLY = 8'h07;

reg	[7:0]		crc_remainder;
reg	[2:0]		state;
reg	[2:0]		bit_cnt;

wire	[7:0]	CRC8[8:0];

wire	[7:0]	shift_in = (state==2)? 8'd0:din_data;

// assign	CRC8[0] = crc_remainder;
// assign	CRC8[1] = CRC8[0][7]? {CRC8[0][6:0],shift_in[7]}^POLY : {CRC8[0][6:0],shift_in[7]};
// assign	CRC8[2] = CRC8[1][7]? {CRC8[1][6:0],shift_in[6]}^POLY : {CRC8[1][6:0],shift_in[6]};
// assign	CRC8[3] = CRC8[2][7]? {CRC8[2][6:0],shift_in[5]}^POLY : {CRC8[2][6:0],shift_in[5]};
// assign	CRC8[4] = CRC8[3][7]? {CRC8[3][6:0],shift_in[4]}^POLY : {CRC8[3][6:0],shift_in[4]};
// assign	CRC8[5] = CRC8[4][7]? {CRC8[4][6:0],shift_in[3]}^POLY : {CRC8[4][6:0],shift_in[3]};
// assign	CRC8[6] = CRC8[5][7]? {CRC8[5][6:0],shift_in[2]}^POLY : {CRC8[5][6:0],shift_in[2]};
// assign	CRC8[7] = CRC8[6][7]? {CRC8[6][6:0],shift_in[1]}^POLY : {CRC8[6][6:0],shift_in[1]};
// assign	CRC8[8] = CRC8[7][7]? {CRC8[7][6:0],shift_in[0]}^POLY : {CRC8[7][6:0],shift_in[0]};

assign  CRC8[0]=crc_remainder;

assign	CRC8[1][0] = CRC8[0][7]^shift_in[7];
assign	CRC8[1][1] = CRC8[0][7]^CRC8[0][0];
assign	CRC8[1][2] = CRC8[0][7]^CRC8[0][1];
assign	CRC8[1][3] = CRC8[0][2];
assign	CRC8[1][4] = CRC8[0][3];
assign	CRC8[1][5] = CRC8[0][4];
assign	CRC8[1][6] = CRC8[0][5];
assign	CRC8[1][7] = CRC8[0][6];

assign	CRC8[2][0] = CRC8[1][7]^shift_in[6];
assign	CRC8[2][1] = CRC8[1][7]^CRC8[1][0];
assign	CRC8[2][2] = CRC8[1][7]^CRC8[1][1];
assign	CRC8[2][3] = CRC8[1][2];
assign	CRC8[2][4] = CRC8[1][3];
assign	CRC8[2][5] = CRC8[1][4];
assign	CRC8[2][6] = CRC8[1][5];
assign	CRC8[2][7] = CRC8[1][6];

assign	CRC8[3][0] = CRC8[2][7]^shift_in[5];
assign	CRC8[3][1] = CRC8[2][7]^CRC8[2][0];
assign	CRC8[3][2] = CRC8[2][7]^CRC8[2][1];
assign	CRC8[3][3] = CRC8[2][2];
assign	CRC8[3][4] = CRC8[2][3];
assign	CRC8[3][5] = CRC8[2][4];
assign	CRC8[3][6] = CRC8[2][5];
assign	CRC8[3][7] = CRC8[2][6];

assign	CRC8[4][0] = CRC8[3][7]^shift_in[4];
assign	CRC8[4][1] = CRC8[3][7]^CRC8[3][0];
assign	CRC8[4][2] = CRC8[3][7]^CRC8[3][1];
assign	CRC8[4][3] = CRC8[3][2];
assign	CRC8[4][4] = CRC8[3][3];
assign	CRC8[4][5] = CRC8[3][4];
assign	CRC8[4][6] = CRC8[3][5];
assign	CRC8[4][7] = CRC8[3][6];

assign	CRC8[5][0] = CRC8[4][7]^shift_in[3];
assign	CRC8[5][1] = CRC8[4][7]^CRC8[4][0];
assign	CRC8[5][2] = CRC8[4][7]^CRC8[4][1];
assign	CRC8[5][3] = CRC8[4][2];
assign	CRC8[5][4] = CRC8[4][3];
assign	CRC8[5][5] = CRC8[4][4];
assign	CRC8[5][6] = CRC8[4][5];
assign	CRC8[5][7] = CRC8[4][6];

assign	CRC8[6][0] = CRC8[5][7]^shift_in[2];
assign	CRC8[6][1] = CRC8[5][7]^CRC8[5][0];
assign	CRC8[6][2] = CRC8[5][7]^CRC8[5][1];
assign	CRC8[6][3] = CRC8[5][2];
assign	CRC8[6][4] = CRC8[5][3];
assign	CRC8[6][5] = CRC8[5][4];
assign	CRC8[6][6] = CRC8[5][5];
assign	CRC8[6][7] = CRC8[5][6];

assign	CRC8[7][0] = CRC8[6][7]^shift_in[1];
assign	CRC8[7][1] = CRC8[6][7]^CRC8[6][0];
assign	CRC8[7][2] = CRC8[6][7]^CRC8[6][1];
assign	CRC8[7][3] = CRC8[6][2];
assign	CRC8[7][4] = CRC8[6][3];
assign	CRC8[7][5] = CRC8[6][4];
assign	CRC8[7][6] = CRC8[6][5];
assign	CRC8[7][7] = CRC8[6][6];

assign	CRC8[8][0] = CRC8[7][7]^shift_in[0];
assign	CRC8[8][1] = CRC8[7][7]^CRC8[7][0];
assign	CRC8[8][2] = CRC8[7][7]^CRC8[7][1];
assign	CRC8[8][3] = CRC8[7][2];
assign	CRC8[8][4] = CRC8[7][3];
assign	CRC8[8][5] = CRC8[7][4];
assign	CRC8[8][6] = CRC8[7][5];
assign	CRC8[8][7] = CRC8[7][6];

reg	din_last_r;
always @ (posedge clk)
	din_last_r<=din_last;

always @ (posedge clk or negedge rst_n)
begin
	if(~rst_n) begin
		crc_remainder<=0;
		state<=0;
		dout_last<=1;
		dout_data<=0;
		dout_valid<=0;
		bit_cnt<=0;
	end
	else begin
		case(state)
		//开始运算
		0:begin
			if({din_last_r,din_last}==2'b10) begin
				dout_last<=0;
				dout_data<=din_data;
				dout_valid<=din_valid;
				state<=1;
				crc_remainder<=din_valid? din_data : 8'd0;
			end
		end
		//运算过程
		1:begin
			dout_data<=din_data;
			dout_valid<=din_valid;
			if(din_valid) crc_remainder<=CRC8[8];
			if(din_last) begin
				bit_cnt<=0;
				state<=2;
			end
		end
		//尾部补8个0继续运算,算出余数
		2:begin
			dout_valid<=0;
			crc_remainder<=CRC8[8];
			if(bit_cnt<0)
				bit_cnt<=bit_cnt+8;
			else
				state<=3;
		end
		//输出余数
		3:begin
			dout_data<=crc_remainder>>bit_cnt;
			dout_valid<=1;
			bit_cnt<=bit_cnt-8;
			if(bit_cnt==0) begin
				dout_last<=1;
				state<=4;
			end
		end
		4:begin
			dout_valid<=0;
			state<=0;
		end
		default:state<=0;
		endcase
	end
end

endmodule

你可能感兴趣的:(fpga开发)