64B/66B编码 自定义PHY层设计

一、前言

之前的一篇文章讲解了64B/66B的基本原理,本篇在基于64B/66B GT Transceiver的基础之上设计自定义PHY。基本框图如下。

二、GT Mdule

GT Module就按照4个GT CHannel共享一个GT COMMON进行设置,如下图。要将例子工程中的GT COMMON取出,使其控制多个通道。如果按照例子工程的架构,当例化多个通道时,工程会出错,原因就是一个GT QARD只有一个GT COMMON。

GT Channel包括一个时钟模块,通过IP核给出来的TXOUTCLK生成TXUSERCLK2、RXUSERCLK2等时钟。GT IP就是例化的一个64B/66B编码的7系列GT Transceiver/

 例子工程结构如下:

 正确的结构如下:

GT Module主体结构代码如下:

IBUFDS_GTE2 #(.CLKCM_CFG      ("TRUE"             ),.CLKRCV_TRST    ("TRUE"             ),.CLKSWING_CFG   (2'b11              ) 
)
IBUFDS_GTE2_inst (.O              (w_gtrefclk         ),.ODIV2          (                   ),.CEB            (0                  ),.I              (i_gtrefclk_p       ),.IB             (i_gtrefclk_n       ) );gtwizard_0_common #
(.WRAPPER_SIM_GTRESET_SPEEDUP        ("TRUE"                         ),.SIM_QPLLREFCLK_SEL                 (QPLLREFCLKSEL_IN               )
)
common0_i
(.QPLLREFCLKSEL_IN                   (QPLLREFCLKSEL_IN               ),.GTREFCLK0_IN                       (w_gtrefclk                     ),.GTREFCLK1_IN                       (0                              ),.QPLLLOCK_OUT                       (w_qplllock                     ),.QPLLLOCKDETCLK_IN                  (i_sysclk                       ),.QPLLOUTCLK_OUT                     (w_qplloutclk                   ),.QPLLOUTREFCLK_OUT                  (w_qplloutrefclk                ),.QPLLREFCLKLOST_OUT                 (w_qpllrefclklost               ),    .QPLLRESET_IN                       (w_qpllreset|w_common_rst       ));gtwizard_0_common_reset # 
(.STABLE_CLOCK_PERIOD                (50                             )    
)                       
common_reset_i                      
(                           .STABLE_CLOCK                       (i_sysclk                       ),   .SOFT_RESET                         (i_tx_rst                       ),   .COMMON_RESET                       (w_common_rst                   )    
);GT_channel GT_channel_u0(.i_sysclk                           (i_sysclk                       ),.i_gtrefclk                         (w_gtrefclk                     ),.i_rx_rst                           (i_rx_rst                       ),.i_tx_rst                           (i_tx_rst                       ),.o_tx_done                          (o_tx_done                      ),.o_rx_done                          (o_rx_done                      ),.i_tx_polarity                      (i_tx_polarity                  ),.i_tx_diffctrl                      (i_tx_diffctrl                  ),.i_txpostcursor                     (i_txpostcursor                 ),.i_txpercursor                      (i_txpercursor                  ),     .i_rx_polarity                      (i_rx_polarity                  ),.i_loopback                         (i_loopback                     ),.i_drpaddr                          (i_drpaddr                      ), .i_drpclk                           (i_drpclk                       ),.i_drpdi                            (i_drpdi                        ), .o_drpdo                            (o_drpdo                        ), .i_drpen                            (i_drpen                        ),.o_drprdy                           (o_drprdy                       ), .i_drpwe                            (i_drpwe                        ),.i_qplllock                         (w_qplllock                     ), .i_qpllrefclklost                   (w_qpllrefclklost               ), .o_qpllreset                        (w_qpllreset                    ),.i_qplloutclk                       (w_qplloutclk                   ), .i_qplloutrefclk                    (w_qplloutrefclk                ), .i_data_valid                       (i_data_valid                   ),.o_rx_clk                           (o_rx_clk                       ),.o_rx_data                          (o_rx_data                      ),.o_rx_valid                         (o_rx_valid                     ),.o_rx_header                        (o_rx_header                    ),.o_rx_header_valid                  (o_rx_header_valid              ),.i_rx_slipbit                       (i_rx_slipbit                   ),.o_tx_clk                           (o_tx_clk                       ),.i_tx_data                          (i_tx_data                      ),.i_tx_header                        (i_tx_header                    ),.i_tx_sequence                      (i_tx_sequence                  ),      .o_gt_tx_p                          (o_gt_tx_p                      ),.o_gt_tx_n                          (o_gt_tx_n                      ),.i_gt_rx_p                          (i_gt_rx_p                      ),.i_gt_rx_n                          (i_gt_rx_n                      )
);GT_channel GT_channel_u1(.i_sysclk                           (i_sysclk                       ),.i_gtrefclk                         (w_gtrefclk                     ),.i_rx_rst                           (i_rx_rst_2                     ),.i_tx_rst                           (i_tx_rst_2                     ),.o_tx_done                          (o_tx_done_2                    ),.o_rx_done                          (o_rx_done_2                    ),.i_tx_polarity                      (i_tx_polarity_2                ),.i_tx_diffctrl                      (i_tx_diffctrl_2                ),.i_txpostcursor                     (i_txpostcursor_2               ),.i_txpercursor                      (i_txpercursor_2                ),     .i_rx_polarity                      (i_rx_polarity_2                ),.i_loopback                         (i_loopback_2                   ),.i_drpaddr                          (i_drpaddr_2                    ), .i_drpclk                           (i_drpclk_2                     ),.i_drpdi                            (i_drpdi_2                      ), .o_drpdo                            (o_drpdo_2                      ), .i_drpen                            (i_drpen_2                      ),.o_drprdy                           (o_drprdy_2                     ), .i_drpwe                            (i_drpwe_2                      ),.i_qplllock                         (w_qplllock                     ), .i_qpllrefclklost                   (w_qpllrefclklost               ), .o_qpllreset                        (                               ),.i_qplloutclk                       (w_qplloutclk                   ), .i_qplloutrefclk                    (w_qplloutrefclk                ), .i_data_valid                       (i_data_valid_2                 ),.o_rx_clk                           (o_rx_clk_2                     ),.o_rx_data                          (o_rx_data_2                    ),.o_rx_valid                         (o_rx_valid_2                   ),.o_rx_header                        (o_rx_header_2                  ),.o_rx_header_valid                  (o_rx_header_valid_2            ),.i_rx_slipbit                       (i_rx_slipbit_2                 ),.o_tx_clk                           (o_tx_clk_2                     ),.i_tx_data                          (i_tx_data_2                    ),.i_tx_header                        (i_tx_header_2                  ),.i_tx_sequence                      (i_tx_sequence_2                ),      .o_gt_tx_p                          (o_gt_tx_p_2                    ),.o_gt_tx_n                          (o_gt_tx_n_2                    ),.i_gt_rx_p                          (i_gt_rx_p_2                    ),.i_gt_rx_n                          (i_gt_rx_n_2                    )
);

