以太网帧的最小长度_关于以太网切包

本文深入探讨了以太网帧的最小长度标准,详细解释了为何存在这样的限制,并介绍在实际网络通信中如何进行以太网数据包的切割,确保网络传输的高效性和稳定性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

以太网切包

/*为什么要切包
一个传输的以太网帧长度最小为64个字节,最长为1518个字节:[ 6字节目的Mac地址 + 6字节源Mac地址 + 2字节的type类型 + 46-1500个字节的数据 + 4字节的FCS ] 如果传输的以太网帧太长,传输过程中,若发生一个错误,就要重传帧,其他终端将一直等待,效率很低。因此把帧的长度控制在46~1500字节之间。*/
/*本工程的要求是要求报文范围是1~9600字节,报文与报文之间的间隔至少要在46字节以上,设计以太网切包模块。
如果输入的报文长度小于46字节,那么就要在后面进行补0操作,输出46字节的报文;
如果输入的报文长度大于46且小于1500字节,不进行操作,直接输出报文;
如果输入的报文长度大于1500字节,那么就要对报文进行切包操作,切包之后的数据若小于46则进行补0,输出报文;*/
module eth_packet(
    input clk,
    input rst_n,
    input [7:0] din,
    input din_vld,
    input din_sop, // 报文头
    input din_eop, // 报文尾
    output reg[7:0] dout,
    output reg dout_vld,
    output reg dout_sop,
    output reg dout_eop    

);

wire add_cnt_wr,end_cnt_wr;
wire add_cnt_zero,end_cnt_zero;
wire fir_cnt_wr;
wire data_fifo_q_eoc; 
wire data_fifo_rdreq;
wire [7:0]data_fifo_q;
wire [10:0]len_fifo_q;
wire len_fifo_empty;
wire [11:0]data_fifo_data;
wire data_fifo_wrreq;
wire data_fifo_empty;
wire [10:0]len_fifo_data;
wire len_fifo_rdreq;
wire len_fifo_wrreq;
wire start_cnt_zero;
wire data_fifo_full;
wire len_fifo_full;

reg [10:0]cnt_wr;
reg [5:0]cnt_zero;
reg flag_zero;
reg flag;

always @(posedge clk or negedge rst_n)begin 
    if(~rst_n)
        cnt_wr <= 0;
    else if (add_cnt_wr) 
         if (end_cnt_wr)
         cnt_wr <= 0;
        else cnt_wr <= cnt_wr + 1'b1;
end

assign add_cnt_wr =din_vld;
assign end_cnt_wr =add_cnt_wr && ((cnt_wr==1500-1) || din_eop);

assign fir_cnt_wr = add_cnt_wr && cnt_wr==0;  //输出报文的第一个字节;
assign data_fifo_q_eoc = data_fifo_rdreq && data_fifo_q[0]; // 输出报文的最后一个字节,即处理完一个完整的报文;

always @(posedge clk or negedge rst_n)begin 
    if(~rst_n)
        cnt_zero <= 0;
    else if (add_cnt_zero) 
         if (end_cnt_zero)
         cnt_zero <= 0;
        else cnt_zero <= cnt_zero + 1'b1;
end

assign add_cnt_zero =flag_zero;
assign end_cnt_zero =add_cnt_zero && (46-len_fifo_q-1);

always @(posedge clk or negedge rst_n)begin 
    if(~rst_n)
         flag <= 0;
    else if (flag==0 && flag_zero ==0 && len_fifo_empty ==0) 
         flag <= 1;
    else if(data_fifo_q_eoc)
         flag <= 0;
end

always @(posedge clk or negedge rst_n)begin 
    if(~rst_n)
         flag_zero <= 0;
    else if (start_cnt_zero) 
         flag_zero <= 1;
    else if(end_cnt_zero)
         flag_zero <= 0;
end

assign start_cnt_zero = data_fifo_q_eoc && len_fifo_q <11'd46 ;

always @(posedge clk or negedge rst_n)begin 
    if(~rst_n)
         dout <= 0;
    else if (data_fifo_rdreq) 
         dout <=data_fifo_data[11:4];
    else 
         dout <= 0;
end

always @(posedge clk or negedge rst_n)begin 
    if(~rst_n)
         dout_vld <= 0;
    else if (data_fifo_rdreq) 
         dout_vld <= 1;
    else 
         dout_vld <= 0;
end

always @(posedge clk or negedge rst_n)begin 
    if(~rst_n)
         dout_sop <= 0;
    else if (fir_cnt_wr) 
         dout_sop <= 1;
    else 
         dout_sop <= 0;
end

always @(posedge clk or negedge rst_n)begin 
    if(~rst_n)
         dout_eop <= 0;
    else if ( (data_fifo_q_eoc && start_cnt_zero ==1'b0) || end_cnt_zero ) 
         dout_eop <= 1;
    else 
         dout_eop <= 0;
end

// 同步数据fifo
fifo_generator_0 data_fifo_12b (
  .clk(clk),      // input wire clk
  .srst(rst_n),    // input wire srst
  .din(data_fifo_data),      // input wire [11 : 0] din
  .wr_en(data_fifo_wrreq),  // input wire wr_en
  .rd_en(data_fifo_rdreq),  // input wire rd_en
  .dout(data_fifo_q),    // output wire [11 : 0] dout
  .full(data_fifo_full),    // output wire full
  .empty(data_fifo_empty)  // output wire empty
);
assign data_fifo_wrreq = din_vld && ~data_fifo_full;
assign data_fifo_data = {din,din_sop,din_eop,fir_cnt_wr,end_cnt_wr};
assign data_fifo_rdreq = flag && data_fifo_empty==1'b0;

// 同步信息fifo 
fifo_generator_1 len_fifo_11b (
  .clk(clk),      // input wire clk
  .srst(rst_n),    // input wire srst
  .din(len_fifo_data),      // input wire [10 : 0] din
  .wr_en(len_fifo_wrreq),  // input wire wr_en
  .rd_en(len_fifo_rdreq),  // input wire rd_en
  .dout(dout),    // output wire [10 : 0] dout
  .full(len_fifo_full),    // output wire full
  .empty(len_fifo_empty)  // output wire empty
);
assign len_fifo_data = cnt_wr + 1;
assign len_fifo_rdreq = (data_fifo_q_eoc && start_cnt_zero ==1'b0) || end_cnt_zero ; // 处理传输完一个完整的报文且不需要补0 || 补0结束; 
assign len_fifo_wrreq = end_cnt_wr && ~len_fifo_full;

endmodule
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值