書接上回:
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