1/////////////////////////////////////////////////////////////////// 2// 3// Copyright 2017 Ettus Research, A National Instruments Company 4// 5// SPDX-License-Identifier: LGPL-3.0-or-later 6// 7// Module: n3xx_mgt_io_core 8// Description: 9// Encapsulates the PSC/PMA, the MAC layer and the control interface 10// for 1GbE, 10GbE and Aurora 11// 12////////////////////////////////////////////////////////////////////// 13 14module n3xx_mgt_io_core #( 15 parameter PROTOCOL = "10GbE", // Must be {10GbE, 1GbE, Aurora, Disabled} 16 parameter REG_BASE = 0, 17 parameter REG_DWIDTH = 32, 18 parameter REG_AWIDTH = 14, 19 parameter GT_COMMON = 1, 20 parameter [7:0] PORTNUM = 8'd0, 21 parameter MDIO_EN = 0, 22 parameter [4:0] MDIO_PHYADDR = 5'd0 23)( 24 // Resets 25 input areset, 26 input bus_rst, 27 // Clocks 28 input gt_refclk, 29 input gb_refclk, 30 input misc_clk, 31 input bus_clk, 32 input user_clk, 33 input sync_clk, 34 // SFP high-speed IO 35 output txp, 36 output txn, 37 input rxp, 38 input rxn, 39 // SFP low-speed IO 40 input sfpp_rxlos, 41 input sfpp_tx_fault, 42 output sfpp_tx_disable, 43 // Data port: Ethernet TX 44 input [63:0] s_axis_tdata, 45 input [3:0] s_axis_tuser, 46 input s_axis_tlast, 47 input s_axis_tvalid, 48 output s_axis_tready, 49 // Data port: Ethernet RX 50 output [63:0] m_axis_tdata, 51 output [3:0] m_axis_tuser, 52 output m_axis_tlast, 53 output m_axis_tvalid, 54 input m_axis_tready, 55 // Register port 56 input reg_wr_req, 57 input [REG_AWIDTH-1:0] reg_wr_addr, 58 input [REG_DWIDTH-1:0] reg_wr_data, 59 input reg_rd_req, 60 input [REG_AWIDTH-1:0] reg_rd_addr, 61 output reg_rd_resp, 62 output [REG_DWIDTH-1:0] reg_rd_data, 63 // GT Common 64 input qpllrefclklost, 65 input qplllock, 66 input qplloutclk, 67 input qplloutrefclk, 68 input mmcm_locked, 69 output qpllreset, 70 output gt_pll_lock, 71 output gt_tx_out_clk_unbuf, 72 73 // Misc 74 output [31:0] port_info, 75 output link_up, 76 output reg activity 77); 78 79 //----------------------------------------------------------------- 80 // Registers 81 //----------------------------------------------------------------- 82 localparam [7:0] COMPAT_NUM = 8'd2; 83 84 // Common registers 85 localparam [REG_AWIDTH-1:0] REG_PORT_INFO = REG_BASE + 'h0; 86 localparam [REG_AWIDTH-1:0] REG_MAC_CTRL_STATUS = REG_BASE + 'h4; 87 localparam [REG_AWIDTH-1:0] REG_PHY_CTRL_STATUS = REG_BASE + 'h8; 88 localparam [REG_AWIDTH-1:0] REG_MAC_LED_CTL = REG_BASE + 'hC; 89 90 // Ethernet specific 91 localparam [REG_AWIDTH-1:0] REG_ETH_MDIO_BASE = REG_BASE + 'h10; 92 // Aurora specific 93 localparam [REG_AWIDTH-1:0] REG_AURORA_OVERRUNS = REG_BASE + 'h20; 94 localparam [REG_AWIDTH-1:0] REG_CHECKSUM_ERRORS = REG_BASE + 'h24; 95 localparam [REG_AWIDTH-1:0] REG_BIST_CHECKER_SAMPS = REG_BASE + 'h28; 96 localparam [REG_AWIDTH-1:0] REG_BIST_CHECKER_ERRORS = REG_BASE + 'h2C; 97 98 wire reg_rd_resp_mdio; 99 reg reg_rd_resp_glob = 1'b0; 100 wire [REG_DWIDTH-1:0] reg_rd_data_mdio; 101 reg [REG_DWIDTH-1:0] reg_rd_data_glob = 32'h0; 102 103 // Protocol specific constants 104 wire [7:0] mgt_protocol; 105 wire [31:0] mac_ctrl_rst_val, phy_ctrl_rst_val; 106 wire [1:0] mac_led_ctl_rst_val = 2'h0; 107 108 // Flush logic: If the link is not up, we will flush all packets coming from 109 // the device. This avoids the MAC backpressuring when the PHY is down. 110 // The device will always send discovery packets to the transports during 111 // initialization, and they have no way of knowing if it's safe to travel 112 // down this route. c2mac == "CHDR to MAC" 113 wire [63:0] c2mac_tdata; 114 wire [3:0] c2mac_tuser; 115 wire c2mac_tlast; 116 wire c2mac_tvalid; 117 wire c2mac_tready; 118 119 axis_packet_flush #( 120 .WIDTH(64+3), // tdata + tuser 121 .TIMEOUT_W(1), // Not using timeout 122 .FLUSH_PARTIAL_PKTS(0), 123 .PIPELINE("NONE") 124 ) linkup_flush ( 125 .clk(bus_clk), 126 .reset(bus_rst), 127 .enable(~link_up), // enable flushing when link down 128 .timeout(1'b0), 129 .flushing(/* not required */), 130 .done(/* not required */), 131 // Input from device/crossbar 132 .s_axis_tdata ({s_axis_tuser, s_axis_tdata}), 133 .s_axis_tlast (s_axis_tlast), 134 .s_axis_tvalid (s_axis_tvalid), 135 .s_axis_tready (s_axis_tready), 136 // Output to MAC 137 .m_axis_tdata ({c2mac_tuser, c2mac_tdata}), 138 .m_axis_tlast (c2mac_tlast), 139 .m_axis_tvalid (c2mac_tvalid), 140 .m_axis_tready (c2mac_tready) 141 ); 142 143 generate 144 if (PROTOCOL == "Aurora") begin 145 assign mgt_protocol = 8'd3; 146 assign mac_ctrl_rst_val = 32'h0; 147 assign phy_ctrl_rst_val = 32'h0; 148 end else if (PROTOCOL == "10GbE") begin 149 assign mgt_protocol = 8'd2; 150 assign mac_ctrl_rst_val = {31'h0, 1'b1}; // tx_enable on reset 151 assign phy_ctrl_rst_val = 32'h0; 152 end else if (PROTOCOL == "1GbE") begin 153 assign mgt_protocol = 8'd1; 154 assign mac_ctrl_rst_val = {31'h0, 1'b1}; // tx_enable on reset 155 assign phy_ctrl_rst_val = 32'h0; 156 end else begin 157 assign mgt_protocol = 8'd0; 158 assign mac_ctrl_rst_val = 32'h0; 159 assign phy_ctrl_rst_val = 32'h0; 160 end 161 endgenerate 162 163 // Writable registers 164 reg [31:0] mac_ctrl_reg = 32'h0; 165 reg [31:0] phy_ctrl_reg = 32'h0; 166 reg [1:0] mac_led_ctl = 2'h0; 167 168 always @(posedge bus_clk) begin 169 if (bus_rst) begin 170 mac_ctrl_reg <= mac_ctrl_rst_val; 171 phy_ctrl_reg <= phy_ctrl_rst_val; 172 mac_led_ctl <= mac_led_ctl_rst_val; 173 end else if (reg_wr_req) begin 174 case(reg_wr_addr) 175 REG_MAC_CTRL_STATUS: 176 mac_ctrl_reg <= reg_wr_data; 177 REG_PHY_CTRL_STATUS: 178 phy_ctrl_reg <= reg_wr_data; 179 REG_MAC_LED_CTL: 180 mac_led_ctl <= reg_wr_data[1:0]; 181 endcase 182 end 183 end 184 185 // Readable registers 186 wire [31:0] overruns; 187 wire [31:0] checksum_errors; 188 wire [47:0] bist_checker_samps; 189 wire [47:0] bist_checker_errors; 190 wire [31:0] mac_status, phy_status; 191 wire [31:0] mac_status_bclk, phy_status_bclk; 192 193 assign port_info = {COMPAT_NUM, 6'h0, activity, link_up, mgt_protocol, PORTNUM}; 194 195 always @(posedge bus_clk) begin 196 // No reset handling needed for readback 197 if (reg_rd_req) begin 198 reg_rd_resp_glob <= 1'b1; 199 case(reg_rd_addr) 200 REG_PORT_INFO: 201 reg_rd_data_glob <= port_info; 202 REG_MAC_CTRL_STATUS: 203 reg_rd_data_glob <= mac_status_bclk; 204 REG_PHY_CTRL_STATUS: 205 reg_rd_data_glob <= phy_status_bclk; 206 REG_MAC_LED_CTL: 207 reg_rd_data_glob <= {30'd0, mac_led_ctl}; 208 REG_AURORA_OVERRUNS: 209 reg_rd_data_glob <= overruns; 210 REG_CHECKSUM_ERRORS: 211 reg_rd_data_glob <= checksum_errors; 212 REG_BIST_CHECKER_SAMPS: 213 reg_rd_data_glob <= bist_checker_samps[47:16]; //Scale num samples by 2^16 214 REG_BIST_CHECKER_ERRORS: 215 reg_rd_data_glob <= bist_checker_errors[31:0]; //Don't scale errors 216 default: 217 reg_rd_resp_glob <= 1'b0; 218 endcase 219 end if (reg_rd_resp_glob) begin 220 reg_rd_resp_glob <= 1'b0; 221 end 222 end 223 224 synchronizer #( .STAGES(2), .WIDTH(32), .INITIAL_VAL(32'h0) ) mac_status_sync_i ( 225 .clk(bus_clk), .rst(1'b0), .in(mac_status), .out(mac_status_bclk) 226 ); 227 228 synchronizer #( .STAGES(2), .WIDTH(32), .INITIAL_VAL(32'h0) ) phy_status_sync_i ( 229 .clk(bus_clk), .rst(1'b0), .in(phy_status), .out(phy_status_bclk) 230 ); 231 232 // Regport Mux for response 233 regport_resp_mux #( 234 .WIDTH (REG_DWIDTH), 235 .NUM_SLAVES (2) 236 ) reg_resp_mux_i ( 237 .clk(bus_clk), .reset(bus_rst), 238 .sla_rd_resp({reg_rd_resp_mdio, reg_rd_resp_glob}), 239 .sla_rd_data({reg_rd_data_mdio, reg_rd_data_glob}), 240 .mst_rd_resp(reg_rd_resp), .mst_rd_data(reg_rd_data) 241 ); 242 243 //----------------------------------------------------------------- 244 // Ethernet Specific: MDIO 245 //----------------------------------------------------------------- 246 247 wire mdc, mdio_m2s, mdio_s2m, mdio_s2m_sync; 248 generate 249 if ((PROTOCOL == "10GbE" || PROTOCOL == "1GbE") && (MDIO_EN == 1)) begin 250 mdio_master #( 251 .REG_BASE (REG_ETH_MDIO_BASE), 252 .REG_AWIDTH (REG_AWIDTH), 253 .MDC_DIVIDER (8'd200) 254 ) mdio_master_i ( 255 .clk (bus_clk), 256 .rst (bus_rst), 257 .mdc (mdc), 258 .mdio_in (mdio_s2m_sync), 259 .mdio_out (mdio_m2s), 260 .mdio_tri (), 261 .reg_wr_req (reg_wr_req), 262 .reg_wr_addr (reg_wr_addr), 263 .reg_wr_data (reg_wr_data), 264 .reg_rd_req (reg_rd_req), 265 .reg_rd_addr (reg_rd_addr), 266 .reg_rd_data (reg_rd_data_mdio), 267 .reg_rd_resp (reg_rd_resp_mdio) 268 ); 269 270 // We can cross mdio_s2m into the bus_clk domain. A synchronizer is safe 271 // here because the bit is inherently async 272 synchronizer #(.INITIAL_VAL(1'b0)) mdio_s2m_sync_i ( 273 .clk(bus_clk), .rst(1'b0 /* no reset */), .in(mdio_s2m), .out(mdio_s2m_sync) 274 ); 275 end else begin 276 assign mdc = 1'b0; 277 assign mdio_m2s = 1'b0; 278 assign reg_rd_resp_mdio = 1'b0; 279 assign reg_rd_data_mdio = 32'h0; 280 end 281 endgenerate 282 283 generate 284 if (PROTOCOL == "10GbE") begin 285 //----------------------------------------------------------------- 286 // 10 Gigabit Ethernet 287 //----------------------------------------------------------------- 288 wire [63:0] xgmii_txd; 289 wire [7:0] xgmii_txc; 290 wire [63:0] xgmii_rxd; 291 wire [7:0] xgmii_rxc; 292 wire xge_phy_resetdone; 293 294 if (GT_COMMON == 1) begin 295 ten_gige_phy ten_gige_phy_i ( 296 // Clocks and Reset 297 .areset(areset | phy_ctrl_reg[0]), // Asynchronous reset for entire core. 298 .refclk(gt_refclk), // Transciever reference clock: 156.25MHz 299 .clk156(gb_refclk), // Globally buffered core clock: 156.25MHz 300 .dclk(misc_clk), // Management/DRP clock: 78.125MHz 301 .sim_speedup_control(1'b0), 302 // GMII Interface (client MAC <=> PCS) 303 .xgmii_txd(xgmii_txd), // Transmit data from client MAC. 304 .xgmii_txc(xgmii_txc), // Transmit control signal from client MAC. 305 .xgmii_rxd(xgmii_rxd), // Received Data to client MAC. 306 .xgmii_rxc(xgmii_rxc), // Received control signal to client MAC. 307 // Tranceiver Interface 308 .txp(txp), // Differential +ve of serial transmission from PMA to PMD. 309 .txn(txn), // Differential -ve of serial transmission from PMA to PMD. 310 .rxp(rxp), // Differential +ve for serial reception from PMD to PMA. 311 .rxn(rxn), // Differential -ve for serial reception from PMD to PMA. 312 // Management: MDIO Interface 313 .mdc(mdc), // Management Data Clock 314 .mdio_in(mdio_m2s), // Management Data In 315 .mdio_out(mdio_s2m), // Management Data Out 316 .mdio_tri(), // Management Data Tristate 317 .prtad(MDIO_PHYADDR), // MDIO address 318 // General IO's 319 .core_status(phy_status[7:0]), // Core status 320 .resetdone(xge_phy_resetdone), 321 .signal_detect(~sfpp_rxlos), // Input from PMD to indicate presence of optical input. (Undocumented, but it seems Xilinx expect this to be inverted.) 322 .tx_fault(sfpp_tx_fault), 323 .tx_disable(sfpp_tx_disable), 324 .qpllreset(qpllreset), 325 .qplllock(qplllock), 326 .qplloutclk(qplloutclk), 327 .qplloutrefclk(qplloutrefclk), 328 .tx_out_clk(gt_tx_out_clk_unbuf) 329 ); 330 end else begin 331 ten_gige_phy ten_gige_phy_i ( 332 // Clocks and Reset 333 .areset(areset | phy_ctrl_reg[0]), // Asynchronous reset for entire core. 334 .refclk(gt_refclk), // Transciever reference clock: 156.25MHz 335 .clk156(gb_refclk), // Globally buffered core clock: 156.25MHz 336 .dclk(misc_clk), // Management/DRP clock: 78.125MHz 337 .sim_speedup_control(1'b0), 338 // GMII Interface (client MAC <=> PCS) 339 .xgmii_txd(xgmii_txd), // Transmit data from client MAC. 340 .xgmii_txc(xgmii_txc), // Transmit control signal from client MAC. 341 .xgmii_rxd(xgmii_rxd), // Received Data to client MAC. 342 .xgmii_rxc(xgmii_rxc), // Received control signal to client MAC. 343 // Tranceiver Interface 344 .txp(txp), // Differential +ve of serial transmission from PMA to PMD. 345 .txn(txn), // Differential -ve of serial transmission from PMA to PMD. 346 .rxp(rxp), // Differential +ve for serial reception from PMD to PMA. 347 .rxn(rxn), // Differential -ve for serial reception from PMD to PMA. 348 // Management: MDIO Interface 349 .mdc(mdc), // Management Data Clock 350 .mdio_in(mdio_m2s), // Management Data In 351 .mdio_out(mdio_s2m), // Management Data Out 352 .mdio_tri(), // Management Data Tristate 353 .prtad(MDIO_PHYADDR), // MDIO address 354 // General IO's 355 .core_status(phy_status[7:0]), // Core status 356 .resetdone(xge_phy_resetdone), 357 .signal_detect(~sfpp_rxlos), // Input from PMD to indicate presence of optical input. (Undocumented, but it seems Xilinx expect this to be inverted.) 358 .tx_fault(sfpp_tx_fault), 359 .tx_disable(sfpp_tx_disable) 360 ); 361 assign qpllreset = 1'b0; 362 assign gt_pll_lock = 1'b0; 363 assign gt_tx_out_clk_unbuf = 1'b0; 364 end 365 366 xge_mac_wrapper #( 367 .PORTNUM(PORTNUM), 368 .WISHBONE(0) 369 ) xge_mac_wrapper_i ( 370 // XGMII 371 .xgmii_clk(gb_refclk), 372 .xgmii_txd(xgmii_txd), 373 .xgmii_txc(xgmii_txc), 374 .xgmii_rxd(xgmii_rxd), 375 .xgmii_rxc(xgmii_rxc), 376 // Client FIFO Interfaces 377 .sys_clk(bus_clk), 378 .sys_rst(bus_rst), 379 .rx_tdata(m_axis_tdata), 380 .rx_tuser(m_axis_tuser), 381 .rx_tlast(m_axis_tlast), 382 .rx_tvalid(m_axis_tvalid), 383 .rx_tready(m_axis_tready), 384 .tx_tdata(c2mac_tdata), 385 .tx_tuser(c2mac_tuser), // Bit[3] (error) is ignored for now. 386 .tx_tlast(c2mac_tlast), 387 .tx_tvalid(c2mac_tvalid), 388 .tx_tready(c2mac_tready), 389 // Other 390 .phy_ready(xge_phy_resetdone), 391 .ctrl_tx_enable(mac_ctrl_reg[0]), 392 .status_crc_error(mac_status[0]), 393 .status_fragment_error(mac_status[1]), 394 .status_txdfifo_ovflow(mac_status[2]), 395 .status_txdfifo_udflow(mac_status[3]), 396 .status_rxdfifo_ovflow(mac_status[4]), 397 .status_rxdfifo_udflow(mac_status[5]), 398 .status_pause_frame_rx(mac_status[6]), 399 .status_local_fault(mac_status[7]), 400 .status_remote_fault(mac_status[8]), 401 .wb_ack_o(), 402 .wb_dat_o(), 403 .wb_adr_i(1'b0), 404 .wb_clk_i(1'b0), 405 .wb_cyc_i(1'b0), 406 .wb_dat_i(1'b0), 407 .wb_rst_i(1'b0), 408 .wb_stb_i(1'b0), 409 .wb_we_i (1'b0), 410 .wb_int_o() 411 ); 412 413 assign phy_status[31:8] = 24'h0; 414 assign mac_status[31:9] = 23'h0; 415 assign link_up = phy_status_bclk[0]; 416 417 end else if (PROTOCOL == "1GbE") begin 418 419 //----------------------------------------------------------------- 420 // 1 Gigabit Ethernet 421 //----------------------------------------------------------------- 422 wire [7:0] gmii_txd, gmii_rxd; 423 wire gmii_tx_en, gmii_tx_er, gmii_rx_dv, gmii_rx_er; 424 wire gmii_clk; 425 wire gt0_qplloutclk, gt0_qplloutrefclk; //unused in 7-series Zynq 426 427 assign gt0_qplloutclk = 1'b0; 428 assign gt0_qplloutrefclk = 1'b0; 429 assign sfpp_tx_disable = 1'b0; // Always on. 430 431 if (GT_COMMON == 1) begin 432 one_gige_phy one_gige_phy_i ( 433 .reset(areset | phy_ctrl_reg[0]), // Asynchronous reset for entire core. 434 .independent_clock(bus_clk), 435 .pma_reset_out(/*unused*/), 436 .gt0_qplloutclk_in(gt0_qplloutclk), 437 .gt0_qplloutrefclk_in(gt0_qplloutrefclk), 438 // Tranceiver Interface 439 .gtrefclk(gt_refclk), // Reference clock for MGT: 125MHz, very high quality. 440 .gtrefclk_bufg(gb_refclk), // Reference clock routed through a BUFG 441 .txp(txp), // Differential +ve of serial transmission from PMA to PMD. 442 .txn(txn), // Differential -ve of serial transmission from PMA to PMD. 443 .rxp(rxp), // Differential +ve for serial reception from PMD to PMA. 444 .rxn(rxn), // Differential -ve for serial reception from PMD to PMA. 445 // GMII Interface (client MAC <=> PCS) 446 .gmii_clk(gmii_clk), // Clock to client MAC. 447 .gmii_txd(gmii_txd), // Transmit data from client MAC. 448 .gmii_tx_en(gmii_tx_en), // Transmit control signal from client MAC. 449 .gmii_tx_er(gmii_tx_er), // Transmit control signal from client MAC. 450 .gmii_rxd(gmii_rxd), // Received Data to client MAC. 451 .gmii_rx_dv(gmii_rx_dv), // Received control signal to client MAC. 452 .gmii_rx_er(gmii_rx_er), // Received control signal to client MAC. 453 // Management: MDIO Interface 454 .mdc(mdc), // Management Data Clock 455 .mdio_i(mdio_m2s), // Management Data In 456 .mdio_o(mdio_s2m), // Management Data Out 457 .mdio_t(), // Management Data Tristate 458 .phyaddr(MDIO_PHYADDR), // MDIO address 459 .configuration_vector(5'd0), // Alternative to MDIO interface. 460 .configuration_valid(1'b1), // Validation signal for Config vector (MUST be 1 for proper functionality...undocumented) 461 // General IO's 462 .status_vector(phy_status[15:0]), // Core status. 463 .signal_detect(1'b1 /*Optical module not supported*/) // Input from PMD to indicate presence of optical input. 464 ); 465 end else begin 466 one_gige_phy one_gige_phy_i ( 467 .reset(areset | phy_ctrl_reg[0]), // Asynchronous reset for entire core. 468 .independent_clock(bus_clk), 469 // Tranceiver Interface 470 .gtrefclk(gt_refclk), // Reference clock for MGT: 125MHz, very high quality. 471 .gtrefclk_bufg(gb_refclk), // Reference clock routed through a BUFG 472 .txp(txp), // Differential +ve of serial transmission from PMA to PMD. 473 .txn(txn), // Differential -ve of serial transmission from PMA to PMD. 474 .rxp(rxp), // Differential +ve for serial reception from PMD to PMA. 475 .rxn(rxn), // Differential -ve for serial reception from PMD to PMA. 476 // GMII Interface (client MAC <=> PCS) 477 .gmii_clk(gmii_clk), // Clock to client MAC. 478 .gmii_txd(gmii_txd), // Transmit data from client MAC. 479 .gmii_tx_en(gmii_tx_en), // Transmit control signal from client MAC. 480 .gmii_tx_er(gmii_tx_er), // Transmit control signal from client MAC. 481 .gmii_rxd(gmii_rxd), // Received Data to client MAC. 482 .gmii_rx_dv(gmii_rx_dv), // Received control signal to client MAC. 483 .gmii_rx_er(gmii_rx_er), // Received control signal to client MAC. 484 // Management: MDIO Interface 485 .mdc(mdc), // Management Data Clock 486 .mdio_i(mdio_m2s), // Management Data In 487 .mdio_o(mdio_s2m), // Management Data Out 488 .mdio_t(), // Management Data Tristate 489 .phyaddr(MDIO_PHYADDR), // MDIO address 490 .configuration_vector(5'd0), // Alternative to MDIO interface. 491 .configuration_valid(1'b1), // Validation signal for Config vector (MUST be 1 for proper functionality...undocumented) 492 // General IO's 493 .status_vector(phy_status[15:0]), // Core status. 494 .signal_detect(1'b1 /*Optical module not supported*/) // Input from PMD to indicate presence of optical input. 495 ); 496 assign qpllreset = 1'b0; 497 assign gt_pll_lock = 1'b0; 498 assign gt_tx_out_clk_unbuf = 1'b0; 499 end 500 501 simple_gemac_wrapper #(.RX_FLOW_CTRL(0), .PORTNUM(PORTNUM)) simple_gemac_wrapper_i 502 ( 503 .clk125(gmii_clk), 504 .reset(areset), 505 506 .GMII_GTX_CLK(), 507 .GMII_TX_EN(gmii_tx_en), 508 .GMII_TX_ER(gmii_tx_er), 509 .GMII_TXD(gmii_txd), 510 .GMII_RX_CLK(gmii_clk), 511 .GMII_RX_DV(gmii_rx_dv), 512 .GMII_RX_ER(gmii_rx_er), 513 .GMII_RXD(gmii_rxd), 514 515 .sys_clk(bus_clk), 516 .rx_tdata(m_axis_tdata), 517 .rx_tuser(m_axis_tuser), 518 .rx_tlast(m_axis_tlast), 519 .rx_tvalid(m_axis_tvalid), 520 .rx_tready(m_axis_tready), 521 .tx_tdata(c2mac_tdata), 522 .tx_tuser(c2mac_tuser), 523 .tx_tlast(c2mac_tlast), 524 .tx_tvalid(c2mac_tvalid), 525 .tx_tready(c2mac_tready), 526 527 .wb_clk_i(1'b0), 528 .wb_rst_i(1'b0), 529 .wb_adr_i(8'h0), 530 .wb_dat_i(32'h0), 531 .wb_we_i(1'b0), 532 .wb_stb_i(1'b0), 533 .wb_cyc_i(1'b0), 534 .wb_dat_o(), 535 .wb_ack_o(), 536 .wb_int_o(), 537 .mdc(), 538 .mdio_out(1'b0), 539 .mdio_tri(), 540 .mdio_in(), 541 .debug_tx(), 542 .debug_rx() 543 ); 544 545 assign phy_status[31:16] = 16'h0; 546 assign mac_status[31:0] = 32'h0; 547 assign link_up = phy_status_bclk[0]; 548 549 assign gt_tx_out_clk_unbuf = 1'b0; 550 551 end else if (PROTOCOL == "Aurora") begin 552 553 //----------------------------------------------------------------- 554 // Aurora 555 //----------------------------------------------------------------- 556 wire user_rst; 557 wire [63:0] m2p_tdata, p2m_tdata; 558 wire m2p_tvalid, m2p_tready, p2m_tvalid; 559 wire channel_up, hard_err, soft_err, mac_crit_err; 560 561 wire bist_checker_en = mac_ctrl_reg[0]; 562 wire bist_gen_en = mac_ctrl_reg[1]; 563 wire bist_loopback_en = mac_ctrl_reg[2]; 564 wire [5:0] bist_gen_rate = mac_ctrl_reg[8:3]; 565 wire phy_areset = mac_ctrl_reg[9]; 566 wire mac_clear = mac_ctrl_reg[10]; 567 wire bist_checker_locked; 568 569 assign sfpp_tx_disable = 1'b0; // Always on. 570 571 if (GT_COMMON == 1) begin 572 aurora_phy_x1 aurora_phy_i ( 573 // Resets 574 .areset(areset | phy_areset), 575 // Clocks 576 .refclk(gt_refclk), 577 .init_clk(misc_clk), 578 .user_clk(user_clk), 579 .user_rst(user_rst), 580 .sync_clk(sync_clk), 581 .qpllclk(qplloutclk), 582 .qpllrefclk(qplloutrefclk), 583 // GTX Serial I/O 584 .tx_p(txp), 585 .tx_n(txn), 586 .rx_p(rxp), 587 .rx_n(rxn), 588 // AXI4-Stream TX Interface 589 .s_axis_tdata(m2p_tdata), 590 .s_axis_tvalid(m2p_tvalid), 591 .s_axis_tready(m2p_tready), 592 // AXI4-Stream RX Interface 593 .m_axis_tdata(p2m_tdata), 594 .m_axis_tvalid(p2m_tvalid), 595 // AXI4-Lite Config Interface (unused) 596 .s_axi_awaddr(32'h0), 597 .s_axi_araddr(32'h0), 598 .s_axi_awvalid(1'b0), 599 .s_axi_awready(), 600 .s_axi_wdata(32'h0), 601 .s_axi_wvalid(1'b0), 602 .s_axi_wstrb(1'b0), 603 .s_axi_wready(), 604 .s_axi_bvalid(), 605 .s_axi_bresp(), 606 .s_axi_bready(1'b1), 607 .s_axi_arready(), 608 .s_axi_arvalid(1'b0), 609 .s_axi_rdata(), 610 .s_axi_rvalid(), 611 .s_axi_rresp(), 612 .s_axi_rready(1'b1), 613 // Status and Error Reporting Interface 614 .channel_up(channel_up), 615 .hard_err(hard_err), 616 .soft_err(soft_err), 617 .qplllock(qplllock), 618 .qpllreset(qpllreset), 619 .qpllrefclklost(qpllrefclklost), 620 .tx_out_clk(gt_tx_out_clk_unbuf), 621 .gt_pll_lock(gt_pll_lock), 622 .mmcm_locked(mmcm_locked) 623 ); 624 end else begin 625 aurora_phy_x1 aurora_phy_i ( 626 // Resets 627 .areset(areset | phy_areset), 628 // Clocks 629 .refclk(gt_refclk), 630 .init_clk(misc_clk), 631 .user_clk(user_clk), 632 .user_rst(user_rst), 633 // GTX Serial I/O 634 .tx_p(txp), 635 .tx_n(txn), 636 .rx_p(rxp), 637 .rx_n(rxn), 638 // AXI4-Stream TX Interface 639 .s_axis_tdata(m2p_tdata), 640 .s_axis_tvalid(m2p_tvalid), 641 .s_axis_tready(m2p_tready), 642 // AXI4-Stream RX Interface 643 .m_axis_tdata(p2m_tdata), 644 .m_axis_tvalid(p2m_tvalid), 645 // AXI4-Lite Config Interface (unused) 646 .s_axi_awaddr(32'h0), 647 .s_axi_araddr(32'h0), 648 .s_axi_awvalid(1'b0), 649 .s_axi_awready(), 650 .s_axi_wdata(32'h0), 651 .s_axi_wvalid(1'b0), 652 .s_axi_wstrb(1'b0), 653 .s_axi_wready(), 654 .s_axi_bvalid(), 655 .s_axi_bresp(), 656 .s_axi_bready(1'b1), 657 .s_axi_arready(), 658 .s_axi_arvalid(1'b0), 659 .s_axi_rdata(), 660 .s_axi_rvalid(), 661 .s_axi_rresp(), 662 .s_axi_rready(1'b1), 663 // Status and Error Reporting Interface 664 .channel_up(channel_up), 665 .hard_err(hard_err), 666 .soft_err(soft_err) 667 ); 668 assign qpllreset = 1'b0; 669 assign gt_pll_lock = 1'b0; 670 assign gt_tx_out_clk_unbuf = 1'b0; 671 end 672 673 aurora_axis_mac #( 674 .PHY_ENDIANNESS ("LITTLE"), 675 .PACKET_MODE (1), 676 .MAX_PACKET_SIZE(1024), 677 .BIST_ENABLED (1) 678 ) aurora_mac_i ( 679 // Clocks and resets 680 .phy_clk(user_clk), .phy_rst(user_rst), 681 .sys_clk(bus_clk), .sys_rst(bus_rst), 682 .clear(mac_clear), 683 // PHY Interface (Synchronous to phy_clk) 684 .phy_s_axis_tdata(p2m_tdata), 685 .phy_s_axis_tvalid(p2m_tvalid), 686 .phy_m_axis_tdata(m2p_tdata), 687 .phy_m_axis_tvalid(m2p_tvalid), 688 .phy_m_axis_tready(m2p_tready), 689 // User Interface (Synchronous to sys_clk) 690 .s_axis_tdata(c2mac_tdata), 691 .s_axis_tlast(c2mac_tlast), 692 .s_axis_tvalid(c2mac_tvalid), 693 .s_axis_tready(c2mac_tready), 694 .m_axis_tdata(m_axis_tdata), 695 .m_axis_tlast(m_axis_tlast), 696 .m_axis_tvalid(m_axis_tvalid), 697 .m_axis_tready(m_axis_tready), 698 // PHY Status Inputs (Synchronous to phy_clk) 699 .channel_up(channel_up), 700 .hard_err(hard_err), 701 .soft_err(soft_err), 702 // Status and Error Outputs (Synchronous to sys_clk) 703 .overruns(overruns), 704 .soft_errors(), 705 .checksum_errors(checksum_errors), 706 .critical_err(mac_crit_err), 707 // BIST Interface (Synchronous to sys_clk) 708 .bist_gen_en(bist_gen_en), 709 .bist_gen_rate(bist_gen_rate), 710 .bist_checker_en(bist_checker_en), 711 .bist_loopback_en(bist_loopback_en), 712 .bist_checker_locked(bist_checker_locked), 713 .bist_checker_samps(bist_checker_samps), 714 .bist_checker_errors(bist_checker_errors) 715 ); 716 717 assign m_axis_tuser = 4'd0; 718 719 wire channel_up_bclk, hard_err_bclk, soft_err_bclk, mac_crit_err_bclk, gt_pll_lock_bclk; 720 synchronizer #(.INITIAL_VAL(1'b0)) channel_up_sync ( 721 .clk(bus_clk), .rst(1'b0 /* no reset */), .in(channel_up), .out(channel_up_bclk)); 722 synchronizer #(.INITIAL_VAL(1'b0)) hard_err_sync ( 723 .clk(bus_clk), .rst(1'b0 /* no reset */), .in(hard_err), .out(hard_err_bclk)); 724 synchronizer #(.INITIAL_VAL(1'b0)) soft_err_sync ( 725 .clk(bus_clk), .rst(1'b0 /* no reset */), .in(soft_err), .out(soft_err_bclk)); 726 synchronizer #(.INITIAL_VAL(1'b0)) mac_crit_err_sync ( 727 .clk(bus_clk), .rst(1'b0 /* no reset */), .in(mac_crit_err), .out(mac_crit_err_bclk)); 728 729 if (GT_COMMON == 1) begin 730 synchronizer #(.INITIAL_VAL(1'b0)) gt_pll_lock_sync ( 731 .clk(bus_clk), .rst(1'b0 /* no reset */), .in(gt_pll_lock), .out(gt_pll_lock_bclk)); 732 end else begin 733 assign gt_pll_lock_bclk = 1'b0; 734 end 735 736 reg [19:0] bist_lock_latency; 737 always @(posedge bus_clk) begin 738 if (!bist_checker_en && !bist_checker_locked) 739 bist_lock_latency <= 20'd0; 740 else if (bist_checker_en && !bist_checker_locked) 741 bist_lock_latency <= bist_lock_latency + 20'd1; 742 end 743 744 reg mac_crit_err_latch; 745 always @(posedge bus_clk) begin 746 if (bus_rst | mac_clear) begin 747 mac_crit_err_latch <= 1'b0; 748 end else begin 749 if (mac_crit_err_bclk) 750 mac_crit_err_latch <= 1'b1; 751 end 752 end 753 754 assign phy_status = {30'd0, hard_err, channel_up}; 755 assign mac_status = { 756 6'h0, //[31:26] 757 mac_crit_err_latch, //[25] 758 1'b1, //[24] 759 gt_pll_lock_bclk, //[23] 760 qpllrefclklost, //[22] 761 qplllock, //[21] 762 qpllreset, //[20] 763 bist_lock_latency[19:4], //[19:4] 764 bist_checker_locked, //[3] 765 soft_err_bclk, //[2] 766 hard_err_bclk, //[1] 767 channel_up_bclk //[0] 768 }; 769 770 assign link_up = channel_up_bclk; 771 772 end else begin 773 774 //----------------------------------------------------------------- 775 // Disabled 776 //----------------------------------------------------------------- 777 778 assign phy_status = 'h0; 779 assign mac_status = 'h0; 780 assign link_up = 1'b0; 781 782 assign sfpp_tx_disable = 1'b0; // Always on. 783 784 assign c2mac_tready = 1'b1; 785 assign m_axis_tdata = 64'h0; 786 assign m_axis_tuser = 4'h0; 787 assign m_axis_tlast = 1'b0; 788 assign m_axis_tvalid = 1'b0; 789 790 assign qpllreset = 1'b0; 791 assign gt_pll_lock = 1'b0; 792 assign gt_tx_out_clk_unbuf = 1'b0; 793 794 end 795 endgenerate 796 797 wire identify_enable = mac_led_ctl[0]; 798 wire identify_value = mac_led_ctl[1]; 799 800 //----------------------------------------------------------------- 801 // Activity detector 802 //----------------------------------------------------------------- 803 804 wire activity_int; 805 806 pulse_stretch act_pulse_str_i ( 807 .clk(bus_clk), 808 .rst(bus_rst | ~link_up), 809 .pulse((s_axis_tvalid & s_axis_tready) | (m_axis_tvalid & m_axis_tready)), 810 .pulse_stretched(activity_int) 811 ); 812 813 always @ (posedge bus_clk) activity <= identify_enable ? identify_value : activity_int; 814 815endmodule 816