最近调试lattice 的sgmii接口。 项目最初的架构大概是这样的,用于调试。
FPGA这边的架构,就是 Tri_mac 转为 sgmii,然后再通过pcs出去。其实sgmii核自带了一个pcs核,最坑人的是PCS必须是外部时钟,最后没有办法只能自己生成一个pcs核和sgmii核对接起来。由于MDIO,我们这边没有去使用。使用的是强制输出。我调试了两天才发现可能是交换机这边设置可能有问题,这边使用的 BCM56634,一开始也不熟悉,最后去请教了别人才把自动连接把它关了。然后ok了。我把交换机芯片这边的配置如下:
最后附上我serdes这边的代码;
`timescale 1ns/100ps module top_hb ( // G/MII Interface data_in_mii, en_in_mii, err_in_mii, data_out_mii, dv_out_mii, err_out_mii, col_out_mii, crs_out_mii, // GB Timing References in_clk_125, in_ce_sink, in_ce_source, out_clk_125, out_ce_sink, out_ce_source, // SERIAL GMII Interface refclkp, refclkn, hdinp0, hdinn0, hdoutp0, hdoutn0, // Control Interface gbe_mode, sgmii_mode, rst_n, // Host Bus hclk, hcs_n, hwrite_n, haddr, hdatain, hdataout, hready_n, //Debug Port debug_link_timer_short, mr_an_complete ); // I/O Declarations input rst_n; // System Reset, Active Low input hclk; input gbe_mode ; // GBE Mode (0=SGMII 1=GBE) input sgmii_mode ; // SGMII PCS Mode (0=MAC 1=PHY) input in_clk_125 ; // GMII Input Data Path clock 125Mhz input in_ce_sink ; output in_ce_source ; input [7:0] data_in_mii; // G/MII Incoming Data input en_in_mii; // G/MII Incoming Data Valid input err_in_mii; // G/MII Incoming Error input out_clk_125 ; // GMII Output Data Path clock 125Mhz input out_ce_sink ; output out_ce_source ; output [7:0] data_out_mii; // G/MII Outgoing Data output dv_out_mii; // G/MII Outgoing Data Valid output err_out_mii; // G/MII Outgoing Error output col_out_mii; // G/MII Collision Detect output crs_out_mii; // G/MII Carrier Sense Detect input refclkp; input refclkn; // exemplar attribute refclkp NOPAD true // exemplar attribute refclkn NOPAD true input hdinp0; // Incoming SGMII (on SERDES) input hdinn0; // Incoming SGMII (on SERDES) // exemplar attribute hdinp0 NOPAD true // exemplar attribute hdinn0 NOPAD true output hdoutp0; // Outgoing SGMII (on SERDES) output hdoutn0; // Outgoing SGMII (on SERDES) // exemplar attribute hdoutp0 NOPAD true // exemplar attribute hdoutn0 NOPAD true input hcs_n; input hwrite_n; input [5:0] haddr; input [7:0] hdatain; output [7:0] hdataout; output hready_n; input debug_link_timer_short; output mr_an_complete; // Primary G/MII Outputs -- Latched Before Leaving FPGA reg [7:0] data_out_mii; reg dv_out_mii; reg err_out_mii; reg col_out_mii; reg crs_out_mii; // G/MII Signals from input latches to SGMII channel reg [7:0] data_buf2chan; reg en_buf2chan; reg err_buf2chan; // G/MII Signals from SGMII channel to output latches wire [7:0] data_chan2buf; wire dv_chan2buf; wire err_chan2buf; wire col_chan2buf; wire crs_chan2buf; // 8-bit Interface Signals from SGMII channel to QuadPCS/SERDES wire [7:0] data_chan2quad; wire kcntl_chan2quad; wire disparity_cntl_chan2quad; wire xmit_autoneg; // 8-bit Interface Signals from QuadPCS/SERDES to SGMII channel wire [7:0] data_quad2chan; wire kcntl_quad2chan; wire disp_err_quad2chan; wire cv_err_quad2chan; wire link_status; wire serdes_recovered_clk; wire refclk2fpga; // Misc Signals wire mdin; wire mdout; wire mdout_en; wire mr_an_enable; wire mr_restart_an; wire [15:0] mr_adv_ability; wire mr_an_complete; wire mr_page_rx; wire [15:0] mr_lp_adv_ability; wire mr_main_reset; wire mr_loopback_enable; wire [1:0] mr_speed_selection; wire mr_power_down; wire mr_isolate; wire mr_duplex_mode; wire mr_col_test; wire mr_unidir_enable; wire an_link_ok; wire debug_link_timer_short; wire [1:0] operational_rate; wire tx_pll_lol; wire rx_cdr_lol; wire quad_rst; wire tx_pcs_rst; wire rx_pcs_rst; wire rx_serdes_rst; wire nc_1; wire nc_2; wire nc_3; // Active High Reset wire rst; ///assign rst = ~rst_n; // Instantiate Global Reset Controller //GSR GSR_INST (.GSR(rst_n)); //PUR PUR_INST (.PUR(1'b1)); tx_reset_sm tx_reset_sm ( .rst_n (rst_n), .refclkdiv2 (in_clk_125), .tx_pll_lol_qd_s (tx_pll_lol), .rst_qd_c (quad_rst), .tx_pcs_rst_ch_c ({nc_3, nc_2, nc_1, tx_pcs_rst}) ); // Buffer Incoming MII Data at Primary I/O always @(posedge in_clk_125 or negedge rst_n) begin if (rst_n == 1'b0) begin data_buf2chan <= 8'd0; en_buf2chan <= 0; err_buf2chan <= 0; end else begin data_buf2chan <= data_in_mii; en_buf2chan <= en_in_mii; err_buf2chan <= err_in_mii; end end // Buffer Outgoing MII Data at Primary I/O always @(posedge out_clk_125 or negedge rst_n) begin if (rst_n == 1'b0) begin data_out_mii <= 8'd0; dv_out_mii <= 0; err_out_mii <= 0; col_out_mii <= 0; crs_out_mii <= 0; end else begin data_out_mii <= data_chan2buf; dv_out_mii <= dv_chan2buf; err_out_mii <= err_chan2buf; col_out_mii <= col_chan2buf; crs_out_mii <= crs_chan2buf; end end /* // Control Interface input rst_n ; input signal_detect ; input gbe_mode ; input sgmii_mode ; input [1:0] operational_rate ; input debug_link_timer_short ; input force_isolate ; input force_loopback ; input force_unidir ; */ // Instantiate SGMII IP Core sgmii u1_dut ( // Clock and Reset .rst_n (rst_n ), .tx_clk_125 (in_clk_125), .tx_clock_enable_sink (in_ce_sink), .tx_clock_enable_source (in_ce_source), .rx_clk_125 (), .rx_clock_enable_sink (), .rx_clock_enable_source (), // Control .gbe_mode (1'b0), .sgmii_mode (1'b0), // .debug_link_timer_short (1'b0), .force_isolate (1'b0), .force_loopback (1'b0), .force_unidir (1'b0), //// .operational_rate (2'b10), .rx_compensation_err (), .ctc_drop_flag (), .ctc_add_flag (), .an_link_ok (an_link_ok), // (G)MII TX Port .tx_d (data_buf2chan), .tx_en (en_buf2chan), .tx_er (err_buf2chan), // (G)MII RX Port .rx_d (), .rx_dv (), .rx_er (), .col (), .crs (), // 8BI TX Port .tx_data (data_chan2quad), .tx_kcntl (kcntl_chan2quad), .tx_disparity_cntl (disparity_cntl_chan2quad), // 8BI RX Port .signal_detect (), .serdes_recovered_clk (), .rx_data (), .rx_kcntl (), .rx_even (1'b0), // Signal Not Used in Normal Mode .rx_disp_err (), .rx_cv_err (), .rx_err_decode_mode (1'b0), // 0= Normal Mode, always tie low for SC Familiy .xmit_autoneg (xmit_autoneg), // Management Interface I/O .mr_adv_ability (16'h4001), .mr_an_enable (1'b0), .mr_main_reset (1'b0), .mr_restart_an (1'b0), .mr_an_complete (mr_an_complete), .mr_lp_adv_ability (mr_lp_adv_ability), .mr_page_rx (mr_page_rx) ); // Host Bus Register Interface for SGMII IP Core // (G)MII Rate Resolution for SGMII IP Core // QUAD ASB 8B10B + SERDES ////单端晶振 pcs u_pcs( // serdes clk pins // .hdoutp_ch0(hdoutp0), .hdoutn_ch0(hdoutn0), .rxiclk_ch0(), .txiclk_ch0(in_clk_125), .rx_full_clk_ch0( ), .rx_half_clk_ch0( ), .tx_full_clk_ch0( ), .tx_half_clk_ch0( ), .txdata_ch0(data_chan2quad), .tx_k_ch0(kcntl_chan2quad), .xmit_ch0(xmit_autoneg), .tx_disp_correct_ch0(disparity_cntl_chan2quad), .rxdata_ch0(), .rx_k_ch0(), .rx_disp_err_ch0(), .rx_cv_err_ch0(), .sb_felb_ch0_c(1'b0), .sb_felb_rst_ch0_c(1'b0), .tx_pwrup_ch0_c(1'b1), .rx_pwrup_ch0_c(1'b1), .rx_los_low_ch0_s(), .lsm_status_ch0_s(), .rx_cdr_lol_ch0_s(), .tx_pcs_rst_ch0_c(tx_pcs_rst), .rst_qd_c(quad_rst), ///// misc .fpga_txrefclk(in_clk_125), .tx_serdes_rst_c(1'b0), ///quad_rst .tx_pll_lol_qd_s(tx_pll_lol), .serdes_rst_qd_c(1'b0)); /* pcs_top u_pcs( .rstn (rst_n), // refclkp, // refclkn, .txdata_ch0(data_chan2quad), .tx_k_ch0(kcntl_chan2quad), .hdoutp_ch0(hdoutp0), .hdoutn_ch0(hdoutn0), .clk_pcs(in_clk_125) ); */ endmodule