【CRC校验方法】+【FPGA实现(发送端)】
书接上回:
https://www.cnblogs.com/VerweileDoch/p/18105959
发送端的逻辑和接收端类似,但是需要进行八位内的逆运算和取反:
always @(posedge sys_clk) begin if(sys_rst_n == 1'b0) begin r1_crc_value <= 32'h0; end else if(crc_cycle == 1'b1 && crc_cnt == 'd3) begin r1_crc_value <= 32'h0; end else if(i_vaild == 1'b0 && r1_i_vaild == 1'b1) begin r1_crc_value <= crc_value; end end reg [7:0] inver_i; always @(*) begin for (inver_i = 0;inver_i < 8;inver_i = inver_i + 1'b1 ) begin r2_crc_value[31 - inver_i] <= r1_crc_value[24 + inver_i]; r2_crc_value[23 - inver_i] <= r1_crc_value[16 + inver_i]; r2_crc_value[15 - inver_i] <= r1_crc_value[08 + inver_i]; r2_crc_value[07 - inver_i] <= r1_crc_value[0 + inver_i]; end end always @(posedge sys_clk) begin if(sys_rst_n == 1'b0) begin r_o_data <= 8'hff; end else if(r1_i_vaild == 1'b1 && crc_cycle == 1'b0) begin r_o_data <= r1_i_data; end else if(crc_cycle == 1'b1) begin r_o_data <= ~(r2_crc_value[(31-(crc_cnt << 3))-:8]); end else begin r_o_data <= 8'hff; end end
完整代码:
module CRC_buffer #( parameter UDP_CODE = 8'h11 , parameter TX_TARGET_PORT = 16'd808 , parameter TX_SOURCE_PORT = 16'd8080 , parameter RX_Sync_Frame = 32'hF05AA50F , parameter TX_SOURCE_Addr = {8'd192,8'd168,8'd0,8'd1} , parameter TX_TARGET_Addr = {8'hFF,8'hFF,8'hFF,8'hFF} , //Length parameter TX_PREAMBLE = {8'h55,8'h55,8'h55,8'h55,8'h55,8'h55,8'h55,8'hD5}, parameter TX_TARGET_MAC = {8'hFF,8'hFF,8'hFF,8'hFF,8'hFF,8'hFF} ,// broadcast packet parameter TX_SOURECE_MAC = {8'hA8,8'hB2,8'h3C,8'h7D,8'h97,8'hD7} , parameter Length_HeartBeat = 16'd92 , parameter Length_UDP = 16'd72 , parameter Length_HeartBeat_all = 8'd114 , parameter Length_EnCODE_Packet = 8'd114 )( input wire sys_clk , input wire sys_rst_n , input wire i_vaild , input wire [7:0] i_data , output wire o_vaild , output wire [7:0] o_data ); wire [31:00] crc_value ; reg [31:00] r1_crc_value ; reg [31:00] r2_crc_value ; reg r1_i_vaild ; reg r2_i_vaild ; reg [7:0] r1_i_data ; reg [15:00] i_vaild_cnt ; reg crc_cycle ; reg r_crc_cycle ; reg [03:00] crc_cnt ; reg [07:00] r_o_data ; always @(posedge sys_clk) begin if(sys_rst_n == 1'b0) begin i_vaild_cnt <= 16'd0; end else if(i_vaild == 1'b1) begin if(i_vaild_cnt == Length_EnCODE_Packet - 1'b1) begin i_vaild_cnt <= 16'd0; end else begin i_vaild_cnt <= i_vaild_cnt + 1'b1; end end end always @(posedge sys_clk) begin r1_i_vaild <= i_vaild; r2_i_vaild <= r1_i_vaild; r1_i_data <= i_data ; r_crc_cycle <= crc_cycle; end always @(posedge sys_clk) begin if(sys_rst_n == 1'b0) begin r1_crc_value <= 32'h0; end else if(crc_cycle == 1'b1 && crc_cnt == 'd3) begin r1_crc_value <= 32'h0; end else if(i_vaild == 1'b0 && r1_i_vaild == 1'b1) begin r1_crc_value <= crc_value; end end reg [7:0] inver_i; always @(*) begin for (inver_i = 0;inver_i < 8;inver_i = inver_i + 1'b1 ) begin r2_crc_value[31 - inver_i] <= r1_crc_value[24 + inver_i]; r2_crc_value[23 - inver_i] <= r1_crc_value[16 + inver_i]; r2_crc_value[15 - inver_i] <= r1_crc_value[08 + inver_i]; r2_crc_value[07 - inver_i] <= r1_crc_value[0 + inver_i]; end end always @(posedge sys_clk) begin if(sys_rst_n == 1'b0) begin crc_cycle <= 1'b0; end else if(crc_cycle == 1'b1 && crc_cnt == 'd3) begin crc_cycle <= 1'b0; end else if(i_vaild == 1'b0 && r1_i_vaild == 1'b1) begin crc_cycle <= 1'b1; end else begin crc_cycle <= crc_cycle; end end always @(posedge sys_clk) begin if(sys_rst_n == 1'b0) begin crc_cnt <= 4'h0; end else if(crc_cycle == 1'b1) begin if(crc_cnt== 'd3) begin crc_cnt <= 4'h0; end else begin crc_cnt <= crc_cnt + 1'b1; end end else begin crc_cnt <= 4'h0; end end always @(posedge sys_clk) begin if(sys_rst_n == 1'b0) begin r_o_data <= 8'hff; end else if(r1_i_vaild == 1'b1 && crc_cycle == 1'b0) begin r_o_data <= r1_i_data; end else if(crc_cycle == 1'b1) begin r_o_data <= ~(r2_crc_value[(31-(crc_cnt << 3))-:8]); end else begin r_o_data <= 8'hff; end end assign o_vaild = (r2_i_vaild)||(r_crc_cycle); assign o_data = r_o_data; CRC32_D8_Out CRC32_D8_Out_inst0 ( .i_clk ( sys_clk ), .i_rst_n ( sys_rst_n ), .i_data ( i_data ), .i_vaild ( i_vaild ), .o_crc_error ( ), .o_crc_end ( ), .o_crc_value ( crc_value ) ); reg [07:00] test_cnt; always @(posedge sys_clk) begin if(sys_rst_n == 1'b0) begin test_cnt <= 8'd0; end else if(o_vaild == 1'b1) begin test_cnt <= test_cnt + 1'b1; end else begin test_cnt <= 8'd0; end end endmodule
module CRC32_D8_Out ( input wire i_clk , input wire i_rst_n , input wire [7:0] i_data , input wire i_vaild , output wire o_crc_error , output wire o_crc_end , output wire [31:0] o_crc_value ); reg r_i_vaild ; reg [7:0] r_i_data ; reg [31:0] crc_r ; reg [31:0] crc_lfsr ; reg r_crc32_error ; reg [15:0] vaild_cnt ; reg filter_vaild ; wire crc_end ; reg r_crc_end ; /////////////////////////////////////////////////////////////////////////// assign crc_end = (i_vaild == 1'b0 && r_i_vaild == 1'b1); assign o_crc_error = r_crc32_error; assign o_crc_end = r_crc_end ; assign o_crc_value = crc_r ; always @(posedge i_clk) begin if (i_rst_n==0) begin vaild_cnt <= 'd0; end else if(i_vaild == 1'b0 && r_i_vaild == 1'b1) begin vaild_cnt <= 'd0; end else if(i_vaild == 1'b1) begin vaild_cnt <= vaild_cnt + 1'b1; end else begin vaild_cnt <= vaild_cnt; end end always @(*) begin if(vaild_cnt >= 4'd8 && i_vaild == 1'b1) begin filter_vaild <= 1'b1; end else begin filter_vaild <= 1'b0; end end always @(posedge i_clk) begin r_i_vaild <= i_vaild; r_crc_end <= crc_end; end always@(posedge i_clk) begin if (i_rst_n==0) begin r_crc32_error <= 1'b0; end else if (i_vaild == 1'b0 && r_i_vaild == 1'b1) begin if (crc_r==32'hc704dd7b) begin r_crc32_error <= 1'b0; end else begin r_crc32_error <= 1'b1; end end else begin r_crc32_error <= 1'b0; end end always @(posedge i_clk) begin if(i_rst_n == 1'b0) begin crc_r <= 32'hffff_ffff; end else if(filter_vaild == 1'b1) begin crc_r <= crc_lfsr; end else if(i_vaild == 1'b0 && r_i_vaild == 1'b1)begin crc_r <= 32'hffff_ffff; end else begin crc_r <= crc_r; end end reg [3:0] data_inver_i; always @(*) begin for(data_inver_i = 0;data_inver_i < 8;data_inver_i = data_inver_i + 1) begin r_i_data[data_inver_i] <= i_data[7-data_inver_i]; end end always @(*) begin crc_lfsr[0] = crc_r[24] ^ crc_r[30] ^ r_i_data[0] ^ r_i_data[6]; crc_lfsr[1] = crc_r[24] ^ crc_r[25] ^ crc_r[30] ^ crc_r[31] ^ r_i_data[0] ^ r_i_data[1] ^ r_i_data[6] ^ r_i_data[7]; crc_lfsr[2] = crc_r[24] ^ crc_r[25] ^ crc_r[26] ^ crc_r[30] ^ crc_r[31] ^ r_i_data[0] ^ r_i_data[1] ^ r_i_data[2] ^ r_i_data[6] ^ r_i_data[7]; crc_lfsr[3] = crc_r[25] ^ crc_r[26] ^ crc_r[27] ^ crc_r[31] ^ r_i_data[1] ^ r_i_data[2] ^ r_i_data[3] ^ r_i_data[7]; crc_lfsr[4] = crc_r[24] ^ crc_r[26] ^ crc_r[27] ^ crc_r[28] ^ crc_r[30] ^ r_i_data[0] ^ r_i_data[2] ^ r_i_data[3] ^ r_i_data[4] ^ r_i_data[6]; crc_lfsr[5] = crc_r[24] ^ crc_r[25] ^ crc_r[27] ^ crc_r[28] ^ crc_r[29] ^ crc_r[30] ^ crc_r[31] ^ r_i_data[0] ^ r_i_data[1] ^ r_i_data[3] ^ r_i_data[4] ^ r_i_data[5] ^ r_i_data[6] ^ r_i_data[7]; crc_lfsr[6] = crc_r[25] ^ crc_r[26] ^ crc_r[28] ^ crc_r[29] ^ crc_r[30] ^ crc_r[31] ^ r_i_data[1] ^ r_i_data[2] ^ r_i_data[4] ^ r_i_data[5] ^ r_i_data[6] ^ r_i_data[7]; crc_lfsr[7] = crc_r[24] ^ crc_r[26] ^ crc_r[27] ^ crc_r[29] ^ crc_r[31] ^ r_i_data[0] ^ r_i_data[2] ^ r_i_data[3] ^ r_i_data[5] ^ r_i_data[7]; crc_lfsr[8] = crc_r[0] ^ crc_r[24] ^ crc_r[25] ^ crc_r[27] ^ crc_r[28] ^ r_i_data[0] ^ r_i_data[1] ^ r_i_data[3] ^ r_i_data[4]; crc_lfsr[9] = crc_r[1] ^ crc_r[25] ^ crc_r[26] ^ crc_r[28] ^ crc_r[29] ^ r_i_data[1] ^ r_i_data[2] ^ r_i_data[4] ^ r_i_data[5]; crc_lfsr[10] = crc_r[2] ^ crc_r[24] ^ crc_r[26] ^ crc_r[27] ^ crc_r[29] ^ r_i_data[0] ^ r_i_data[2] ^ r_i_data[3] ^ r_i_data[5]; crc_lfsr[11] = crc_r[3] ^ crc_r[24] ^ crc_r[25] ^ crc_r[27] ^ crc_r[28] ^ r_i_data[0] ^ r_i_data[1] ^ r_i_data[3] ^ r_i_data[4]; crc_lfsr[12] = crc_r[4] ^ crc_r[24] ^ crc_r[25] ^ crc_r[26] ^ crc_r[28] ^ crc_r[29] ^ crc_r[30] ^ r_i_data[0] ^ r_i_data[1] ^ r_i_data[2] ^ r_i_data[4] ^ r_i_data[5] ^ r_i_data[6]; crc_lfsr[13] = crc_r[5] ^ crc_r[25] ^ crc_r[26] ^ crc_r[27] ^ crc_r[29] ^ crc_r[30] ^ crc_r[31] ^ r_i_data[1] ^ r_i_data[2] ^ r_i_data[3] ^ r_i_data[5] ^ r_i_data[6] ^ r_i_data[7]; crc_lfsr[14] = crc_r[6] ^ crc_r[26] ^ crc_r[27] ^ crc_r[28] ^ crc_r[30] ^ crc_r[31] ^ r_i_data[2] ^ r_i_data[3] ^ r_i_data[4] ^ r_i_data[6] ^ r_i_data[7]; crc_lfsr[15] = crc_r[7] ^ crc_r[27] ^ crc_r[28] ^ crc_r[29] ^ crc_r[31] ^ r_i_data[3] ^ r_i_data[4] ^ r_i_data[5] ^ r_i_data[7]; crc_lfsr[16] = crc_r[8] ^ crc_r[24] ^ crc_r[28] ^ crc_r[29] ^ r_i_data[0] ^ r_i_data[4] ^ r_i_data[5]; crc_lfsr[17] = crc_r[9] ^ crc_r[25] ^ crc_r[29] ^ crc_r[30] ^ r_i_data[1] ^ r_i_data[5] ^ r_i_data[6]; crc_lfsr[18] = crc_r[10] ^ crc_r[26] ^ crc_r[30] ^ crc_r[31] ^ r_i_data[2] ^ r_i_data[6] ^ r_i_data[7]; crc_lfsr[19] = crc_r[11] ^ crc_r[27] ^ crc_r[31] ^ r_i_data[3] ^ r_i_data[7]; crc_lfsr[20] = crc_r[12] ^ crc_r[28] ^ r_i_data[4]; crc_lfsr[21] = crc_r[13] ^ crc_r[29] ^ r_i_data[5]; crc_lfsr[22] = crc_r[14] ^ crc_r[24] ^ r_i_data[0]; crc_lfsr[23] = crc_r[15] ^ crc_r[24] ^ crc_r[25] ^ crc_r[30] ^ r_i_data[0] ^ r_i_data[1] ^ r_i_data[6]; crc_lfsr[24] = crc_r[16] ^ crc_r[25] ^ crc_r[26] ^ crc_r[31] ^ r_i_data[1] ^ r_i_data[2] ^ r_i_data[7]; crc_lfsr[25] = crc_r[17] ^ crc_r[26] ^ crc_r[27] ^ r_i_data[2] ^ r_i_data[3]; crc_lfsr[26] = crc_r[18] ^ crc_r[24] ^ crc_r[27] ^ crc_r[28] ^ crc_r[30] ^ r_i_data[0] ^ r_i_data[3] ^ r_i_data[4] ^ r_i_data[6]; crc_lfsr[27] = crc_r[19] ^ crc_r[25] ^ crc_r[28] ^ crc_r[29] ^ crc_r[31] ^ r_i_data[1] ^ r_i_data[4] ^ r_i_data[5] ^ r_i_data[7]; crc_lfsr[28] = crc_r[20] ^ crc_r[26] ^ crc_r[29] ^ crc_r[30] ^ r_i_data[2] ^ r_i_data[5] ^ r_i_data[6]; crc_lfsr[29] = crc_r[21] ^ crc_r[27] ^ crc_r[30] ^ crc_r[31] ^ r_i_data[3] ^ r_i_data[6] ^ r_i_data[7]; crc_lfsr[30] = crc_r[22] ^ crc_r[28] ^ crc_r[31] ^ r_i_data[4] ^ r_i_data[7]; crc_lfsr[31] = crc_r[23] ^ crc_r[29] ^ r_i_data[5]; end // always /////////////////////////////////////////////////////////////////////////// endmodule

浙公网安备 33010602011771号