三、PHY TX模块

PHY TX模块的主要功能就是封装帧以及大小端转换,以及暂停控制。

  • 由于64B/66B编码判定传输开始和传输结束是通过不同的数据帧进行的,所以就要对发送的数据进行封帧处理。
  • 在此过程中需要注意将数据由大端模式转换为小端的数据(GT IP核使用的是小端数据)。
  • 暂停控制:UG476上指出在使用外部计数器时,当Sequence Counter计数到32时,需要暂停以下,使Gearbox中积累的数据吐出去。

接下来具体说明变速箱GearBox的实现过程,以10GBase-R的物理层为例,若Serdes的位宽要求为32bit,PCS层采用64B/66B的编解码方式,在与Serdes进行数据传输过程中,需要GearBox实现66bit到32bit的转换、32bit到66bit的转换。

继续以上图为例子,XGMII层每拍输出32bit数据,每2拍组合成64bit报文,并且需要编码出2bit的同步头,为了简单化,假设待匹配的Serdes只有1个lane,且位宽为32bit,即GearBox输出是每拍32bit。

显然,输入带宽是大于输出带宽,属于带宽膨胀,因此输入必须暂停,什么时候停呢,见下图波形所示,每32拍停一拍,即待发送的buffer数据积攒够了32bit,此时,产生暂停输入标志位,也就是“反压”住输入信号,让GearBox可以完成数据完整输出。

(引自:详解GearBox设计原理 (qq.com))

基本思想如下:也就是要让Sequence Counter等于32和0的时候输出的数据不变,因为发送数据过程采用的时流水线拼接处理,所以要在Sequence Counter即将等于32的时候去截断数据流(处理过程挺复杂的)。

