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