一、三速以太网
千兆以太网PHY芯片是适配百兆和十兆的,十兆就不管了,我们的设计只适应千兆和百兆。
根据上图,我们是可以获取当前主机网口的速率信息的。
always@(posedge w_rxc_bufr)
beginif(w_rec_valid == 'd0) beginro_speed <= w_rec_data[2:1];ro_link <= w_rec_data[0];end else beginro_speed <= ro_speed;ro_link <= ro_link ;end
end
千兆网的设计我们前面的章节介绍的很详细了,至于百兆,主要区别就在于时钟速率从125Mhz变为了25Mhz,双沿采样变为单沿采样,所以我们只需要在ODDR和IDDR使用的时候注意单沿问题即可。
对于接收数据而言,上下沿采样到的数据是一样的,也就是说一次收到的数据高四位和低四位一样,完整的8bit数据需要前一拍数据后一拍数据拼接
always@(posedge w_rxc_bufr)
beginif(i_speed1000)ro_rec_data <= w_rec_data;else ro_rec_data <= {w_rec_data[3:0],ro_rec_data[7:4]};
end
对于发送数据而言,r_tx_cnt_10_100信号是1bit的,不断在01变化,相当于一个时钟指示信号,通过这样的方式实现单沿传输,一个时钟只传输4bit,在下一个时钟再去传输延迟一拍数据的高4bit,这是因为用户进来的数据是8bit的。
genvar txd_i;
generate for(txd_i = 0 ;txd_i < 4 ; txd_i = txd_i + 1)
beginassign w_send_d1[txd_i] = i_speed1000 ? i_send_data[txd_i] : r_tx_cnt_10_100 == 0 ? i_send_data[txd_i] : ri_send_data[txd_i + 4];assign w_send_d2[txd_i] = i_speed1000 ? i_send_data[txd_i + 4] : r_tx_cnt_10_100 == 0 ? i_send_data[txd_i] : ri_send_data[txd_i + 4];ODDR #(.DDR_CLK_EDGE ("OPPOSITE_EDGE" ),.INIT (1'b0 ),.SRTYPE ("SYNC" ) ) ODDR_u (.Q (o_txd[txd_i] ), .C (w_txc ),.CE (1 ),.D1 (w_send_d1[txd_i] ), .D2 (w_send_d2[txd_i] ), .R (0 ),.S (0 ) );
end
endgenerate
二、上板效果
网口速率在这里更改
wireshark抓包和网络调试助手回环检测,一切正常
VIVADO上板通过ILA抓包:数据与发送数据一致
注:JTAG进行抓信号时,ILA频率要大于JTAG频率2.5倍,对于千兆而言不用管,但是抓百兆数据信号时,要调整一下JTAG的时钟频率!!