这个逻辑通过信号w_gt_send_valid 实现,达到30的时候拉低w_gt_send_valid ,这是因为要考虑组帧时候的FIFO读潜伏期。

assign          w_gt_send_valid = ro_tx_sequence == 30 ? 0 : 1  ;

另外一个情况需要特殊处理的就是在读第一个FIFO数据的时候 w_gt_send_valid =0的时刻到来,这时候需要特殊处理,因为再组帧的过程中第一帧是需要特殊处理的,如果处理不过会影响到后面的处理过程,时序图可以自己画以下。当检测w_gt_send_valid =0时需要使得读FIFO使能无效一个时钟周期(截流),并使得send_cnt在此时刻的数据保持两个时钟周期,需要使得输出保持。

总之最基本的思想就是:也就是要让Sequence Counter等于32和0的时候输出的数据不变

仿真图如下:

主要代码如下:

always@(posedge i_tx_clk,posedge i_tx_rst)
beginif(i_tx_rst)ro_tx_sequence <= 'd0;else if(ro_tx_sequence == 32)ro_tx_sequence <= 'd0;else ro_tx_sequence <= ro_tx_sequence + 1;
endalways@(posedge i_tx_clk,posedge i_tx_rst)
beginif(i_tx_rst)r_input_end <= 'd0;else if(s_axis_last)r_input_end <= 'd1;else if(s_axis_valid)r_input_end <= 'd0;else r_input_end <= r_input_end;
endalways@(posedge i_tx_clk,posedge i_tx_rst)
beginif(i_tx_rst)r_send_cnt <= 'd0;else if(r_input_end && r_send_cnt == r_len - 0)r_send_cnt <= 'd0;else if(r_invalid && r_send_cnt)r_send_cnt <= r_send_cnt;else if(r_invalid && r_fifo_rden_2d && !r_fifo_rden_3d)r_send_cnt <= r_send_cnt + 1;else if((!r_invalid && r_fifo_rden_1d && !r_fifo_rden_2d) || (r_send_cnt&& w_gt_send_valid))r_send_cnt <= r_send_cnt + 1;else r_send_cnt <= r_send_cnt;
endalways@(posedge i_tx_clk,posedge i_tx_rst)
beginif(i_tx_rst)r_fifo_dout_little <= 'd0;else if(r_fifo_rden)r_fifo_dout_little <= w_fifo_dout_little;else r_fifo_dout_little <= r_fifo_dout_little;
endalways@(posedge i_tx_clk,posedge i_tx_rst)
beginif(i_tx_rst)r_axis_keep <= 'd0;else if(s_axis_last)r_axis_keep <= s_axis_keep;else r_axis_keep <= r_axis_keep;
endalways@(posedge i_tx_clk,posedge i_tx_rst)
beginif(i_tx_rst)ro_tx_data <= 'd0;else if(r_send_cnt && r_input_end && ((r_axis_keep > 8'b1111_1100 && r_send_cnt == r_len - 0) || (r_axis_keep <= 8'b1111_1100 && r_send_cnt == r_len - 1)))case(r_axis_keep)8'b1111_1111:ro_tx_data <= {7'h16,7'h16,7'h16,7'h16,7'h16,7'h16,6'd0,r_fifo_dout_little[63:56],8'h99};//灏剧鍙戦��1涓�8'b1111_1110:ro_tx_data <= {7'h16,7'h16,7'h16,7'h16,7'h16,7'h16,7'h16,7'h16,8'h8e};//灏剧鍙戦��8涓�8'b1111_1100:ro_tx_data <= {w_fifo_dout_little[47:0],r_fifo_dout_little[63:56],8'hFF};//灏剧鍙戦��7涓�8'b1111_1000:ro_tx_data <= {7'h16,1'd0,w_fifo_dout_little[39:0],r_fifo_dout_little[63:56],8'he8};//灏剧鍙戦��6涓�8'b1111_0000:ro_tx_data <= {7'h16,7'h16,2'd0,w_fifo_dout_little[31:0],r_fifo_dout_little[63:56],8'hD4};8'b1110_0000:ro_tx_data <= {7'h16,7'h16,7'h16,3'd0,w_fifo_dout_little[23:0],r_fifo_dout_little[63:56],8'hc3};8'b1100_0000:ro_tx_data <= {7'h16,7'h16,7'h16,7'h16,4'd0,w_fifo_dout_little[15:0],r_fifo_dout_little[63:56],8'hB2};8'b1000_0000:ro_tx_data <= {7'h16,7'h16,7'h16,7'h16,7'h16,5'd0,w_fifo_dout_little[7:0],r_fifo_dout_little[63:56],8'hA5};endcaseelse case(r_send_cnt)0       :ro_tx_data <= {w_fifo_dout_little[55:0],8'h71};default :ro_tx_data <= {w_fifo_dout_little[55:0],r_fifo_dout_little[63:56]};endcase
endalways@(posedge i_tx_clk,posedge i_tx_rst)
beginif(i_tx_rst)ro_tx_header <= 'd0;else if(r_send_cnt && r_input_end && ((r_axis_keep > 8'b1111_1100 && r_send_cnt == r_len - 0) || (r_axis_keep <= 8'b1111_1100 && r_send_cnt == r_len - 1)))ro_tx_header <= 2'b10;else if(r_send_cnt == 0 && r_fifo_rden_2d && r_invalid)ro_tx_header <= 2'b10;else if(r_send_cnt == 0 && r_fifo_rden_1d)ro_tx_header <= 2'b10;elsero_tx_header <= 2'b01;
endalways@(posedge i_tx_clk,posedge i_tx_rst)
beginif(i_tx_rst)r_fifo_rden <= 'd0;else if(w_fifo_empty || !w_gt_send_valid)   r_fifo_rden <= 'd0;else if(!w_fifo_empty)r_fifo_rden <= 'd1;else r_fifo_rden <= r_fifo_rden;
endalways@(posedge i_tx_clk,posedge i_tx_rst)
beginif(i_tx_rst)r_fifo_rden_1d <= 'd0;else r_fifo_rden_1d <= r_fifo_rden;
endalways@(posedge i_tx_clk,posedge i_tx_rst)
beginif(i_tx_rst)r_fifo_rden_2d <= 'd0;else r_fifo_rden_2d <= r_fifo_rden_1d;
endalways@(posedge i_tx_clk,posedge i_tx_rst)
beginif(i_tx_rst)r_fifo_rden_3d <= 'd0;else r_fifo_rden_3d <= r_fifo_rden_2d;
endalways@(posedge i_tx_clk,posedge i_tx_rst)
beginif(i_tx_rst)r_fifo_empty <= 'd0;else r_fifo_empty <= {r_fifo_empty[0],w_fifo_empty};
endalways@(posedge i_tx_clk,posedge i_tx_rst)
beginif(i_tx_rst)rs_axis_ready <= 'd1;else if(s_axis_last)rs_axis_ready <= 'd0;else if(r_input_end && r_send_cnt == r_len - 0)rs_axis_ready <= 'd1;else rs_axis_ready <= rs_axis_ready;
endalways@(posedge i_tx_clk,posedge i_tx_rst)
beginif(i_tx_rst)r_invalid <= 'd0;else if(r_invalid && r_send_cnt)r_invalid <= 'd0;else if(r_fifo_rden && !w_gt_send_valid && r_send_cnt == 0)r_invalid <= 'd1;else r_invalid <= r_invalid;
end

四、PHY RX

1、PHY RX Bitslip模块

该模块的主要作用是实现字节对齐功能。

这个模块的主要思想如下:

  • 在64B/66B编码当中,只有2‘b10和2’b01代表有效的数据头,因此在字节对齐的过程中一直检测输入进来的数据头是否有效。
  • 当检测到错误数据头时,通过计数器进行计数加一进行记录,当间隔一定时钟周期之后便会检测这些计数器,如果计数器不为0,则发送滑动信号,使对齐窗口滑动1个bit。
  • 注意,间隔周期一定要大于32RXUSERCLK2(Xilinx文档 UG476指定的最小间隔周期为32个RXUSERCLK2)
  • 为了防止误判,可以设置只有当连续检测到64(如果出现误判可以再次翻倍)个正确的数据头部时,才会判定数据头已经对齐。
  • 在Xilinx 例子工程的Block_syn模块中,在对其之后也会一直检测是否有错误的数据头,并对计数器进行复位,而本模块没有对计数器进行复位。

本模块字节对齐过程:

可以看到当字节对齐之后,无效头计数器的数值应该都为0,只有有效数据头计数器在一直增加。

挡在同步过程中检测到一个无效的数据头(黄色数据线的地方)便会重新启动字节同步

例子工程的块对齐模块:

可以看到在对其之后,begin信号会一直对计数器进行复位。

2、PHY RX模块

PHY RX模块的主要功能就是解帧以及大小端转换、字节对齐。

  • 由于64B/66B编码判定传输开始和传输结束是通过不同的数据帧进行的,所以就要对接收到的数据帧进行解帧
  • 在此过程中需要注意将GT IP传输过来的阿小端的数据转换为我们经常使用的大端的接口数据。
  • 字节对齐,也就是在解帧的过程中要去除控制字符,并将接口的形式转换为AXI-Streaming接口的形式。在这里要特别注意EOF帧的在转换过程中Keep信号的处理。

在接收数据的时候需要注意,每隔32个时钟周期就有一个无效的数据发送过来,在设计的过程中需要考虑垓情况。尤其在刚接收到SOF帧后紧接着后面的无效数据,这种情况,要单独讨论,接收端的r_invalid便是用来处理此种情况。(这个需要后期在仔细思考)。

主要代码:

assign w_sof         = ri_rx_header_valid & ri_rx_header == 2'b10 & ri_rx_data[7 :0] == 8'h71 & ri_rx_valid;
assign w_eof         = ri_rx_header_valid & ri_rx_header == 2'b10 & (ri_rx_data[7 :0] == 8'h99 ||ri_rx_data[7 :0] == 8'h8e ||ri_rx_data[7 :0] == 8'hff ||ri_rx_data[7 :0] == 8'he8 ||ri_rx_data[7 :0] == 8'hd4 ||ri_rx_data[7 :0] == 8'hc3 ||ri_rx_data[7 :0] == 8'hb2 ||ri_rx_data[7 :0] == 8'ha5 ) & ri_rx_valid;
assign w_eof_s1     = i_rx_header_valid & i_rx_header == 2'b10 & (i_rx_data[7 :0] == 8'h99 ||i_rx_data[7 :0] == 8'h8e ||i_rx_data[7 :0] == 8'hff ||i_rx_data[7 :0] == 8'he8 ||i_rx_data[7 :0] == 8'hd4 ||i_rx_data[7 :0] == 8'hc3 ||i_rx_data[7 :0] == 8'hb2 ||i_rx_data[7 :0] == 8'ha5 ) & i_rx_valid;
assign w_eof_local = ri_rx_data[7 :0] == 8'h99 ? 1 : ri_rx_data[7 :0] == 8'h8e ? 8 :ri_rx_data[7 :0] == 8'hff ? 7 :ri_rx_data[7 :0] == 8'he8 ? 6 :ri_rx_data[7 :0] == 8'hd4 ? 5 :ri_rx_data[7 :0] == 8'hc3 ? 4 :ri_rx_data[7 :0] == 8'hb2 ? 3 :ri_rx_data[7 :0] == 8'ha5 ? 2 :'d0;
assign w_eof_local_s1 = i_rx_data[7 :0] == 8'h99 ? 1 : i_rx_data[7 :0] == 8'h8e ? 8 :i_rx_data[7 :0] == 8'hff ? 7 :i_rx_data[7 :0] == 8'he8 ? 6 :i_rx_data[7 :0] == 8'hd4 ? 5 :i_rx_data[7 :0] == 8'hc3 ? 4 :i_rx_data[7 :0] == 8'hb2 ? 3 :i_rx_data[7 :0] == 8'ha5 ? 2 :'d0;
always@(posedge i_rx_clk,posedge i_rx_rst)
beginif(i_rx_rst) beginri_rx_data          <= 'd0;ri_rx_valid         <= 'd0;ri_rx_valid_1d      <= 'd0;ri_rx_header        <= 'd0;ri_rx_header_valid  <= 'd0;end else beginri_rx_data          <= i_rx_data            ;ri_rx_valid         <= i_rx_valid           ;ri_rx_valid_1d      <= ri_rx_valid          ;ri_rx_header        <= i_rx_header          ;ri_rx_header_valid  <= i_rx_header_valid    ;end 
endalways@(posedge i_rx_clk,posedge i_rx_rst)
beginif(i_rx_rst)ri_rx_data_1d       <= 'd0;else if(ri_rx_valid)ri_rx_data_1d       <= ri_rx_data           ;else ri_rx_data_1d       <= ri_rx_data_1d        ;
end
always@(posedge i_rx_clk,posedge i_rx_rst)
beginif(i_rx_rst) beginr_sof <= 'd0;r_eof <= 'd0;r_eof_local <= 'd0;end else beginr_sof <= w_sof;r_eof <= w_eof;r_eof_local <= w_eof_local;end
endalways@(posedge i_rx_clk,posedge i_rx_rst)
beginif(i_rx_rst)r_receiving <= 'd0;else if(r_eof)r_receiving <= 'd0;else if(w_sof)r_receiving <= 'd1;else r_receiving <= r_receiving;
end// always@(posedge i_rx_clk,posedge i_rx_rst)
// begin
//     if(i_rx_rst)
//         rm_axis_data <= 'd0;
//     else if(r_receiving)
//         s
//     else 
//         rm_axis_data <= rm_axis_data;
// endalways@(posedge i_rx_clk,posedge i_rx_rst)
beginif(i_rx_rst)rm_axis_data <= 'd0;else if(r_eof && r_eof_local < 8)rm_axis_data <= {ri_rx_data_1d[63:16]};else if(w_eof && w_eof_local < 8)rm_axis_data <= {ri_rx_data[15:8],ri_rx_data_1d[63:8]};else if(w_eof && (w_eof_local == 8 || w_eof_local == 1))rm_axis_data <= {ri_rx_data[7 :0],ri_rx_data_1d[63:8]};else if(r_receiving && ri_rx_valid)rm_axis_data <= {ri_rx_data[7 :0],ri_rx_data_1d[63:8]};else rm_axis_data <= 'd0;
endalways@(posedge i_rx_clk,posedge i_rx_rst)
beginif(i_rx_rst)rm_axis_keep <= 8'b1111_1111;else if(r_eof && (r_eof_local >1 && r_eof_local < 8))case(r_eof_local)1           :rm_axis_keep <= 8'b1111_1111;2           :rm_axis_keep <= 8'b1000_0000;3           :rm_axis_keep <= 8'b1100_0000;4           :rm_axis_keep <= 8'b1110_0000;5           :rm_axis_keep <= 8'b1111_0000;6           :rm_axis_keep <= 8'b1111_1000;7           :rm_axis_keep <= 8'b1111_1100;8           :rm_axis_keep <= 8'b1111_1110;default     :rm_axis_keep <= 8'b1111_1111;endcaseelse if(w_eof && (w_eof_local == 8 || w_eof_local == 1))case(w_eof_local)1           :rm_axis_keep <= 8'b1111_1111;2           :rm_axis_keep <= 8'b1000_0000;3           :rm_axis_keep <= 8'b1100_0000;4           :rm_axis_keep <= 8'b1110_0000;5           :rm_axis_keep <= 8'b1111_0000;6           :rm_axis_keep <= 8'b1111_1000;7           :rm_axis_keep <= 8'b1111_1100;8           :rm_axis_keep <= 8'b1111_1110;default     :rm_axis_keep <= 8'b1111_1111;endcase// else if(w_eof_s1 && w_eof_local_s1 == 8)   //         rm_axis_keep <= 8'b1111_1111;else rm_axis_keep <= 8'b1111_1111;
endalways@(posedge i_rx_clk,posedge i_rx_rst)
beginif(i_rx_rst)rm_axis_last <= 'd0;else if(rm_axis_last && rm_axis_valid)rm_axis_last <= 'd0;else if(rm_axis_valid && r_eof && (r_eof_local >1 && r_eof_local < 8))rm_axis_last <= 'd1;else if(rm_axis_valid && w_eof && (w_eof_local == 8 || w_eof_local == 1))rm_axis_last <= 'd1;else rm_axis_last <= rm_axis_last;
endalways@(posedge i_rx_clk,posedge i_rx_rst)
beginif(i_rx_rst)rm_axis_valid <= 'd0;else if(r_sof)rm_axis_valid <= 'd1;else if(rm_axis_last && rm_axis_valid)rm_axis_valid <= 'd0;else if((!ri_rx_valid && ri_rx_header != 2'b10) || r_invalid)rm_axis_valid <= 'd0;else if(r_revalid)rm_axis_valid <= 'd1;else rm_axis_valid <= rm_axis_valid;
endalways@(posedge i_rx_clk,posedge i_rx_rst)
beginif(i_rx_rst)r_revalid <= 'd0;else if(r_invalid)r_revalid <= 'd1;else if(!rm_axis_last && rm_axis_valid && !ri_rx_valid && ri_rx_valid_1d)r_revalid <= 'd1;else r_revalid <= 'd0;
endalways@(posedge i_rx_clk,posedge i_rx_rst)
beginif(i_rx_rst)r_invalid <= 'd0;else if(r_sof & !ri_rx_valid)r_invalid <= 'd1;else r_invalid <= 'd0;
end

 五、上板测试

