10G MAC层设计系列-(4)MAC TX模块

发布于:2024-05-05 ⋅ 阅读:(29) ⋅ 点赞:(0)

一、前言

MAC TX模块就是要将IP层传输过来的数据封装前导码、MAC地址、帧类型以及进行CRC校验,并与CRC值一块组成以太网帧。

二、模块设计

首先对输入的数据进行缓存,原因是在之后要进行封装MAC帧头,所以需要控制数据流的流动

FIFO_DATA_64X256 U_FIFO_DATA_64X256 (
  .clk      (i_clk              ), 
  .srst     (i_rst              ), 
  .din      (rs_axis_data       ), 
  .wr_en    (rs_axis_valid      ), 
  .rd_en    (r_fifo_data_rden   ), 
  .dout     (w_fifo_data_out    ), 
  .full     (w_fifo_data_full   ), 
  .empty    (w_fifo_data_empty  )  
);

FIFO_LEN_16X32 u_FIFO_LEN_16X32 (
  .clk      (i_clk                  ),
  .srst     (i_rst                  ),
  .din      (rs_axis_user[79:64]    ),
  .wr_en    (rs_axis_last           ),
  .rd_en    (r_fifo_len_rden        ), 
  .dout     (w_fifo_len_out         ), 
  .full     (w_fifo_len_full        ), 
  .empty    (w_fifo_len_empty       )  
);

FIFO_LEN_16X32 u_FIFO_TYPE_16X32 (
  .clk      (i_clk                  ),
  .srst     (i_rst                  ),
  .din      (rs_axis_user[15:0]     ),
  .wr_en    (rs_axis_last           ),
  .rd_en    (r_fifo_type_rden       ), 
  .dout     (w_fifo_type_out        ), 
  .full     (w_fifo_type_full       ), 
  .empty    (w_fifo_type_empty      )  
);

FIFO_KEEP_8X32 u_FIFO_KEEP_8X32 (
  .clk      (i_clk                  ), 
  .srst     (i_rst                  ), 
  .din      (rs_axis_keep           ), 
  .wr_en    (rs_axis_last           ), 
  .rd_en    (r_fifo_keep_rden       ),  
  .dout     (w_fifo_keep_out        ),  
  .full     (w_fifo_keep_full       ),  
  .empty    (w_fifo_keep_empty      )  
);

检测到帧长FIFO不为空之后,读取帧长、KEEP信息、TYPE信息,并根据帧长读取数据,在此过程中需要将数据转换成xgmii接口形式,并封装前导码、MAC地址、帧类型、尾部CRC。同时需要在帧起始加入起始符FB、帧结束需要加入结束符FD,在空闲时发送07.同时需要是用控制信号指示控制符。

