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