一、前言
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