1-------------------------------------------------------------------------------
2-- Title      : 1000base-X MAC/Endpoint
3-- Project    : White Rabbit
4-------------------------------------------------------------------------------
5-- File       : wr_endpoint.vhd
6-- Author     : Tomasz Wlostowski
7-- Company    : CERN BE-CO-HT
8-- Created    : 2010-04-26
9-- Last update: 2017-02-20
10-- Platform   : FPGA-generics
11-- Standard   : VHDL
12-------------------------------------------------------------------------------
13-- Description: Module implements the top level for the White Rabbit Endpoint
14-- It's basically an extended Ethernet MAC providing extra timing/switch-specific
15-- features such as:
16-- - VLANs: inserting/removing tags (for ACCESS/TRUNK port support)
17-- - RX/TX precise timestaping
18-- - full PCS for optical Gigabit Ethernet
19-- - decodes MAC addresses, VIDs and priorities and passes them to the RTU.
20-- Refer to the manual for more details.
21-------------------------------------------------------------------------------
22--
23-- Copyright (c) 2011 - 2017 CERN / BE-CO-HT
24--
25-- This source file is free software; you can redistribute it
26-- and/or modify it under the terms of the GNU Lesser General
27-- Public License as published by the Free Software Foundation;
28-- either version 2.1 of the License, or (at your option) any
29-- later version.
30--
31-- This source is distributed in the hope that it will be
32-- useful, but WITHOUT ANY WARRANTY; without even the implied
33-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
34-- PURPOSE.  See the GNU Lesser General Public License for more
35-- details.
36--
37-- You should have received a copy of the GNU Lesser General
38-- Public License along with this source; if not, download it
39-- from http://www.gnu.org/licenses/lgpl-2.1.html
40--
41-------------------------------------------------------------------------------
42
43library ieee;
44use ieee.std_logic_1164.all;
45use ieee.numeric_std.all;
46
47library work;
48
49use work.gencores_pkg.all;
50use work.endpoint_private_pkg.all;
51use work.endpoint_pkg.all;
52use work.ep_wbgen2_pkg.all;
53use work.wr_fabric_pkg.all;
54use work.wishbone_pkg.all;
55
56entity wr_endpoint is
57
58  generic (
59    g_interface_mode        : t_wishbone_interface_mode      := CLASSIC;
60    g_address_granularity   : t_wishbone_address_granularity := WORD;
61    g_tx_force_gap_length   : integer                        := 0;
62    g_tx_runt_padding       : boolean                        := true;
63    g_simulation            : boolean                        := false;
64    g_pcs_16bit             : boolean                        := true;
65    g_rx_buffer_size        : integer                        := 1024;
66    g_with_rx_buffer        : boolean                        := true;
67    g_with_flow_control     : boolean                        := true;
68    g_with_timestamper      : boolean                        := true;
69    g_with_dpi_classifier   : boolean                        := false;
70    g_with_vlans            : boolean                        := true;
71    g_with_rtu              : boolean                        := true;
72    g_with_leds             : boolean                        := true;
73    g_with_dmtd             : boolean                        := false;
74    g_with_packet_injection : boolean                        := false;
75    g_use_new_rxcrc         : boolean                        := false;
76    g_use_new_txcrc         : boolean                        := false;
77    g_with_stop_traffic     : boolean                        := false
78    );
79  port (
80
81-------------------------------------------------------------------------------
82-- Clocks
83-------------------------------------------------------------------------------
84
85-- Endpoint transmit reference clock. Must be 125 MHz +- 100 ppm
86    clk_ref_i : in std_logic;
87
88-- reference clock / 2 (62.5 MHz, in-phase with refclk)
89    clk_sys_i : in std_logic;
90
91-- DMTD offset clock for phase tracking - used only if g_with_dmtd == true
92    clk_dmtd_i : in std_logic;
93
94-- resets for various clock domains
95    rst_sys_n_i   : in std_logic;
96    rst_ref_n_i   : in std_logic;
97    rst_dmtd_n_i  : in std_logic;
98    rst_txclk_n_i : in std_logic;
99    rst_rxclk_n_i : in std_logic;
100
101-- PPS input (1 clk_ref_i cycle HI) for synchronizing timestamp counter
102    pps_csync_p1_i : in std_logic;
103
104-- PPS valid input (clk_ref_i domain), when 1, the external PPS generator/servo
105-- is not adjusting the time scale, so we can safely timestamp.
106    pps_valid_i : in std_logic := '1';
107
108-------------------------------------------------------------------------------
109-- PHY Interace (8/16 bit PCS)
110-------------------------------------------------------------------------------
111
112    phy_rst_o            : out std_logic;
113    phy_loopen_o         : out std_logic;
114    phy_loopen_vec_o     : out std_logic_vector(2 downto 0);
115    phy_tx_prbs_sel_o    : out std_logic_vector(2 downto 0);
116    phy_sfp_tx_fault_i   : in  std_logic;
117    phy_sfp_los_i        : in  std_logic;
118    phy_sfp_tx_disable_o : out std_logic;
119    phy_rdy_i            : in  std_logic;
120
121    phy_ref_clk_i      : in  std_logic;
122    phy_tx_data_o      : out std_logic_vector(f_pcs_data_width(g_pcs_16bit)-1 downto 0);
123    phy_tx_k_o         : out std_logic_vector(f_pcs_k_width(g_pcs_16bit)-1 downto 0);
124    phy_tx_disparity_i : in  std_logic;
125    phy_tx_enc_err_i   : in  std_logic;
126
127    phy_rx_data_i     : in std_logic_vector(f_pcs_data_width(g_pcs_16bit)-1 downto 0);
128    phy_rx_clk_i      : in std_logic;
129    phy_rx_k_i        : in std_logic_vector(f_pcs_k_width(g_pcs_16bit)-1 downto 0);
130    phy_rx_enc_err_i  : in std_logic;
131    phy_rx_bitslide_i : in std_logic_vector(f_pcs_bts_width(g_pcs_16bit)-1 downto 0);
132
133-------------------------------------------------------------------------------
134-- GMII Interface (8-bit)
135-------------------------------------------------------------------------------
136
137    gmii_tx_clk_i : in  std_logic := '0';
138    gmii_txd_o    : out std_logic_vector(7 downto 0);
139    gmii_tx_en_o  : out std_logic;
140    gmii_tx_er_o  : out std_logic;
141
142    gmii_rx_clk_i : in std_logic                    := '0';
143    gmii_rxd_i    : in std_logic_vector(7 downto 0) := x"00";
144    gmii_rx_er_i  : in std_logic                    := '0';
145    gmii_rx_dv_i  : in std_logic                    := '0';
146
147    ---------------------------------------------------------------------------
148    -- Wishbone I/O
149    ---------------------------------------------------------------------------
150
151    src_dat_o   : out std_logic_vector(15 downto 0);
152    src_adr_o   : out std_logic_vector(1 downto 0);
153    src_sel_o   : out std_logic_vector(1 downto 0);
154    src_cyc_o   : out std_logic;
155    src_stb_o   : out std_logic;
156    src_we_o    : out std_logic;
157    src_stall_i : in  std_logic;
158    src_ack_i   : in  std_logic;
159    src_err_i   : in  std_logic;
160
161    snk_dat_i   : in  std_logic_vector(15 downto 0);
162    snk_adr_i   : in  std_logic_vector(1 downto 0);
163    snk_sel_i   : in  std_logic_vector(1 downto 0);
164    snk_cyc_i   : in  std_logic;
165    snk_stb_i   : in  std_logic;
166    snk_we_i    : in  std_logic;
167    snk_stall_o : out std_logic;
168    snk_ack_o   : out std_logic;
169    snk_err_o   : out std_logic;
170    snk_rty_o   : out std_logic;
171
172-------------------------------------------------------------------------------
173-- TX timestamping unit interface
174-------------------------------------------------------------------------------
175
176-- Port ID value
177    txtsu_port_id_o  : out std_logic_vector(4 downto 0);
178-- Frame ID value
179    txtsu_frame_id_o : out std_logic_vector(16 -1 downto 0);
180
181-- TX Timestamp and correctness info
182    txtsu_ts_value_o     : out std_logic_vector(28 + 4 - 1 downto 0);
183    txtsu_ts_incorrect_o : out std_logic;
184
185-- TX timestamp strobe: HI tells the TX timestamping unit that a timestamp is
186-- available on txtsu_ts_value_o, txtsu_fid_o andd txtsu_port_id_o. The correctness
187-- of the timestamping is indiacted on txtsu_ts_incorrect_o. Line remains HI
188-- until assertion of txtsu_ack_i.
189    txtsu_stb_o : out std_logic;
190
191-- TX timestamp acknowledge: HI indicates that TXTSU has successfully received
192-- the timestamp
193    txtsu_ack_i : in std_logic;
194
195-------------------------------------------------------------------------------
196-- RTU interface
197-------------------------------------------------------------------------------
198
199-- 1 indicates that coresponding RTU port is full.
200    rtu_full_i : in std_logic;
201
202-- 1 indicates that coresponding RTU port is almost full.
203    rtu_almost_full_i : in std_logic;
204
205-- request strobe, single HI pulse begins evaluation of the request.
206    rtu_rq_strobe_p1_o : out std_logic;
207
208    rtu_rq_abort_o : out std_logic;
209
210-- source and destination MAC addresses extracted from the packet header
211    rtu_rq_smac_o : out std_logic_vector(48 - 1 downto 0);
212    rtu_rq_dmac_o : out std_logic_vector(48 - 1 downto 0);
213
214-- VLAN id (extracted from the header for TRUNK ports and assigned by the port
215-- for ACCESS ports)
216    rtu_rq_vid_o : out std_logic_vector(12 - 1 downto 0);
217
218-- HI means that packet has valid assigned a valid VID (low - packet is untagged)
219    rtu_rq_has_vid_o : out std_logic;
220
221-- packet priority (either extracted from the header or assigned per port).
222    rtu_rq_prio_o : out std_logic_vector(3 - 1 downto 0);
223
224-- HI indicates that packet has assigned priority.
225    rtu_rq_has_prio_o : out std_logic;
226
227-------------------------------------------------------------------------------
228-- Wishbone bus
229-------------------------------------------------------------------------------
230
231    wb_cyc_i   : in  std_logic;
232    wb_stb_i   : in  std_logic;
233    wb_we_i    : in  std_logic;
234    wb_sel_i   : in  std_logic_vector(3 downto 0);
235    wb_adr_i   : in  std_logic_vector(7 downto 0);
236    wb_dat_i   : in  std_logic_vector(31 downto 0);
237    wb_dat_o   : out std_logic_vector(31 downto 0);
238    wb_ack_o   : out std_logic;
239    wb_stall_o : out std_logic;
240
241-------------------------------------------------------------------------------
242-- direct output of packet filter  (for TRU/HW-RSTP)
243-------------------------------------------------------------------------------
244
245   pfilter_pclass_o : out std_logic_vector(7 downto 0);
246   pfilter_drop_o   : out std_logic;
247   pfilter_done_o   : out std_logic;
248
249-------------------------------------------------------------------------------
250-- control of PAUSE sending (ML: not used and not tested... TRU uses packet injection) --
251-------------------------------------------------------------------------------
252
253   fc_tx_pause_req_i   : in  std_logic                     := '0';
254   fc_tx_pause_delay_i : in  std_logic_vector(15 downto 0) := x"0000";
255   fc_tx_pause_ready_o : out std_logic;
256
257-------------------------------------------------------------------------------
258-- information about received PAUSE (for SWcore)
259-------------------------------------------------------------------------------
260
261   fc_rx_pause_start_p_o   : out std_logic;
262   fc_rx_pause_quanta_o    : out std_logic_vector(15 downto 0);
263   fc_rx_pause_prio_mask_o : out std_logic_vector(7 downto 0);
264   fc_rx_buffer_occupation_o : out std_logic_vector(7 downto 0);
265-------------------------------------------------------------------------------
266-- Packet Injection Interface (for TRU/HW-RSTP)
267-------------------------------------------------------------------------------
268
269-- injection request: triggers transmission of the packet to be injected,
270-- allowed when inject_ready = 1
271    inject_req_i : in std_logic := '0';
272
273-- injection ready flag: when true, user application can request asynchronous
274-- injection of a predefined packet
275    inject_ready_o : out std_logic;
276
277-- injection template selection (8 available)
278    inject_packet_sel_i : in std_logic_vector(2 downto 0) := "000";
279
280-- user-defined value to be embedded in the injected packet at a predefined
281-- location
282    inject_user_value_i : in std_logic_vector(15 downto 0) := x"0000";
283
284-------------------------------------------------------------------------------
285-- Misc stuff
286-------------------------------------------------------------------------------
287    rmon_events_o : out std_logic_vector(c_epevents_sz-1 downto 0);
288
289    txts_o     : out std_logic; 		                -- 2013-Nov-28 peterj added for debugging/calibration
290    rxts_o     : out std_logic; 		                -- 2013-Nov-28 peterj added for debugging/calibration
291
292    led_link_o : out std_logic;
293    led_act_o  : out std_logic;
294
295-- HI physically kills the link (turn of laser)
296    link_kill_i : in std_logic := '0';
297
298-- HI indicates that link is up (so cable connected), LOW indicates that link is faulty
299-- (e.g.: cable disconnected)
300    link_up_o : out std_logic;
301
302    stop_traffic_i : in std_logic := '0';
303
304    dbg_tx_pcs_wr_count_o     : out std_logic_vector(5+4 downto 0);
305    dbg_tx_pcs_rd_count_o     : out std_logic_vector(5+4 downto 0);
306    nice_dbg_o  : out t_dbg_ep
307    );
308
309end wr_endpoint;
310
311architecture syn of wr_endpoint is
312
313  constant c_zeros : std_logic_vector(63 downto 0) := (others => '0');
314  constant c_ones  : std_logic_vector(63 downto 0) := (others => '0');
315
316-------------------------------------------------------------------------------
317  component dmtd_phase_meas
318    generic (
319      g_deglitcher_threshold : integer;
320      g_counter_bits         : integer);
321    port (
322      rst_sys_n_i    : in  std_logic;
323      rst_dmtd_n_i   : in  std_logic;
324      clk_sys_i      : in  std_logic;
325      clk_a_i        : in  std_logic;
326      clk_b_i        : in  std_logic;
327      clk_dmtd_i     : in  std_logic;
328      en_i           : in  std_logic;
329      navg_i         : in  std_logic_vector(11 downto 0);
330      phase_meas_o   : out std_logic_vector(31 downto 0);
331      phase_meas_p_o : out std_logic);
332  end component;
333
334-------------------------------------------------------------------------------
335-- TX FRAMER -> TX PCS signals
336-------------------------------------------------------------------------------
337
338  signal txpcs_fab   : t_ep_internal_fabric;
339  signal txpcs_dreq  : std_logic;
340  signal txpcs_error : std_logic;
341  signal txpcs_busy  : std_logic;
342
343-------------------------------------------------------------------------------
344-- Timestamping/OOB signals
345-------------------------------------------------------------------------------
346
347  signal txoob_fid_value : std_logic_vector(15 downto 0);
348  signal txoob_fid_stb   : std_logic;
349
350  signal txpcs_timestamp_trigger_p_a : std_logic;
351
352  signal txts_timestamp_stb   : std_logic;
353  signal txts_timestamp_valid : std_logic;
354  signal txts_timestamp_value : std_logic_vector(31 downto 0);
355
356
357  signal rxpcs_timestamp_stb         : std_logic;
358  signal rxpcs_timestamp_trigger_p_a : std_logic;
359  signal rxpcs_timestamp_valid       : std_logic;
360  signal rxpcs_timestamp_value       : std_logic_vector(31 downto 0);
361
362
363-------------------------------------------------------------------------------
364-- RX PCS -> RX DEFRAMER signals
365-------------------------------------------------------------------------------
366
367  signal rxpcs_fab             : t_ep_internal_fabric;
368  signal rxpath_fab            : t_ep_internal_fabric;
369  signal rxpcs_busy            : std_logic;
370  signal rxpcs_fifo_almostfull : std_logic;
371
372-------------------------------------------------------------------------------
373-- WB slave signals
374-------------------------------------------------------------------------------
375
376  signal regs_fromwb     : t_ep_out_registers;
377  signal regs_towb       : t_ep_in_registers;
378  signal regs_towb_ep    : t_ep_in_registers;
379  signal regs_towb_tsu   : t_ep_in_registers;
380  signal regs_towb_rpath : t_ep_in_registers;
381  signal regs_towb_tpath : t_ep_in_registers;
382  signal regs_towb_dmtd  : t_ep_in_registers;
383
384-------------------------------------------------------------------------------
385-- flow control signals
386-------------------------------------------------------------------------------
387
388  signal txfra_flow_enable : std_logic;
389  signal rxfra_pause_p     : std_logic;
390  signal rxfra_pause_delay : std_logic_vector(15 downto 0);
391
392  signal txfra_pause_req   : std_logic;
393  signal txfra_pause_ready : std_logic;
394  signal txfra_pause_delay : std_logic_vector(15 downto 0);
395
396  signal link_ok : std_logic;
397
398  signal txfra_enable : std_logic;
399  signal mdio_addr    : std_logic_vector(15 downto 0);
400
401  signal sink_in  : t_wrf_sink_in;
402  signal sink_out : t_wrf_sink_out;
403
404  signal src_in  : t_wrf_source_in;
405  signal src_out : t_wrf_source_out;
406
407  signal rst_n_rx : std_logic;
408
409  signal wb_in  : t_wishbone_slave_in;
410  signal wb_out : t_wishbone_slave_out;
411
412  signal extended_ADDR : std_logic_vector(c_wishbone_address_width-1 downto 0);
413
414  signal phase_meas    : std_logic_vector(31 downto 0);
415  signal phase_meas_p  : std_logic;
416  signal validity_cntr : unsigned(1 downto 0);
417  signal r_dmcr_en     : std_logic;
418  signal r_dmcr_n_avg  : std_logic_vector(11 downto 0);
419
420
421  signal rtu_rq               : t_ep_internal_rtu_request;
422  signal dvalid_tx, dvalid_rx : std_logic;
423
424-------------------------------------------------------------------------------
425-- TRU stuff
426-------------------------------------------------------------------------------
427  signal ep_ctrl        : std_logic;
428  signal pfilter_pclass : std_logic_vector(7 downto 0);
429  signal pfilter_drop   : std_logic;
430  signal pfilter_done   : std_logic;
431  signal tx_pclass      : std_logic_vector(7 downto 0);
432
433-------------------------------------------------------------------------------
434-- RMON signals
435-------------------------------------------------------------------------------
436  signal pcs_rmon     : t_rmon_triggers;
437  signal rx_path_rmon : t_rmon_triggers;
438  signal rmon         : t_rmon_triggers;
439
440-------------------------------------------------------------------------------
441-- chipscope (for desperates)
442-------------------------------------------------------------------------------
443  signal CONTROL0                   : std_logic_vector(35 downto 0);
444  signal TRIG0, TRIG1, TRIG2, TRIG3 : std_logic_vector(31 downto 0);
445
446  component chipscope_icon
447    port (
448      CONTROL0 : inout std_logic_vector(35 downto 0));
449  end component;
450
451  component chipscope_ila
452    port (
453      CONTROL : inout std_logic_vector(35 downto 0);
454      CLK     : in    std_logic;
455      TRIG0   : in    std_logic_vector(31 downto 0);
456      TRIG1   : in    std_logic_vector(31 downto 0);
457      TRIG2   : in    std_logic_vector(31 downto 0);
458      TRIG3   : in    std_logic_vector(31 downto 0));
459  end component;
460
461begin
462
463  rst_n_rx  <= rst_rxclk_n_i and phy_rdy_i;
464
465-------------------------------------------------------------------------------
466-- 1000Base-X PCS
467-------------------------------------------------------------------------------
468
469  mdio_addr <= regs_fromwb.mdio_asr_phyad_o & regs_fromwb.mdio_cr_addr_o;
470
471  U_PCS_1000BASEX : ep_1000basex_pcs
472    generic map (
473      g_simulation => g_simulation,
474      g_16bit      => g_pcs_16bit)
475    port map (
476      rst_sys_n_i   => rst_sys_n_i,
477      rst_rxclk_n_i => rst_rxclk_n_i,
478      rst_txclk_n_i => rst_txclk_n_i,
479      clk_sys_i     => clk_sys_i,
480
481      rxpcs_fab_o             => rxpcs_fab,
482      rxpcs_busy_o            => rxpcs_busy,
483      rxpcs_fifo_almostfull_i => rxpcs_fifo_almostfull,
484
485      rxpcs_timestamp_trigger_p_a_o => rxpcs_timestamp_trigger_p_a,
486      rxpcs_timestamp_i             => rxpcs_timestamp_value,
487      rxpcs_timestamp_stb_i         => rxpcs_timestamp_stb,
488      rxpcs_timestamp_valid_i       => rxpcs_timestamp_valid,
489
490      txpcs_fab_i   => txpcs_fab,
491      txpcs_busy_o  => txpcs_busy,
492      txpcs_dreq_o  => txpcs_dreq,
493      txpcs_error_o => txpcs_error,
494
495      txpcs_timestamp_trigger_p_a_o => txpcs_timestamp_trigger_p_a,
496
497      link_ok_o  => link_ok,
498      link_ctr_i => ep_ctrl,
499
500      serdes_rst_o             => phy_rst_o,
501      serdes_loopen_o          => phy_loopen_o,
502      serdes_loopen_vec_o      => phy_loopen_vec_o,
503      serdes_tx_prbs_sel_o     => phy_tx_prbs_sel_o,
504      serdes_sfp_tx_fault_i    => phy_sfp_tx_fault_i,
505      serdes_sfp_los_i         => phy_sfp_los_i,
506      serdes_sfp_tx_disable_o  => phy_sfp_tx_disable_o,
507      serdes_rdy_i             => phy_rdy_i,
508
509      serdes_tx_clk_i       => phy_ref_clk_i,
510      serdes_tx_data_o      => phy_tx_data_o,
511      serdes_tx_k_o         => phy_tx_k_o,
512      serdes_tx_disparity_i => phy_tx_disparity_i,
513      serdes_tx_enc_err_i   => phy_tx_enc_err_i,
514      serdes_rx_data_i      => phy_rx_data_i,
515      serdes_rx_clk_i       => phy_rx_clk_i,
516      serdes_rx_k_i         => phy_rx_k_i,
517      serdes_rx_enc_err_i   => phy_rx_enc_err_i,
518      serdes_rx_bitslide_i  => phy_rx_bitslide_i,
519
520      rmon_o => pcs_rmon,
521
522      mdio_addr_i  => mdio_addr,
523      mdio_data_i  => regs_fromwb.mdio_cr_data_o,
524      mdio_data_o  => regs_towb_ep.mdio_asr_rdata_i,
525      mdio_stb_i   => regs_fromwb.mdio_cr_data_wr_o,
526      mdio_rw_i    => regs_fromwb.mdio_cr_rw_o,
527      mdio_ready_o => regs_towb_ep.mdio_asr_ready_i,
528      dbg_tx_pcs_wr_count_o => dbg_tx_pcs_wr_count_o,
529      dbg_tx_pcs_rd_count_o => dbg_tx_pcs_rd_count_o,
530      nice_dbg_o   => nice_dbg_o.pcs);
531
532
533-------------------------------------------------------------------------------
534-- TX FRAMER
535-------------------------------------------------------------------------------
536
537--  txfra_enable <= link_ok and regs_fromwb.ecr_tx_en_o;
538
539--   txfra_pause_req <= '0';
540
541  U_Tx_Path : ep_tx_path
542    generic map (
543      g_with_packet_injection => g_with_packet_injection,
544      g_with_vlans            => g_with_vlans,
545      g_with_timestamper      => g_with_timestamper,
546      g_force_gap_length      => g_tx_force_gap_length,
547      g_runt_padding          => g_tx_runt_padding,
548      g_use_new_crc           => g_use_new_txcrc)
549    port map (
550      clk_sys_i        => clk_sys_i,
551      rst_n_i          => rst_sys_n_i,
552      pcs_error_i      => txpcs_error,
553      pcs_busy_i       => txpcs_busy,
554      pcs_fab_o        => txpcs_fab,
555      pcs_dreq_i       => txpcs_dreq,
556      snk_i            => sink_in,
557      snk_o            => sink_out,
558      fc_pause_req_i   => txfra_pause_req,
559      fc_pause_ready_o => txfra_pause_ready,
560      fc_pause_delay_i => txfra_pause_delay,
561      fc_flow_enable_i => txfra_flow_enable,
562      ep_ctrl_i        => ep_ctrl,
563      regs_i           => regs_fromwb,
564      regs_o           => regs_towb_tpath,
565
566      txts_timestamp_i       => txts_timestamp_value,
567      txts_timestamp_valid_i => txts_timestamp_valid,
568
569      txtsu_port_id_o      => txtsu_port_id_o,
570      txtsu_fid_o          => txtsu_frame_id_o,
571      txtsu_ts_value_o     => txtsu_ts_value_o,
572      txtsu_ts_incorrect_o => txtsu_ts_incorrect_o,
573      txtsu_stb_o          => txtsu_stb_o,
574      txtsu_ack_i          => txtsu_ack_i,
575
576      inject_req_i        => inject_req_i,
577      inject_user_value_i => inject_user_value_i,
578      inject_packet_sel_i => inject_packet_sel_i,
579      inject_ready_o      => inject_ready_o);
580
581
582  txfra_flow_enable <= '1';
583
584  sink_in.dat <= snk_dat_i;
585  sink_in.adr <= snk_adr_i;
586  sink_in.sel <= snk_sel_i;
587  sink_in.cyc <= snk_cyc_i;
588  sink_in.stb <= snk_stb_i;
589  sink_in.we  <= snk_we_i;
590  snk_stall_o <= sink_out.stall;
591  snk_ack_o   <= sink_out.ack;
592  snk_err_o   <= sink_out.err;
593  snk_rty_o   <= sink_out.rty;
594
595
596-------------------------------------------------------------------------------
597-- RX deframer
598-------------------------------------------------------------------------------
599
600  U_Rx_Path : ep_rx_path
601    generic map (
602      g_with_vlans          => g_with_vlans,
603      g_with_dpi_classifier => g_with_dpi_classifier,
604      g_with_rtu            => g_with_rtu,
605      g_with_rx_buffer      => g_with_rx_buffer,
606      g_rx_buffer_size      => g_rx_buffer_size,
607      g_use_new_crc         => g_use_new_rxcrc)
608    port map (
609      clk_sys_i => clk_sys_i,
610      clk_rx_i  => phy_rx_clk_i,
611
612      rst_n_sys_i => rst_sys_n_i,
613      rst_n_rx_i  => rst_n_rx,
614
615      pcs_fab_i             => rxpath_fab,
616      pcs_fifo_almostfull_o => rxpcs_fifo_almostfull,
617      pcs_busy_i            => rxpcs_busy,
618
619      fc_pause_p_o         => fc_rx_pause_start_p_o,  --rxfra_pause_p,
620      fc_pause_quanta_o    => fc_rx_pause_quanta_o,   --rxfra_pause_delay,
621      fc_pause_prio_mask_o => fc_rx_pause_prio_mask_o,
622      fc_buffer_occupation_o => fc_rx_buffer_occupation_o,
623
624      rmon_o => rx_path_rmon,
625      regs_i => regs_fromwb,
626      regs_o => regs_towb_rpath,
627
628      pfilter_pclass_o => pfilter_pclass,
629      pfilter_drop_o   => pfilter_drop,
630      pfilter_done_o   => pfilter_done,
631
632      rtu_full_i     => rtu_full_i,
633      rtu_rq_o       => rtu_rq,
634      rtu_rq_valid_o => rtu_rq_strobe_p1_o,
635      rtu_rq_abort_o => rtu_rq_abort_o,
636      src_wb_o       => src_out,
637      src_wb_i       => src_in,
638      nice_dbg_o     => nice_dbg_o.rxpath);
639
640
641  rtu_rq_smac_o     <= rtu_rq.smac;
642  rtu_rq_dmac_o     <= rtu_rq.dmac;
643  rtu_rq_vid_o      <= rtu_rq.vid;
644  rtu_rq_prio_o     <= rtu_rq.prio;
645  rtu_rq_has_vid_o  <= rtu_rq.has_vid;
646  rtu_rq_has_prio_o <= rtu_rq.has_prio;
647
648  src_dat_o    <= src_out.dat;
649  src_adr_o    <= src_out.adr;
650  src_sel_o    <= src_out.sel;
651  src_cyc_o    <= src_out.cyc;
652  src_stb_o    <= src_out.stb;
653  src_we_o     <= src_out.we;
654  src_in.stall <= src_stall_i;
655  src_in.ack   <= src_ack_i;
656  src_in.err   <= src_err_i;
657  src_in.rty   <= '0';
658
659-------------------------------------------------------------------------------
660-- Flow control unit
661-------------------------------------------------------------------------------
662
663  --U_FLOW_CTL : ep_flow_control
664  --  port map (
665  --    clk_sys_i => clk_sys_i,
666  --    rst_n_i   => rst_n_i,
667
668  --    rx_pause_p1_i    => rxfra_pause_p,
669  --    rx_pause_delay_i => rxfra_pause_delay,
670
671  --    tx_pause_o       => txfra_pause,
672  --    tx_pause_delay_o => txfra_pause_delay,
673  --    tx_pause_ack_i   => txfra_pause_ack,
674
675  --    tx_flow_enable_o => txfra_flow_enable,
676
677  --    rx_buffer_used_i => rx_buffer_used,
678
679  --    ep_fcr_txpause_i   => regs.fcr_txpause_o,
680  --    ep_fcr_rxpause_i   => regs.fcr_rxpause_o,
681  --    ep_fcr_tx_thr_i    => regs.fcr_tx_thr_o,
682  --    ep_fcr_tx_quanta_i => regs.fcr_tx_quanta_o,
683  --    rmon_rcvd_pause_o  => rmon.rx_pause,
684  --    rmon_sent_pause_o  => rmon.tx_pause
685  --    );
686
687-------------------------------------------------------------------------------
688-- Timestamping unit
689-------------------------------------------------------------------------------
690
691  U_EP_TSU : ep_timestamping_unit
692    generic map (
693      g_timestamp_bits_r => 28,
694      g_timestamp_bits_f => 4,
695      g_ref_clock_rate   => f_pcs_clock_rate(g_pcs_16bit))
696    port map (
697      clk_ref_i      => clk_ref_i,
698      clk_rx_i       => phy_rx_clk_i,
699      clk_sys_i      => clk_sys_i,
700      rst_n_rx_i     => rst_rxclk_n_i,
701      rst_n_sys_i    => rst_sys_n_i,
702      rst_n_ref_i    => rst_ref_n_i,
703      pps_csync_p1_i => pps_csync_p1_i,
704      pps_valid_i    => pps_valid_i,
705
706      tx_timestamp_trigger_p_a_i => txpcs_timestamp_trigger_p_a,
707      rx_timestamp_trigger_p_a_i => rxpcs_timestamp_trigger_p_a,
708
709      rxts_timestamp_o       => rxpcs_timestamp_value,
710      rxts_timestamp_valid_o => rxpcs_timestamp_valid,
711      rxts_timestamp_stb_o   => rxpcs_timestamp_stb,
712
713      txts_timestamp_o       => txts_timestamp_value,
714      txts_timestamp_valid_o => txts_timestamp_valid,
715
716      txts_o                 => txts_o,                   -- 2013-Nov-28 peterj added for debugging/calibration
717      rxts_o                 => rxts_o, 		              -- 2013-Nov-28 peterj added for debugging/calibration
718
719      regs_i => regs_fromwb,
720      regs_o => regs_towb_tsu);
721
722
723-------------------------------------------------------------------------------
724-- Wishbone controller & IO registers
725-------------------------------------------------------------------------------
726
727  extended_ADDR <= std_logic_vector(resize(unsigned(wb_adr_i), c_wishbone_address_width));
728
729  U_Slave_adapter : wb_slave_adapter
730    generic map (
731      g_master_use_struct  => true,
732      g_master_mode        => CLASSIC,
733      g_master_granularity => WORD,
734      g_slave_use_struct   => false,
735      g_slave_mode         => g_interface_mode,
736      g_slave_granularity  => g_address_granularity)
737    port map (
738      clk_sys_i  => clk_sys_i,
739      rst_n_i    => rst_sys_n_i,
740      sl_adr_i   => extended_ADDR,
741      sl_dat_i   => wb_dat_i,
742      sl_sel_i   => wb_sel_i,
743      sl_cyc_i   => wb_cyc_i,
744      sl_stb_i   => wb_stb_i,
745      sl_we_i    => wb_we_i,
746      sl_dat_o   => wb_dat_o,
747      sl_ack_o   => wb_ack_o,
748      sl_stall_o => wb_stall_o,
749      master_i   => wb_out,
750      master_o   => wb_in);
751
752  U_WB_SLAVE : ep_wishbone_controller
753    port map (
754      rst_n_i    => rst_sys_n_i,
755      clk_sys_i  => clk_sys_i,
756      wb_adr_i   => wb_in.adr(4 downto 0),
757      wb_dat_i   => wb_in.dat,
758      wb_dat_o   => wb_out.dat,
759      wb_cyc_i   => wb_in.cyc,
760      wb_sel_i   => wb_in.sel,
761      wb_stb_i   => wb_in.stb,
762      wb_we_i    => wb_in.we,
763      wb_ack_o   => wb_out.ack,
764      wb_stall_o => open,
765
766      tx_clk_i => clk_ref_i,
767      rx_clk_i => phy_rx_clk_i,
768
769      regs_o => regs_fromwb,
770      regs_i => regs_towb
771      );
772
773  wb_out.stall <= '0';
774  wb_out.rty   <= '0';
775  wb_out.err   <= '0';
776  wb_out.int   <= '0';
777
778  regs_towb <= regs_towb_ep or regs_towb_tsu or regs_towb_rpath or regs_towb_tpath or regs_towb_dmtd;
779
780
781  p_link_activity : process(clk_sys_i)
782  begin
783    if rising_edge(clk_sys_i) then
784
785      if(rst_sys_n_i = '0') or
786        (regs_fromwb.dsr_lact_o = '1' and regs_fromwb.dsr_lact_load_o = '1') then
787        regs_towb_ep.dsr_lact_i <= '0';
788      else
789        regs_towb_ep.dsr_lact_i <= dvalid_rx or dvalid_tx;
790      end if;
791    end if;
792  end process;
793
794  -- drive unused regs_towb_ep signals
795  regs_towb_ep.ecr_feat_vlan_i           <= '0';
796  regs_towb_ep.ecr_feat_dmtd_i           <= '0';
797  regs_towb_ep.ecr_feat_ptp_i            <= '0';
798  regs_towb_ep.ecr_feat_dpi_i            <= '0';
799  regs_towb_ep.tscr_cs_done_i            <= '0';
800  regs_towb_ep.tscr_rx_cal_result_i      <= '0';
801  regs_towb_ep.tcar_pcp_map_i            <= (others => '0');
802  regs_towb_ep.dsr_lstatus_i             <= '0';
803  regs_towb_ep.dmcr_en_i                 <= '0';
804  regs_towb_ep.dmcr_n_avg_i              <= (others => '0');
805  regs_towb_ep.inj_ctrl_pic_conf_ifg_i   <= (others => '0');
806  regs_towb_ep.inj_ctrl_pic_conf_sel_i   <= (others => '0');
807  regs_towb_ep.inj_ctrl_pic_conf_valid_i <= '0';
808  regs_towb_ep.inj_ctrl_pic_mode_id_i    <= (others => '0');
809  regs_towb_ep.inj_ctrl_pic_mode_valid_i <= '0';
810  regs_towb_ep.inj_ctrl_pic_ena_i        <= '0';
811
812-------------------------------------------------------------------------------
813-- DMTD phase meter
814------------------------------------------------------------------------------
815
816  gen_with_dmtd : if(g_with_dmtd) generate
817    U_DMTD : dmtd_phase_meas
818      generic map (
819        g_counter_bits         => 14,
820        g_deglitcher_threshold => 1000)
821      port map (
822        clk_sys_i => clk_sys_i,
823
824        clk_a_i    => phy_ref_clk_i,
825        clk_b_i    => phy_rx_clk_i,
826        clk_dmtd_i => clk_dmtd_i,
827
828        rst_sys_n_i  => rst_sys_n_i,
829        rst_dmtd_n_i => rst_dmtd_n_i,
830
831        en_i           => r_dmcr_en,
832        navg_i         => r_dmcr_n_avg,
833        phase_meas_o   => phase_meas,
834        phase_meas_p_o => phase_meas_p);
835
836
837
838    regs_towb_dmtd.dmcr_en_i    <= r_dmcr_en;
839    regs_towb_dmtd.dmcr_n_avg_i <= r_dmcr_n_avg;
840
841    p_dmtd_update : process(clk_sys_i)
842    begin
843      if rising_edge(clk_sys_i) then
844        if rst_sys_n_i = '0' then
845          validity_cntr              <= (others => '0');
846          regs_towb_ep.dmsr_ps_rdy_i <= '0';
847        else
848
849          if(regs_fromwb.dmcr_en_load_o = '1') then
850            r_dmcr_en    <= regs_fromwb.dmcr_en_o;
851            r_dmcr_n_avg <= regs_fromwb.dmcr_n_avg_o;
852          end if;
853
854          if(r_dmcr_en = '0') then
855            validity_cntr              <= (others => '0');
856            regs_towb_ep.dmsr_ps_rdy_i <= '0';
857          elsif(regs_fromwb.dmsr_ps_rdy_o = '1' and regs_fromwb.dmsr_ps_rdy_load_o = '1') then
858            regs_towb_ep.dmsr_ps_rdy_i <= '0';
859          elsif(phase_meas_p = '1') then
860
861            if(validity_cntr = "11") then
862              regs_towb_ep.dmsr_ps_rdy_i <= '1';
863              regs_towb_ep.dmsr_ps_val_i <= phase_meas(23 downto 0);  -- discard few
864            else
865              regs_towb_ep.dmsr_ps_rdy_i <= '0';
866              validity_cntr              <= validity_cntr + 1;
867            end if;
868          end if;
869        end if;
870      end if;
871    end process;
872
873  end generate gen_with_dmtd;
874
875  gen_without_dmtd : if(not g_with_dmtd) generate
876    regs_towb_ep.dmsr_ps_rdy_i <= '0';
877    regs_towb_ep.dmsr_ps_val_i <= (others => 'X');
878    regs_towb_dmtd             <= c_ep_in_registers_init_value;
879  end generate gen_without_dmtd;
880
881  dvalid_tx <= snk_cyc_i and snk_stb_i and link_ok;
882  dvalid_rx <= src_out.cyc and src_out.stb and link_ok;
883
884  gen_leds : if g_with_leds generate
885    U_Led_Ctrl : ep_leds_controller
886      generic map (
887        g_blink_period_log2 => 22)
888      port map (
889        clk_sys_i   => clk_sys_i,
890        rst_n_i     => rst_sys_n_i,
891        dvalid_tx_i => dvalid_tx,
892        dvalid_rx_i => dvalid_rx,
893        link_ok_i   => link_ok,
894        led_link_o  => led_link_o,
895        led_act_o   => led_act_o);
896  end generate gen_leds;
897
898  -------------------------- TRU stuff -----------------------------------
899  link_up_o <= link_ok;                 -- indicates that link is UP
900
901  pfilter_pclass_o <= pfilter_pclass;
902  pfilter_done_o   <= pfilter_done;
903  pfilter_drop_o   <= pfilter_drop;
904
905  txfra_pause_req     <= fc_tx_pause_req_i;
906  fc_tx_pause_ready_o <= txfra_pause_ready;
907  txfra_pause_delay   <= fc_tx_pause_delay_i;
908
909  -- TRU needs to be able to share the control of ouput path, i.e. turn off the laser
910  p_ep_ctrl : process(clk_sys_i)
911  begin
912    if rising_edge(clk_sys_i) then
913      if rst_sys_n_i = '0' then
914        ep_ctrl <= '1';
915      else
916        ep_ctrl <= not link_kill_i;
917      end if;
918    end if;
919  end process;
920
921  GEN_STOP: if(g_with_stop_traffic) generate
922    rxpath_fab.sof    <= rxpcs_fab.sof    when(stop_traffic_i='0') else '0';
923    rxpath_fab.dvalid <= rxpcs_fab.dvalid when(stop_traffic_i='0') else '0';
924    rxpath_fab.eof   <= rxpcs_fab.eof;
925    rxpath_fab.error <= rxpcs_fab.error;
926    rxpath_fab.bytesel <= rxpcs_fab.bytesel;
927    rxpath_fab.has_rx_timestamp <= rxpcs_fab.has_rx_timestamp;
928    rxpath_fab.rx_timestamp_valid <= rxpcs_fab.rx_timestamp_valid;
929    rxpath_fab.data <= rxpcs_fab.data;
930    rxpath_fab.addr <= rxpcs_fab.addr;
931  end generate;
932
933  GEN_NO_STOP: if(not g_with_stop_traffic) generate
934    rxpath_fab <= rxpcs_fab;
935  end generate;
936
937  -------------------------- RMON events -----------------------------------
938  rmon.rx_pcs_err      <= rx_path_rmon.rx_pcs_err;  --from ep_rx_path
939  rmon.rx_giant        <= rx_path_rmon.rx_giant;
940  rmon.rx_runt         <= rx_path_rmon.rx_runt;
941  rmon.rx_crc_err      <= rx_path_rmon.rx_crc_err;
942  rmon.rx_pause        <= rx_path_rmon.rx_pause;
943  rmon.rx_pfilter_drop <= rx_path_rmon.rx_pfilter_drop;
944  rmon.rx_pclass       <= rx_path_rmon.rx_pclass;
945  rmon.rx_tclass       <= rx_path_rmon.rx_tclass;
946  rmon.rx_drop_at_rtu_full <= rx_path_rmon.rx_drop_at_rtu_full;
947  rmon.tx_underrun     <= pcs_rmon.tx_underrun;
948  rmon.rx_overrun      <= pcs_rmon.rx_overrun;
949  rmon.rx_invalid_code <= pcs_rmon.rx_invalid_code;
950  rmon.rx_sync_lost    <= pcs_rmon.rx_sync_lost;
951
952
953  rmon_event_tx : gc_sync_ffs
954    generic map(
955      g_sync_edge => "negative")
956    port map (
957      clk_i    => clk_sys_i,
958      rst_n_i  => rst_sys_n_i,
959      data_i   => txpcs_timestamp_trigger_p_a,
960      synced_o => open,
961      npulse_o => open,
962      ppulse_o => rmon.tx_frame);
963
964  rmon_event_rx : gc_sync_ffs
965    generic map(
966      g_sync_edge => "negative")
967    port map (
968      clk_i    => clk_sys_i,
969      rst_n_i  => rst_sys_n_i,
970      data_i   => rxpcs_timestamp_trigger_p_a,
971      synced_o => open,
972      npulse_o => open,
973      ppulse_o => rmon.rx_frame);
974
975  f_pack_rmon_triggers(rmon, rmon_events_o(c_epevents_sz-1 downto 0));
976
977--   CS_ICON : chipscope_icon
978--    port map (
979--     CONTROL0 => CONTROL0);
980--   CS_ILA : chipscope_ila
981--    port map (
982--      CONTROL => CONTROL0,
983--      CLK     => phy_ref_clk_i,
984--      TRIG0   => TRIG0,
985--      TRIG1   => TRIG1,
986--      TRIG2   => TRIG2,
987--      TRIG3   => TRIG3);
988--
989--   TRIG0(15    downto   0) <= phy_rx_data_i;
990--   TRIG0(17    downto  16) <= phy_rx_k_i;
991--   TRIG0(              18) <= phy_rx_enc_err_i;
992--   TRIG0(23    downto  19) <= phy_rx_bitslide_i;
993
994  -- Drive unsued GMII outputs
995  gmii_txd_o   <= (others => '0');
996  gmii_tx_en_o <= '0';
997  gmii_tx_er_o <= '0';
998
999end syn;
1000
1001
1002