上板测试如下,GT 放置两个通道,两个通道之间互相发送和接收数据。

六、总结 

商用的PHY芯片肯定比这些要复杂的多,我们在这边只要了解64B/66B编码的原因,以及PHY的原理和处理过程、思想就好了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/584.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

docker环境搭建

项目环境搭建 1、安装 Linux 虚拟机 &#xff08;1&#xff09;下载安装&#xff1a; VM VirtualBox 下载安装&#xff1a;Downloads – Oracle VM VirtualBox&#xff0c;要先开启CPU虚拟化 &#xff08;2&#xff09;通过vagrant&#xff0c;在VirtualBox中安装虚拟机 下…

STM32学习和实践笔记(15):STM32中断系统

中断概念 CPU执行程序时&#xff0c;由于发生了某种随机的事件(外部或内部)&#xff0c;引起CPU暂 时中断正在运行的程序&#xff0c;转去执行一段特殊的服务程序(中断服务子程序 或中断处理程序)&#xff0c;以处理该事件&#xff0c;该事件处理完后又返回被中断的程序 继…

MySQL基础-----约束详解

目录 一. 概述: 二.约束演示&#xff1a; 三.外键约束&#xff1a; 3.1介绍&#xff1a; 3.2外键约束语法&#xff1a; 3.3删除&#xff0c;更新行为&#xff1a; 一. 概述: &#x1f9d0;&#x1f9d0;概念&#xff1a;约束是作用于表中字段上的规则&#xff0c;用于限制…

