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