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

一、前言

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

三、仿真图

相关推荐
DS小龙哥5 小时前
基于Zynq FPGA的雷龙SD NAND存储芯片性能测试
fpga开发·sd nand·雷龙·spi nand·spi nand flash·工业级tf卡·嵌入式tf卡
上理考研周导师15 小时前
第二章 虚拟仪器及其构成原理
fpga开发
FPGA技术实战16 小时前
《探索Zynq MPSoC》学习笔记(二)
fpga开发·mpsoc
bigbig猩猩1 天前
FPGA(现场可编程门阵列)的时序分析
fpga开发
Terasic友晶科技1 天前
第2篇 使用Intel FPGA Monitor Program创建基于ARM处理器的汇编或C语言工程<二>
fpga开发·汇编语言和c语言
码农阿豪1 天前
基于Zynq FPGA对雷龙SD NAND的测试
fpga开发·sd nand·spi nand·spi nand flash·工业级tf卡·嵌入式tf卡
江山如画,佳人北望1 天前
EDA技术简介
fpga开发
淘晶驰AK1 天前
电子设计竞赛准备经历分享
嵌入式硬件·fpga开发
最好有梦想~1 天前
FPGA时序分析和约束学习笔记(4、IO传输模型)
笔记·学习·fpga开发