css面试题整理

css面试题 一、HTML语义化标签二、块级元素、内联元素、 行内块元素三、盒模型 一、HTML语义化标签 什么是HTML语义化标签&#xff1f;语义化标签的优势&#xff1f; HTML语义化标签顾名思义就是赋予标签含义&#xff0c;比如说<p>标签代表的是段落&#xff0c;还有<…

springboot结合vue实现文件上传下载功能

紧接着上一次的博客&#xff0c;这次来实现一下文件(主要是图片)的上传和下载功能&#xff0c;上一次的博客如下所示&#xff1a; Springboot集成JWT token实现权限验证-CSDN博客 其实文件的上传和下载功能(后端的部分)&#xff0c;在我之前的博客就已经有写了&#xff0c;所以…

LD-Pruner、EdgeFusion(On-Device T2I)、FreeDiff、TextCenGen、MemLLM

本文首发于公众号&#xff1a;机器感知 https://mp.weixin.qq.com/s/KiyNfwYWU-wBiCO-hE9qkA 苏 The devil is in the object boundary: towards annotation-free instance segmentation using Foundation Models Foundation models, pre-trained on a large amount of data…

# 从浅入深 学习 SpringCloud 微服务架构(三)注册中心 Eureka(1)

从浅入深 学习 SpringCloud 微服务架构&#xff08;三&#xff09;注册中心 Eureka&#xff08;1&#xff09; 段子手168 1、微服务的注册中心 注册中心可以说是微服务架构中的”通讯录”&#xff0c;它记录了服务和服务地址的映射关系。 在分布式架构中服务会注册到这里&am…

