以太网MAC层处理CRC的两种方法
1.资源消耗少,但是处理慢的方法;
输入数据存入FIFO1,校验数据存入FIFO2,存FIFO的过程中校验并将数据存入FIFO2,存完1以后读出FIFO2的数据并且判断,如果正确则输出数据流,错误则不输出;
这种方法只需要两个FIFO,但是面临一个问题是:FIFO的数据只能读出,直接清空时序很难控制,也不利于数据流处理;
可参考代码:
MAC接收:
module mac_rx #( parameter Protocol_UDP = 8'h11 , parameter Protocol_ICMP = 8'h01 , parameter UDP_MAC_CODE = {8'h08,8'h00} , parameter ARP_MAC_CODE = {8'h08,8'h06} , parameter Packet_IP = {8'h08,8'h00} , parameter Packet_ARP = {8'h08,8'h06} , parameter default_rx_target_mac = {8'h00,8'h00,8'h00,8'h00,8'h00,8'h00}, parameter default_rx_source_mac = {8'h00,8'h00,8'h00,8'h00,8'h00,8'h00}, parameter RX_SOURCE_PORT = 16'd0808 , parameter RX_TARGET_PORT = 16'd8080 , parameter RX_Sync_Frame = {8'hF0,8'h5A,8'hA5,8'h0F} )( input wire sys_rst_n , input wire eth_rx_clk , /*--------GMII port--------*/ input wire eth_rx_vaild , input wire [7:0] eth_rx_data , //ARP module input wire i_target_mac_vaild , input wire [47:0] i_target_mac , input wire i_source_mac_vaild , input wire [47:0] i_source_mac , //arp output wire rx_arp_vaild , output wire [7:0] rx_arp_data , //icmp output wire rx_icmp_vaild , output wire [7:0] rx_icmp_data , //udp output wire rx_udp_vaild , output wire [7:0] rx_udp_data , output wire rx_udp_sync ); /////////////////////////////////////////////////////////////////////////// //rxfifo wire rxfifo_wr_clk ; wire rxfifo_wr_en ; wire [7:0] rxfifo_wr_data ; wire rxfifo_rd_clk ; reg rxfifo_rd_en ; wire [7:0] rxfifo_rd_data ; wire rxfifo_full ; wire rxfifo_empty ; reg [15:0] rxfifo_rd_cnt ; //crc wire crc_error ; wire crc_end ; //rx cnt reg r_rx_vaild ; reg [15:0] rx_vaild_cnt ; reg [13:0] packet_length ; //check reg udp_check_define ; reg udp_check_ip ; reg arp_check_define ; reg icmp_check ; reg source_port_check ; reg target_port_check ; reg packet_vaild ; //status fifo wire status_wr_en ; wire [18:0] status_wr_data ; reg status_rd_en ; wire [18:0] status_rd_data ; reg [18:0] r1_status_rd_data ; wire status_full ; wire status_empty ; reg status_cycle ; reg status_check_udp_ip ; reg status_check_arp ; reg status_check_icmp ; reg r1_rx_udp_vaild ; //sync head reg frame_sync_check ; reg frame_sync_vaild ; reg [7:0] frame_sync_cnt ; //mac reg [47:0] r1_target_mac ; reg [47:0] r1_source_mac ; // reg r1_rx_arp_vaild ; reg [7:0] r1_rx_arp_data ; reg r1_rx_icmp_vaild ; reg [7:0] r1_rx_icmp_data ; /////////////////////////////////////////////////////////////////////////// always @(posedge eth_rx_clk) begin r_rx_vaild <= eth_rx_vaild; end always @(posedge eth_rx_clk) begin if(sys_rst_n == 1'b0) begin r1_target_mac <= default_rx_target_mac; end else if(i_target_mac_vaild == 1'b1) begin r1_target_mac <= i_target_mac; end end always @(posedge eth_rx_clk) begin if(sys_rst_n == 1'b0) begin r1_source_mac <= default_rx_source_mac; end else if(i_source_mac_vaild == 1'b1) begin r1_source_mac <= i_source_mac; end end always @(posedge eth_rx_clk) begin if(sys_rst_n == 1'b0) begin rx_vaild_cnt <= 16'b0; end else if(eth_rx_vaild == 1'b0 && r_rx_vaild == 1'b1) begin rx_vaild_cnt <= 16'b0; end else if(eth_rx_vaild == 1'b1) begin rx_vaild_cnt <= rx_vaild_cnt + 1'b1; end else begin rx_vaild_cnt <= rx_vaild_cnt; end end always @(posedge eth_rx_clk) begin if(sys_rst_n == 1'b0) begin packet_length <= 'd0; end else if(eth_rx_vaild == 1'b0 && r_rx_vaild == 1'b1) begin packet_length <= rx_vaild_cnt; end else begin packet_length <= packet_length; end end // rxfifo && CRC //-------------------------------------------------------------------------------------------// //rxfifo wr assign rxfifo_wr_clk = eth_rx_clk; assign rxfifo_wr_en = eth_rx_vaild; assign rxfifo_wr_data = eth_rx_data; //rxfifo rd assign rxfifo_rd_clk = eth_rx_clk; CRC32_D8 CRC32_D8_inst0 ( .i_clk ( eth_rx_clk ), .i_rst_n ( sys_rst_n ), .i_vaild ( eth_rx_vaild ), .i_data ( eth_rx_data ), .o_crc_error ( crc_error ), .o_crc_end ( crc_end ) ); eth_rxfifo_w8d8192 eth_rxfifo ( .rst ( !sys_rst_n ), // input wire rst .wr_clk ( rxfifo_wr_clk ), // input wire wr_clk .rd_clk ( rxfifo_rd_clk ), // input wire rd_clk .din ( rxfifo_wr_data ), // input wire [7 : 0] din .wr_en ( rxfifo_wr_en ), // input wire wr_en .rd_en ( rxfifo_rd_en ), // input wire rd_en .dout ( rxfifo_rd_data ), // output wire [7 : 0] dout .full ( rxfifo_full ), // output wire full .empty ( rxfifo_empty ), // output wire empty .wr_rst_busy( ), // output wire wr_rst_busy .rd_rst_busy( ) // output wire rd_rst_busy ); //-------------------------------------------------------------------------------------------// //Port && UDP && Packet Check //-------------------------------------------------------------------------------------------// always @(posedge eth_rx_clk) begin if(sys_rst_n == 1'b0) begin udp_check_define <= 1'b0; end else if(crc_end == 1'b1) begin udp_check_define <= 1'b0; end else if(eth_rx_vaild == 1'b1 && rx_vaild_cnt == 'd20 && eth_rx_data == UDP_MAC_CODE[15:8]) begin udp_check_define <= 1'b1; end else if(eth_rx_vaild == 1'b1 && rx_vaild_cnt == 'd21 && eth_rx_data != UDP_MAC_CODE[07:0]) begin udp_check_define <= 1'b0; end else begin udp_check_define <= udp_check_define; end end always @(posedge eth_rx_clk) begin if(sys_rst_n == 1'b0) begin arp_check_define <= 1'b0; end else if(crc_end == 1'b1) begin arp_check_define <= 1'b0; end else if(eth_rx_vaild == 1'b1 && rx_vaild_cnt == 'd20 && eth_rx_data == ARP_MAC_CODE[15:8]) begin arp_check_define <= 1'b1; end else if(eth_rx_vaild == 1'b1 && rx_vaild_cnt == 'd21 && eth_rx_data != ARP_MAC_CODE[07:0]) begin arp_check_define <= 1'b0; end else begin arp_check_define <= arp_check_define; end end always @(posedge eth_rx_clk) begin if(sys_rst_n == 1'b0) begin udp_check_ip <= 1'b0; end else if(eth_rx_vaild == 1'b0 && r_rx_vaild == 1'b1) begin udp_check_ip <= 1'b0; end else if(eth_rx_vaild == 1'b1 && rx_vaild_cnt == 'd31 && eth_rx_data == Protocol_UDP[7:0]) begin udp_check_ip <= 1'b1; end else begin udp_check_ip <= udp_check_ip; end end always @(posedge eth_rx_clk) begin if(sys_rst_n == 1'b0) begin icmp_check <= 1'b0; end else if(crc_end == 1'b1) begin icmp_check <= 1'b0; end else if(eth_rx_vaild == 1'b1 && rx_vaild_cnt == 'd31 && eth_rx_data == Protocol_ICMP[7:0]) begin icmp_check <= 1'b1; end else begin icmp_check <= icmp_check; end end always @(posedge eth_rx_clk) begin if(sys_rst_n == 1'b0) begin source_port_check <= 1'b0; end else if(eth_rx_vaild == 1'b0 && r_rx_vaild == 1'b1) begin source_port_check <= 1'b0; end else if(eth_rx_vaild == 1'b1 && rx_vaild_cnt == 'd42 && eth_rx_data == RX_SOURCE_PORT[15:8]) begin source_port_check <= 1'b1; end else if(eth_rx_vaild == 1'b1 && rx_vaild_cnt == 'd43 && eth_rx_data != RX_SOURCE_PORT[07:0]) begin source_port_check <= 1'b0; end else begin source_port_check <= source_port_check; end end always @(posedge eth_rx_clk) begin if(sys_rst_n == 1'b0) begin target_port_check <= 1'b0; end else if(eth_rx_vaild == 1'b0 && r_rx_vaild == 1'b1) begin target_port_check <= 1'b0; end else if(eth_rx_vaild == 1'b1 && rx_vaild_cnt == 'd44 && eth_rx_data == RX_TARGET_PORT[15:8]) begin target_port_check <= 1'b1; end else if(eth_rx_vaild == 1'b1 && rx_vaild_cnt == 'd45 && eth_rx_data != RX_TARGET_PORT[07:0]) begin target_port_check <= 1'b0; end else begin target_port_check <= target_port_check; end end always @(posedge eth_rx_clk) begin if(sys_rst_n == 1'b0) begin frame_sync_check <= 1'b0; end else if(crc_end == 1'b1) begin frame_sync_check <= 1'b0; end else if(eth_rx_vaild == 1'b1 && rx_vaild_cnt == 'd50 && eth_rx_data == RX_Sync_Frame[31:24]) begin frame_sync_check <= 1'b1; end else if(eth_rx_vaild == 1'b1 && rx_vaild_cnt == 'd51 && eth_rx_data != RX_Sync_Frame[23:16]) begin frame_sync_check <= 1'b0; end else if(eth_rx_vaild == 1'b1 && rx_vaild_cnt == 'd52 && eth_rx_data != RX_Sync_Frame[15:08]) begin frame_sync_check <= 1'b0; end else if(eth_rx_vaild == 1'b1 && rx_vaild_cnt == 'd53 && eth_rx_data != RX_Sync_Frame[07:0]) begin frame_sync_check <= 1'b0; end else begin frame_sync_check <= frame_sync_check; end end always @(posedge eth_rx_clk) begin if(sys_rst_n == 1'b0) begin packet_vaild <= 1'b0; end else if(crc_end == 1'b1) begin packet_vaild <= 1'b0; end else if(eth_rx_vaild == 1'b0 && r_rx_vaild == 1'b1 && udp_check_ip == 1'b1 && udp_check_define == 1'b1 && source_port_check == 1'b1 && target_port_check == 1'b1) begin packet_vaild <= 1'b1; end else begin packet_vaild <= packet_vaild; end end //-------------------------------------------------------------------------------------------// assign status_wr_en = crc_end; assign status_wr_data = {arp_check_define, //18 icmp_check, //17 frame_sync_check, //16 (!crc_error), //15 (packet_vaild), //14 packet_length}; //13:0 as_rxfifo_w16d64 status_buffer_fifo ( .wr_clk ( eth_rx_clk ), // input wire wr_clk .rd_clk ( eth_rx_clk ), // input wire rd_clk .din ( status_wr_data ), // input wire [18 : 0] din .wr_en ( status_wr_en ), // input wire wr_en .rd_en ( status_rd_en ), // input wire rd_en .dout ( status_rd_data ), // output wire [18 : 0] dout .full ( status_full ), // output wire full .empty ( status_empty ) // output wire empty ); always @(posedge eth_rx_clk) begin if(sys_rst_n == 1'b0) begin r1_status_rd_data <= 16'd0; end else if(status_rd_en == 1'b1 && status_cycle == 1'b0) begin r1_status_rd_data <= status_rd_data; end end always @(posedge eth_rx_clk) begin if(sys_rst_n == 1'b0) begin status_rd_en <= 1'b0; end else if(status_rd_en == 1'b1 || status_cycle == 1'b1) begin status_rd_en <= 1'b0; end else if(status_empty == 1'b0 && status_cycle == 1'b0) begin status_rd_en <= 1'b1; end else begin status_rd_en <= 1'b0; end end always @(posedge eth_rx_clk) begin if(sys_rst_n == 1'b0) begin status_cycle <= 1'b0; end else if(rxfifo_rd_en == 1'b1 && rxfifo_rd_cnt == r1_status_rd_data[13:0] - 1'b1) begin status_cycle <= 1'b0; end else if(status_rd_en == 1'b1 && status_cycle == 1'b0) begin status_cycle <= 1'b1; end else begin status_cycle <= status_cycle; end end always @(posedge eth_rx_clk) begin if(sys_rst_n == 1'b0) begin rxfifo_rd_en <= 1'b0; end else if(rxfifo_rd_en == 1'b1 && rxfifo_rd_cnt == r1_status_rd_data[13:0] - 1'b1) begin rxfifo_rd_en <= 1'b0; end else if(status_rd_en == 1'b1 && status_cycle == 1'b0) begin rxfifo_rd_en <= 1'b1; end else begin rxfifo_rd_en <= rxfifo_rd_en; end end always @(posedge eth_rx_clk) begin if(sys_rst_n == 1'b0) begin rxfifo_rd_cnt <= 16'd0; end else if(rxfifo_rd_en == 1'b1) begin if(rxfifo_rd_cnt == r1_status_rd_data[13:0] - 1'b1) begin rxfifo_rd_cnt <= 16'd0; end else begin rxfifo_rd_cnt <= rxfifo_rd_cnt + 1'b1; end end else begin rxfifo_rd_cnt <= rxfifo_rd_cnt; end end always @(posedge eth_rx_clk) begin if(sys_rst_n == 1'b0) begin status_check_udp_ip <= 1'b0; end else if(rxfifo_rd_en == 1'b1 && rxfifo_rd_cnt == r1_status_rd_data[13:0] - 1'b1) begin status_check_udp_ip <= 1'b0; end else if(status_rd_en == 1'b1 && status_cycle == 1'b0) begin if(status_rd_data[18] == 1'b0 && status_rd_data[17] == 1'b0 && status_rd_data[16] == 1'b0 && status_rd_data[15] == 1'b1 && status_rd_data[14] == 1'b1) begin status_check_udp_ip <= 1'b1; end else begin status_check_udp_ip <= 1'b0; end end else begin status_check_udp_ip <= status_check_udp_ip; end end always @(posedge eth_rx_clk) begin if(sys_rst_n == 1'b0) begin r1_rx_udp_vaild <= 1'b0; end else if(status_cycle == 1'b1 && status_check_udp_ip == 1'b1 && rxfifo_rd_en == 1'b1) begin if(rxfifo_rd_cnt >= 'd49 && rxfifo_rd_cnt < r1_status_rd_data[13:0] - 1'b1 - 3'd4) begin r1_rx_udp_vaild <= 1'b1; end else begin r1_rx_udp_vaild <= 1'b0; end end else begin r1_rx_udp_vaild <= 1'b0; end end assign rx_udp_vaild = r1_rx_udp_vaild; assign rx_udp_data = (rx_udp_vaild == 1'b1)?(rxfifo_rd_data):(0); always @(posedge eth_rx_clk) begin if(sys_rst_n == 1'b0) begin frame_sync_vaild <= 1'b0; end else if(rxfifo_rd_en == 1'b1 && rxfifo_rd_cnt == r1_status_rd_data[13:0] - 1'b1) begin frame_sync_vaild <= 1'b0; end else if(frame_sync_vaild == 1'b1 && frame_sync_cnt == 'd15) begin frame_sync_vaild <= 1'b0; end else if(status_rd_en == 1'b1 && status_cycle == 1'b0) begin if(status_rd_data[18] == 1'b0 && status_rd_data[17] == 1'b0 && status_rd_data[16] == 1'b1 && status_rd_data[15] == 1'b1 && status_rd_data[14] == 1'b1) begin frame_sync_vaild <= 1'b1; end else begin frame_sync_vaild <= 1'b0; end end else begin frame_sync_vaild <= frame_sync_vaild; end end always @(posedge eth_rx_clk) begin if(sys_rst_n == 1'b0) begin frame_sync_cnt <= 'd0; end else if(rxfifo_rd_en == 1'b1 && rxfifo_rd_cnt == r1_status_rd_data[13:0] - 1'b1) begin frame_sync_cnt <= 'd0; end else if(frame_sync_vaild == 1'b1) begin if(frame_sync_cnt == 'd15) begin frame_sync_cnt <= 'd0; end else begin frame_sync_cnt <= frame_sync_cnt + 1'b1; end end end assign rx_udp_sync = frame_sync_vaild; //arp always @(posedge eth_rx_clk) begin if(sys_rst_n == 1'b0) begin status_check_arp <= 1'b0; end else if(rxfifo_rd_en == 1'b1 && rxfifo_rd_cnt == r1_status_rd_data[13:0] - 1'b1) begin status_check_arp <= 1'b0; end else if(status_rd_en == 1'b1 && status_cycle == 1'b0) begin if(status_rd_data[18] == 1'b1 && status_rd_data[17] == 1'b0 && status_rd_data[16] == 1'b0 && status_rd_data[15] == 1'b1 && status_rd_data[14] == 1'b0) begin status_check_arp <= 1'b1; end else begin status_check_arp <= 1'b0; end end else begin status_check_arp <= status_check_arp; end end always @(posedge eth_rx_clk) begin if(sys_rst_n == 1'b0) begin r1_rx_arp_vaild <= 1'b0; end else if(status_cycle == 1'b1 && status_check_arp == 1'b1 && rxfifo_rd_en == 1'b1) begin if(rxfifo_rd_cnt >= 'd7 && rxfifo_rd_cnt < r1_status_rd_data[13:0] - 1'b1 - 3'd4) begin r1_rx_arp_vaild <= 1'b1; end else begin r1_rx_arp_vaild <= 1'b0; end end else begin r1_rx_arp_vaild <= 1'b0; end end assign rx_arp_vaild = r1_rx_arp_vaild; assign rx_arp_data = (rx_arp_vaild == 1'b1)?(rxfifo_rd_data):(0); //icmp always @(posedge eth_rx_clk) begin if(sys_rst_n == 1'b0) begin status_check_icmp <= 1'b0; end else if(rxfifo_rd_en == 1'b1 && rxfifo_rd_cnt == r1_status_rd_data[13:0] - 1'b1) begin status_check_icmp <= 1'b0; end else if(status_rd_en == 1'b1 && status_cycle == 1'b0) begin if(status_rd_data[18] == 1'b0 && status_rd_data[17] == 1'b1 && status_rd_data[16] == 1'b0 && status_rd_data[15] == 1'b1 && status_rd_data[14] == 1'b0) begin status_check_icmp <= 1'b1; end else begin status_check_icmp <= 1'b0; end end else begin status_check_icmp <= status_check_icmp; end end endmodule
1.资源消耗多,但是处理快的方法;
输入数据存入双口RAM1,校验数据存入RAM2,同时把RAM的读起始地址存入FIFO1,存完数据以后校验,如果正确则从约定地址开始读取数据,如果不正确则直接重置RAM1,RAM2的初始地址;
这个方法可以更快的处理这个数据流,但是需要更多的RAM资源。
assign o_m_axis_data = r_o_m_axis_data ; assign o_m_axis_user = r_o_m_axis_user ; assign o_m_axis_keep = (r_o_m_axis_valid)?(r_o_m_axis_keep):0; assign o_m_axis_last = r_o_m_axis_last ; assign o_m_axis_valid = r_o_m_axis_valid; always @(posedge i_xgmii_clk) begin if(i_xgmii_rst) begin r_s_axis_data <= 0; r_s_axis_user <= 0; r_s_axis_keep <= 0; r_s_axis_last <= 0; r_s_axis_valid <= 0; r_1d_s_axis_data <= 0; r_1d_s_axis_user <= 0; r_1d_s_axis_keep <= 0; r_1d_s_axis_last <= 0; r_1d_s_axis_valid <= 0; r_1d_bram_data_inst0_enb <= 0; r_1d_fifo_crc_rd_en <= 0; end else begin r_s_axis_data <= i_s_axis_data ; r_s_axis_user <= i_s_axis_user ; r_s_axis_keep <= i_s_axis_keep ; r_s_axis_last <= i_s_axis_last ; r_s_axis_valid <= i_s_axis_valid ; r_1d_s_axis_data <= r_s_axis_data ; r_1d_s_axis_user <= r_s_axis_user ; r_1d_s_axis_keep <= r_s_axis_keep ; r_1d_s_axis_last <= r_s_axis_last ; r_1d_s_axis_valid <= r_s_axis_valid ; r_1d_bram_data_inst0_enb <= r_bram_data_inst0_enb; r_1d_fifo_crc_rd_en <= r_fifo_crc_rd_en ; end end BRAM_64x256_SD BRAM_64x256_SD_inst0 ( .clka ( i_xgmii_clk ), // input wire clka .ena ( r_s_axis_valid ), // input wire ena .wea ( r_s_axis_valid ), // input wire [0 : 0] wea .addra ( r_bram_data_inst0_addra ), // input wire [7 : 0] addra .dina ( r_s_axis_data ), // input wire [63 : 0] dina .clkb ( i_xgmii_clk ), // input wire clkb .enb ( r_bram_data_inst0_enb ), // input wire enb .addrb ( r_bram_data_inst0_addrb ), // input wire [7 : 0] addrb .doutb ( w_bram_data_inst0_data ) // output wire [63 : 0] doutb ); BRAM_16x32_SD BRAM_16x32_SD_inst0 ( .clka ( i_xgmii_clk ), // input wire clka .ena ( r_s_axis_last ), // input wire ena .wea ( r_s_axis_last ), // input wire [0 : 0] wea .addra ( r_bram_lens_inst0_addra ), // input wire [4 : 0] addra .dina ( r_s_axis_user[64+:16] ), // input wire [15 : 0] dina .clkb ( i_xgmii_clk ), // input wire clkb .enb ( r_bram_lens_inst0_enb ), // input wire enb .addrb ( r_bram_lens_inst0_addrb ), // input wire [4 : 0] addrb .doutb ( w_bram_lens_inst0_data ) // output wire [15 : 0] doutb ); BRAM_8x32 BRAM_8x32_SD_inst0 ( .clka ( i_xgmii_clk ), // input wire clka .ena ( r_s_axis_last ), // input wire ena .wea ( r_s_axis_last ), // input wire [0 : 0] wea .addra ( r_bram_keep_inst0_addra ), // input wire [4 : 0] addra .dina ( r_s_axis_keep ), // input wire [7 : 0] dina .clkb ( i_xgmii_clk ), // input wire clkb .enb ( r_bram_keep_inst0_enb ), // input wire enb .addrb ( r_bram_keep_inst0_addrb ), // input wire [4 : 0] addrb .doutb ( w_bram_keep_inst0_data ) // output wire [7 : 0] doutb ); BRAM_64x32 BRAM_64x32_SD_inst0 ( .clka ( i_xgmii_clk ),// input wire clka .ena ( r_s_axis_last ),// input wire ena .wea ( r_s_axis_last ),// input wire [0 : 0] wea .addra ( r_bram_user_inst0_addra ),// input wire [4 : 0] addra .dina ( r_s_axis_user[63:00] ),// input wire [63 : 0] dina .clkb ( i_xgmii_clk ),// input wire clkb .enb ( r_bram_user_inst0_enb ),// input wire enb .addrb ( r_bram_user_inst0_addrb ),// input wire [4 : 0] addrb .doutb ( w_bram_user_inst0_data ) // output wire [63 : 0] doutb ); FIFO_1x32 FIFO_1x32_inst0 ( .clk ( i_xgmii_clk ), // input wire clk .din ( i_crc_error ), // input wire [0 : 0] din .wr_en ( i_crc_out ), // input wire wr_en .rd_en ( r_fifo_crc_rd_en ), // input wire rd_en .dout ( w_fifo_crc_dout ), // output wire [0 : 0] dout .full ( w_fifo_crc_full ), // output wire full .empty ( w_fifo_crc_empty ) // output wire empty ); FIFO_8x32 FIFO_8x32_inst0 ( .clk ( i_xgmii_clk ), // input wire clk .din ( r_bram_data_inst0_addra ), // input wire [7 : 0] din .wr_en ( r_s_axis_valid && !r_1d_s_axis_valid ), // input wire wr_en .rd_en ( r_fifo_init_rden ), // input wire rd_en .dout ( w_fifo_data_init_addra ), // output wire [7 : 0] dout .full ( w_FIFO_8x32_inst0_full ), // output wire full .empty ( w_FIFO_8x32_inst0_empty ) // output wire empty ); FIFO_8x32 FIFO_8x32_inst1 ( .clk ( i_xgmii_clk ), // input wire clk .din ( {3'b0,r_bram_lens_inst0_addra} ), // input wire [7 : 0] din .wr_en ( r_s_axis_last && !r_1d_s_axis_last ), // input wire wr_en .rd_en ( r_fifo_init_rden ), // input wire rd_en .dout ( w_bram_lens_init_addra ), // output wire [7 : 0] dout .full ( w_FIFO_8x32_inst1_full ), // output wire full .empty ( w_FIFO_8x32_inst1_empty ) // output wire empty ); FIFO_8x32 FIFO_8x32_inst2 ( .clk ( i_xgmii_clk ), // input wire clk .din ( {3'b0,r_bram_keep_inst0_addra} ), // input wire [7 : 0] din .wr_en ( r_s_axis_last && !r_1d_s_axis_last ), // input wire wr_en .rd_en ( r_fifo_init_rden ), // input wire rd_en .dout ( w_bram_keep_init_addra ), // output wire [7 : 0] dout .full ( w_FIFO_8x32_inst2_full ), // output wire full .empty ( w_FIFO_8x32_inst2_empty ) // output wire empty ); FIFO_8x32 FIFO_8x32_inst3 ( .clk ( i_xgmii_clk ), // input wire clk .din ( {3'b0,r_bram_user_inst0_addra} ), // input wire [7 : 0] din .wr_en ( r_s_axis_last && !r_1d_s_axis_last ), // input wire wr_en .rd_en ( r_fifo_init_rden ), // input wire rd_en .dout ( w_bram_user_init_addra ), // output wire [7 : 0] dout .full ( w_FIFO_8x32_inst3_full ), // output wire full .empty ( w_FIFO_8x32_inst3_empty ) // output wire empty ); always @(posedge i_xgmii_clk) begin if(i_xgmii_rst) begin r_fifo_crc_rd_en <= 1'b0; end else if(!w_fifo_crc_empty && !r_fifo_crc_rd_en && !r_fifo_crc_lock) begin r_fifo_crc_rd_en <= 1'b1; end else begin r_fifo_crc_rd_en <= 1'b0; end end always @(posedge i_xgmii_clk) begin if(i_xgmii_rst) begin r_fifo_init_rden <= 1'b0; end else if(!w_fifo_crc_empty && !r_fifo_crc_rd_en && !r_fifo_crc_lock) begin r_fifo_init_rden <= 1'b1; end else begin r_fifo_init_rden <= 1'b0; end end always @(posedge i_xgmii_clk) begin if(i_xgmii_rst) begin r_fifo_crc_lock <= 1'b0; end else if(r_bram_data_inst0_enb && r_data_cnt == r_out_lens - 1) begin r_fifo_crc_lock <= 1'b0; end else if(!w_fifo_crc_empty && !r_fifo_crc_rd_en && !r_fifo_crc_lock) begin r_fifo_crc_lock <= 1'b1; end else begin r_fifo_crc_lock <= r_fifo_crc_lock; end end //bram data always @(posedge i_xgmii_clk) begin if(i_xgmii_rst) begin r_bram_data_inst0_addra <= 'd0; end else if(r_1d_fifo_crc_rd_en && w_fifo_crc_dout) begin r_bram_data_inst0_addra <= w_fifo_data_init_addra; end else if(r_s_axis_valid) begin r_bram_data_inst0_addra <= r_bram_data_inst0_addra + 1; end else begin r_bram_data_inst0_addra <= r_bram_data_inst0_addra; end end //bram lens always @(posedge i_xgmii_clk) begin if(i_xgmii_rst) begin r_bram_lens_inst0_addra <= 'd0; end else if(r_1d_fifo_crc_rd_en && w_fifo_crc_dout) begin r_bram_lens_inst0_addra <= w_bram_lens_init_addra; end else if(r_s_axis_last) begin r_bram_lens_inst0_addra <= r_bram_lens_inst0_addra + 1; end else begin r_bram_lens_inst0_addra <= r_bram_lens_inst0_addra; end end //bram keep always @(posedge i_xgmii_clk) begin if(i_xgmii_rst) begin r_bram_keep_inst0_addra <= 'd0; end else if(r_1d_fifo_crc_rd_en && w_fifo_crc_dout) begin r_bram_keep_inst0_addra <= w_bram_keep_init_addra; end else if(r_s_axis_last) begin r_bram_keep_inst0_addra <= r_bram_keep_inst0_addra + 1; end else begin r_bram_keep_inst0_addra <= r_bram_keep_inst0_addra; end end //bram user always @(posedge i_xgmii_clk) begin if(i_xgmii_rst) begin r_bram_user_inst0_addra <= 'd0; end else if(r_1d_fifo_crc_rd_en && w_fifo_crc_dout) begin r_bram_user_inst0_addra <= w_bram_user_init_addra; end else if(r_s_axis_last) begin r_bram_user_inst0_addra <= r_bram_user_inst0_addra + 1; end else begin r_bram_user_inst0_addra <= r_bram_user_inst0_addra; end end /*当CRC校验正确,为RAM的读出地址赋予他们RAM当初的写入地址,取出lens,keep,user等数据*/ /*当CRC校验错误,他们的写入地址将被重置,由下一轮数据覆盖 */ always @(posedge i_xgmii_clk) begin if(i_xgmii_rst) begin r_out_run <= 1'd0; end else if(r_bram_data_inst0_enb && r_data_cnt == r_out_lens - 1) begin r_out_run <= 1'd0; end else if(r_1d_fifo_crc_rd_en && !w_fifo_crc_dout) begin r_out_run <= 1'd1; end else begin r_out_run <= r_out_run; end end //lens always @(posedge i_xgmii_clk) begin if(i_xgmii_rst) begin r_bram_lens_inst0_enb <= 1'b0; end else if(r_1d_fifo_crc_rd_en && !w_fifo_crc_dout) begin r_bram_lens_inst0_enb <= 1'b1; end else begin r_bram_lens_inst0_enb <= 1'b0; end end always @(posedge i_xgmii_clk) begin if(i_xgmii_rst) begin r_lens_valid <= 1'b0; end else begin r_lens_valid <= r_bram_lens_inst0_enb; end end always @(posedge i_xgmii_clk) begin if(i_xgmii_rst) begin r_out_lens <= 16'h0; end else if(r_lens_valid) begin r_out_lens <= w_bram_lens_inst0_data; end else begin r_out_lens <= r_out_lens; end end always @(posedge i_xgmii_clk) begin if(i_xgmii_rst) begin r_bram_lens_inst0_addrb <= 0; end else if(r_1d_fifo_crc_rd_en && !w_fifo_crc_dout) begin r_bram_lens_inst0_addrb <= w_bram_lens_init_addra; end else begin r_bram_lens_inst0_addrb <= r_bram_lens_inst0_addrb; end end //keep always @(posedge i_xgmii_clk) begin if(i_xgmii_rst) begin r_bram_keep_inst0_enb <= 1'b0; end else if(r_1d_fifo_crc_rd_en && !w_fifo_crc_dout) begin r_bram_keep_inst0_enb <= 1'b1; end else begin r_bram_keep_inst0_enb <= 1'b0; end end always @(posedge i_xgmii_clk) begin if(i_xgmii_rst) begin r_bram_keep_inst0_addrb <= 0; end else if(r_1d_fifo_crc_rd_en && !w_fifo_crc_dout) begin r_bram_keep_inst0_addrb <= w_bram_keep_init_addra; end else begin r_bram_keep_inst0_addrb <= r_bram_keep_inst0_addrb; end end //user always @(posedge i_xgmii_clk) begin if(i_xgmii_rst) begin r_bram_user_inst0_enb <= 1'b0; end else if(r_1d_fifo_crc_rd_en && !w_fifo_crc_dout) begin r_bram_user_inst0_enb <= 1'b1; end else begin r_bram_user_inst0_enb <= 1'b0; end end always @(posedge i_xgmii_clk) begin if(i_xgmii_rst) begin r_bram_user_inst0_addrb <= 0; end else if(r_1d_fifo_crc_rd_en && !w_fifo_crc_dout) begin r_bram_user_inst0_addrb <= w_bram_user_init_addra; end else begin r_bram_user_inst0_addrb <= r_bram_user_inst0_addrb; end end //data always @(posedge i_xgmii_clk) begin if(i_xgmii_rst) begin r_bram_data_inst0_enb <= 1'b0; end else if(r_bram_data_inst0_enb && r_data_cnt == r_out_lens - 1) begin r_bram_data_inst0_enb <= 1'b0; end else if(r_lens_valid) begin r_bram_data_inst0_enb <= 1'b1; end end always @(posedge i_xgmii_clk) begin if(i_xgmii_rst) begin r_data_cnt <= 0; end else if(r_bram_data_inst0_enb && r_data_cnt == r_out_lens - 1) begin r_data_cnt <= 0; end else if(r_bram_data_inst0_enb) begin r_data_cnt <= r_data_cnt + 1; end else begin r_data_cnt <= r_data_cnt; end end always @(posedge i_xgmii_clk) begin if(i_xgmii_rst) begin r_bram_data_inst0_addrb <= 0; end else if(r_lens_valid) begin r_bram_data_inst0_addrb <= w_fifo_data_init_addra; end else if(r_bram_data_inst0_enb) begin r_bram_data_inst0_addrb <= r_bram_data_inst0_addrb + 1'b1; end else begin r_bram_data_inst0_addrb <= r_bram_data_inst0_addrb; end end always @(posedge i_xgmii_clk) begin if(i_xgmii_rst) begin r_o_m_axis_data <= 0; end else begin r_o_m_axis_data <= w_bram_data_inst0_data; end end always @(posedge i_xgmii_clk) begin if(i_xgmii_rst) begin r_o_m_axis_keep <= 8'b0000_0000; end else if(!r_bram_data_inst0_enb && r_1d_bram_data_inst0_enb) begin r_o_m_axis_keep <= w_bram_keep_inst0_data; end else begin r_o_m_axis_keep <= 8'hff; end end always @(posedge i_xgmii_clk) begin if(i_xgmii_rst) begin r_o_m_axis_last <= 1'b0; end else if(!r_bram_data_inst0_enb && r_1d_bram_data_inst0_enb) begin r_o_m_axis_last <= 1'b1; end else begin r_o_m_axis_last <= 1'b0; end end always @(posedge i_xgmii_clk) begin if(i_xgmii_rst) begin r_o_m_axis_valid <= 1'b0; end else if(r_1d_bram_data_inst0_enb) begin r_o_m_axis_valid <= 1'b1; end else begin r_o_m_axis_valid <= 0; end end
需要注意:
1.CRC数据在接受完整帧数据才能校验完成,所以校验环节要在一帧完成以后;
2.当CRC校验正确,输出数据的过程中要给一个LOCK信号;