文章目录
- 前言
- 一、设计框图
- 1.1、xxv_ethernet_0
- 1.2、xxv_ethernet_0_sharedlogic_wrapper
- 1.3、xxv_ethernet_0_clocking_wrapper
- 1.4、xxv_ethernet_0_common_wrapper
- 二、IP核配置
- 三、仿真
- 四、上板测速
- 五、总结
前言
前面我们学习了很多基于XILINX 7系列的高速接口使用,本文将介绍xilinx UltraScale+的10G/25G Ethernet Subsystem IP核的使用。大体使用与7系列相差无几,甚至更加简单。大家如果看过7系列那部分的内容,这个上手非常快。
一、设计框图
)
设计框图与7系列大致相似。直接使用官方例程也是可以的,但是这样子更加清晰,我们自己将来使用的时候更加方便,在梳理的过程中也可以加深印象。
1.1、xxv_ethernet_0
xxv_ethernet_0 xxv_ethernet_u0 (
.gt_txp_out (o_gt_txp ), // output wire [0 : 0] gt_txp_out
.gt_txn_out (o_gt_txn ), // output wire [0 : 0] gt_txn_out
.gt_rxp_in (i_gt_rxp ), // input wire [0 : 0] gt_rxp_in
.gt_rxn_in (i_gt_rxn ), // input wire [0 : 0] gt_rxn_in
.rx_core_clk_0 (w_rx_core_clk ), // input wire rx_core_clk_0
.rx_serdes_reset_0 (w_rx_serdes_reset ), // input wire rx_serdes_reset_0
.txoutclksel_in_0 (3'b101 ), // input wire [2 : 0] txoutclksel_in_0
.rxoutclksel_in_0 (3'b101 ), // input wire [2 : 0] rxoutclksel_in_0
.rxrecclkout_0 (w_rxrecclkout ), // output wire rxrecclkout_0
.sys_reset (i_sys_reset ), // input wire sys_reset
.dclk (i_dclk ), // input wire dclk
.tx_clk_out_0 (o_tx_clk_out ), // output wire tx_clk_out_0
.rx_clk_out_0 (o_rx_clk_out ), // output wire rx_clk_out_0
.gtpowergood_out_0 (), // output wire gtpowergood_out_0
.qpll0clk_in (i_qpll0outclk ), // input wire [0 : 0] qpll0clk_in
.qpll0refclk_in (i_qpll0outrefclk ), // input wire [0 : 0] qpll0refclk_in
.qpll1clk_in (i_qpll1outclk ), // input wire [0 : 0] qpll1clk_in
.qpll1refclk_in (i_qpll1outrefclk ), // input wire [0 : 0] qpll1refclk_in
.gtwiz_reset_qpll0lock_in (i_qpll0lock ), // input wire gtwiz_reset_qpll0lock_in
.gtwiz_reset_qpll0reset_out (o_qpll0reset ), // output wire gtwiz_reset_qpll0reset_out
.gtwiz_reset_qpll1lock_in (i_qpll1lock ), // input wire gtwiz_reset_qpll1lock_in
.gtwiz_reset_qpll1reset_out (o_qpll1reset ), // output wire gtwiz_reset_qpll1reset_out
.gt_reset_tx_done_out_0 (w_gt_reset_tx_done ), // output wire gt_reset_tx_done_out_0
.gt_reset_rx_done_out_0 (w_gt_reset_rx_done ), // output wire gt_reset_rx_done_out_0
.gt_reset_all_in_0 (w_gtwiz_reset_all ), // input wire gt_reset_all_in_0
.gt_tx_reset_in_0 (w_gtwiz_reset_tx_datapath ), // input wire gt_tx_reset_in_0
.gt_rx_reset_in_0 (w_gtwiz_reset_rx_datapath ), // input wire gt_rx_reset_in_0
.rx_reset_0 (w_rx_core_reset ), // input wire rx_reset_0
.rx_axis_tvalid_0 (rx_axis_tvalid ), // output wire rx_axis_tvalid_0
.rx_axis_tdata_0 (rx_axis_tdata ), // output wire [63 : 0] rx_axis_tdata_0
.rx_axis_tlast_0 (rx_axis_tlast ), // output wire rx_axis_tlast_0
.rx_axis_tkeep_0 (rx_axis_tkeep ), // output wire [7 : 0] rx_axis_tkeep_0
.rx_axis_tuser_0 (rx_axis_tuser ), // output wire rx_axis_tuser_0
.ctl_rx_enable_0 (ctl_rx_enable_0 ), // input wire ctl_rx_enable_0
.ctl_rx_check_preamble_0 (ctl_rx_check_preamble_0 ), // input wire ctl_rx_check_preamble_0
.ctl_rx_check_sfd_0 (ctl_rx_check_sfd_0 ), // input wire ctl_rx_check_sfd_0
.ctl_rx_force_resync_0 (ctl_rx_force_resync_0 ), // input wire ctl_rx_force_resync_0
.ctl_rx_delete_fcs_0 (ctl_rx_delete_fcs_0 ), // input wire ctl_rx_delete_fcs_0
.ctl_rx_ignore_fcs_0 (ctl_rx_ignore_fcs_0 ), // input wire ctl_rx_ignore_fcs_0
.ctl_rx_max_packet_len_0 (ctl_rx_max_packet_len_0 ), // input wire [14 : 0] ctl_rx_max_packet_len_0
.ctl_rx_min_packet_len_0 (ctl_rx_min_packet_len_0 ), // input wire [7 : 0] ctl_rx_min_packet_len_0
.ctl_rx_process_lfi_0 (ctl_rx_process_lfi_0 ), // input wire ctl_rx_process_lfi_0
.ctl_rx_test_pattern_0 (ctl_rx_test_pattern_0 ), // input wire ctl_rx_test_pattern_0
.ctl_rx_data_pattern_select_0 (ctl_rx_data_pattern_select_0 ), // input wire ctl_rx_data_pattern_select_0
.ctl_rx_test_pattern_enable_0 (ctl_rx_test_pattern_enable_0 ), // input wire ctl_rx_test_pattern_enable_0
.ctl_rx_custom_preamble_enable_0 (ctl_rx_custom_preamble_enable_0 ), // input wire ctl_rx_custom_preamble_enable_0
.stat_rx_framing_err_0 (stat_rx_framing_err_0 ), // output wire stat_rx_framing_err_0
.stat_rx_framing_err_valid_0 (stat_rx_framing_err_valid_0 ), // output wire stat_rx_framing_err_valid_0
.stat_rx_local_fault_0 (stat_rx_local_fault_0 ), // output wire stat_rx_local_fault_0
.stat_rx_block_lock_0 (stat_rx_block_lock_0 ), // output wire stat_rx_block_lock_0
.stat_rx_valid_ctrl_code_0 (stat_rx_valid_ctrl_code_0 ), // output wire stat_rx_valid_ctrl_code_0
.stat_rx_status_0 (o_stat_rx_status ), // output wire stat_rx_status_0
.stat_rx_remote_fault_0 (stat_rx_remote_fault_0 ), // output wire stat_rx_remote_fault_0
.stat_rx_bad_fcs_0 (stat_rx_bad_fcs_0 ), // output wire [1 : 0] stat_rx_bad_fcs_0_0
.stat_rx_stomped_fcs_0 (stat_rx_stomped_fcs_0 ), // output wire [1 : 0] stat_rx_stomped_fcs_0
.stat_rx_truncated_0 (stat_rx_truncated_0 ), // output wire stat_rx_truncated_0
.stat_rx_internal_local_fault_0 (stat_rx_internal_local_fault_0 ), // output wire stat_rx_internal_local_fault_0
.stat_rx_received_local_fault_0 (stat_rx_received_local_fault_0 ), // output wire stat_rx_received_local_fault_0
.stat_rx_hi_ber_0 (stat_rx_hi_ber_0 ), // output wire stat_rx_hi_ber_0
.stat_rx_got_signal_os_0 (stat_rx_got_signal_os_0 ), // output wire stat_rx_got_signal_os_0
.stat_rx_test_pattern_mismatch_0 (stat_rx_test_pattern_mismatch_0 ), // output wire stat_rx_test_pattern_mismatch_0
.stat_rx_total_bytes_0 (stat_rx_total_bytes_0 ), // output wire [3 : 0] stat_rx_total_bytes_0
.stat_rx_total_packets_0 (stat_rx_total_packets_0 ), // output wire [1 : 0] stat_rx_total_packets_0
.stat_rx_total_good_bytes_0 (stat_rx_total_good_bytes_0 ), // output wire [13 : 0] stat_rx_total_good_bytes_0
.stat_rx_total_good_packets_0 (stat_rx_total_good_packets_0 ), // output wire stat_rx_total_good_packets_0
.stat_rx_packet_bad_fcs_0 (stat_rx_packet_bad_fcs_0 ), // output wire stat_rx_packet_bad_fcs_0
.stat_rx_packet_64_bytes_0 (stat_rx_packet_64_bytes_0 ), // output wire stat_rx_packet_64_bytes_0
.stat_rx_packet_65_127_bytes_0 (stat_rx_packet_65_127_bytes_0 ), // output wire stat_rx_packet_65_127_bytes_0
.stat_rx_packet_128_255_bytes_0 (stat_rx_packet_128_255_bytes_0 ), // output wire stat_rx_packet_128_255_bytes_0
.stat_rx_packet_256_511_bytes_0 (stat_rx_packet_256_511_bytes_0 ), // output wire stat_rx_packet_256_511_bytes_0
.stat_rx_packet_512_1023_bytes_0 (stat_rx_packet_512_1023_bytes_0 ), // output wire stat_rx_packet_512_1023_bytes_0
.stat_rx_packet_1024_1518_bytes_0 (stat_rx_packet_1024_1518_bytes_0 ), // output wire stat_rx_packet_1024_1518_bytes_0
.stat_rx_packet_1519_1522_bytes_0 (stat_rx_packet_1519_1522_bytes_0 ), // output wire stat_rx_packet_1519_1522_bytes_0
.stat_rx_packet_1523_1548_bytes_0 (stat_rx_packet_1523_1548_bytes_0 ), // output wire stat_rx_packet_1523_1548_bytes_0
.stat_rx_packet_1549_2047_bytes_0 (stat_rx_packet_1549_2047_bytes_0 ), // output wire stat_rx_packet_1549_2047_bytes_0
.stat_rx_packet_2048_4095_bytes_0 (stat_rx_packet_2048_4095_bytes_0 ), // output wire stat_rx_packet_2048_4095_bytes_0
.stat_rx_packet_4096_8191_bytes_0 (stat_rx_packet_4096_8191_bytes_0 ), // output wire stat_rx_packet_4096_8191_bytes_0
.stat_rx_packet_8192_9215_bytes_0 (stat_rx_packet_8192_9215_bytes_0 ), // output wire stat_rx_packet_8192_9215_bytes_0
.stat_rx_packet_small_0 (stat_rx_packet_small_0 ), // output wire stat_rx_packet_small_0
.stat_rx_packet_large_0 (stat_rx_packet_large_0 ), // output wire stat_rx_packet_large_0
.stat_rx_unicast_0 (stat_rx_unicast_0 ), // output wire stat_rx_unicast_0
.stat_rx_multicast_0 (stat_rx_multicast_0 ), // output wire stat_rx_multicast_0
.stat_rx_broadcast_0 (stat_rx_broadcast_0 ), // output wire stat_rx_broadcast_0
.stat_rx_oversize_0 (stat_rx_oversize_0 ), // output wire stat_rx_oversize_0
.stat_rx_toolong_0 (stat_rx_toolong_0 ), // output wire stat_rx_toolong_0
.stat_rx_undersize_0 (stat_rx_undersize_0 ), // output wire stat_rx_undersize_0
.stat_rx_fragment_0 (stat_rx_fragment_0 ), // output wire stat_rx_fragment_0
.stat_rx_vlan_0 (stat_rx_vlan_0 ), // output wire stat_rx_vlan_0
.stat_rx_inrangeerr_0 (stat_rx_inrangeerr_0 ), // output wire stat_rx_inrangeerr_0
.stat_rx_jabber_0 (stat_rx_jabber_0 ), // output wire stat_rx_jabber_0
.stat_rx_bad_code_0 (stat_rx_bad_code_0 ), // output wire stat_rx_bad_code_0
.stat_rx_bad_sfd_0 (stat_rx_bad_sfd_0 ), // output wire stat_rx_bad_sfd_0
.stat_rx_bad_preamble_0 (stat_rx_bad_preamble_0 ), // output wire stat_rx_bad_preamble_0
.tx_reset_0 (w_tx_core_reset ), // input wire tx_reset_0
.tx_axis_tready_0 (tx_axis_tready ), // output wire tx_axis_tready_0
.tx_axis_tvalid_0 (tx_axis_tvalid ), // input wire tx_axis_tvalid_0
.tx_axis_tdata_0 (tx_axis_tdata ), // input wire [63 : 0] tx_axis_tdata_0
.tx_axis_tlast_0 (tx_axis_tlast ), // input wire tx_axis_tlast_0
.tx_axis_tkeep_0 (tx_axis_tkeep ), // input wire [7 : 0] tx_axis_tkeep_0
.tx_axis_tuser_0 (tx_axis_tuser ), // input wire tx_axis_tuser_0
.tx_unfout_0 (tx_unfout_0 ), // output wire tx_unfout_0
.tx_preamblein_0 (tx_preamblein_0 ), // input wire [55 : 0] tx_preamblein_0
.rx_preambleout_0 (rx_preambleout_0 ), // output wire [55 : 0] rx_preambleout_0
.stat_tx_local_fault_0 (stat_tx_local_fault_0 ), // output wire stat_tx_local_fault_0
.stat_tx_total_bytes_0 (stat_tx_total_bytes_0 ), // output wire [3 : 0] stat_tx_total_bytes_0_0
.stat_tx_total_packets_0 (stat_tx_total_packets_0 ), // output wire stat_tx_total_packets_0
.stat_tx_total_good_bytes_0 (stat_tx_total_good_bytes_0 ), // output wire [13 : 0] stat_tx_total_good_bytes_0
.stat_tx_total_good_packets_0 (stat_tx_total_good_packets_0 ), // output wire stat_tx_total_good_packets_0
.stat_tx_bad_fcs_0 (stat_tx_bad_fcs_0 ), // output wire stat_tx_bad_fcs_0
.stat_tx_packet_64_bytes_0 (stat_tx_packet_64_bytes_0 ), // output wire stat_tx_packet_64_bytes_0
.stat_tx_packet_65_127_bytes_0 (stat_tx_packet_65_127_bytes_0 ), // output wire stat_tx_packet_65_127_bytes_0
.stat_tx_packet_128_255_bytes_0 (stat_tx_packet_128_255_bytes_0 ), // output wire stat_tx_packet_128_255_bytes_0
.stat_tx_packet_256_511_bytes_0 (stat_tx_packet_256_511_bytes_0 ), // output wire stat_tx_packet_256_511_bytes_0
.stat_tx_packet_512_1023_bytes_0 (stat_tx_packet_512_1023_bytes_0 ), // output wire stat_tx_packet_512_1023_bytes_0
.stat_tx_packet_1024_1518_bytes_0 (stat_tx_packet_1024_1518_bytes_0 ), // output wire stat_tx_packet_1024_1518_bytes_0
.stat_tx_packet_1519_1522_bytes_0 (stat_tx_packet_1519_1522_bytes_0 ), // output wire stat_tx_packet_1519_1522_bytes_0
.stat_tx_packet_1523_1548_bytes_0 (stat_tx_packet_1523_1548_bytes_0 ), // output wire stat_tx_packet_1523_1548_bytes_0
.stat_tx_packet_1549_2047_bytes_0 (stat_tx_packet_1549_2047_bytes_0 ), // output wire stat_tx_packet_1549_2047_bytes_0
.stat_tx_packet_2048_4095_bytes_0 (stat_tx_packet_2048_4095_bytes_0 ), // output wire stat_tx_packet_2048_4095_bytes_0
.stat_tx_packet_4096_8191_bytes_0 (stat_tx_packet_4096_8191_bytes_0 ), // output wire stat_tx_packet_4096_8191_bytes_0
.stat_tx_packet_8192_9215_bytes_0 (stat_tx_packet_8192_9215_bytes_0 ), // output wire stat_tx_packet_8192_9215_bytes_0
.stat_tx_packet_small_0 (stat_tx_packet_small_0 ), // output wire stat_tx_packet_small_0
.stat_tx_packet_large_0 (stat_tx_packet_large_0 ), // output wire stat_tx_packet_large_0
.stat_tx_unicast_0 (stat_tx_unicast_0 ), // output wire stat_tx_unicast_0
.stat_tx_multicast_0 (stat_tx_multicast_0 ), // output wire stat_tx_multicast_0
.stat_tx_broadcast_0 (stat_tx_broadcast_0 ), // output wire stat_tx_broadcast_0
.stat_tx_vlan_0 (stat_tx_vlan_0 ), // output wire stat_tx_vlan_00
.stat_tx_frame_error_0 (stat_tx_frame_error_0 ), // output wire stat_tx_frame_error_0
.ctl_tx_enable_0 (ctl_tx_enable_0 ), // input wire ctl_tx_enable_0
.ctl_tx_send_rfi_0 (ctl_tx_send_rfi_0 ), // input wire ctl_tx_send_rfi_0
.ctl_tx_send_lfi_0 (ctl_tx_send_lfi_0 ), // input wire ctl_tx_send_lfi_0
.ctl_tx_send_idle_0 (ctl_tx_send_idle_0 ), // input wire ctl_tx_send_idle_0
.ctl_tx_fcs_ins_enable_0 (ctl_tx_fcs_ins_enable_0 ), // input wire ctl_tx_fcs_ins_enable_0
.ctl_tx_ignore_fcs_0 (ctl_tx_ignore_fcs_0 ), // input wire ctl_tx_ignore_fcs_0
.ctl_tx_test_pattern_0 (ctl_tx_test_pattern_0 ), // input wire ctl_tx_test_pattern_0
.ctl_tx_test_pattern_enable_0 (ctl_tx_test_pattern_enable_0 ), // input wire ctl_tx_test_pattern_enable_0
.ctl_tx_test_pattern_select_0 (ctl_tx_test_pattern_select_0 ), // input wire ctl_tx_test_pattern_select_0
.ctl_tx_data_pattern_select_0 (ctl_tx_data_pattern_select_0 ), // input wire ctl_tx_data_pattern_select_0
.ctl_tx_test_pattern_seed_a_0 (ctl_tx_test_pattern_seed_a_0 ), // input wire [57 : 0] ctl_tx_test_pattern_seed_a_0
.ctl_tx_test_pattern_seed_b_0 (ctl_tx_test_pattern_seed_b_0 ), // input wire [57 : 0] ctl_tx_test_pattern_seed_b_0
.ctl_tx_ipg_value_0 (ctl_tx_ipg_value_0 ), // input wire [3 : 0] ctl_tx_ipg_value_0
.ctl_tx_custom_preamble_enable_0 (ctl_tx_custom_preamble_enable_0 ), // input wire ctl_tx_custom_preamble_enable_0
.gt_loopback_in_0 (3'b000 ) // input wire [2 : 0] gt_loopback_in_0
);
xxv_ethernet_0模块就是例化的IP核。(里面一大堆控制信号和状态信号),但大部分无需关注,关注以下信号即可:
信号具体含义可查阅xilinx手册pg210,有中文的,阅读起来很快。一般就按照我这么配置即可,这样配置的情况下我们用户无需关注前导码和纠错码,MAC帧只需要用户处理目的地址、源地址、类型/长度和数据。如果有特殊需求,比如自定义前导码什么的,可以查看手册。
assign w_rx_core_clk = o_tx_clk_out;
/*----ctrl rx----*/
assign ctl_rx_enable_0 = 1'b1 ;
assign ctl_rx_check_preamble_0 = 1'b1 ;
assign ctl_rx_check_sfd_0 = 1'b1 ;
assign ctl_rx_force_resync_0 = 1'b0 ;
assign ctl_rx_delete_fcs_0 = 1'b1 ;
assign ctl_rx_ignore_fcs_0 = 1'b0 ;
assign ctl_rx_max_packet_len_0 = P_MAX_LENGTH ;
assign ctl_rx_min_packet_len_0 = P_MIN_LENGTH ;
assign ctl_rx_process_lfi_0 = 1'b0 ;
assign ctl_rx_test_pattern_0 = 1'b0 ;
assign ctl_rx_test_pattern_enable_0 = 1'b0 ;
assign ctl_rx_data_pattern_select_0 = 1'b0 ;
assign ctl_rx_custom_preamble_enable_0 = 1'b0 ;
/*----tx single----*/
assign tx_preamblein_0 = 55'h55_55_55_55_55_55_55;
assign tx_reset_0 = 1'b0 ;
assign ctl_tx_enable_0 = 1'b1 ;
assign ctl_tx_send_rfi_0 = 1'b0 ;
assign ctl_tx_send_lfi_0 = 1'b0 ;
assign ctl_tx_send_idle_0 = 1'b0 ;
assign ctl_tx_fcs_ins_enable_0 = 1'b1 ;
assign ctl_tx_ignore_fcs_0 = 1'b0 ;
assign ctl_tx_test_pattern_0 = 'd0 ;
assign ctl_tx_test_pattern_enable_0 = 'd0 ;
assign ctl_tx_test_pattern_select_0 = 'd0 ;
assign ctl_tx_data_pattern_select_0 = 'd0 ;
assign ctl_tx_test_pattern_seed_a_0 = 'd0 ;
assign ctl_tx_test_pattern_seed_b_0 = 'd0 ;
assign ctl_tx_ipg_value_0 = 4'd12 ;
assign ctl_tx_custom_preamble_enable_0 = 1'b0 ;
1.2、xxv_ethernet_0_sharedlogic_wrapper
xxv_ethernet_0_sharedlogic_wrapper是共享逻辑模块,这是example design当中的模块,这里面处理了GT参考时钟差分转单端、QPLL共享时钟核产生用户各种复位信号,但是我进行了简单的修改方便我们进行设计。
以下为我修改后的代码,简单而言就是将其中的GT参考时钟差分转单端的模块xxv_ethernet_0_clocking_wrapper核QPLL共享时钟逻辑模块xxv_ethernet_0_clocking_wrapper全部都拉了出来,在上层uplus_ten_gig_module模块当中进行例化,这样就可以方便我们用户在uplus_ten_gig_module当中通过例化多个uplus_ten_gig_channel模块来实现多通道数据传输的过程。(不过在U+当中我们直接在IP核配置的时候选择多个core也是非常简单的,不过按照本文当中这样子做会清晰不少)
module xxv_ethernet_0_sharedlogic_wrapper (
// input gt_refclk_p,
// input gt_refclk_n,
// output gt_refclk_out,
//input i_gt_ref_clk,
// input [0:0] qpll0reset,
// output [0:0] qpll0lock,
// output [0:0] qpll0outclk,
// output [0:0] qpll0outrefclk,
// input [0:0] qpll1reset,
// output [0:0] qpll1lock,
// output [0:0] qpll1outclk,
// output [0:0] qpll1outrefclk,
input wire gt_txusrclk2_0,
input wire gt_rxusrclk2_0,
input wire rx_core_clk_0,
input wire gt_tx_reset_in_0,
input wire gt_rx_reset_in_0,
input wire tx_core_reset_in_0,
input wire rx_core_reset_in_0,
output wire tx_core_reset_out_0,
output wire rx_core_reset_out_0,
output wire rx_serdes_reset_out_0,
output wire usr_tx_reset_0,
output wire usr_rx_reset_0,
output wire gtwiz_reset_all_0,
output wire gtwiz_reset_tx_datapath_out_0,
output wire gtwiz_reset_rx_datapath_out_0,
input wire sys_reset,
input wire dclk
);
//wire gt_ref_clk;
// xxv_ethernet_0_clocking_wrapper i_xxv_ethernet_0_clocking_wrapper(
// .gt_refclk_p (gt_refclk_p),
// .gt_refclk_n (gt_refclk_n),
// .gt_refclk_out (gt_refclk_out),
// .gt_refclk (gt_ref_clk));
// xxv_ethernet_0_common_wrapper i_xxv_ethernet_0_common_wrapper
// (
// .refclk(i_gt_ref_clk),
// .qpll0reset(qpll0reset),
// .qpll0lock(qpll0lock),
// .qpll0outclk(qpll0outclk),
// .qpll0outrefclk(qpll0outrefclk),
// .qpll1reset (qpll1reset),
// .qpll1lock (qpll1lock),
// .qpll1outclk (qpll1outclk),
// .qpll1outrefclk (qpll1outrefclk)
// );
xxv_ethernet_0_reset_wrapper i_xxv_ethernet_0_reset_wrapper_0(
.gt_txusrclk2 (gt_txusrclk2_0),
.gt_rxusrclk2 (gt_rxusrclk2_0),
.rx_core_clk (rx_core_clk_0),
.gt_tx_reset_in (gt_tx_reset_in_0),
.gt_rx_reset_in (gt_rx_reset_in_0),
.tx_core_reset_in (tx_core_reset_in_0),
.rx_core_reset_in (rx_core_reset_in_0),
.tx_core_reset_out (tx_core_reset_out_0),
.rx_core_reset_out (rx_core_reset_out_0),
.rx_serdes_reset_out (rx_serdes_reset_out_0),
.usr_tx_reset (usr_tx_reset_0),
.usr_rx_reset (usr_rx_reset_0),
.gtwiz_reset_all (gtwiz_reset_all_0),
.gtwiz_reset_tx_datapath_out (gtwiz_reset_tx_datapath_out_0),
.gtwiz_reset_rx_datapath_out (gtwiz_reset_rx_datapath_out_0),
.sys_reset (sys_reset),
.dclk (dclk)
);
endmodule
1.3、xxv_ethernet_0_clocking_wrapper
该模块里面就是例化了IBUFDS_GTE4原语
1.4、xxv_ethernet_0_common_wrapper
QPLL的相关操作,较为复杂,不用关注太多。
二、IP核配置
第一页就是选选位宽,线速率和通道数
选这个FIFO可以让发送和接收的用户逻辑处于用一个时钟域,将o_tx_clk_out赋值于w_rx_core_clk 即可
assign w_rx_core_clk = o_tx_clk_out;
参考时钟按道理一般来说都是156.25Mhz,但我的板卡是通过FMCP拓展的SFP,它只能提供312,5Mhz数据,用起来好像没有问题,我测试过和使用156.25Mhz参考时钟的其他U+板卡进行通信,并没有任何问题。最后产生的用户时钟都是156.25Mhz。
想使用我这套模板使用这个IP核需要将共享逻辑拉出来(上图),如果直接在第一页勾选多个通道,完全可以将共享逻辑包含在IP核内,IP核会产生一大堆信号,会带有通道编号(下图),使用起来也特别简单,就是不好整理也不好拓展。。。
三、仿真
AXIS_gen_module模块是自己写的一个AXIS数据产生模块,用于仿真和上板测试。在产生用户数据的时候,需要关注stat_rx_status_0信号,该信号拉高说明整个IP核各种同步都结束了,用户此时可以正常发送和接收数据了。
四、上板测速
与之前讲的7系列测速方法一样,产生的数据长度为186时钟周期,也就是1488字节数据,以此观察网卡接收带宽。
五、总结
完整工程参考:https://github.com/shun6-6/U_10g_eth_design