Docker使用教程及docker部署Vue项目

什么是Docker及其工作原理 虚拟化技术Docker是什么&#xff1f;三大基本术语核心算法原理和具体操作步骤 Docker和传统虚拟化技术区别为什么使用Docker&#xff1f;Docker有什么作用&#xff1f;1.解决应用部署的环境问题遇到问题达到效果 2.容器化 docker的各种命令解释运行机…

6.GodotCanvasItem、Node2D及自定义节点

CanvasItem节点 CanvasItem节点&#xff0c;CanvasItem -> Node&#xff0c;所以CanvasItem继承了Node的所有功能Canvas是画布的意思&#xff0c;所以CanvasItem代表了就是可以被绘制的节点&#xff0c;可以设置可视化界面和材质的颜色所有的2D节点和GUI节点都继承于CanvasI…

网络行为分析与异常检测

构建防火墙和使用简单的安全解决方案不足以保护网络免受网络异常或攻击&#xff0c;因为DDoS攻击、未知恶意软件和其他安全威胁一直在上升&#xff0c;改变了网络安全格局。网络管理员必须积极主动地分析网络&#xff0c;获得对网络的完全控制&#xff0c;并全面了解网络流量活…

访问云平台中linux系统图形化界面,登录就出现黑屏的问题解决(ubuntu图形界面)

