一、三速以太网
千兆以太网PHY芯片是适配百兆和十兆的,十兆就不管了,我们的设计只适应千兆和百兆。
根据上图,我们是可以获取当前主机网口的速率信息的。
always@(posedge w_rxc_bufr)
begin
if(w_rec_valid == 'd0) begin
ro_speed <= w_rec_data[2:1];
ro_link <= w_rec_data[0];
end else begin
ro_speed <= ro_speed;
ro_link <= ro_link ;
end
end
千兆网的设计我们前面的章节介绍的很详细了,至于百兆,主要区别就在于时钟速率从125Mhz变为了25Mhz,双沿采样变为单沿采样,所以我们只需要在ODDR和IDDR使用的时候注意单沿问题即可。
对于接收数据而言,上下沿采样到的数据是一样的,也就是说一次收到的数据高四位和低四位一样,完整的8bit数据需要前一拍数据后一拍数据拼接
always@(posedge w_rxc_bufr)
begin
if(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)
begin
assign 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的时钟频率!!