always@(posedge i_clk,posedge i_rst)begin
    if(i_rst)
        ro_xgmii_txd <= {{8{8'h07}}};
    else
        if(r_cnt == 0|| r_cnt == 1 || r_cnt == 2)
            ro_xgmii_txd <= {{8{8'h07}}};
        else if(r_cnt == 3)
            ro_xgmii_txd <= 64'hFB_55_55_55_55_55_55_55;
        else if(r_cnt == 4)
            ro_xgmii_txd <= {8'hd5,ri_set_target_mac,ri_set_source_mac[47:40]};
        else if(r_cnt == 5)
            ro_xgmii_txd <= {ri_set_source_mac[39:0],w_fifo_type_out,r_fifo_data_out_ff1[63:56]};
        // else if(r_cnt == 2)
        //     ro_xgmii_txd <= {w_fifo_type_out[7:0],w_fifo_data_out[63:8]};
        else if(r_cnt == w_fifo_len_out + 5)
            case(w_fifo_keep_out)
                8'b1111_1111:ro_xgmii_txd <= {r_fifo_data_out_ff4[55:0],r_crc_result[31:24]};
                8'b1111_1110:ro_xgmii_txd <= {r_fifo_data_out_ff4[55:8],r_crc_result[31:16]};
                8'b1111_1100:ro_xgmii_txd <= {r_fifo_data_out_ff4[55:16],r_crc_result[31:8]};
                8'b1111_1000:ro_xgmii_txd <= {r_fifo_data_out_ff4[55:24],r_crc_result[31:0]};
                8'b1111_0000:ro_xgmii_txd <= {r_fifo_data_out_ff4[55:32],r_crc_result[31:0],8'hFD};
                8'b1110_0000:ro_xgmii_txd <= {r_fifo_data_out_ff4[55:40],r_crc_result[31:0],8'hFD,{{8'h07}}};
                8'b1100_0000:ro_xgmii_txd <= {r_fifo_data_out_ff4[55:48],r_crc_result[31:0],8'hFD,{2{8'h07}}};
                8'b1000_0000:ro_xgmii_txd <= {r_crc_result[31:0],8'hFD,{3{8'h07}}};
                default     :ro_xgmii_txd <= 'd0;
            endcase
        else if(r_cnt == w_fifo_len_out + 6)
            case(w_fifo_keep_out)
                8'b1111_1111:ro_xgmii_txd <= {r_crc_result[23:0],8'hFD,{4{8'h07}}};
                8'b1111_1110:ro_xgmii_txd <= {r_crc_result[15:0],8'hFD,{5{8'h07}}};
                8'b1111_1100:ro_xgmii_txd <= {r_crc_result[7:0],8'hFD,{6{8'h07}}};
                8'b1111_1000:ro_xgmii_txd <= {8'hFD,{7{8'h07}}};
                // 8'b1111_0000:ro_xgmii_txd <= {8'hFD,{7{8'h07}}};
                // 8'b1110_0000:ro_xgmii_txd <= {8'hFD,{7{8'h07}}};
                // 8'b1100_0000:ro_xgmii_txd <= {r_fifo_data_out_ff3[55:48],r_crc_result,8'hFD,{2{8'h07}}};
                // 8'b1000_0000:ro_xgmii_txd <= {r_crc_result,8'hFD,{3{8'h07}}};
                default     :ro_xgmii_txd <= {{8{8'h07}}};
            endcase
        // else if(r_cnt == w_fifo_len_out + 5)
        //     case(w_fifo_keep_out)
        //         8'b1111_1111:ro_xgmii_txd <= {r_crc_result[7:0],8'hFD,{6{8'h07}}};
        //         8'b1111_1110:ro_xgmii_txd <= {r_crc_result[15:0],8'hFD,{5{8'h07}}};
        //         8'b1111_1100:ro_xgmii_txd <= {r_crc_result[7:0],8'hFD,{6{8'h07}}};
        //         8'b1111_1000:ro_xgmii_txd <= {8'hFD,{7{8'h07}}};
        //         default     :ro_xgmii_txd <= {8{8'h07}};
        //     endcase        
        else
            ro_xgmii_txd <= {r_fifo_data_out_ff4[55:0],r_fifo_data_out_ff3[63:56]};
end
//
always@(posedge i_clk,posedge i_rst)begin
    if(i_rst)
        ro_xgmii_txc <= 8'hff;
    else
        if( r_cnt == 0 || r_cnt == 1 || r_cnt == 2)
            ro_xgmii_txc <= 8'b1111_1111;
        else if(r_cnt == 3)
            ro_xgmii_txc <= 8'b1000_0000;
        // else if(r_cnt == 2)
        //     ro_xgmii_txd <= {w_fifo_type_out[7:0],w_fifo_data_out[63:8]};
        // else if(r_cnt == w_fifo_len_out + 2)
        //     case(w_fifo_keep_out)
        //         8'b1111_1111:ro_xgmii_txd <= {r_fifo_data_out_ff2[55:0],r_fifo_data_out_ff1[63:56]};
        //         8'b1111_1110:ro_xgmii_txd <= {r_fifo_data_out_ff2[55:0],r_fifo_data_out_ff1[63:56]};
        //         8'b1111_1100:ro_xgmii_txd <= {r_fifo_data_out_ff2[55:0],r_fifo_data_out_ff1[63:56]};
        //         8'b1111_1000:ro_xgmii_txd <= {r_fifo_data_out_ff2[55:0],r_fifo_data_out_ff1[63:56]};
        //         8'b1111_0000:ro_xgmii_txd <= {r_fifo_data_out_ff2[55:0],r_fifo_data_out_ff1[63:56]};
        //         8'b1110_0000:ro_xgmii_txd <= {r_fifo_data_out_ff2[55:0],r_fifo_data_out_ff1[63:56]};
        //         8'b1100_0000:ro_xgmii_txd <= {r_fifo_data_out_ff2[55:0],r_fifo_data_out_ff1[63:56]};
        //         8'b1000_0000:ro_xgmii_txd <= {r_fifo_data_out_ff2[55:0],r_fifo_data_out_ff1[63:56]};
        //         default     :ro_xgmii_txd <= {r_fifo_data_out_ff2[55:0],r_fifo_data_out_ff1[63:56]};
        //     endcase
        else if(r_cnt == w_fifo_len_out + 5)
            case(w_fifo_keep_out)
                // 8'b1111_1111:ro_xgmii_txc <= {r_fifo_data_out_ff2[55:0],r_crc_result[31:24]};
                // 8'b1111_1110:ro_xgmii_txd <= {r_fifo_data_out_ff2[55:8],r_crc_result[31:16]};
                // 8'b1111_1100:ro_xgmii_txd <= {r_fifo_data_out_ff2[55:16],r_crc_result[31:8]};
                // 8'b1111_1000:ro_xgmii_txd <= {r_fifo_data_out_ff2[55:24],r_crc_result[31:0]};
                8'b1111_0000:ro_xgmii_txc <= 8'b0000_0001;
                8'b1110_0000:ro_xgmii_txc <= 8'b0000_0011;
                8'b1100_0000:ro_xgmii_txc <= 8'b0000_0111;
                8'b1000_0000:ro_xgmii_txc <= 8'b0000_1111;
                default     :ro_xgmii_txc <= 'd0;
            endcase
        else if(r_cnt == w_fifo_len_out + 6)
            case(w_fifo_keep_out)
                8'b1111_1111:ro_xgmii_txc <= 8'b0001_1111;
                8'b1111_1110:ro_xgmii_txc <= 8'b0011_1111;
                8'b1111_1100:ro_xgmii_txc <= 8'b0111_1111;
                8'b1111_1000:ro_xgmii_txc <= 8'b1111_1111;
                default     :ro_xgmii_txc <= 8'b1111_1111;
            endcase        
        else
            ro_xgmii_txc <= 8'b0000_0000;
end

三、仿真图


网站公告

今日签到

点亮在社区的每一天
去签到