目录 一、问题-图形化界面访问黑屏 二、系统环境 &#xff08;一&#xff09;网络结构示意图 &#xff08;二&#xff09;内部机器版本 三、分析 四、解决过程 &#xff08;一&#xff09;通过MobaXterm远程访问图形化界面(未成功) 1、连接方法 2、连接结果 &#xf…

acwing-y总基础课算法笔记整理

技巧 vector, 变长数组&#xff0c;倍增的思想size() 返回元素个数 capacity() 容量empty() 返回是否为空clear() 清空front()/back()push_back()/pop_back()begin()/end()[]支持比较运算&#xff0c;按字典序pair<int, int>first, 第一个元素second, 第二个元素支持…

pt格式文件转engine小记【yolov5-6.0版本】

背景 项目是使用yolov5-6.0的版本&#xff0c;需要加一个新模型进去&#xff0c;yolov5提供的类别有很多&#xff0c;我这里使用chair椅子。第一步就是先把提供的pt文件转化为tensorrt所需要的engine格式的文件&#xff0c;在官网上有提供转换方法。&#xff08;似乎高版本的y…

查看apk是64位32位(三种方法)

通过检查APK文件&#xff0c;你可以确定该APK支持的架构类型&#xff0c;包括它是为64位&#xff08;例如arm64-v8a、x86_64&#xff09;还是32位&#xff08;例如armeabi-v7a、x86&#xff09;架构准备的。Android应用程序可以包含多个不同的二进制文件&#xff0c;每个文件针…

