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