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_sfp_wrapper 8// Description: 9// Reduces clutter at top level. 10// - Aurora: wraps up sfpp_io, axil_regport and axi_dummy 11// - 1/10G: wrapper around network interface 12// 13////////////////////////////////////////////////////////////////////// 14 15module n3xx_sfp_wrapper #( 16 parameter PROTOCOL = "10GbE", // Must be {10GbE, 1GbE, Aurora, Disabled} 17 parameter DWIDTH = 32, 18 parameter AWIDTH = 14, 19 parameter [7:0] PORTNUM = 8'd0, 20 parameter MDIO_EN = 0, 21 parameter [4:0] MDIO_PHYADDR = 5'd0, 22 parameter [15:0] RFNOC_PROTOVER = {8'd1, 8'd0} 23)( 24 // Resets 25 input areset, 26 input bus_rst, 27 28 // Clocks 29 input gt_refclk, 30 input gb_refclk, 31 input misc_clk, 32 input bus_clk, 33 // FIXME: Merge E320 and N310 files 34 input user_clk, 35 input sync_clk, 36 37 //Axi-lite 38 input s_axi_aclk, 39 input s_axi_aresetn, 40 input [AWIDTH-1:0] s_axi_awaddr, 41 input s_axi_awvalid, 42 output s_axi_awready, 43 44 input [DWIDTH-1:0] s_axi_wdata, 45 input [DWIDTH/8-1:0] s_axi_wstrb, 46 input s_axi_wvalid, 47 output s_axi_wready, 48 49 output [1:0] s_axi_bresp, 50 output s_axi_bvalid, 51 input s_axi_bready, 52 53 input [AWIDTH-1:0] s_axi_araddr, 54 input s_axi_arvalid, 55 output s_axi_arready, 56 57 output [DWIDTH-1:0] s_axi_rdata, 58 output [1:0] s_axi_rresp, 59 output s_axi_rvalid, 60 input s_axi_rready, 61 62 // SFP high-speed IO 63 output txp, 64 output txn, 65 input rxp, 66 input rxn, 67 68 // SFP low-speed IO 69 input sfpp_present_n, 70 input sfpp_rxlos, 71 input sfpp_tx_fault, 72 output sfpp_tx_disable, 73 74 //GT Common 75 input qpllrefclklost, 76 input qplllock, 77 input qplloutclk, 78 input qplloutrefclk, 79 output qpllreset, 80 81 //Aurora MMCM 82 input mmcm_locked, 83 output gt_pll_lock, 84 output gt_tx_out_clk_unbuf, 85 86 // Vita router interface 87 output [63:0] e2v_tdata, 88 output e2v_tlast, 89 output e2v_tvalid, 90 input e2v_tready, 91 92 input [63:0] v2e_tdata, 93 input v2e_tlast, 94 input v2e_tvalid, 95 output v2e_tready, 96 97 // CPU 98 output [63:0] e2c_tdata, 99 output [7:0] e2c_tkeep, 100 output e2c_tlast, 101 output e2c_tvalid, 102 input e2c_tready, 103 104 input [63:0] c2e_tdata, 105 input [7:0] c2e_tkeep, 106 input c2e_tlast, 107 input c2e_tvalid, 108 output c2e_tready, 109 110 // MISC 111 output [31:0] port_info, 112 input [15:0] device_id, 113 114 // Timebase Outputs 115 output sfp_pps, 116 output sfp_refclk, 117 118 // Sideband White Rabbit Control 119 input wr_reset_n, 120 input wr_refclk, 121 122 output wr_dac_sclk, 123 output wr_dac_din, 124 output wr_dac_clr_n, 125 output wr_dac_cs_n, 126 output wr_dac_ldac_n, 127 128 output wr_eeprom_scl_o, 129 input wr_eeprom_scl_i, 130 output wr_eeprom_sda_o, 131 input wr_eeprom_sda_i, 132 133 input wr_uart_rx, 134 output wr_uart_tx, 135 136 // WR AXI Control 137 output wr_axi_aclk, 138 input wr_axi_aresetn, 139 input [31:0] wr_axi_awaddr, 140 input wr_axi_awvalid, 141 output wr_axi_awready, 142 input [DWIDTH-1:0] wr_axi_wdata, 143 input [DWIDTH/8-1:0] wr_axi_wstrb, 144 input wr_axi_wvalid, 145 output wr_axi_wready, 146 output [1:0] wr_axi_bresp, 147 output wr_axi_bvalid, 148 input wr_axi_bready, 149 input [31:0] wr_axi_araddr, 150 input wr_axi_arvalid, 151 output wr_axi_arready, 152 output [DWIDTH-1:0] wr_axi_rdata, 153 output [1:0] wr_axi_rresp, 154 output wr_axi_rvalid, 155 input wr_axi_rready, 156 output wr_axi_rlast, 157 158 output link_up, 159 output activity 160 161); 162 163 localparam REG_BASE_SFP_IO = 14'h0; 164 localparam REG_BASE_ETH_SWITCH = 14'h1000; 165 166 // AXI4-Lite to RegPort (PS to PL Register Access) 167 wire reg_wr_req; 168 wire [AWIDTH-1:0] reg_wr_addr; 169 wire [DWIDTH-1:0] reg_wr_data; 170 wire reg_rd_req; 171 wire [AWIDTH-1:0] reg_rd_addr; 172 wire reg_rd_resp, reg_rd_resp_io, reg_rd_resp_eth_if; 173 wire [DWIDTH-1:0] reg_rd_data, reg_rd_data_io, reg_rd_data_eth_if; 174 175 axil_regport_master #( 176 .DWIDTH (DWIDTH), // Width of the AXI4-Lite data bus (must be 32 or 64) 177 .AWIDTH (AWIDTH), // Width of the address bus 178 .WRBASE (0), // Write address base 179 .RDBASE (0), // Read address base 180 .TIMEOUT (10) // log2(timeout). Read will timeout after (2^TIMEOUT - 1) cycles 181 ) sfp_reg_mst_i ( 182 // Clock and reset 183 .s_axi_aclk (s_axi_aclk), 184 .s_axi_aresetn (s_axi_aresetn), 185 // AXI4-Lite: Write address port (domain: s_axi_aclk) 186 .s_axi_awaddr (s_axi_awaddr), 187 .s_axi_awvalid (s_axi_awvalid), 188 .s_axi_awready (s_axi_awready), 189 // AXI4-Lite: Write data port (domain: s_axi_aclk) 190 .s_axi_wdata (s_axi_wdata), 191 .s_axi_wstrb (s_axi_wstrb), 192 .s_axi_wvalid (s_axi_wvalid), 193 .s_axi_wready (s_axi_wready), 194 // AXI4-Lite: Write response port (domain: s_axi_aclk) 195 .s_axi_bresp (s_axi_bresp), 196 .s_axi_bvalid (s_axi_bvalid), 197 .s_axi_bready (s_axi_bready), 198 // AXI4-Lite: Read address port (domain: s_axi_aclk) 199 .s_axi_araddr (s_axi_araddr), 200 .s_axi_arvalid (s_axi_arvalid), 201 .s_axi_arready (s_axi_arready), 202 // AXI4-Lite: Read data port (domain: s_axi_aclk) 203 .s_axi_rdata (s_axi_rdata), 204 .s_axi_rresp (s_axi_rresp), 205 .s_axi_rvalid (s_axi_rvalid), 206 .s_axi_rready (s_axi_rready), 207 // Register port: Write port (domain: reg_clk) 208 .reg_clk (bus_clk), 209 .reg_wr_req (reg_wr_req), 210 .reg_wr_addr (reg_wr_addr), 211 .reg_wr_data (reg_wr_data), 212 // Register port: Read port (domain: reg_clk) 213 .reg_rd_req (reg_rd_req), 214 .reg_rd_addr (reg_rd_addr), 215 .reg_rd_resp (reg_rd_resp), 216 .reg_rd_data (reg_rd_data) 217 ); 218 219 // Regport Mux for response 220 regport_resp_mux #( 221 .WIDTH (DWIDTH), 222 .NUM_SLAVES (2) 223 ) reg_resp_mux_i ( 224 .clk(bus_clk), .reset(bus_rst), 225 .sla_rd_resp({reg_rd_resp_eth_if, reg_rd_resp_io}), 226 .sla_rd_data({reg_rd_data_eth_if, reg_rd_data_io}), 227 .mst_rd_resp(reg_rd_resp), .mst_rd_data(reg_rd_data) 228 ); 229 230 wire [63:0] sfpo_tdata, sfpi_tdata; 231 wire [3:0] sfpo_tuser, sfpi_tuser; 232 wire sfpo_tlast, sfpi_tlast, sfpo_tvalid, sfpi_tvalid, sfpo_tready, sfpi_tready; 233 234 generate 235 if (PROTOCOL != "WhiteRabbit") begin 236 n3xx_mgt_io_core #( 237 .PROTOCOL (PROTOCOL), 238 .REG_BASE (REG_BASE_SFP_IO), 239 .REG_DWIDTH (DWIDTH), // Width of the AXI4-Lite data bus (must be 32 or 64) 240 .REG_AWIDTH (AWIDTH), // Width of the address bus 241 .MDIO_EN (MDIO_EN), 242 .MDIO_PHYADDR (MDIO_PHYADDR), 243 .PORTNUM (PORTNUM) 244 ) mgt_io_i ( 245 //must reset all channels on quad when sfp1 gtx core is reset 246 .areset (areset), 247 .gt_refclk (gt_refclk), 248 .gb_refclk (gb_refclk), 249 .misc_clk (misc_clk), 250 251 .bus_rst (bus_rst), 252 .bus_clk (bus_clk), 253 254 .txp (txp), 255 .txn (txn), 256 .rxp (rxp), 257 .rxn (rxn), 258 259 .sfpp_rxlos (sfpp_rxlos), 260 .sfpp_tx_fault (sfpp_tx_fault), 261 .sfpp_tx_disable(sfpp_tx_disable), 262 263 //RegPort 264 .reg_wr_req (reg_wr_req), 265 .reg_wr_addr (reg_wr_addr), 266 .reg_wr_data (reg_wr_data), 267 .reg_rd_req (reg_rd_req), 268 .reg_rd_addr (reg_rd_addr), 269 .reg_rd_resp (reg_rd_resp_io), 270 .reg_rd_data (reg_rd_data_io), 271 272 // Vita to Ethernet 273 .s_axis_tdata (sfpi_tdata), 274 .s_axis_tuser (sfpi_tuser), 275 .s_axis_tlast (sfpi_tlast), 276 .s_axis_tvalid (sfpi_tvalid), 277 .s_axis_tready (sfpi_tready), 278 279 // Ethernet to Vita 280 .m_axis_tdata (sfpo_tdata), 281 .m_axis_tuser (sfpo_tuser), 282 .m_axis_tlast (sfpo_tlast), 283 .m_axis_tvalid (sfpo_tvalid), 284 .m_axis_tready (sfpo_tready), 285 286 .port_info (port_info), 287 .link_up (link_up), 288 .activity (activity) 289 ); 290 291 end else begin 292 //--------------------------------------------------------------------------------- 293 // White Rabbit 294 //--------------------------------------------------------------------------------- 295 296 wire wr_sfp_scl, wr_sfp_sda_o, wr_sfp_sda_i; 297 298 n3xx_wr_top #( 299 .g_simulation(1'b0), // in std_logic 300 .g_dpram_size(131072/4), 301 .g_dpram_initf("../../../../bin/wrpc/wrc_phy16.bram") 302 ) wr_inst ( 303 .areset_n_i (wr_reset_n), // in std_logic; -- active low reset, optional 304 .wr_refclk_buf_i (wr_refclk), // in std_logic; -- 20MHz VCXO after IBUFGDS 305 .gige_refclk_buf_i (gt_refclk), // in std_logic; -- 125 MHz MGT Ref after IBUFDS_GTE2 306 .dac_sclk_o (wr_dac_sclk), // out std_logic; -- N3xx cWB-DAC-SCLK 307 .dac_din_o (wr_dac_din), // out std_logic; -- N3xx cWB-DAC-DIN 308 .dac_clr_n_o (wr_dac_clr_n), // out std_logic; -- N3xx cWB-DAC-nCLR 309 .dac_cs_n_o (wr_dac_cs_n), // out std_logic; -- N3xx cWB-DAC-nSYNC 310 .dac_ldac_n_o (wr_dac_ldac_n), // out std_logic; -- N3xx cWB-DAC-nLDAC 311 .LED_ACT (activity), // out std_logic; -- connect to SFP+ ACT 312 .LED_LINK (link_up), // out std_logic; -- connect to SFP+ LINK 313 .sfp_txp_o (txp), // out std_logic; 314 .sfp_txn_o (txn), // out std_logic; 315 .sfp_rxp_i (rxp), // in std_logic; 316 .sfp_rxn_i (rxn), // in std_logic; 317 .sfp_mod_def0_b (sfpp_present_n), // in std_logic; - sfp detect 318 .eeprom_scl_o (wr_eeprom_scl_o), 319 .eeprom_scl_i (wr_eeprom_scl_i), 320 .eeprom_sda_o (wr_eeprom_sda_o), 321 .eeprom_sda_i (wr_eeprom_sda_i), 322 .sfp_scl_o (wr_sfp_scl), 323 .sfp_scl_i (wr_sfp_scl), 324 .sfp_sda_o (wr_sfp_sda_o), 325 .sfp_sda_i (wr_sfp_sda_i), 326 .sfp_tx_fault_i (sfpp_tx_fault), // in std_logic; 327 .sfp_tx_disable_o (sfpp_tx_disable), // out std_logic; 328 .sfp_los_i (sfpp_rxlos), // in std_logic; 329 .wr_uart_rxd (wr_uart_rx), // in std_logic; 330 .wr_uart_txd (wr_uart_tx), // out std_logic; 331 332 .s00_axi_aclk_o (wr_axi_aclk), 333 .s00_axi_aresetn (wr_axi_aresetn), 334 .s00_axi_awaddr (wr_axi_awaddr), 335 .s00_axi_awprot (3'b0), 336 .s00_axi_awvalid (wr_axi_awvalid), 337 .s00_axi_awready (wr_axi_awready), 338 .s00_axi_wdata (wr_axi_wdata), 339 .s00_axi_wstrb (wr_axi_wstrb), 340 .s00_axi_wvalid (wr_axi_wvalid), 341 .s00_axi_wready (wr_axi_wready), 342 .s00_axi_bresp (wr_axi_bresp), 343 .s00_axi_bvalid (wr_axi_bvalid), 344 .s00_axi_bready (wr_axi_bready), 345 .s00_axi_araddr (wr_axi_araddr), 346 .s00_axi_arprot (3'b0), 347 .s00_axi_arvalid (wr_axi_arvalid), 348 .s00_axi_arready (wr_axi_arready), 349 .s00_axi_rdata (wr_axi_rdata), 350 .s00_axi_rresp (wr_axi_rresp), 351 .s00_axi_rvalid (wr_axi_rvalid), 352 .s00_axi_rready (wr_axi_rready), 353 .s00_axi_rlast (wr_axi_rlast), 354 .axi_int_o (), 355 356 .pps_o (sfp_pps), // out std_logic; 357 .clk_pps_o (sfp_refclk), // out std_logic; 358 .link_ok_o (), // out std_logic; 359 .clk_sys_locked_o (), // out std_logic; 360 .clk_dmtd_locked_o (), // out std_logic); 361 .wr_debug0_o (), 362 .wr_debug1_o () 363 ); 364 365 // TEMPORARY mimic the AXGE SFP EEROM 366 sfp_eeprom sfp_eeprom_i ( 367 .clk_i(bus_clk), 368 .sfp_scl(wr_sfp_scl), 369 .sfp_sda_i(wr_sfp_sda_o), 370 .sfp_sda_o(wr_sfp_sda_i)); 371 372 // Assign the port_info vector similarly to mgt_io_core 373 localparam [7:0] COMPAT_NUM = 8'd2; 374 localparam [7:0] MGT_PROTOCOL = 8'd4; 375 assign port_info = {COMPAT_NUM, 6'h0, activity, link_up, MGT_PROTOCOL, PORTNUM}; 376 377 // Tie off unused outputs. 378 assign gt_pll_lock = 1'b0; 379 assign gt_tx_out_clk_unbuf = 1'b0; 380 end 381 endgenerate 382 383 generate 384 // Tie off the Ethernet switch for these protocols that do not use it. 385 if(PROTOCOL == "Aurora" || PROTOCOL == "Disabled" || PROTOCOL == "WhiteRabbit") begin 386 387 //set unused wires to default value 388 assign e2c_tdata = 64'h0; 389 assign e2c_tkeep = 8'h0; 390 assign e2c_tlast = 1'b0; 391 assign e2c_tvalid = 1'b0; 392 assign c2e_tready = 1'b1; 393 394 assign reg_rd_resp_eth_if = 1'b0; 395 assign reg_rd_data_eth_if = 'h0; 396 397 end else begin 398 399 wire [3:0] e2c_tuser; 400 wire [3:0] c2e_tuser; 401 402 // In AXI Stream, tkeep is the byte qualifier that indicates 403 // whether the content of the associated byte 404 // of TDATA is processed as part of the data stream. 405 // tuser as used in eth_interface is the number of valid bytes 406 407 // Converting tuser to tkeep for ingress packets 408 assign e2c_tkeep = ~e2c_tlast ? 8'b1111_1111 409 : (e2c_tuser == 4'd0) ? 8'b1111_1111 410 : (e2c_tuser == 4'd1) ? 8'b0000_0001 411 : (e2c_tuser == 4'd2) ? 8'b0000_0011 412 : (e2c_tuser == 4'd3) ? 8'b0000_0111 413 : (e2c_tuser == 4'd4) ? 8'b0000_1111 414 : (e2c_tuser == 4'd5) ? 8'b0001_1111 415 : (e2c_tuser == 4'd6) ? 8'b0011_1111 416 : 8'b0111_1111; 417 418 // Converting tkeep to tuser for egress packets 419 assign c2e_tuser = ~c2e_tlast ? 4'd0 420 : (c2e_tkeep == 8'b1111_1111) ? 4'd0 421 : (c2e_tkeep == 8'b0111_1111) ? 4'd7 422 : (c2e_tkeep == 8'b0011_1111) ? 4'd6 423 : (c2e_tkeep == 8'b0001_1111) ? 4'd5 424 : (c2e_tkeep == 8'b0000_1111) ? 4'd4 425 : (c2e_tkeep == 8'b0000_0111) ? 4'd3 426 : (c2e_tkeep == 8'b0000_0011) ? 4'd2 427 : (c2e_tkeep == 8'b0000_0001) ? 4'd1 428 : 4'd0; 429 430 431 eth_interface #( 432 .PROTOVER (RFNOC_PROTOVER), 433 .MTU (10), 434 .NODE_INST (0), 435 .REG_AWIDTH (AWIDTH), 436 .BASE (REG_BASE_ETH_SWITCH) 437 ) eth_interface ( 438 .clk (bus_clk), 439 .reset (bus_rst), 440 .device_id (device_id), 441 .reg_wr_req (reg_wr_req), 442 .reg_wr_addr (reg_wr_addr), 443 .reg_wr_data (reg_wr_data), 444 .reg_rd_req (reg_rd_req), 445 .reg_rd_addr (reg_rd_addr), 446 .reg_rd_resp (reg_rd_resp_eth_if), 447 .reg_rd_data (reg_rd_data_eth_if), 448 .my_mac (), 449 .my_ip (), 450 .my_udp_port (), 451 .eth_tx_tdata (sfpi_tdata), 452 .eth_tx_tuser (sfpi_tuser), 453 .eth_tx_tlast (sfpi_tlast), 454 .eth_tx_tvalid (sfpi_tvalid), 455 .eth_tx_tready (sfpi_tready), 456 .eth_rx_tdata (sfpo_tdata), 457 .eth_rx_tuser (sfpo_tuser), 458 .eth_rx_tlast (sfpo_tlast), 459 .eth_rx_tvalid (sfpo_tvalid), 460 .eth_rx_tready (sfpo_tready), 461 .e2v_tdata (e2v_tdata), 462 .e2v_tlast (e2v_tlast), 463 .e2v_tvalid (e2v_tvalid), 464 .e2v_tready (e2v_tready), 465 .v2e_tdata (v2e_tdata), 466 .v2e_tlast (v2e_tlast), 467 .v2e_tvalid (v2e_tvalid), 468 .v2e_tready (v2e_tready), 469 .e2c_tdata (e2c_tdata), 470 .e2c_tuser (e2c_tuser), 471 .e2c_tlast (e2c_tlast), 472 .e2c_tvalid (e2c_tvalid), 473 .e2c_tready (e2c_tready), 474 .c2e_tdata (c2e_tdata), 475 .c2e_tuser (c2e_tuser), 476 .c2e_tlast (c2e_tlast), 477 .c2e_tvalid (c2e_tvalid), 478 .c2e_tready (c2e_tready) 479 ); 480 481 end 482 endgenerate 483 484endmodule // n310_sfp_wrapper 485