# # pin constraints # NET CLK_N LOC = "K22" | DIFF_TERM = "TRUE" | IOSTANDARD = "LVDS_25"; NET CLK_P LOC = "K21" | DIFF_TERM = "TRUE" | IOSTANDARD = "LVDS_25"; NET DIP_Switches_4Bits_TRI_I[0] LOC = "C18" | IOSTANDARD = "LVCMOS25"; NET DIP_Switches_4Bits_TRI_I[1] LOC = "Y6" | IOSTANDARD = "LVCMOS25"; NET DIP_Switches_4Bits_TRI_I[2] LOC = "W6" | IOSTANDARD = "LVCMOS25"; NET DIP_Switches_4Bits_TRI_I[3] LOC = "E4" | IOSTANDARD = "LVCMOS25"; NET ETHERNET_MDC LOC = "R19" | IOSTANDARD = "LVCMOS25"; NET ETHERNET_MDIO LOC = "V20" | IOSTANDARD = "LVCMOS25"; NET ETHERNET_MII_TX_CLK LOC = "L20" | IOSTANDARD = "LVCMOS25"; NET ETHERNET_PHY_RST_N LOC = "J22" | IOSTANDARD = "LVCMOS25" | TIG; NET ETHERNET_RXD[0] LOC = "P19" | IOSTANDARD = "LVCMOS25"; NET ETHERNET_RXD[1] LOC = "Y22" | IOSTANDARD = "LVCMOS25"; NET ETHERNET_RXD[2] LOC = "Y21" | IOSTANDARD = "LVCMOS25"; NET ETHERNET_RXD[3] LOC = "W22" | IOSTANDARD = "LVCMOS25"; NET ETHERNET_RXD[4] LOC = "W20" | IOSTANDARD = "LVCMOS25"; NET ETHERNET_RXD[5] LOC = "V22" | IOSTANDARD = "LVCMOS25"; NET ETHERNET_RXD[6] LOC = "V21" | IOSTANDARD = "LVCMOS25"; NET ETHERNET_RXD[7] LOC = "U22" | IOSTANDARD = "LVCMOS25"; NET ETHERNET_RX_CLK LOC = "P20" | IOSTANDARD = "LVCMOS25"; NET ETHERNET_RX_DV LOC = "T22" | IOSTANDARD = "LVCMOS25"; NET ETHERNET_RX_ER LOC = "U20" | IOSTANDARD = "LVCMOS25"; NET ETHERNET_TXD[0] LOC = "U10" | IOSTANDARD = "LVCMOS25"; NET ETHERNET_TXD[1] LOC = "T10" | IOSTANDARD = "LVCMOS25"; NET ETHERNET_TXD[2] LOC = "AB8" | IOSTANDARD = "LVCMOS25"; NET ETHERNET_TXD[3] LOC = "AA8" | IOSTANDARD = "LVCMOS25"; NET ETHERNET_TXD[4] LOC = "AB9" | IOSTANDARD = "LVCMOS25"; NET ETHERNET_TXD[5] LOC = "Y9" | IOSTANDARD = "LVCMOS25"; NET ETHERNET_TXD[6] LOC = "Y12" | IOSTANDARD = "LVCMOS25"; NET ETHERNET_TXD[7] LOC = "W12" | IOSTANDARD = "LVCMOS25"; NET ETHERNET_TX_CLK LOC = "AB7" | IOSTANDARD = "LVCMOS25"; NET ETHERNET_TX_EN LOC = "T8" | IOSTANDARD = "LVCMOS25"; NET ETHERNET_TX_ER LOC = "U8" | IOSTANDARD = "LVCMOS25"; NET LEDs_4Bits_TRI_O[0] LOC = "D17" | IOSTANDARD = "LVCMOS25"; NET LEDs_4Bits_TRI_O[1] LOC = "AB4" | IOSTANDARD = "LVCMOS25"; NET LEDs_4Bits_TRI_O[2] LOC = "D21" | IOSTANDARD = "LVCMOS25"; NET LEDs_4Bits_TRI_O[3] LOC = "W15" | IOSTANDARD = "LVCMOS25"; NET Push_Buttons_4Bits_TRI_I[0] LOC = "F3" | IOSTANDARD = "LVCMOS25"; NET Push_Buttons_4Bits_TRI_I[1] LOC = "G6" | IOSTANDARD = "LVCMOS25"; NET Push_Buttons_4Bits_TRI_I[2] LOC = "F5" | IOSTANDARD = "LVCMOS25"; NET Push_Buttons_4Bits_TRI_I[3] LOC = "C1" | IOSTANDARD = "LVCMOS25"; NET RESET LOC = "H8" | IOSTANDARD = "LVCMOS15" | TIG; NET RS232_Uart_1_sin LOC = "H17" | IOSTANDARD = "LVCMOS25"; NET RS232_Uart_1_sout LOC = "B21" | IOSTANDARD = "LVCMOS25"; # # additional constraints # NET "CLK" TNM_NET = sys_clk_pin; TIMESPEC TS_sys_clk_pin = PERIOD sys_clk_pin 200000 kHz; ###### Soft ETHERNET # This is a GMII system # AXI_STR_*_ACLK is not the same as S_AXI_ACLK from clock generator # Rx/Tx Client clocks are Rx/Tx PHY clocks so CORE Gen PHY clock constraints propagate to Rx/Tx client clock periods # Time domain crossing constraints (DATAPATHONLY) are set for maximum bus frequency # allowed by IP which is the maximum option in BSB. For lower bus frequency choice in BSB, # the constraints are over constrained. Relaxing them for your system may reduce build time. NET "*ETHERNET*/S_AXI_ACLK" TNM_NET = "axi4lite_clk"; NET "*ETHERNET*/AXI_STR_TXD_ACLK" TNM_NET = "axistream_clk"; NET "*ETHERNET*/AXI_STR_TXC_ACLK" TNM_NET = "axistream_clk"; NET "*ETHERNET*/AXI_STR_RXD_ACLK" TNM_NET = "axistream_clk"; NET "*ETHERNET*/AXI_STR_RXS_ACLK" TNM_NET = "axistream_clk"; ############################################################ # Clock Period Constraints # ############################################################ ############################################################ # RX Clock period Constraints # ############################################################ # Ethernet GMII PHY-side receive clock # __________ # | | # --- GMII_RX_CLK-----| BUFR |---Rx_Client_Clk # |__________| # # Receiver clock period constraints: please do not relax # Changed NET name # Changed TNM_NET name from CoreGen name to be consistent in # EDK constraints # NET "*/rx_gmii_clk_int" TNM_NET = "clk_rx"; NET "*/GMII_RX_CLK" TNM_NET = "phy_clk_rx"; # Added TIMEGRP for later DATAPATHONLY constraint TIMEGRP "rx_clock" = "phy_clk_rx"; TIMESPEC "TS_rx_clk" = PERIOD "rx_clock" 8000 ps HIGH 50 %; ############################################################ # TX Clock period Constraints # ############################################################ ############################################################ # TIG for BUFGMUX SPEED CLK: please do not edit # ############################################################ # Want to TIG any timing paths to the select of the TX clock BUFGMUXs # at this point and subsequent constraints can override. MII_TX_CLK # will remained TIG so that path is not used in any setup/hold timing # analysis. # Changed net name in synthesis of axi_ethernet # PIN "*clock_inst*BUFGMUX*.I?" TNM="clk_bufgmux"; PIN "*I_CLOCK_INST*/*BUFGMUX_SPEED_CLK.I?" TNM="clk_bufgmux"; TIMESPEC "TS_bufgmux" = FROM "async_config" TO "clk_bufgmux" TIG; ############################################################################### # The following two TimeSpecs are from CoreGen Ethernet Core Example Design UCF # file. In systems GTX_CLK is driven by clock generator core, then the derived # period constraint will override these TimeSpecs. ############################################################################### # Ethernet GTX_CLK high quality 125 MHz reference clock # __________ # -GTX_CLK------------| | # | BUFGMUX |---Tx_Client_Clk # -MII_TX_CLK---------|__________| # # Depending on system configuration, the analysis tool may use either gtx_clk # or tx_client_clk so both nets are used in defining PERIOD constraint and # TNM_NETS for subsequent constraints. # The PERIOD constraints may not be analyzed if inferred clock generator # constraints are generated for the system. # Transmitter clock period constraints: please do not relax # Changed NET name # NET "gtx_clk*" TNM_NET = "clk_gtx"; NET "*/GTX_CLK" TNM_NET = "clk_gtx"; # Added TIMEGRP for later DATAPATHONLY constraint TIMEGRP "gtx_clock" = "clk_gtx"; TIMESPEC "TS_gtx_clk" = PERIOD "gtx_clock" 8000 ps HIGH 50 %; # Changed NET name # Changed TNM_NET name from CoreGen name to be consistent in # EDK constraints # NET "*tx_gmii_clk" TNM_NET = "clk_tx_gmii"; NET "*/GMII.tx_gmii_clk_int" TNM_NET = "phy_clk_tx"; TIMEGRP "tx_clock_gmii" = "phy_clk_tx"; TIMESPEC "TS_tx_clk_gmii" = PERIOD "tx_clock_gmii" 8000 ps HIGH 50 %; ############################################################ # Host Clock period Constraint # ############################################################ # Management Clock period constraints: relax as required # Changed NET name # NET "host_clk" TNM_NET = "host"; NET "*/S_AXI_ACLK" TNM_NET = "host_clk"; TIMEGRP "host" = "host_clk" EXCEPT "mdio_logic"; TIMESPEC "TS_host_clk" = PERIOD "host" 10000 ps HIGH 50 % PRIORITY 10; ############################################################ # External GMII Constraints # ############################################################ # GMII Transmitter Constraints: place flip-flops in IOB # Changed 'true' to 'force' # Shortened INST names to remove internal hierarchy # INST "*trimac_block*gmii_interface*gmii_txd*" IOB = true; # INST "*trimac_block*gmii_interface*gmii_tx_en" IOB = true; # INST "*trimac_block*gmii_interface*gmii_tx_er" IOB = true; INST "*gmii_txd*" IOB = force; INST "*gmii_tx_en" IOB = force; INST "*gmii_tx_er" IOB = force; # GMII Receiver Constraints: place flip-flops in IOB # Changed 'true' to 'force' # Shortened INST names to remove internal hierarchy # INST "*trimac_block*gmii_interface*rxd_to_mac*" IOB = true; # INST "*trimac_block*gmii_interface*rx_dv_to_mac" IOB = true; # INST "*trimac_block*gmii_interface*rx_er_to_mac" IOB = true; INST "*rxd_to_mac*" IOB = force; INST "*rx_dv_to_mac" IOB = force; INST "*rx_er_to_mac" IOB = force; ############################################################ # The following are required to maximize setup/hold # ############################################################ # Changed to add Drive strength and INST Name # INST "gmii_txd" SLEW = FAST; # INST "gmii_tx_en" SLEW = FAST; # INST "gmii_tx_er" SLEW = FAST; # INST "gmii_tx_clk" SLEW = FAST; INST "ETHERNET_TXD_?_OBUF" SLEW = FAST; INST "ETHERNET_TX_EN_OBUF" SLEW = FAST; INST "ETHERNET_TX_ER_OBUF" SLEW = FAST; INST "ETHERNET_TX_CLK_OBUF" SLEW = FAST; ############################################################ # GMII: IODELAY Constraints # ############################################################ # Please modify the value of the IDELAY_VALUE # according to your design. # For more information on IDELAYCTRL and IODELAY, please # refer to the Spartan-6 User Guide. # INST "*delay_gmii_rx_dv" IDELAY_VALUE = 6; INST "*delay_gmii_rx_er" IDELAY_VALUE = 6; INST "*data_bus[0].delay_gmii_rxd" IDELAY_VALUE = 6; INST "*data_bus[1].delay_gmii_rxd" IDELAY_VALUE = 6; INST "*data_bus[2].delay_gmii_rxd" IDELAY_VALUE = 6; INST "*data_bus[3].delay_gmii_rxd" IDELAY_VALUE = 6; INST "*data_bus[4].delay_gmii_rxd" IDELAY_VALUE = 6; INST "*data_bus[5].delay_gmii_rxd" IDELAY_VALUE = 6; INST "*data_bus[6].delay_gmii_rxd" IDELAY_VALUE = 6; INST "*data_bus[7].delay_gmii_rxd" IDELAY_VALUE = 6; # Group IODELAY and IDELAYCTRL components to aid placement # INST "*delay_gmii_rx_clk" IODELAY_GROUP = "grp1"; INST "*delay_gmii_rx_dv" IODELAY_GROUP = "grp1"; INST "*delay_gmii_rx_er" IODELAY_GROUP = "grp1"; INST "*delay_gmii_rxd" IODELAY_GROUP = "grp1"; # INST "*dlyctrl" IODELAY_GROUP = "grp1"; # Changed to let the tools pick the LOC # INST *trimac_block*clock_inst*BUFGMUX_SPEED_CLK LOC = BUFGMUX_X3Y13; ############################################################ # For Setup and Hold time analysis on GMII inputs # ############################################################ # Identify GMII Rx Pads only. # This prevents setup/hold analysis being performed on false inputs, # eg, the configuration_vector inputs. # Changed to remove TNM and changed INST Names # INST "gmii_rxd" TNM = IN_GMII; # INST "gmii_rx_er" TNM = IN_GMII; # INST "gmii_rx_dv" TNM = IN_GMII; # Define data valid window with respect to the clock. # The spec states that, worst case, the data is valid 2 ns before the clock edge. # The worst case it to provide zero hold time (a 2ns window in total) # Changed to remove TIMEGRP # TIMEGRP "IN_GMII" OFFSET = IN 2 ns VALID 2 ns BEFORE "gmii_rx_clk"; # Set to allow for 100ps setup/hold trace delay difference in relation to clock OFFSET = IN 2.4 ns VALID 2.8 ns BEFORE "ETHERNET_RX_CLK"; ############################################################ # Crossing of Clock Domain Constraints: please do not edit # ############################################################ # Flow Control logic reclocking - control signal is synchronised # Changed net name in synthesis of axi_ethernet # INST "*trimac_core*FLOW?RX_PAUSE?PAUSE_REQ_TO_TX" TNM="flow_rx_to_tx"; # INST "*trimac_core*FLOW?RX_PAUSE?PAUSE_VALUE_TO_TX*" TNM="flow_rx_to_tx"; INST "*/I_FLOW/I_RX_PAUSE/PAUSE_REQ_TO_TX" TNM="flow_rx_to_tx"; INST "*/I_FLOW/I_RX_PAUSE/PAUSE_VALUE_TO_TX*" TNM="flow_rx_to_tx"; TIMESPEC "TS_flow_rx_to_tx" = FROM "flow_rx_to_tx" TO phy_clk_tx 8000 ps DATAPATHONLY; # Generate a group of all flops NOT in the host clock domain TIMEGRP "all_ffs" = FFS; TIMEGRP "ffs_except_host" = "all_ffs" EXCEPT "host"; # Configuration Register reclocking # Changed net name in synthesis of axi_ethernet # INST "*trimac_core*MANIFGEN?MANAGEN?CONF?RX0_OUT*" TNM="async_config"; # INST "*trimac_core*MANIFGEN?MANAGEN?CONF?RX1_OUT*" TNM="async_config"; # INST "*trimac_core*MANIFGEN?MANAGEN?CONF?FC_OUT_29" TNM="async_config"; INST "*/MANIFGEN.I_MANAGEN/I_CONF/RX0_OUT*" TNM="async_config"; INST "*/MANIFGEN.I_MANAGEN/I_CONF/RX1_OUT*" TNM="async_config"; INST "*/MANIFGEN.I_MANAGEN/I_CONF/FC_OUT_29" TNM="async_config"; # INST "*trimac_core*MANIFGEN?MANAGEN?CONF?TX_OUT*" TNM="async_config"; # INST "*trimac_core*MANIFGEN?MANAGEN?CONF?FC_OUT_30" TNM="async_config"; INST "*/MANIFGEN.I_MANAGEN/I_CONF/TX_OUT*" TNM="async_config"; INST "*/MANIFGEN.I_MANAGEN/I_CONF/FC_OUT_30" TNM="async_config"; # Speed change config # Changed net name in synthesis of axi_ethernet # INST "*trimac_core*MANIFGEN?MANAGEN?CONF?CNFG_SPEED*" TNM="async_config"; # INST "*trimac_core*SPEED_IS*" TNM="async_config"; INST "*/MANIFGEN.I_MANAGEN/I_CONF/CNFG_SPEED*" TNM="async_config"; INST "*/I_?XGEN/*SPEED*" TNM="async_config"; # Changed to comment out. # In BSB systems the Host_clk = S_AXI_ACLK. Since the CORE Gen TIG'd constraints below # are affecting axi_ethernet DATAPATHONLY constraints above (at start of Soft_Ethernet_MAC constraints) # these paths are commented out in favor of using the DATAPATHONLY constraints. The constraints are: # "TS_axi4lite_clk_clk_2_TX_CLIENT_CLK" and "TS_TX_CLIENT_CLK_2_axi4lite_clk_clk" # TIMESPEC "TS_host_clk_to_rx_clk" = FROM "host" TO "rx_clock" TIG; # TIMESPEC "TS_host_clk_to_tx_clk" = FROM "host" TO "tx_clock_gmii" TIG; TIMESPEC "TS_config_to_all" = FROM "async_config" TO "ffs_except_host" TIG; # Address filter specific cross clocking # Changed net name in synthesis of axi_ethernet # INST "*trimac_core*addr_filter_top/dynamic_af_gen.dynamic_config/unicast_addr_*" TNM="addr_config_to_rx"; INST "*/I_ADDR_FILTER_TOP/dynamic_af_gen.I_DYNAMIC_CONFIG/unicast_addr_*" TNM="addr_config_to_rx"; TIMESPEC "TS_addr_config_to_rx" = FROM "addr_config_to_rx" TO "ffs_except_host" TIG; ############################################################ # Ignore paths to resync flops # ############################################################ # Changed to replace TIG with DATAPATHONLY constraints # INST "*data_sync" TNM = "resync_reg"; # TIMESPEC "ts_resync_flops" = TO "resync_reg" TIG; ###################################################################### # MDIO Constraints: please do not edit unless TS_host_clk is relaxed # # in which case the multiplier needs to be adjusted to give the # # required 400ns (or faster) # ###################################################################### # Place the MDIO logic in it's own timing groups # Changed net name in synthesis of axi_ethernet # INST "*trimac_core*MANIFGEN?MANAGEN?PHY?ENABLE_REG" TNM = "mdio_logic"; # INST "*trimac_core*MANIFGEN?MANAGEN?PHY?READY_INT" TNM = "mdio_logic"; # INST "*trimac_core*MANIFGEN?MANAGEN?PHY?STATE_COUNT*" TNM = FFS "mdio_logic"; # INST "*trimac_core*MANIFGEN?MANAGEN?PHY?MDIO_TRISTATE" TNM = "mdio_logic"; # INST "*trimac_core*MANIFGEN?MANAGEN?PHY?MDIO_OUT" TNM = "mdio_logic"; INST "*/I_RXGEN/ENABLE_REG" TNM = "mdio_logic"; INST "*/MANIFGEN.I_MANAGEN/MIIM_READY_INT" TNM = "mdio_logic"; INST "*/MANIFGEN.I_MANAGEN/I_PHY/STATE_COUNT*" TNM = FFS "mdio_logic"; INST "*/MANIFGEN.I_MANAGEN/I_PHY/MDIO_TRISTATE" TNM = "mdio_logic"; INST "*/MANIFGEN.I_MANAGEN/I_PHY/MDIO_OUT" TNM = "mdio_logic"; # The MDIO logic is constrained to a 400ns period. this is generated by relating the required # period to that specified for host_clk. This ensures the two clocks are related timed # correctly. TIMESPEC "TS_mdio" = PERIOD "mdio_logic" "TS_host_clk" * 40 PRIORITY 0; ############################################################ # Crossing of Clock Domain Constraints: please do not edit # # In addition to CoreGen constraints # ############################################################ # The following TimeSpecs are required only when AXILite clock differs from AXI-Stream clock # Data path timing depends on the destination clock period TIMESPEC "TS_axistreamclks_2_axi4liteclks" = FROM axistream_clk TO axi4lite_clk 20000 ps DATAPATHONLY; #assumes axi4lite_clk <= 50 MHz TIMESPEC "TS_axi4liteclks_2_axistreamclks" = FROM axi4lite_clk TO axistream_clk 8333 ps DATAPATHONLY; #assumes axistream_clk <= 120 MHz # TNM_NET phy_clk_rx is rx_client_clk # TIMESPECs for AXI streaming clock crossing to/from rx_client_clk TIMESPEC "TS_axistreamclks_2_RX_CLIENT_CLK" = FROM axistream_clk TO phy_clk_rx 8000 ps DATAPATHONLY; #assumes phy_clk_rx <= 125 MHz TIMESPEC "TS_RX_CLIENT_CLK_2_axistreamclks" = FROM phy_clk_rx TO axistream_clk 8333 ps DATAPATHONLY; #assumes axistream_clk <= 120 MHz # TIMESPECs for AXI-Lite clock crossing to/from tx_client_clk TIMESPEC "TS_axi4liteclks_2_RX_CLIENT_CLK" = FROM axi4lite_clk TO phy_clk_rx 8000 ps DATAPATHONLY; #assumes phy_clk_rx <= 125 MHz TIMESPEC "TS_RX_CLIENT_CLK_2_axi4liteclks" = FROM phy_clk_rx TO axi4lite_clk 20000 ps DATAPATHONLY; #assumes axi4lite_clk <= 50 MHz # Depending on system configuration, the analysis tool may use either TNM_NET clk_gtx # or TNM_NET phy_clk_tx so only one set will be analyzed # TNM_NET phy_clk_tx is tx_client_clk # TIMESPECs for AXI streaming clock crossing to/from tx_client_clk TIMESPEC "TS_axistreamclks_2_TX_CLIENT_CLK" = FROM axistream_clk TO phy_clk_tx 8000 ps DATAPATHONLY; #assumes phy_clk_tx <= 125 MHz TIMESPEC "TS_TX_CLIENT_CLK_2_axistreamclks" = FROM phy_clk_tx TO axistream_clk 8333 ps DATAPATHONLY; #assumes axistream_clk <= 120 MHz # TIMESPECs for AXI-Lite clock crossing to/from tx_client_clk TIMESPEC "TS_axi4liteclks_2_TX_CLIENT_CLK" = FROM axi4lite_clk TO phy_clk_tx 8000 ps DATAPATHONLY; #assumes phy_clk_tx <= 125 MHz TIMESPEC "TS_TX_CLIENT_CLK_2_axi4liteclks" = FROM phy_clk_tx TO axi4lite_clk 20000 ps DATAPATHONLY; #assumes axi4lite_clk <= 50 MHz # TNM_NET clk_gtx is */GTX_CLK # TIMESPECs for AXI Streaming clock crossing to/from */GTX_CLK TIMESPEC "TS_axistreamclks_2_GTX_CLK" = FROM axistream_clk TO clk_gtx 8000 ps DATAPATHONLY; #assumes clk_gtx <= 125 MHz TIMESPEC "TS_GTX_CLK_2_axistreamclks" = FROM clk_gtx TO axistream_clk 8333 ps DATAPATHONLY; #assumes axistream_clk <= 120 MHz # TIMESPECs for AXI-Lite clock crossing to/from */GTX_CLK TIMESPEC "TS_axi4lite_clk_2_GTX_CLK" = FROM axi4lite_clk TO clk_gtx 8000 ps DATAPATHONLY; #assumes clk_gtx <= 125 MHz TIMESPEC "TS_GTX_CLK_2_axi4lite_clk" = FROM clk_gtx TO axi4lite_clk 20000 ps DATAPATHONLY; #assumes axi4lite_clk <= 50 MHz # Depending on system configuration, the analysis tool may use either TNM_NET clk_gtx # or TNM_NET phy_clk_tx so only one set will be analyzed # Rx Clock crossings - Some paths are analyzed by the TS_flow_rx_to_tx constraint also # Needed since ts_resync_flops is commented out TIMESPEC "TS_RX_CLIENT_CLK_2_TX_CLIENT_CLK" = FROM phy_clk_rx TO phy_clk_tx 8000 ps DATAPATHONLY; #assumes phy_clk_tx <= 125 MHz TIMESPEC "TS_TX_CLIENT_CLK_2_RX_CLIENT_CLK" = FROM phy_clk_tx TO phy_clk_rx 8000 ps DATAPATHONLY; #assumes phy_clk_rx <= 125 MHz TIMESPEC "TS_RX_CLIENT_CLK_2_GTX_CLK" = FROM phy_clk_rx TO clk_gtx 8000 ps DATAPATHONLY; #assumes phy_clk_tx <= 125 MHz TIMESPEC "TS_GTX_CLK_2_RX_CLIENT_CLK" = FROM clk_gtx TO phy_clk_rx 8000 ps DATAPATHONLY; #assumes phy_clk_rx <= 125 MHz