1097 矩阵行平移(语文题,选做)

输入样例&#xff1a; 7 2 99 11 87 23 67 20 75 89 37 94 27 91 63 50 11 44 38 50 26 40 26 24 73 85 63 28 62 18 68 15 83 27 97 88 25 43 23 78 98 20 30 81 99 77 36 48 59 25 34 22 输出样例&#xff1a; 529 481 479 263 417 342 343 样例解读 需要平移的是第 1、…

【Java】常见锁策略 CAS机制 锁优化策略

前言 在本文会详细介绍各种锁策略、CAS机制以及锁优化策略 不仅仅局限于Java&#xff0c;任何和锁相关的话题&#xff0c;都可能会涉及到下面的内容。 这些特性主要是给锁的实现者来参考的. 普通的程序猿也需要了解一些, 对于合理的使用锁也是有很大帮助的 文章目录 前言✍一、…

Spring Boot 2.x 将 logback 1.2.x 升级至 1.3.x

场景 安全部门针对代码进行漏洞扫描时&#xff0c;发现 logback-core 和 logback-classic 都属于 1.2.x 版本&#xff0c;这个版本存在 CVE 漏洞&#xff0c;并且建议升级到 1.3.x 版本。 问题 将两个包直接升级到 1.3.x 版本时&#xff0c;Spring Boot Web 服务启动直接出现…

CNN卷积神经网络之LeNet-5原理与实战

文章目录 CNN卷积神经网络之LeNet-5原理与实战1、LeNet-5网络结构&#xff1a;1.1、LeNet-5由两个部分组成&#xff1a;1.2、模型单元结构&#xff1a;1.3、数据的传输&#xff1a; 2、LeNet-5网络参数详解&#xff1a; CNN卷积神经网络之LeNet-5原理与实战 1、LeNet-5网络结构…

MySql8快速迁移版的制作过程

首先说明&#xff0c;mysql 8的安装不同与mysql5.x。 做程序的朋友都知道&#xff0c;程序好做&#xff0c;客户难伺候&#xff0c;因为限于用户的情况&#xff0c;如何能让用户把程序运行起来很关键&#xff0c;比如日前我在做 山东高中信息技术 学考 考前练习 系统时&#x…

VirtualBox虚拟机使用win11系统,忘记密码如何重置密码

1. 点击重启同时按住Shift&#xff08;按住不放&#xff09; 2. 直到出现下面的界面&#xff0c;释放Shift&#xff0c;并进入疑难解答 3. 进入高级选项 4. 进入命令提示符 5. 发现当前是在X盘&#xff1f; 6. 进入C:\Windows\System32 c: cd Windows\System32 7. 备份osk.exe…